Kevo Plus door locks now working in Home Assistant

Maybe attempt to install python2 on the homeassistant account?

sudo apt-get install python2.7

I’ve updated the library to work in python3 to eliminate the issues your having. I’ll update this post tonight with more details.

I have updated the pykevoplus library written by cseelye to python3. The installation is a bit different as is some of the scripting.

I have hopes that someone will eventually pick up from where I have left off and create a full fledged component for using the pykevoplus library. As it stands now, we have very basic status information, and the ability to lock and unlock the device. There is currently no proper error handling or any ability to alert the user to bolt jams or low battery situations.

These instructions assume that you’re running within a virtual environment on a raspberry pi, so you may have to adjust directories slightly You will need to create additional scripts for each lock. These instructions only cover a single lock named "front door."

1. Install pykevoplus v2.0

$ wget -O pykevoplus_v2.0.tar.gz https://github.com/Bahnburner/pykevoplus/archive/v2.0.tar.gz
$ sudo pip3 install pykevoplus_v2.0.tar.gz

2. Create directories for your scripts

$ mkdir /home/hass/.homeassistant/kevo
$ cd /home/hass/.homeassistant/kevo

3. Get your Lock ID’s

$ python
>>> from pykevoplus import Kevo
>>> locks = Kevo.GetLocks("***USERNAME***", "***PASSWORD***")
>>> for lock in locks:
...    print(repr(lock))
...

Output

KevoLock(name=Front Door, id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, state=Locked)

We will be using the lock ID returned from that command in the following scripts

4. Create the following files in /home/hass/.homeassistant/kevo
status-front.py

from pykevoplus import KevoLock
lock = KevoLock.FromLockID("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "***USERNAME***", "***PASSWORD***")
print(lock.GetBoltState())

lock-front.py

from pykevoplus import KevoLock
lock = KevoLock.FromLockID("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "***USERNAME***", "***PASSWORD***")
lock.Lock()
print(lock.GetBoltState())

unlock-front.py

from pykevoplus import KevoLock
lock = KevoLock.FromLockID("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "***USERNAME***", "***PASSWORD***")
lock.Unlock()
print(lock.GetBoltState())

5. Fix permissions

$ chmod 755 -R ./

6. Add the switch to your configuration.yaml

- platform: command_line
  scan_interval: 30
  switches:
    door_front:
      command_on: "python3 /home/hass/.homeassistant/kevo/lock-front.py"
      command_off: "python3 /home/hass/.homeassistant/kevo/unlock-front.py"
      command_state: "python3 /home/hass/.homeassistant/kevo/status-front.py"
      value_template: >
        {% if value == "Locked" %}
          true
        {% elif value == "Unlocked" %}
          false
        {% else %}
        {% endif %}

Why not turn this into an official HA component? Have you reached out to the HA core team to see if this is something they would allow a PR for?

I’m on the market for a smart lock now, and would only go the BT (Kevo) route if I could get it working with HA and have “One-Touch” unlock. Having to pull out the phone and open an app, or manually entering in a code just seems old school to me. Might as well just pull out yer key.

Sounds like this Kevo/HA integration is still very much a shim with limited functionality.

I don’t have enough knowledge of python to migrate this to a full HA component. I’ve asked a few other devs if they would like to take on the project, but without a device to test on, none were willing to help.

I’ve gone ahead and created a custom component and it all seems to work on my own setup. If you get your python3 version of pykevoplus onto PyPI, then my custom component can be fully released and potentially turned into a full official component.

1 Like

Holy crap. THANK YOU!

Let me work on that.

Done.

Uploaded as pykevocontrol, but the package still installs as pykevoplus to ensure there’s no changes needed to scripting.

I’m actually running into issues getting it to install your version of the package as a dependency. Once I get this figured out, I’ll throw it on github and let you play with it.

Interesting. Do you think it’s a issue with the new and old version sharing a package name? I can always change the entire project to pykevocontrol and reupload if it helps.

I tested on a fresh venv before uploading to pypi and had no issues installing or checking the status of my locks.

I don’t think it’s an issue on your part. For some reason, my home assistant install is not installing the dependency. I’ve gone and uploaded my latest version to github here. If you throw that kevo.py into your home assistant environment at CONFIG_DIRECTORY/custom_components/lock, you can then add

lock:
  platform: kevo
  email: [email protected]
  password: xxxxxxxx

to your configuration.yaml and you should be ready to roll.

Let me know how it works for you and if you run into any issues.

Just reuploaded a new commit of the custom component where I’ve fixed my stupid mistake. Let me know if you get a chance to try it.

I’ll be in installing it as soon as I get home. I was out with the wife running errands.

Working well so far.

Great. I’m going to put together what I need to submit this as a pull request so that it can be an official component included in a future HA release.

Awesome. Thank you for putting this component together.

I’ve ran into an issue when locking my doors. If the front door is locked and the back door is unlocked, running this script:

lock_doors:
  sequence:
    - service: lock.lock
      entity_id: lock.front_door
    - delay:
        seconds: 10
    - service: lock.lock
      entity_id: lock.back_door

results in this error:

2017-08-19 08:42:15 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/asyncio/tasks.py", line 181, in _step
    result = coro.throw(exc)
  File "/srv/hass/lib/python3.6/site-packages/homeassistant/core.py", line 1025, in _event_to_service_call
    yield from service_handler.func(service_call)
  File "/srv/hass/lib/python3.6/site-packages/homeassistant/components/lock/__init__.py", line 95, in async_handle_lock_service
    yield from entity.async_lock(code=code)
  File "/usr/local/lib/python3.6/asyncio/futures.py", line 331, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/local/lib/python3.6/asyncio/tasks.py", line 244, in _wakeup
    future.result()
  File "/usr/local/lib/python3.6/asyncio/futures.py", line 244, in result
    raise self._exception
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/hass/.homeassistant/custom_components/lock/kevo.py", line 58, in lock
    self._kevo.Lock()
  File "/srv/hass/lib/python3.6/site-packages/pykevoplus/__init__.py", line 108, in _wrapped
    return method(self, *args, **kwargs)
  File "/srv/hass/lib/python3.6/site-packages/pykevoplus/__init__.py", line 253, in Lock
    self.WaitForLocked()
  File "/srv/hass/lib/python3.6/site-packages/pykevoplus/__init__.py", line 235, in WaitForLocked
    self._WaitForState("locked", timeout)
  File "/srv/hass/lib/python3.6/site-packages/pykevoplus/__init__.py", line 108, in _wrapped
    return method(self, *args, **kwargs)
  File "/srv/hass/lib/python3.6/site-packages/pykevoplus/__init__.py", line 197, in _WaitForState
    raise KevoError("Timeout waiting for {}".format(state.lower()))
pykevoplus.KevoError: Timeout waiting for locked

I wrote a quick script to add some logic and only send lock requests to unlocked doors and am no longer receiving the error. It looks like the component panics if we try to lock an already locked door.

I am researching a future purchase of a smart lock. Does anyone know if this will work with hassio?

I’m not extremely familiar with hassio, but so long as you can install custom components into your install, it should.

Just tried to install this component in Hass.io and I’m getting the following error on startup:

Error while setting up platform kevo
Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/homeassistant/helpers/entity_component.py", line 171, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT, loop=self.hass.loop)
  File "/usr/lib/python3.6/asyncio/tasks.py", line 352, in wait_for
    return fut.result()
  File "/usr/lib/python3.6/asyncio/futures.py", line 244, in result
    raise self._exception
  File "/usr/lib/python3.6/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/lock/kevo.py", line 32, in setup_platform
    kevos = Kevo.GetLocks(email, password)
  File "/config/deps/lib/python3.6/site-packages/pykevoplus/__init__.py", line 88, in GetLocks
    lock_id = lock_info.get("data-lock-id")
AttributeError: 'NoneType' object has no attribute 'get'