From 1b54218d465827de39f6ca28745fc536ede64278 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 8 Feb 2017 06:37:11 +0200 Subject: [PATCH] Create a file for zwave workarounds. (#5798) * Create a file for zwave workarounds. Add sensor->binary_sensor for fgfs101 (#2) * Don't use default None --- .../components/binary_sensor/zwave.py | 45 ++++--------- homeassistant/components/zwave/__init__.py | 13 +++- homeassistant/components/zwave/workaround.py | 67 +++++++++++++++++++ 3 files changed, 90 insertions(+), 35 deletions(-) create mode 100644 homeassistant/components/zwave/workaround.py diff --git a/homeassistant/components/binary_sensor/zwave.py b/homeassistant/components/binary_sensor/zwave.py index b0054d7b00f..8dd02cc4b43 100644 --- a/homeassistant/components/binary_sensor/zwave.py +++ b/homeassistant/components/binary_sensor/zwave.py @@ -9,6 +9,7 @@ import datetime import homeassistant.util.dt as dt_util from homeassistant.helpers.event import track_point_in_time from homeassistant.components import zwave +from homeassistant.components.zwave import workaround from homeassistant.components.binary_sensor import ( DOMAIN, BinarySensorDevice) @@ -16,22 +17,6 @@ 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) -PHILIO_3_IN_1_SENSOR_GEN_4 = 0x000d -PHILIO_3_IN_1_SENSOR_GEN_4_MOTION = (PHILIO, PHILIO_3_IN_1_SENSOR_GEN_4, 0) -WENZHOU = 0x0118 -WENZHOU_SLIM_SENSOR_MOTION = (WENZHOU, PHILIO_SLIM_SENSOR, 0) - -WORKAROUND_NO_OFF_EVENT = 'trigger_no_off_event' - -DEVICE_MAPPINGS = { - PHILIO_SLIM_SENSOR_MOTION: WORKAROUND_NO_OFF_EVENT, - PHILIO_3_IN_1_SENSOR_GEN_4_MOTION: WORKAROUND_NO_OFF_EVENT, - WENZHOU_SLIM_SENSOR_MOTION: WORKAROUND_NO_OFF_EVENT, -} - def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the Z-Wave platform for binary sensors.""" @@ -42,23 +27,19 @@ def setup_platform(hass, config, add_devices, discovery_info=None): value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]] value.set_change_verified(False) - # Make sure that we have values for the key before converting to int - if (value.node.manufacturer_id.strip() and - value.node.product_id.strip()): - specific_sensor_key = (int(value.node.manufacturer_id, 16), - int(value.node.product_id, 16), - value.index) + device_mapping = workaround.get_device_mapping(value) + if device_mapping == workaround.WORKAROUND_NO_OFF_EVENT: + # Default the multiplier to 4 + re_arm_multiplier = (zwave.get_config_value(value.node, 9) or 4) + add_devices([ + ZWaveTriggerSensor(value, "motion", + hass, re_arm_multiplier * 8) + ]) + return - 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 = (zwave.get_config_value(value.node, - 9) or 4) - add_devices([ - ZWaveTriggerSensor(value, "motion", - hass, re_arm_multiplier * 8) - ]) - return + if workaround.get_device_component_mapping(value) == DOMAIN: + add_devices([ZWaveBinarySensor(value, None)]) + return if value.command_class == zwave.const.COMMAND_CLASS_SENSOR_BINARY: add_devices([ZWaveBinarySensor(value, None)]) diff --git a/homeassistant/components/zwave/__init__.py b/homeassistant/components/zwave/__init__.py index 5afd74c1503..4268ebcd2bb 100755 --- a/homeassistant/components/zwave/__init__.py +++ b/homeassistant/components/zwave/__init__.py @@ -21,6 +21,7 @@ from homeassistant.util import convert, slugify import homeassistant.config as conf_util import homeassistant.helpers.config_validation as cv from . import const +from . import workaround REQUIREMENTS = ['pydispatcher==2.0.5'] @@ -343,12 +344,18 @@ def setup(hass, config): _LOGGER.debug("Adding Node_id=%s Generic_command_class=%s, " "Specific_command_class=%s, " "Command_class=%s, Value type=%s, " - "Genre=%s", node.node_id, + "Genre=%s as %s", node.node_id, node.generic, node.specific, value.command_class, value.type, - value.genre) - name = "{}.{}".format(component, object_id(value)) + value.genre, component) + workaround_component = workaround.get_device_component_mapping( + value) + if workaround_component != component: + _LOGGER.debug("Using %s instead of %s", + workaround_component, component) + component = workaround_component + name = "{}.{}".format(component, object_id(value)) node_config = customize.get_overrides(hass, DOMAIN, name) if node_config.get(CONF_IGNORED): diff --git a/homeassistant/components/zwave/workaround.py b/homeassistant/components/zwave/workaround.py new file mode 100644 index 00000000000..7712c1868db --- /dev/null +++ b/homeassistant/components/zwave/workaround.py @@ -0,0 +1,67 @@ +"""Zwave workarounds.""" +from . import const + +# Manufacturers +FIBARO = 0x010f +PHILIO = 0x013c +WENZHOU = 0x0118 + +# Product IDs +PHILIO_SLIM_SENSOR = 0x0002 +PHILIO_3_IN_1_SENSOR_GEN_4 = 0x000d + +# Product Types +FGFS101_FLOOD_SENSOR_TYPE = 0x0b00 +PHILIO_SENSOR = 0x0002 + +# Mapping devices +PHILIO_SLIM_SENSOR_MOTION = (PHILIO, PHILIO_SENSOR, PHILIO_SLIM_SENSOR, 0) +PHILIO_3_IN_1_SENSOR_GEN_4_MOTION = ( + PHILIO, PHILIO_SENSOR, PHILIO_3_IN_1_SENSOR_GEN_4, 0) +WENZHOU_SLIM_SENSOR_MOTION = (WENZHOU, PHILIO_SENSOR, PHILIO_SLIM_SENSOR, 0) + +# Workarounds +WORKAROUND_NO_OFF_EVENT = 'trigger_no_off_event' + +# List of workarounds by (manufacturer_id, product_type, product_id, index) +DEVICE_MAPPINGS = { + PHILIO_SLIM_SENSOR_MOTION: WORKAROUND_NO_OFF_EVENT, + PHILIO_3_IN_1_SENSOR_GEN_4_MOTION: WORKAROUND_NO_OFF_EVENT, + WENZHOU_SLIM_SENSOR_MOTION: WORKAROUND_NO_OFF_EVENT, +} + +# Component mapping devices +FIBARO_FGFS101_SENSOR_ALARM = ( + FIBARO, FGFS101_FLOOD_SENSOR_TYPE, const.COMMAND_CLASS_SENSOR_ALARM) + +# List of component workarounds by +# (manufacturer_id, product_type, command_class) +DEVICE_COMPONENT_MAPPING = { + FIBARO_FGFS101_SENSOR_ALARM: 'binary_sensor', +} + + +def get_device_component_mapping(value): + """Get mapping of value to another component.""" + if (value.node.manufacturer_id.strip() and + value.node.product_type.strip()): + manufacturer_id = int(value.node.manufacturer_id, 16) + product_type = int(value.node.product_type, 16) + return DEVICE_COMPONENT_MAPPING.get( + (manufacturer_id, product_type, value.command_class)) + + return None + + +def get_device_mapping(value): + """Get mapping of value to a workaround.""" + if (value.node.manufacturer_id.strip() and + value.node.product_id.strip() and + value.node.product_type.strip()): + manufacturer_id = int(value.node.manufacturer_id, 16) + product_type = int(value.node.product_type, 16) + product_id = int(value.node.product_id, 16) + return DEVICE_MAPPINGS.get( + (manufacturer_id, product_type, product_id, value.index)) + + return None