From 39e03eebcf0a4279edcf7f747368ed7b0f6951b5 Mon Sep 17 00:00:00 2001 From: devdelay Date: Mon, 2 May 2016 22:38:48 -0400 Subject: [PATCH] Add Z-Wave lock support --- homeassistant/components/lock/__init__.py | 5 +- homeassistant/components/lock/zwave.py | 64 +++++++++++++++++++++++ homeassistant/components/zwave.py | 8 ++- 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 homeassistant/components/lock/zwave.py diff --git a/homeassistant/components/lock/__init__.py b/homeassistant/components/lock/__init__.py index 299c5fbb778..8b27929e816 100644 --- a/homeassistant/components/lock/__init__.py +++ b/homeassistant/components/lock/__init__.py @@ -18,7 +18,7 @@ import homeassistant.helpers.config_validation as cv from homeassistant.const import ( ATTR_CODE, ATTR_CODE_FORMAT, ATTR_ENTITY_ID, STATE_LOCKED, STATE_UNLOCKED, STATE_UNKNOWN, SERVICE_LOCK, SERVICE_UNLOCK) -from homeassistant.components import (group, verisure, wink) +from homeassistant.components import (group, verisure, wink, zwave) DOMAIN = 'lock' SCAN_INTERVAL = 30 @@ -33,7 +33,8 @@ MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10) # Maps discovered services to their platforms DISCOVERY_PLATFORMS = { wink.DISCOVER_LOCKS: 'wink', - verisure.DISCOVER_LOCKS: 'verisure' + verisure.DISCOVER_LOCKS: 'verisure', + zwave.DISCOVER_LOCKS: 'zwave', } LOCK_SERVICE_SCHEMA = vol.Schema({ diff --git a/homeassistant/components/lock/zwave.py b/homeassistant/components/lock/zwave.py new file mode 100644 index 00000000000..9a3b24deb8a --- /dev/null +++ b/homeassistant/components/lock/zwave.py @@ -0,0 +1,64 @@ +""" +Zwave platform that handles simple door locks. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/lock.zwave/ +""" +# Because we do not compile openzwave on CI +# pylint: disable=import-error +from homeassistant.components.lock import DOMAIN, LockDevice +from homeassistant.components import zwave + + +# pylint: disable=unused-argument +def setup_platform(hass, config, add_devices, discovery_info=None): + """Find and return Z-Wave switches.""" + if discovery_info is None or zwave.NETWORK is None: + return + + node = zwave.NETWORK.nodes[discovery_info[zwave.ATTR_NODE_ID]] + value = node.values[discovery_info[zwave.ATTR_VALUE_ID]] + + if value.command_class != zwave.COMMAND_CLASS_DOOR_LOCK: + return + if value.type != zwave.TYPE_BOOL: + return + if value.genre != zwave.GENRE_USER: + return + + value.set_change_verified(False) + add_devices([ZwaveLock(value)]) + + +class ZwaveLock(zwave.ZWaveDeviceEntity, LockDevice): + """Representation of a Z-Wave switch.""" + + def __init__(self, value): + """Initialize the Z-Wave switch device.""" + from openzwave.network import ZWaveNetwork + from pydispatch import dispatcher + + zwave.ZWaveDeviceEntity.__init__(self, value, DOMAIN) + + self._state = value.data + dispatcher.connect( + self._value_changed, ZWaveNetwork.SIGNAL_VALUE_CHANGED) + + def _value_changed(self, value): + """Called when a value has changed on the network.""" + if self._value.value_id == value.value_id: + self._state = value.data + self.update_ha_state() + + @property + def is_locked(self): + """Return true if device is locked.""" + return self._state + + def lock(self, **kwargs): + """Lock the device.""" + self._value.data = True + + def unlock(self, **kwargs): + """Unlock the device.""" + self._value.data = False diff --git a/homeassistant/components/zwave.py b/homeassistant/components/zwave.py index 94e8b85df6b..dcc80126be7 100644 --- a/homeassistant/components/zwave.py +++ b/homeassistant/components/zwave.py @@ -39,11 +39,12 @@ DISCOVER_SWITCHES = "zwave.switch" DISCOVER_LIGHTS = "zwave.light" DISCOVER_BINARY_SENSORS = 'zwave.binary_sensor' DISCOVER_THERMOSTATS = 'zwave.thermostat' +DISCOVER_LOCKS = 'zwave.lock' EVENT_SCENE_ACTIVATED = "zwave.scene_activated" COMMAND_CLASS_SWITCH_MULTILEVEL = 38 - +COMMAND_CLASS_DOOR_LOCK = 98 COMMAND_CLASS_SWITCH_BINARY = 37 COMMAND_CLASS_SENSOR_BINARY = 48 COMMAND_CLASS_SENSOR_MULTILEVEL = 49 @@ -91,6 +92,11 @@ DISCOVERY_COMPONENTS = [ [COMMAND_CLASS_THERMOSTAT_SETPOINT], TYPE_WHATEVER, GENRE_WHATEVER), + ('lock', + DISCOVER_LOCKS, + [COMMAND_CLASS_DOOR_LOCK], + TYPE_BOOL, + GENRE_USER), ]