From 79495d9f3a459e691ef20b7a3affd9fe8f413e9b Mon Sep 17 00:00:00 2001 From: Vincent Le Bourlot Date: Sat, 1 Feb 2020 11:40:48 +0100 Subject: [PATCH] Add Tahoma lock support (#31311) * Added lock support for tahoma * Fixed logging to conform with pylint W1201 and E1205. * Implemented @springstan suggestions. * Fixed a typo... * Implemented @springstan suggestions (v2). * Implemented @springstan suggestions (v3). --- homeassistant/components/tahoma/__init__.py | 3 +- homeassistant/components/tahoma/lock.py | 90 +++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 homeassistant/components/tahoma/lock.py diff --git a/homeassistant/components/tahoma/__init__.py b/homeassistant/components/tahoma/__init__.py index 0d74d6018a5..f14e3019ac0 100644 --- a/homeassistant/components/tahoma/__init__.py +++ b/homeassistant/components/tahoma/__init__.py @@ -31,7 +31,7 @@ CONFIG_SCHEMA = vol.Schema( extra=vol.ALLOW_EXTRA, ) -TAHOMA_COMPONENTS = ["scene", "sensor", "cover", "switch", "binary_sensor"] +TAHOMA_COMPONENTS = ["binary_sensor", "cover", "lock", "scene", "sensor", "switch"] TAHOMA_TYPES = { "io:AwningValanceIOComponent": "cover", @@ -52,6 +52,7 @@ TAHOMA_TYPES = { "io:VerticalExteriorAwningIOComponent": "cover", "io:VerticalInteriorBlindVeluxIOComponent": "cover", "io:WindowOpenerVeluxIOComponent": "cover", + "opendoors:OpenDoorsSmartLockComponent": "lock", "rtds:RTDSContactSensor": "sensor", "rtds:RTDSMotionSensor": "sensor", "rtds:RTDSSmokeSensor": "smoke", diff --git a/homeassistant/components/tahoma/lock.py b/homeassistant/components/tahoma/lock.py new file mode 100644 index 00000000000..e320fd9e13d --- /dev/null +++ b/homeassistant/components/tahoma/lock.py @@ -0,0 +1,90 @@ +"""Support for Tahoma lock.""" +from datetime import timedelta +import logging + +from homeassistant.components.lock import LockDevice +from homeassistant.const import ATTR_BATTERY_LEVEL, STATE_LOCKED, STATE_UNLOCKED + +from . import DOMAIN as TAHOMA_DOMAIN, TahomaDevice + +_LOGGER = logging.getLogger(__name__) + +SCAN_INTERVAL = timedelta(seconds=120) + + +def setup_platform(hass, config, add_entities, discovery_info=None): + """Set up the Tahoma lock.""" + controller = hass.data[TAHOMA_DOMAIN]["controller"] + devices = [] + for device in hass.data[TAHOMA_DOMAIN]["devices"]["lock"]: + devices.append(TahomaLock(device, controller)) + add_entities(devices, True) + + +class TahomaLock(TahomaDevice, LockDevice): + """Representation a Tahoma lock.""" + + def __init__(self, tahoma_device, controller): + """Initialize the device.""" + super().__init__(tahoma_device, controller) + self._lock_status = None + self._available = False + self._battery_level = None + self._name = None + + def update(self): + """Update method.""" + self.controller.get_states([self.tahoma_device]) + self._battery_level = self.tahoma_device.active_states["core:BatteryState"] + self._name = self.tahoma_device.active_states["core:NameState"] + if self._battery_level == "low": + _LOGGER.warning("Lock %s has low battery", self._name) + if self._battery_level == "verylow": + _LOGGER.error("Lock %s has very low battery", self._name) + if ( + self.tahoma_device.active_states.get("core:LockedUnlockedState") + == STATE_LOCKED + ): + self._lock_status = STATE_LOCKED + else: + self._lock_status = STATE_UNLOCKED + self._available = ( + self.tahoma_device.active_states.get("core:AvailabilityState") + == "available" + ) + + def unlock(self, **kwargs): + """Unlock method.""" + _LOGGER.debug("Unlocking %s", self._name) + self.apply_action("unlock") + + def lock(self, **kwargs): + """Lock method.""" + _LOGGER.debug("Locking %s", self._name) + self.apply_action("lock") + + @property + def name(self): + """Return the name of the lock.""" + return self._name + + @property + def available(self): + """Return True if the lock is available.""" + return self._available + + @property + def is_locked(self): + """Return True if the lock is locked.""" + return self._lock_status == STATE_LOCKED + + @property + def device_state_attributes(self): + """Return the lock state attributes.""" + attr = { + ATTR_BATTERY_LEVEL: self._battery_level, + } + super_attr = super().device_state_attributes + if super_attr is not None: + attr.update(super_attr) + return attr