Migrate lock component to async (#5748)

This commit is contained in:
Pascal Vizeli 2017-02-06 21:25:34 +01:00 committed by GitHub
parent 32dc276c53
commit 2b124a008c
4 changed files with 58 additions and 26 deletions

View File

@ -4,7 +4,9 @@ Component to interface with various locks that can be controlled remotely.
For more details about this component, please refer to the documentation For more details about this component, please refer to the documentation
at https://home-assistant.io/components/lock/ at https://home-assistant.io/components/lock/
""" """
import asyncio
from datetime import timedelta from datetime import timedelta
import functools as ft
import logging import logging
import os import os
@ -67,38 +69,54 @@ def unlock(hass, entity_id=None, code=None):
hass.services.call(DOMAIN, SERVICE_UNLOCK, data) hass.services.call(DOMAIN, SERVICE_UNLOCK, data)
def setup(hass, config): @asyncio.coroutine
def async_setup(hass, config):
"""Track states and offer events for locks.""" """Track states and offer events for locks."""
component = EntityComponent( component = EntityComponent(
_LOGGER, DOMAIN, hass, SCAN_INTERVAL, GROUP_NAME_ALL_LOCKS) _LOGGER, DOMAIN, hass, SCAN_INTERVAL, GROUP_NAME_ALL_LOCKS)
component.setup(config)
def handle_lock_service(service): yield from component.async_setup(config)
@asyncio.coroutine
def async_handle_lock_service(service):
"""Handle calls to the lock services.""" """Handle calls to the lock services."""
target_locks = component.extract_from_service(service) target_locks = component.async_extract_from_service(service)
code = service.data.get(ATTR_CODE) code = service.data.get(ATTR_CODE)
for item in target_locks: for entity in target_locks:
if service.service == SERVICE_LOCK: if service.service == SERVICE_LOCK:
item.lock(code=code) yield from entity.async_lock(code=code)
else: else:
item.unlock(code=code) yield from entity.async_unlock(code=code)
for item in target_locks: update_tasks = []
if not item.should_poll:
for entity in target_locks:
if not entity.should_poll:
continue continue
item.update_ha_state(True) update_coro = hass.loop.create_task(
entity.async_update_ha_state(True))
if hasattr(entity, 'async_update'):
update_tasks.append(update_coro)
else:
yield from update_coro
if update_tasks:
yield from asyncio.wait(update_tasks, loop=hass.loop)
descriptions = yield from hass.loop.run_in_executor(
None, load_yaml_config_file, os.path.join(
os.path.dirname(__file__), 'services.yaml'))
hass.services.async_register(
DOMAIN, SERVICE_UNLOCK, async_handle_lock_service,
descriptions.get(SERVICE_UNLOCK), schema=LOCK_SERVICE_SCHEMA)
hass.services.async_register(
DOMAIN, SERVICE_LOCK, async_handle_lock_service,
descriptions.get(SERVICE_LOCK), schema=LOCK_SERVICE_SCHEMA)
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
hass.services.register(DOMAIN, SERVICE_UNLOCK, handle_lock_service,
descriptions.get(SERVICE_UNLOCK),
schema=LOCK_SERVICE_SCHEMA)
hass.services.register(DOMAIN, SERVICE_LOCK, handle_lock_service,
descriptions.get(SERVICE_LOCK),
schema=LOCK_SERVICE_SCHEMA)
return True return True
@ -125,10 +143,26 @@ class LockDevice(Entity):
"""Lock the lock.""" """Lock the lock."""
raise NotImplementedError() raise NotImplementedError()
def async_lock(self, **kwargs):
"""Lock the lock.
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.loop.run_in_executor(
None, ft.partial(self.lock, **kwargs))
def unlock(self, **kwargs): def unlock(self, **kwargs):
"""Unlock the lock.""" """Unlock the lock."""
raise NotImplementedError() raise NotImplementedError()
def async_unlock(self, **kwargs):
"""Unlock the lock.
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.loop.run_in_executor(
None, ft.partial(self.unlock, **kwargs))
@property @property
def state_attributes(self): def state_attributes(self):
"""Return the state attributes.""" """Return the state attributes."""

View File

@ -43,9 +43,9 @@ class DemoLock(LockDevice):
def lock(self, **kwargs): def lock(self, **kwargs):
"""Lock the device.""" """Lock the device."""
self._state = STATE_LOCKED self._state = STATE_LOCKED
self.update_ha_state() self.schedule_update_ha_state()
def unlock(self, **kwargs): def unlock(self, **kwargs):
"""Unlock the device.""" """Unlock the device."""
self._state = STATE_UNLOCKED self._state = STATE_UNLOCKED
self.update_ha_state() self.schedule_update_ha_state()

View File

@ -82,10 +82,10 @@ class MqttLock(LockDevice):
payload) payload)
if payload == self._payload_lock: if payload == self._payload_lock:
self._state = True self._state = True
self.update_ha_state() self.schedule_update_ha_state()
elif payload == self._payload_unlock: elif payload == self._payload_unlock:
self._state = False self._state = False
self.update_ha_state() self.schedule_update_ha_state()
if self._state_topic is None: if self._state_topic is None:
# Force into optimistic mode. # Force into optimistic mode.
@ -121,7 +121,7 @@ class MqttLock(LockDevice):
if self._optimistic: if self._optimistic:
# Optimistically assume that switch has changed state. # Optimistically assume that switch has changed state.
self._state = True self._state = True
self.update_ha_state() self.schedule_update_ha_state()
def unlock(self, **kwargs): def unlock(self, **kwargs):
"""Unlock the device.""" """Unlock the device."""
@ -130,4 +130,4 @@ class MqttLock(LockDevice):
if self._optimistic: if self._optimistic:
# Optimistically assume that switch has changed state. # Optimistically assume that switch has changed state.
self._state = False self._state = False
self.update_ha_state() self.schedule_update_ha_state()

View File

@ -35,13 +35,11 @@ class VeraLock(VeraDevice, LockDevice):
"""Lock the device.""" """Lock the device."""
self.vera_device.lock() self.vera_device.lock()
self._state = STATE_LOCKED self._state = STATE_LOCKED
self.update_ha_state()
def unlock(self, **kwargs): def unlock(self, **kwargs):
"""Unlock the device.""" """Unlock the device."""
self.vera_device.unlock() self.vera_device.unlock()
self._state = STATE_UNLOCKED self._state = STATE_UNLOCKED
self.update_ha_state()
@property @property
def is_locked(self): def is_locked(self):