From 9c0ec2b4341901b061eaf90e8f76a8fa375844d0 Mon Sep 17 00:00:00 2001 From: vlb Date: Thu, 30 Jan 2020 12:14:56 +0100 Subject: [PATCH 1/6] Added lock support for tahoma --- homeassistant/components/tahoma/__init__.py | 3 +- homeassistant/components/tahoma/lock.py | 89 +++++++++++++++++++++ 2 files changed, 91 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 0d74d6018a5028..0e8ad260fcaca7 100644 --- a/homeassistant/components/tahoma/__init__.py +++ b/homeassistant/components/tahoma/__init__.py @@ -31,7 +31,7 @@ extra=vol.ALLOW_EXTRA, ) -TAHOMA_COMPONENTS = ["scene", "sensor", "cover", "switch", "binary_sensor"] +TAHOMA_COMPONENTS = ["scene", "sensor", "cover", "switch", "binary_sensor", "lock"] TAHOMA_TYPES = { "io:AwningValanceIOComponent": "cover", @@ -52,6 +52,7 @@ "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 00000000000000..854725917cbb87 --- /dev/null +++ b/homeassistant/components/tahoma/lock.py @@ -0,0 +1,89 @@ +"""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._state = STATE_UNLOCKED + 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 " + self._name + " has low battery") + if self._battery_level == "verylow": + _LOGGER.error("Lock " + self._name + " has very low battery") + if self.tahoma_device.active_states.get("core:LockedUnlockedState") == "locked": + self._state = STATE_LOCKED + else: + self._state = STATE_UNLOCKED + self._available = ( + self.tahoma_device.active_states.get("core:AvailabilityState") + == "available" + ) + + def open(self, **kwargs): + """Open method.""" + pass + + def unlock(self, **kwargs): + """Unlock method.""" + _LOGGER.info("unlocking ", self._name) + self.apply_action("unlock") + + def lock(self, **kwargs): + """Lock method.""" + _LOGGER.info("locking ", self._name) + self.apply_action("lock") + + @property + def is_locked(self): + """Return true if the lock is locked.""" + return self._state == STATE_LOCKED + + @property + def state(self): + """Return the state.""" + return self._state + + @property + def device_state_attributes(self): + """Return the device state attributes.""" + attr = {} + super_attr = super().device_state_attributes + if super_attr is not None: + attr.update(super_attr) + attr[ATTR_BATTERY_LEVEL] = self.tahoma_device.active_states["core:BatteryState"] + attr["availability"] = self.tahoma_device.active_states[ + "core:AvailabilityState" + ] + attr["name"] = self.tahoma_device.active_states["core:NameState"] + return attr From 8b54501f85a4e82915035e9254d551dccc8041ad Mon Sep 17 00:00:00 2001 From: vlb Date: Thu, 30 Jan 2020 13:05:43 +0100 Subject: [PATCH 2/6] Fixed logging to conform with pylint W1201 and E1205. --- homeassistant/components/tahoma/lock.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/tahoma/lock.py b/homeassistant/components/tahoma/lock.py index 854725917cbb87..660a2dcee647f4 100644 --- a/homeassistant/components/tahoma/lock.py +++ b/homeassistant/components/tahoma/lock.py @@ -38,9 +38,9 @@ def update(self): 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 " + self._name + " has low battery") + _LOGGER.warning("Lock %s has low battery", self._name) if self._battery_level == "verylow": - _LOGGER.error("Lock " + self._name + " has very low battery") + _LOGGER.error("Lock %s has very low battery", self._name) if self.tahoma_device.active_states.get("core:LockedUnlockedState") == "locked": self._state = STATE_LOCKED else: @@ -56,12 +56,12 @@ def open(self, **kwargs): def unlock(self, **kwargs): """Unlock method.""" - _LOGGER.info("unlocking ", self._name) + _LOGGER.info("unlocking %s", self._name) self.apply_action("unlock") def lock(self, **kwargs): """Lock method.""" - _LOGGER.info("locking ", self._name) + _LOGGER.info("locking %s", self._name) self.apply_action("lock") @property From 989d5002a7d97e46f938a6dc6822f0dcd62dcde2 Mon Sep 17 00:00:00 2001 From: vlb Date: Fri, 31 Jan 2020 08:42:28 +0100 Subject: [PATCH 3/6] Implemented @springstan suggestions. --- homeassistant/components/tahoma/lock.py | 38 +++++++++++++------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/homeassistant/components/tahoma/lock.py b/homeassistant/components/tahoma/lock.py index 660a2dcee647f4..9a037a33c31381 100644 --- a/homeassistant/components/tahoma/lock.py +++ b/homeassistant/components/tahoma/lock.py @@ -3,7 +3,12 @@ import logging from homeassistant.components.lock import LockDevice -from homeassistant.const import ATTR_BATTERY_LEVEL, STATE_LOCKED, STATE_UNLOCKED +from homeassistant.const import ( + ATTR_BATTERY_LEVEL, + ATTR_NAME, + STATE_LOCKED, + STATE_UNLOCKED, +) from . import DOMAIN as TAHOMA_DOMAIN, TahomaDevice @@ -27,7 +32,7 @@ class TahomaLock(TahomaDevice, LockDevice): def __init__(self, tahoma_device, controller): """Initialize the device.""" super().__init__(tahoma_device, controller) - self._state = STATE_UNLOCKED + self._lock_status = STATE_UNLOCKED self._available = False self._battery_level = None self._name = None @@ -41,10 +46,13 @@ def update(self): _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") == "locked": - self._state = STATE_LOCKED + if ( + self.tahoma_device.active_states.get("core:LockedUnlockedState") + == STATE_LOCKED + ): + self._lock_status = STATE_LOCKED else: - self._state = STATE_UNLOCKED + self._lock_status = STATE_UNLOCKED self._available = ( self.tahoma_device.active_states.get("core:AvailabilityState") == "available" @@ -56,12 +64,12 @@ def open(self, **kwargs): def unlock(self, **kwargs): """Unlock method.""" - _LOGGER.info("unlocking %s", self._name) + _LOGGER.debug("unlocking %s", self._name) self.apply_action("unlock") def lock(self, **kwargs): """Lock method.""" - _LOGGER.info("locking %s", self._name) + _LOGGER.debug("locking %s", self._name) self.apply_action("lock") @property @@ -69,21 +77,15 @@ def is_locked(self): """Return true if the lock is locked.""" return self._state == STATE_LOCKED - @property - def state(self): - """Return the state.""" - return self._state - @property def device_state_attributes(self): """Return the device state attributes.""" - attr = {} + attr = { + ATTR_BATTERY_LEVEL: self.tahoma_device.active_states["core:BatteryState"], + "availability": self.tahoma_device.active_states["core:AvailabilityState"], + ATTR_NAME: self.tahoma_device.active_states["core:NameState"], + } super_attr = super().device_state_attributes if super_attr is not None: attr.update(super_attr) - attr[ATTR_BATTERY_LEVEL] = self.tahoma_device.active_states["core:BatteryState"] - attr["availability"] = self.tahoma_device.active_states[ - "core:AvailabilityState" - ] - attr["name"] = self.tahoma_device.active_states["core:NameState"] return attr From 488c7f3c3a690e97f972d7fbab196306b5edd44b Mon Sep 17 00:00:00 2001 From: vlb Date: Fri, 31 Jan 2020 09:16:02 +0100 Subject: [PATCH 4/6] Fixed a typo... --- homeassistant/components/tahoma/lock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/tahoma/lock.py b/homeassistant/components/tahoma/lock.py index 9a037a33c31381..2a7d541357db1d 100644 --- a/homeassistant/components/tahoma/lock.py +++ b/homeassistant/components/tahoma/lock.py @@ -75,7 +75,7 @@ def lock(self, **kwargs): @property def is_locked(self): """Return true if the lock is locked.""" - return self._state == STATE_LOCKED + return self._lock_status == STATE_LOCKED @property def device_state_attributes(self): From 62489b4c013601f1bf46e4935e6339fefbd323fe Mon Sep 17 00:00:00 2001 From: vlb Date: Fri, 31 Jan 2020 09:52:53 +0100 Subject: [PATCH 5/6] Implemented @springstan suggestions (v2). --- homeassistant/components/tahoma/__init__.py | 2 +- homeassistant/components/tahoma/lock.py | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/tahoma/__init__.py b/homeassistant/components/tahoma/__init__.py index 0e8ad260fcaca7..f14e3019ac0f04 100644 --- a/homeassistant/components/tahoma/__init__.py +++ b/homeassistant/components/tahoma/__init__.py @@ -31,7 +31,7 @@ extra=vol.ALLOW_EXTRA, ) -TAHOMA_COMPONENTS = ["scene", "sensor", "cover", "switch", "binary_sensor", "lock"] +TAHOMA_COMPONENTS = ["binary_sensor", "cover", "lock", "scene", "sensor", "switch"] TAHOMA_TYPES = { "io:AwningValanceIOComponent": "cover", diff --git a/homeassistant/components/tahoma/lock.py b/homeassistant/components/tahoma/lock.py index 2a7d541357db1d..44625267964471 100644 --- a/homeassistant/components/tahoma/lock.py +++ b/homeassistant/components/tahoma/lock.py @@ -32,7 +32,7 @@ class TahomaLock(TahomaDevice, LockDevice): def __init__(self, tahoma_device, controller): """Initialize the device.""" super().__init__(tahoma_device, controller) - self._lock_status = STATE_UNLOCKED + self._lock_status = None self._available = False self._battery_level = None self._name = None @@ -58,18 +58,14 @@ def update(self): == "available" ) - def open(self, **kwargs): - """Open method.""" - pass - def unlock(self, **kwargs): """Unlock method.""" - _LOGGER.debug("unlocking %s", self._name) + _LOGGER.debug("Unlocking %s", self._name) self.apply_action("unlock") def lock(self, **kwargs): """Lock method.""" - _LOGGER.debug("locking %s", self._name) + _LOGGER.debug("Locking %s", self._name) self.apply_action("lock") @property From 1fb9fd01ed35e482fe71871f9071c31ec63f4d77 Mon Sep 17 00:00:00 2001 From: vlb Date: Fri, 31 Jan 2020 10:21:22 +0100 Subject: [PATCH 6/6] Implemented @springstan suggestions (v3). --- homeassistant/components/tahoma/lock.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/tahoma/lock.py b/homeassistant/components/tahoma/lock.py index 44625267964471..e320fd9e13d7a1 100644 --- a/homeassistant/components/tahoma/lock.py +++ b/homeassistant/components/tahoma/lock.py @@ -3,12 +3,7 @@ import logging from homeassistant.components.lock import LockDevice -from homeassistant.const import ( - ATTR_BATTERY_LEVEL, - ATTR_NAME, - STATE_LOCKED, - STATE_UNLOCKED, -) +from homeassistant.const import ATTR_BATTERY_LEVEL, STATE_LOCKED, STATE_UNLOCKED from . import DOMAIN as TAHOMA_DOMAIN, TahomaDevice @@ -68,18 +63,26 @@ def lock(self, **kwargs): _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 True if the lock is locked.""" return self._lock_status == STATE_LOCKED @property def device_state_attributes(self): - """Return the device state attributes.""" + """Return the lock state attributes.""" attr = { - ATTR_BATTERY_LEVEL: self.tahoma_device.active_states["core:BatteryState"], - "availability": self.tahoma_device.active_states["core:AvailabilityState"], - ATTR_NAME: self.tahoma_device.active_states["core:NameState"], + ATTR_BATTERY_LEVEL: self._battery_level, } super_attr = super().device_state_attributes if super_attr is not None: