core/homeassistant/components/verisure/lock.py

130 lines
4.0 KiB
Python
Raw Normal View History

"""Support for Verisure locks."""
import logging
from time import sleep, time
from homeassistant.components.lock import LockDevice
from homeassistant.const import ATTR_CODE, STATE_LOCKED, STATE_UNLOCKED
from . import CONF_CODE_DIGITS, CONF_DEFAULT_LOCK_CODE, CONF_LOCKS, HUB as hub
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Verisure lock platform."""
locks = []
if int(hub.config.get(CONF_LOCKS, 1)):
hub.update_overview()
2016-02-27 20:50:19 +00:00
locks.extend([
VerisureDoorlock(device_label)
for device_label in hub.get(
"$.doorLockStatusList[*].deviceLabel")])
add_entities(locks)
class VerisureDoorlock(LockDevice):
2016-03-07 21:13:18 +00:00
"""Representation of a Verisure doorlock."""
def __init__(self, device_label):
"""Initialize the Verisure lock."""
self._device_label = device_label
self._state = None
self._digits = hub.config.get(CONF_CODE_DIGITS)
self._changed_by = None
self._change_timestamp = 0
self._default_lock_code = hub.config.get(CONF_DEFAULT_LOCK_CODE)
@property
def name(self):
2016-03-07 21:13:18 +00:00
"""Return the name of the lock."""
return hub.get_first(
"$.doorLockStatusList[?(@.deviceLabel=='%s')].area",
2017-06-30 06:53:14 +00:00
self._device_label)
@property
def state(self):
2016-03-07 21:13:18 +00:00
"""Return the state of the lock."""
return self._state
@property
def available(self):
"""Return True if entity is available."""
return hub.get_first(
"$.doorLockStatusList[?(@.deviceLabel=='%s')]",
self._device_label) is not None
@property
def changed_by(self):
"""Last change triggered by."""
return self._changed_by
@property
def code_format(self):
2016-03-07 21:13:18 +00:00
"""Return the required six digit code."""
2016-02-27 20:50:19 +00:00
return '^\\d{%s}$' % self._digits
def update(self):
2016-02-28 11:03:47 +00:00
"""Update lock status."""
if time() - self._change_timestamp < 10:
return
hub.update_overview()
status = hub.get_first(
"$.doorLockStatusList[?(@.deviceLabel=='%s')].lockedState",
self._device_label)
if status == 'UNLOCKED':
self._state = STATE_UNLOCKED
elif status == 'LOCKED':
self._state = STATE_LOCKED
elif status != 'PENDING':
_LOGGER.error('Unknown lock state %s', status)
self._changed_by = hub.get_first(
"$.doorLockStatusList[?(@.deviceLabel=='%s')].userString",
self._device_label)
@property
def is_locked(self):
2016-02-28 11:03:47 +00:00
"""Return true if lock is locked."""
return self._state == STATE_LOCKED
def unlock(self, **kwargs):
2016-02-28 11:03:47 +00:00
"""Send unlock command."""
if self._state is None:
return
code = kwargs.get(ATTR_CODE, self._default_lock_code)
if code is None:
_LOGGER.error("Code required but none provided")
return
self.set_lock_state(code, STATE_UNLOCKED)
def lock(self, **kwargs):
2016-02-28 11:03:47 +00:00
"""Send lock command."""
if self._state == STATE_LOCKED:
return
code = kwargs.get(ATTR_CODE, self._default_lock_code)
if code is None:
_LOGGER.error("Code required but none provided")
return
self.set_lock_state(code, STATE_LOCKED)
def set_lock_state(self, code, state):
"""Send set lock state command."""
lock_state = 'lock' if state == STATE_LOCKED else 'unlock'
transaction_id = hub.session.set_lock_state(
code,
self._device_label,
lock_state)['doorLockStateChangeTransactionId']
_LOGGER.debug("Verisure doorlock %s", state)
transaction = {}
while 'result' not in transaction:
sleep(0.5)
transaction = hub.session.get_lock_state_transaction(
transaction_id)
if transaction['result'] == 'OK':
self._state = state
self._change_timestamp = time()