Add workaround for ignoring zwave devices and reversing cover open/close (#5922)

This commit is contained in:
Andrey 2017-02-13 20:59:42 +02:00 committed by GitHub
parent b2d1774293
commit 0feb1c3e28
3 changed files with 50 additions and 35 deletions

View file

@ -10,17 +10,9 @@ import logging
from homeassistant.components.cover import DOMAIN
from homeassistant.components.zwave import ZWaveDeviceEntity
from homeassistant.components import zwave
from homeassistant.components.zwave import workaround
from homeassistant.components.cover import CoverDevice
SOMFY = 0x47
SOMFY_ZRTSI = 0x5a52
SOMFY_ZRTSI_CONTROLLER = (SOMFY, SOMFY_ZRTSI)
WORKAROUND = 'workaround'
DEVICE_MAPPINGS = {
SOMFY_ZRTSI_CONTROLLER: WORKAROUND
}
_LOGGER = logging.getLogger(__name__)
@ -58,16 +50,9 @@ class ZwaveRollershutter(zwave.ZWaveDeviceEntity, CoverDevice):
self._open_id = None
self._close_id = None
self._current_position = None
self._workaround = None
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_type, 16))
if specific_sensor_key in DEVICE_MAPPINGS:
if DEVICE_MAPPINGS[specific_sensor_key] == WORKAROUND:
_LOGGER.debug("Controller without positioning feedback")
self._workaround = 1
self._workaround = workaround.get_device_mapping(value)
if self._workaround:
_LOGGER.debug("Using workaround %s", self._workaround)
def update_properties(self):
"""Callback on data changes for node values."""
@ -81,6 +66,8 @@ class ZwaveRollershutter(zwave.ZWaveDeviceEntity, CoverDevice):
self._close_id = self.get_value(
class_id=zwave.const.COMMAND_CLASS_SWITCH_MULTILEVEL,
label=['Close', 'Down'], member='value_id')
if self._workaround == workaround.WORKAROUND_REVERSE_OPEN_CLOSE:
self._open_id, self._close_id = self._close_id, self._open_id
@property
def is_closed(self):
@ -95,14 +82,15 @@ class ZwaveRollershutter(zwave.ZWaveDeviceEntity, CoverDevice):
@property
def current_cover_position(self):
"""Return the current position of Zwave roller shutter."""
if not self._workaround:
if self._current_position is not None:
if self._current_position <= 5:
return 0
elif self._current_position >= 95:
return 100
else:
return self._current_position
if self._workaround == workaround.WORKAROUND_NO_POSITION:
return None
if self._current_position is not None:
if self._current_position <= 5:
return 0
elif self._current_position >= 95:
return 100
else:
return self._current_position
def open_cover(self, **kwargs):
"""Move the roller shutter up."""

View file

@ -376,6 +376,10 @@ def setup(hass, config):
workaround_component = workaround.get_device_component_mapping(
value)
if workaround_component and workaround_component != component:
if workaround_component == workaround.WORKAROUND_IGNORE:
_LOGGER.info("Ignoring device %s",
"{}.{}".format(component, object_id(value)))
continue
_LOGGER.debug("Using %s instead of %s",
workaround_component, component)
component = workaround_component

View file

@ -5,6 +5,7 @@ from . import const
FIBARO = 0x010f
PHILIO = 0x013c
WENZHOU = 0x0118
SOMFY = 0x47
# Product IDs
PHILIO_SLIM_SENSOR = 0x0002
@ -12,32 +13,51 @@ PHILIO_3_IN_1_SENSOR_GEN_4 = 0x000d
# Product Types
FGFS101_FLOOD_SENSOR_TYPE = 0x0b00
FGRM222_SHUTTER2 = 0x0301
PHILIO_SENSOR = 0x0002
SOMFY_ZRTSI = 0x5a52
# Mapping devices
PHILIO_SLIM_SENSOR_MOTION = (PHILIO, PHILIO_SENSOR, PHILIO_SLIM_SENSOR, 0)
PHILIO_3_IN_1_SENSOR_GEN_4_MOTION = (
PHILIO_SLIM_SENSOR_MOTION_MTII = (PHILIO, PHILIO_SENSOR, PHILIO_SLIM_SENSOR, 0)
PHILIO_3_IN_1_SENSOR_GEN_4_MOTION_MTII = (
PHILIO, PHILIO_SENSOR, PHILIO_3_IN_1_SENSOR_GEN_4, 0)
WENZHOU_SLIM_SENSOR_MOTION = (WENZHOU, PHILIO_SENSOR, PHILIO_SLIM_SENSOR, 0)
WENZHOU_SLIM_SENSOR_MOTION_MTII = (
WENZHOU, PHILIO_SENSOR, PHILIO_SLIM_SENSOR, 0)
# Workarounds
WORKAROUND_NO_OFF_EVENT = 'trigger_no_off_event'
WORKAROUND_NO_POSITION = 'workaround_no_position'
WORKAROUND_REVERSE_OPEN_CLOSE = 'reverse_open_close'
WORKAROUND_IGNORE = 'workaround_ignore'
# 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,
DEVICE_MAPPINGS_MTII = {
PHILIO_SLIM_SENSOR_MOTION_MTII: WORKAROUND_NO_OFF_EVENT,
PHILIO_3_IN_1_SENSOR_GEN_4_MOTION_MTII: WORKAROUND_NO_OFF_EVENT,
WENZHOU_SLIM_SENSOR_MOTION_MTII: WORKAROUND_NO_OFF_EVENT,
}
SOMFY_ZRTSI_CONTROLLER_MT = (SOMFY, SOMFY_ZRTSI)
FIBARO_FGRM222_MT = (FIBARO, FGRM222_SHUTTER2)
# List of workarounds by (manufacturer_id, product_type)
DEVICE_MAPPINGS_MT = {
SOMFY_ZRTSI_CONTROLLER_MT: WORKAROUND_NO_POSITION,
FIBARO_FGRM222_MT: WORKAROUND_REVERSE_OPEN_CLOSE,
}
# Component mapping devices
FIBARO_FGFS101_SENSOR_ALARM = (
FIBARO, FGFS101_FLOOD_SENSOR_TYPE, const.COMMAND_CLASS_SENSOR_ALARM)
FIBARO_FGRM222_BINARY = (
FIBARO, FGRM222_SHUTTER2, const.COMMAND_CLASS_SWITCH_BINARY)
# List of component workarounds by
# (manufacturer_id, product_type, command_class)
DEVICE_COMPONENT_MAPPING = {
FIBARO_FGFS101_SENSOR_ALARM: 'binary_sensor',
FIBARO_FGRM222_BINARY: WORKAROUND_IGNORE,
}
@ -61,7 +81,10 @@ def get_device_mapping(value):
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(
result = DEVICE_MAPPINGS_MTII.get(
(manufacturer_id, product_type, product_id, value.index))
if result:
return result
return DEVICE_MAPPINGS_MT.get((manufacturer_id, product_type))
return None