Anki Vector integration

Anybody get any further with this

Hey guys, I’m bumping this thread to let you know that Vector 2.0 is finally out for pre-order, including the Escape Pod (it’s the ability to host Vector’s server on a RPI) !!! :smiley:
I just pre ordered it (Vector 2.0 Advanced AI / Companion Robot | Digital Dream Labs), will let you guys know as soon as I receive it to try to host the Escape Pod on Hassio !

1 Like

Came in here to say just this, escape pod sounds like an amazing extension to Home Assistant! I would love Vector to be the face of my HA!

Anything new?

cyb3rdog has created s Docker image for Escape Pod which we might be able to add as a local add on to HA and work from there…

Hi Vector Owners,
I’ve been working on getting the python SDK to work with Home Assistant.
I’ve created a modified addon for AppDaemon 4 with the SDK installed and certificates, creating a python script I have got it polling Vector every 5 mins.
It will automatically create entities within HA if they don’t exist.
Its quite a hacky way of doing it all but will allow you to create some automations with Vector - this could be improved massively.
I have only started playing with Python, so if you come up with any improvements - Please share with everyone and me :slight_smile:

I have worked out an easier solution for everyone to install the SDK within the official AppDaemon 4 addon which I recommend playing with first instead of creating a local addon (which has some benefits).

I have written some instructions below which will assume that you’re familiar with Vector’s SDK and Home Assistant, particularly SSH / FTP in to your Home Assistant.

  1. Install the official AppDaemon 4 addon

  2. Add the following lines in the configuration page:

init_commands:
  - python3 -m anki_vector.configure
  - 'y'
  - '!secret vector_id'
  - '!secret vector_ip'
  - '!secret vector_serial'
  - '!secret vector_email'
  - '!secret vector_password'
python_packages:
  - cyb3r_vector_sdk
system_packages:
  - py3-pillow
  - py3-numpy
  1. SSH (SFTP) in to /config then open secret.yaml
    Enter your credentials below for the SDK inside secret.yaml
vector_id: Vector-0000 #Vectors Name
vector_ip: 192.168.***.*** #Vectors IP
vector_serial: '00000000' #Vectors Serial#
vector_email: [email protected] #Email address used for Vector
vector_password: P@55w0rd #Password used for Vector
  1. SSH (SFTP) in to /config and open configuration.yaml, copy & paste the below in to the file:
camera:
  - platform: local_file
    name: VectorCam
    file_path: /config/www/vectorcam.jpg
  1. SSH (SFTP) in to /config/www, download the image below Vector Cam Disabled and place in /www directory. Ensure its names as ‘vectorcamdisabled.jpg’.

  2. SSH (SFTP) in to /config/appdaemon/apps - create a file called vector.py

  3. Open vector.py then copy & paste my example below and save:

import appdaemon.plugins.hass.hassapi as hass
import anki_vector
from PIL import Image
import datetime


class VectorWorld(hass.Hass):
  def initialize(self):
      self.listen_event(self.vector_event, "VECTOR_EVENT")
      self.listen_event(self.vector_camera, "VECTOR_CAMERA")
      runtime = datetime.datetime.now()
      addseconds = (round((runtime.minute*60 + runtime.second)/300)+1)*300
      runtime = runtime.replace(minute=0, second=0, microsecond=0) + datetime.timedelta(seconds=addseconds)
      self.run_every(self.vector_status,runtime,300) #300 = 5mins
 
  def vector_event(self, event_name, data, kwargs):
      self.log("Vector say Hello World...")
      with anki_vector.Robot("00000000") as robot: #Your Vector Serial Number
          robot.behavior.say_text("Hello World from Home Assistant")
          robot.conn.release_control()
 
  def vector_status(self, kwargs):
      self.log("Vector Status...")
      with anki_vector.Robot("00000000",behavior_control_level=None) as robot: #Your Vector Serial Number
          battery_state = robot.get_battery_state()
          version_state = robot.get_version_state()
          charger = battery_state.is_on_charger_platform
          self.set_state("sensor.VectorOS", state = "{0}".format(version_state.os_version), attributes = {"friendly_name": "Vector Software"}) 
          self.set_state("sensor.VectorCharger", state = "{0}".format(battery_state.is_charging), attributes = {"device_class": "plug","friendly_name": "Vector Charging"}) 
          self.set_state("sensor.VectoronCharger", state = "{0}".format(charger), attributes = {"device_class": "plug","friendly_name": "Vector On Charger"}) 
          self.set_state("sensor.Vectorchargertime", state = "{0}".format(battery_state.suggested_charger_sec), attributes = {"friendly_name": "Vector Charging Time"}) 
          self.set_state("sensor.VectorVoltage", state = "{:0.2f}".format(battery_state.battery_volts), attributes = {"state_class": "measurement","unit_of_measurement": "V","friendly_name": "Vector Voltage"})
          self.set_state("sensor.VectorBattery", state = "{0}".format(battery_state.battery_level), attributes = {"friendly_name": "Vector Battery Level"})
          self.log("Vectors battery is currently {:0.2f} volts".format(battery_state.battery_volts))
          if charger == 1 and self.get_state("input_boolean.vector_charger")=="off":
              self.log("Vector drive off charger...")
              robot.conn.request_control()
              robot.behavior.drive_off_charger()
              robot.conn.release_control()
              self.set_state("sensor.VectoronCharger", state = "False", attributes = {"device_class": "plug","friendly_name": "Vector On Charger"}) 
          elif charger == 0 and self.get_state("input_boolean.vector_charger")=="on":
              self.log("Vector drive on charger...")
              robot.conn.request_control()
              robot.behavior.drive_on_charger()
              robot.conn.release_control()
              self.set_state("sensor.VectoronCharger", state = "True", attributes = {"device_class": "plug","friendly_name": "Vector On Charger"}) 
          else:
              self.log("Vector ignore")
          if self.get_state("input_boolean.vectorcam")=="on":
              self.log("Camera enabled...")
              robot.conn.request_control()
              robot.camera.init_camera_feed()
              image = robot.camera.latest_image.raw_image
              rgb_im = image.convert("RGB") 
              rgb_im.save("/config/www/vectorcam.jpg") 
              robot.conn.release_control()
#              robot.close_camera_feed()
          else:
              self.log("Camera disabled...")
              rgb_im = Image.open("/config/www/vectorcamdisabled.jpg")
              rgb_im.save("/config/www/vectorcam.jpg")
#          robot.disconnect()
       
  def vector_camera(self, event_name, data, kwargs):
      self.log("Vectorcamera...")
      with anki_vector.Robot("00000000",behavior_control_level=None) as robot: #Your Vector Serial Number
          robot.camera.init_camera_feed()
          image = robot.camera.latest_image.raw_image
          rgb_im = image.convert("RGB") 
          rgb_im.save("/config/www/vectorcam.jpg") 
  1. In the same directory (/config/appdaemon/apps) open apps.yaml then copy & paste the below and save:
---
vector_test:
  module: vector
  class: VectorWorld
  1. Create two input booleans (toggle switches) in Home Assistant via Helpers.
    One called ‘VectorCam’ and one called ‘Vector Charger’.

  2. Start AppDaemon and monitor logs for any errors.

Ensure Vector is on and connected to your network.

The entities that will automatically create once the SDK successfully deploy and connect to Vector are:
sensor.vectorcharger Vector Charging
sensor.vectoroncharger Vector On Charger
sensor.vectorbattery Vector Battery Level
sensor.vectorchargertime Vector Charging Time
sensor.vectorvoltage Vector Voltage
sensor.vectoros Vector Software
input_boolean.vectorcam VectorCam
input_boolean.vector_charger Vector Charger

Hopefully I haven’t missed anything but I will update if I notice anything missing!

vectorcamdisabled|640x360



.

2 Likes

Hey Ryan,

This looks great but won’t work with escape pod, only the go sdk works with it as shown here: Escape Pod: Changelog, Limitations & Known Issues - Digital Dream Labs Knowledge Base
Any clues on how to change the sdk?

Hi GreyJackal,

If you use Cyb3rdog workaround for the SDK, it should in theory work with it but I haven’t tried that yet… I know the latest Escape Pod unfortunately breaks a few things with 3rd party extensions so believe you’ll have to stick with V1.

GitHub - cyb3rdog/escapepod_python_sdk: The EscapePod Python SDK for Cyb3rVector’s EscapePod Extension Proxy

Hey Ryan. Is this still working for you? I get an error when I try to do it:

ImportError: Error loading shared library ld-linux-armhf.so.3: No such file or directory (needed by /usr/lib/python3.10/site-packages/grpc/_cython/cygrpc.cpython-310-arm-linux-gnueabihf.so)
[15:30:24] FATAL: Failed executing init command: python3 -m anki_vector.configure
cont-init: info: /etc/cont-init.d/appdaemon.sh exited 1
cont-init: warning: some scripts exited nonzero

@kaylasiemon
I haven’t tested it recently since HA has updated python to 3.10, looks like that is the issue due to cyb3rdogs SDK only supports up to 3.9.

1 Like

Only get 3 entities now…

Authenticating with Anki Cloud... DONE
Attempting to download guid from Vector-xxxx at 192.168.1.28:443... DONE
Writing config file to '/root/.anki_vector/sdk_config.ini'...
SUCCESS!
cont-init: info: /etc/cont-init.d/appdaemon.sh exited 0
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service legacy-services: starting
services-up: info: copying legacy longrun appdaemon (no readiness notification)
s6-rc: info: service legacy-services successfully started
[21:14:42] INFO: Starting AppDaemon...
2022-10-02 22:14:49.391186 INFO AppDaemon: AppDaemon Version 4.2.1 starting
2022-10-02 22:14:49.391569 INFO AppDaemon: Python version is 3.10.5
2022-10-02 22:14:49.391853 INFO AppDaemon: Configuration read from: /config/appdaemon/appdaemon.yaml
2022-10-02 22:14:49.392229 INFO AppDaemon: Added log: AppDaemon
2022-10-02 22:14:49.392621 INFO AppDaemon: Added log: Error
2022-10-02 22:14:49.393121 INFO AppDaemon: Added log: Access
2022-10-02 22:14:49.393489 INFO AppDaemon: Added log: Diag
2022-10-02 22:14:49.666237 INFO AppDaemon: Loading Plugin HASS using class HassPlugin from module hassplugin
2022-10-02 22:14:50.283146 INFO HASS: HASS Plugin Initializing
2022-10-02 22:14:50.283590 INFO HASS: HASS Plugin initialization complete
2022-10-02 22:14:50.284775 INFO AppDaemon: Initializing HTTP
2022-10-02 22:14:50.286380 INFO AppDaemon: Using 'ws' for event stream
2022-10-02 22:14:50.294727 INFO AppDaemon: Starting API
2022-10-02 22:14:50.300652 INFO AppDaemon: Starting Admin Interface
2022-10-02 22:14:50.301472 INFO AppDaemon: Starting Dashboards
2022-10-02 22:14:50.334188 INFO HASS: Connected to Home Assistant 2022.9.7
2022-10-02 22:14:50.361635 INFO AppDaemon: App 'vector_test' added
2022-10-02 22:14:50.363654 INFO AppDaemon: Found 1 total apps
2022-10-02 22:14:50.364678 INFO AppDaemon: Starting Apps with 1 workers and 1 pins
2022-10-02 22:14:50.366506 INFO AppDaemon: Running on port 5050
2022-10-02 22:14:50.396339 INFO AppDaemon: New client Admin Client connected
2022-10-02 22:14:50.467488 INFO HASS: Evaluating startup conditions
2022-10-02 22:14:50.486163 INFO HASS: Startup condition met: hass state=RUNNING
2022-10-02 22:14:50.486935 INFO HASS: All startup conditions met
2022-10-02 22:14:50.545005 INFO AppDaemon: Got initial state from namespace default
2022-10-02 22:14:52.386018 INFO AppDaemon: Scheduler running in realtime
2022-10-02 22:14:52.400392 INFO AppDaemon: Adding /config/appdaemon/apps to module import path
2022-10-02 22:14:52.405377 INFO AppDaemon: Loading App Module: /config/appdaemon/apps/vector.py
2022-10-02 22:14:53.474408 WARNING AppDaemon: No app description found for: /config/appdaemon/apps/hello.py - ignoring
2022-10-02 22:14:53.476570 INFO AppDaemon: Initializing app vector_test using class VectorWorld from module vector
2022-10-02 22:14:53.495037 INFO AppDaemon: App initialization complete
2022-10-02 22:16:24.953582 INFO AppDaemon: Client disconnection from Admin Client
2022-10-02 22:19:53.223064 INFO vector_test: Vector Status...
2022-10-02 22:19:53.227258 WARNING vector_test: ------------------------------------------------------------
2022-10-02 22:19:53.228109 WARNING vector_test: Unexpected error in worker for App vector_test:
2022-10-02 22:19:53.228938 WARNING vector_test: Worker Ags: {'id': '93fd326a91e946e78d858fe88267a035', 'name': 'vector_test', 'objectid': 'b156cd419a7649ca8a26929e6a3bd1c1', 'type': 'scheduler', 'function': <bound method VectorWorld.vector_status of <vector.VectorWorld object at 0x7fb9e2ebc0>>, 'pin_app': True, 'pin_thread': 0, 'kwargs': {'interval': 300, '__thread_id': 'thread-0'}}
2022-10-02 22:19:53.229594 WARNING vector_test: ------------------------------------------------------------
2022-10-02 22:19:53.233378 WARNING vector_test: Traceback (most recent call last):
  File "/usr/lib/python3.10/site-packages/appdaemon/threading.py", line 904, in worker
    funcref(self.AD.sched.sanitize_timer_kwargs(app, args["kwargs"]))
  File "/config/appdaemon/apps/vector.py", line 24, in vector_status
    with anki_vector.Robot("xxxxxxx",behavior_control_level=None) as robot: #Your Vector Serial Number
  File "/usr/lib/python3.10/site-packages/anki_vector/robot.py", line 758, in __enter__
    self.connect(self.behavior_activation_timeout)
  File "/usr/lib/python3.10/site-packages/anki_vector/robot.py", line 646, in connect
    self.conn.connect(timeout=timeout)
  File "/usr/lib/python3.10/site-packages/anki_vector/connection.py", line 483, in connect
    raise e
  File "/usr/lib/python3.10/site-packages/anki_vector/connection.py", line 496, in _connect
    self._control_events = _ControlEventManager(self._loop)
  File "/usr/lib/python3.10/site-packages/anki_vector/connection.py", line 86, in __init__
    self._granted_event = asyncio.Event(loop=loop)
  File "/usr/lib/python3.10/asyncio/locks.py", line 168, in __init__
    super().__init__(loop=loop)
  File "/usr/lib/python3.10/asyncio/mixins.py", line 17, in __init__
    raise TypeError(
TypeError: As of 3.10, the *loop* parameter was removed from Event() since it is no longer necessary
2022-10-02 22:19:53.234052 WARNING vector_test: ------------------------------------------------------------
2022-10-02 22:22:26.300097 INFO AppDaemon: New client Admin Client connected
2022-10-02 22:24:53.030793 INFO vector_test: Vector Status...
2022-10-02 22:24:53.036032 WARNING vector_test: ------------------------------------------------------------
2022-10-02 22:24:53.037248 WARNING vector_test: Unexpected error in worker for App vector_test:
2022-10-02 22:24:53.038400 WARNING vector_test: Worker Ags: {'id': '93fd326a91e946e78d858fe88267a035', 'name': 'vector_test', 'objectid': 'b156cd419a7649ca8a26929e6a3bd1c1', 'type': 'scheduler', 'function': <bound method VectorWorld.vector_status of <vector.VectorWorld object at 0x7fb9e2ebc0>>, 'pin_app': True, 'pin_thread': 0, 'kwargs': {'interval': 300, '__thread_id': 'thread-0'}}
2022-10-02 22:24:53.039680 WARNING vector_test: ------------------------------------------------------------
2022-10-02 22:24:53.041361 WARNING vector_test: Traceback (most recent call last):
  File "/usr/lib/python3.10/site-packages/appdaemon/threading.py", line 904, in worker
    funcref(self.AD.sched.sanitize_timer_kwargs(app, args["kwargs"]))
  File "/config/appdaemon/apps/vector.py", line 24, in vector_status
    with anki_vector.Robot("xxxxxxx",behavior_control_level=None) as robot: #Your Vector Serial Number
  File "/usr/lib/python3.10/site-packages/anki_vector/robot.py", line 758, in __enter__
    self.connect(self.behavior_activation_timeout)
  File "/usr/lib/python3.10/site-packages/anki_vector/robot.py", line 646, in connect
    self.conn.connect(timeout=timeout)
  File "/usr/lib/python3.10/site-packages/anki_vector/connection.py", line 483, in connect
    raise e
  File "/usr/lib/python3.10/site-packages/anki_vector/connection.py", line 496, in _connect
    self._control_events = _ControlEventManager(self._loop)
  File "/usr/lib/python3.10/site-packages/anki_vector/connection.py", line 86, in __init__
    self._granted_event = asyncio.Event(loop=loop)
  File "/usr/lib/python3.10/asyncio/locks.py", line 168, in __init__
    super().__init__(loop=loop)
  File "/usr/lib/python3.10/asyncio/mixins.py", line 17, in __init__
    raise TypeError(
TypeError: As of 3.10, the *loop* parameter was removed from Event() since it is no longer necessary
2022-10-02 22:24:53.042755 WARNING vector_test: ------------------------------------------------------------

Same issue, only 3 entities, no cam

2023-01-19 23:00:00.024194 WARNING vector_test: ------------------------------------------------------------
2023-01-19 23:00:00.026720 WARNING vector_test: Unexpected error in worker for App vector_test:
2023-01-19 23:00:00.027728 WARNING vector_test: Worker Ags: {'id': '0a634d3b2f4e4fc8a2f82cf1df94f73a', 'name': 'vector_test', 'objectid': '1024e361a1c749d8be424b392d371e5c', 'type': 'scheduler', 'function': <bound method VectorWorld.vector_status of <vector.VectorWorld object at 0x7fa52eca90>>, 'pin_app': True, 'pin_thread': 1, 'kwargs': {'interval': 300, '__thread_id': 'thread-1'}}
2023-01-19 23:00:00.028325 WARNING vector_test: ------------------------------------------------------------
2023-01-19 23:00:00.031980 WARNING vector_test: Traceback (most recent call last):
  File "/usr/lib/python3.10/site-packages/appdaemon/threading.py", line 904, in worker
    funcref(self.AD.sched.sanitize_timer_kwargs(app, args["kwargs"]))
  File "/config/appdaemon/apps/vector.py", line 24, in vector_status
    with anki_vector.Robot("00902a3f",behavior_control_level=None) as robot: #Your Vector Serial Number
  File "/usr/lib/python3.10/site-packages/anki_vector/robot.py", line 758, in __enter__
    self.connect(self.behavior_activation_timeout)
  File "/usr/lib/python3.10/site-packages/anki_vector/robot.py", line 646, in connect
    self.conn.connect(timeout=timeout)
  File "/usr/lib/python3.10/site-packages/anki_vector/connection.py", line 483, in connect
    raise e
  File "/usr/lib/python3.10/site-packages/anki_vector/connection.py", line 496, in _connect
    self._control_events = _ControlEventManager(self._loop)
  File "/usr/lib/python3.10/site-packages/anki_vector/connection.py", line 86, in __init__
    self._granted_event = asyncio.Event(loop=loop)
  File "/usr/lib/python3.10/asyncio/locks.py", line 168, in __init__
    super().__init__(loop=loop)
  File "/usr/lib/python3.10/asyncio/mixins.py", line 17, in __init__
    raise TypeError(
TypeError: As of 3.10, the *loop* parameter was removed from Event() since it is no longer necessary
2023-01-19 23:00:00.032575 WARNING vector_test: ------------------------------------------------------------

With the new piper / faster-whisper stuff is it plausible to add these inclusions to this process so we can have two-way communication with vector and home assistant?

Also, will the stuff above work with vector when he is not escape podded?

That’s cool. But it seems like this pulls information from the DDL cloud, rather than something like Wirepod or Escapepod.

@Hellman_x

Yes, It needed DDL servers to gain access to vector.
Now that the DDL servers are gone this won’t work anymore.

Can the code be refactored to work with wire-pod?

@NonaSuomy
I’m sure it can be done but it will require someone with the needed skills. It’s not that simple coz the python library will need updating too.

The good thing about it is that now it’s only needs to work with wirepod.l and no need to make it compatible with ddl anymore.

I would even be happy if someone could just make a wirepod GO addon that just dumps what you said to vector to the HA assist web API as that would be less susceptible to failure points like python versions etc. The Vector stats are cool. Much nicer to get him to do real work in HA. Command Assist would probably be the easiest and Notifications Services sent to wirepod for him to say stuff would be the next best.

I’ve been trying to make a Wire-Pod add-on for HA, I’ve got it running but I am not that familiar with HA add-ons / Docker.
I need to try and work out how to properly use the persistent storage within the Docker environment so that when HA is rebooted, the stored settings are not lost.
I think it might be the case that a bash script is written to copy over and copy back the relevant data files for Wire-Pod, before the chipper script is started.



For anyone that wants to give it a go, familiarise yourself with HA local add-on, how to FTP in to HA or create files within the addons folder.

Create a folder called wire-pod inside the addons directory

Create a Dockerfile inside /addons/wire-pod/, with the following:

ARG BUILD_FROM=ubuntu:jammy
# hadolint ignore=DL3006
FROM ${BUILD_FROM}

# Edit your timezone here:
ENV TZ=Europe/London
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# Install software
RUN apt-get update \
 && apt-get install -y \
    sudo \
    nano \
    git

# Setup Sudoers
RUN adduser --disabled-password --gecos '' wirepod
RUN adduser wirepod sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

# Switch to created wirepod user
USER wirepod

# Create /wire-pod directory
RUN sudo mkdir /wire-pod
RUN sudo chown -R wirepod:wirepod /wire-pod
RUN cd /wire-pod

# Download wire-pod
RUN git clone https://github.com/kercre123/wire-pod/ wire-pod

# Build wire-pod
WORKDIR /wire-pod
RUN chmod a+x ./setup.sh
RUN chmod a+x ./chipper/start.sh
RUN sudo STT=vosk ./setup.sh

# Start chipper
WORKDIR /wire-pod/chipper
CMD sudo /wire-pod/chipper/start.sh

Create a config.yaml inside /addons/wire-pod/, with the following:

---
name: Wire-Pod
version: 1.0
slug: wire-pod
description: Docker Ubuntu base for WirePod
url: https://github.com/hassio-addons/addon-ubuntu-base
webui: http://[HOST]:[PORT:8080]
arch:
  - aarch64
  - amd64
  - armv7
homeassistant_api: true
uart: true
ports:
  443/tcp: 443
  80/tcp: 80
  8080/tcp: 8080

Create a build.yaml inside /addons/wire-pod/, with the following:

---
build_from:
  aarch64: arm64v8/ubuntu:jammy
  amd64: amd64/ubuntu:jammy
  armv7: arm32v7/ubuntu:jammy

Give it a few minutes and then install within the ‘Add-on Store’ under local add-on

3 Likes

Thanks for sharing Ryan,

Hopefully I can try this out next weekend…

Happy new year :tada:

1 Like