diff --git a/homeassistant/components/binary_sensor/zwave.py b/homeassistant/components/binary_sensor/zwave.py index 8b21500cc854ba4a1223378bb1443a46c6c9ed1c..920e2b702db3f3667d9fbcca1d27e9911cbc2d4a 100644 --- a/homeassistant/components/binary_sensor/zwave.py +++ b/homeassistant/components/binary_sensor/zwave.py @@ -5,11 +5,14 @@ For more details about this platform, please refer to the documentation https://home-assistant.io/components/binary_sensor.zwave/ """ import logging +import datetime +import homeassistant.util.dt as dt_util +from homeassistant.helpers.event import track_point_in_time from homeassistant.components.zwave import ( ATTR_NODE_ID, ATTR_VALUE_ID, COMMAND_CLASS_SENSOR_BINARY, NETWORK, - ZWaveDeviceEntity) + ZWaveDeviceEntity, get_config_value) from homeassistant.components.binary_sensor import ( DOMAIN, BinarySensorDevice) @@ -17,6 +20,16 @@ from homeassistant.components.binary_sensor import ( _LOGGER = logging.getLogger(__name__) DEPENDENCIES = [] +PHILIO = 0x013c +PHILIO_SLIM_SENSOR = 0x0002 +PHILIO_SLIM_SENSOR_MOTION = (PHILIO, PHILIO_SLIM_SENSOR, 0) + +WORKAROUND_NO_OFF_EVENT = 'trigger_no_off_event' + +DEVICE_MAPPINGS = { + PHILIO_SLIM_SENSOR_MOTION: WORKAROUND_NO_OFF_EVENT, +} + def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the Z-Wave platform for sensors.""" @@ -27,8 +40,21 @@ def setup_platform(hass, config, add_devices, discovery_info=None): node = NETWORK.nodes[discovery_info[ATTR_NODE_ID]] value = node.values[discovery_info[ATTR_VALUE_ID]] + specific_sensor_key = (int(value.node.manufacturer_id, 16), + int(value.node.product_id, 16), + value.index) + value.set_change_verified(False) - if value.command_class == COMMAND_CLASS_SENSOR_BINARY: + if specific_sensor_key in DEVICE_MAPPINGS: + if DEVICE_MAPPINGS[specific_sensor_key] == WORKAROUND_NO_OFF_EVENT: + # Default the multiplier to 4 + re_arm_multiplier = (get_config_value(value.node, 9) or 4) + add_devices([ + ZWaveTriggerSensor(value, "motion", + hass, re_arm_multiplier * 8) + ]) + + elif value.command_class == COMMAND_CLASS_SENSOR_BINARY: add_devices([ZWaveBinarySensor(value, "opening")]) @@ -65,3 +91,43 @@ class ZWaveBinarySensor(BinarySensorDevice, ZWaveDeviceEntity): """Called when a value has changed on the network.""" if self._value.value_id == value.value_id: self.update_ha_state() + + +class ZWaveTriggerSensor(ZWaveBinarySensor): + """ + Represents a stateless sensor which triggers events just 'On' + within Z-Wave. + """ + + def __init__(self, sensor_value, sensor_class, hass, re_arm_sec=60): + super(ZWaveTriggerSensor, self).__init__(sensor_value, sensor_class) + self._hass = hass + self.invalidate_after = dt_util.utcnow() + self.re_arm_sec = re_arm_sec + + def value_changed(self, value): + """Called when a value has changed on the network.""" + if self._value.value_id == value.value_id: + self.update_ha_state() + if value.data: + # only allow this value to be true for 60 secs + self.invalidate_after = dt_util.utcnow() + datetime.timedelta( + seconds=self.re_arm_sec) + track_point_in_time( + self._hass, self.update_ha_state, + self.invalidate_after) + + @property + def state(self): + """Returns the state of the sensor.""" + if not self._value.data or \ + (self.invalidate_after is not None and + self.invalidate_after <= dt_util.utcnow()): + return False + + return True + + @property + def is_on(self): + """Return True if the binary sensor is on.""" + return self.state diff --git a/homeassistant/components/sensor/zwave.py b/homeassistant/components/sensor/zwave.py index 3ed3a7b90f0521997618a760df425480cc864a43..066ada12546a18aca5a9efa9b39d052847931d07 100644 --- a/homeassistant/components/sensor/zwave.py +++ b/homeassistant/components/sensor/zwave.py @@ -6,33 +6,22 @@ at https://home-assistant.io/components/sensor.zwave/ """ # Because we do not compile openzwave on CI # pylint: disable=import-error -import datetime - -import homeassistant.util.dt as dt_util from homeassistant.components.sensor import DOMAIN from homeassistant.components.zwave import ( ATTR_NODE_ID, ATTR_VALUE_ID, COMMAND_CLASS_ALARM, COMMAND_CLASS_METER, COMMAND_CLASS_SENSOR_MULTILEVEL, NETWORK, - TYPE_DECIMAL, ZWaveDeviceEntity, get_config_value) -from homeassistant.const import ( - STATE_OFF, STATE_ON, TEMP_CELCIUS, TEMP_FAHRENHEIT) + TYPE_DECIMAL, ZWaveDeviceEntity) +from homeassistant.const import (TEMP_CELCIUS, TEMP_FAHRENHEIT) from homeassistant.helpers.entity import Entity -from homeassistant.helpers.event import track_point_in_time -PHILIO = '0x013c' -PHILIO_SLIM_SENSOR = '0x0002' -PHILIO_SLIM_SENSOR_MOTION = (PHILIO, PHILIO_SLIM_SENSOR, 0) -FIBARO = '0x010f' -FIBARO_WALL_PLUG = '0x1000' +FIBARO = 0x010f +FIBARO_WALL_PLUG = 0x1000 FIBARO_WALL_PLUG_SENSOR_METER = (FIBARO, FIBARO_WALL_PLUG, 8) -WORKAROUND_NO_OFF_EVENT = 'trigger_no_off_event' WORKAROUND_IGNORE = 'ignore' DEVICE_MAPPINGS = { - PHILIO_SLIM_SENSOR_MOTION: WORKAROUND_NO_OFF_EVENT, - # For some reason Fibaro Wall Plug reports 2 power consumptions. # One value updates as the power consumption changes # and the other does not change. @@ -61,19 +50,13 @@ def setup_platform(hass, config, add_devices, discovery_info=None): # groups[1].associations): # node.groups[1].add_association(NETWORK.controller.node_id) - specific_sensor_key = (value.node.manufacturer_id, - value.node.product_id, + specific_sensor_key = (int(value.node.manufacturer_id, 16), + int(value.node.product_id, 16), value.index) # Check workaround mappings for specific devices. if specific_sensor_key in DEVICE_MAPPINGS: - if DEVICE_MAPPINGS[specific_sensor_key] == WORKAROUND_NO_OFF_EVENT: - # Default the multiplier to 4 - re_arm_multiplier = (get_config_value(value.node, 9) or 4) - add_devices([ - ZWaveTriggerSensor(value, hass, re_arm_multiplier * 8) - ]) - elif DEVICE_MAPPINGS[specific_sensor_key] == WORKAROUND_IGNORE: + if DEVICE_MAPPINGS[specific_sensor_key] == WORKAROUND_IGNORE: return # Generic Device mappings @@ -116,41 +99,6 @@ class ZWaveSensor(ZWaveDeviceEntity, Entity): self.update_ha_state() -class ZWaveTriggerSensor(ZWaveSensor): - """ - Represents a stateless sensor which triggers events just 'On' - within Z-Wave. - """ - - def __init__(self, sensor_value, hass, re_arm_sec=60): - super(ZWaveTriggerSensor, self).__init__(sensor_value) - self._hass = hass - self.invalidate_after = dt_util.utcnow() - self.re_arm_sec = re_arm_sec - - def value_changed(self, value): - """Called when a value has changed on the network.""" - if self._value.value_id == value.value_id: - self.update_ha_state() - if value.data: - # only allow this value to be true for 60 secs - self.invalidate_after = dt_util.utcnow() + datetime.timedelta( - seconds=self.re_arm_sec) - track_point_in_time( - self._hass, self.update_ha_state, - self.invalidate_after) - - @property - def state(self): - """Returns the state of the sensor.""" - if not self._value.data or \ - (self.invalidate_after is not None and - self.invalidate_after <= dt_util.utcnow()): - return STATE_OFF - - return STATE_ON - - class ZWaveMultilevelSensor(ZWaveSensor): """Represents a multi level sensor Z-Wave sensor.""" @property