Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nuki lock'n'go and unlatch services and add attributes #8687

Merged
merged 4 commits into from
Aug 7, 2017

Conversation

pschmitt
Copy link
Contributor

@pschmitt pschmitt commented Jul 28, 2017

Description:

The Nuki locks have a Lock'n'go feature which consists in unlocking, waiting for a certain amount of time (20 seconds by default) then locking again.
https://nuki.io/en/support/smart-lock/sl-features/locking-with-the-smart-lock/

Also there is an unlatch function which will effectively open the door.

TL;DR

  • Add 2 new services: nuki.nuki_lock_n_go and nuki.nuki_unlatch
  • Add 2 new attributes: battery_critical and nuki_id

Related issue (if applicable): Fixes #5988

Pull request in home-assistant.github.io with documentation (if applicable): home-assistant/home-assistant.io#3078

Example entry for configuration.yaml (if applicable):

lock:
  - platform: nuki
    host: 192.168.10.13
    token: XXXXXXX

Checklist:

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • New dependencies have been added to the REQUIREMENTS variable ([example][ex-requir]).
  • New dependencies are only imported inside functions that use them ([example][ex-import]).
  • New dependencies have been added to requirements_all.txt by running script/gen_requirements_all.py.
  • New files were added to .coveragerc.

"""Callback when entity is added to hass."""
if not DOMAIN in self.hass.data:
self.hass.data[DOMAIN] = {}
if not 'lock' in self.hass.data[DOMAIN]:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test for membership should be 'not in'

@asyncio.coroutine
def async_added_to_hass(self):
"""Callback when entity is added to hass."""
if not DOMAIN in self.hass.data:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test for membership should be 'not in'

@pschmitt pschmitt changed the title WIP: Add lock'n'go service WIP: Add nuki lock'n'go and unlatch services and add attributes Jul 28, 2017
@pschmitt pschmitt changed the title WIP: Add nuki lock'n'go and unlatch services and add attributes Add nuki lock'n'go and unlatch services and add attributes Jul 28, 2017
@@ -5,27 +5,47 @@
https://home-assistant.io/components/lock.nuki/
"""
from datetime import timedelta
from os import path
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this line below import logging.

@@ -5,27 +5,47 @@
https://home-assistant.io/components/lock.nuki/
"""
from datetime import timedelta
from os import path
import asyncio
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this line above from datatime...

ATTR_BATTERY_CRITICAL = 'battery_critical'
ATTR_NUKI_ID = 'nuki_id'
ATTR_UNLATCH = 'unlatch'
DOMAIN = 'nuki'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Platforms always inherit the domain from their base component, in this case that's lock. You should call this constant something else, like NUKI_DATA. You can import DOMAIN too from homeassistant.components.lock and use that below in the service handler.

def service_handler(service):
"""Service handler for nuki services."""
entity_ids = extract_entity_ids(hass, service)
all_locks = hass.data[DOMAIN]['lock']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update to use the new name for 'nuki' eg:

all_locks = hass.data[NUKI_DATA][DOMAIN]

entity_ids = extract_entity_ids(hass, service)
all_locks = hass.data[DOMAIN]['lock']
target_locks = []
if entity_ids is None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extract_entity_ids will return an empty list if missing entity_id in service data. It won't return None. Just change to:

if not entity_ids:



class NukiLock(LockDevice):
"""Representation of a Nuki lock."""

def __init__(self, nuki_lock):
def __init__(self, nuki_lock, hass):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't pass in hass. It will be set on the entity when it's added to home assistant.

"""Initialize the lock."""
self.hass = hass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove.

@asyncio.coroutine
def async_added_to_hass(self):
"""Callback when entity is added to hass."""
if DOMAIN not in self.hass.data:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use NUKI_DATA instead of DOMAIN, and DOMAIN instead of 'lock' in this method.

@@ -72,3 +140,15 @@ def lock(self, **kwargs):
def unlock(self, **kwargs):
"""Unlock the device."""
self._nuki_lock.unlock()

def lock_n_go(self, **kwargs):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def lock_n_go(self, unlatch=False, **kwargs):

ATTR_BATTERY_CRITICAL: self._battery_critical,
ATTR_NUKI_ID: self._nuki_lock.nuki_id}
return data

@Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is old code, but Throttle should only be used in a common data instance method to protect from multiple updates from different entity against a common API. Applying the throttle here will just limit updates for the same NukiLock entity. It will not limit updates from other NukiLock entities during the same time. So for this use case, there's already built in functionality in the EntityComponent class that the lock base component uses. Just define SCAN_INTERVAL in this module if you want to override the default SCAN_INTERVAL = timedelta(seconds=30).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll just remove that. There is no reason to alter the scan interval here.

@MartinHjelmare MartinHjelmare self-assigned this Aug 7, 2017
Copy link
Member

@MartinHjelmare MartinHjelmare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two fixes left, then this is good to merge.

@@ -80,19 +79,18 @@ def service_handler(service):
path.join(path.dirname(__file__), 'services.yaml'))

hass.services.register(
DOMAIN, SERVICE_LOCK_N_GO, service_handler,
NUKI_DATA, SERVICE_LOCK_N_GO, service_handler,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, services are registered under the base component domain, even from the platforms. So use DOMAIN here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woops. I'll fix that in a minute.

descriptions.get(SERVICE_LOCK_N_GO), schema=LOCK_N_GO_SERVICE_SCHEMA)
hass.services.register(
DOMAIN, SERVICE_UNLATCH, service_handler,
NUKI_DATA, SERVICE_UNLATCH, service_handler,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

@MartinHjelmare
Copy link
Member

MartinHjelmare commented Aug 7, 2017

Btw if this fixes #5988 you can prefix the issue tag with "fixes " in the description to auto close that issue when this PR is merged.

Copy link
Member

@MartinHjelmare MartinHjelmare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@MartinHjelmare MartinHjelmare merged commit 3aceca9 into home-assistant:dev Aug 7, 2017
@fabaff fabaff mentioned this pull request Aug 12, 2017
dethpickle pushed a commit to dethpickle/home-assistant that referenced this pull request Aug 18, 2017
…stant#8687)

* Add lock'n'go service

* Add unlatch service

* Implement changes requested by @MartinHjelmare

* Fix service domain
@home-assistant home-assistant locked and limited conversation to collaborators Dec 11, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants