Added invert_percent configuration for zwave rollershutter (#23101)

* Added invert_percent configuration for zwave rollershutter

* Added invert_percent configuration for zwave rollershutter

* Fix typo in zwave default configuration
This commit is contained in:
Tommaso Marchionni 2019-06-17 23:44:47 +02:00 committed by Paulus Schoutsen
parent 7564d1fb52
commit cb5426c1fa
3 changed files with 47 additions and 8 deletions

View file

@ -47,6 +47,7 @@ ATTR_POWER = 'power_consumption'
CONF_POLLING_INTENSITY = 'polling_intensity'
CONF_IGNORED = 'ignored'
CONF_INVERT_OPENCLOSE_BUTTONS = 'invert_openclose_buttons'
CONF_INVERT_PERCENT = 'invert_percent'
CONF_REFRESH_VALUE = 'refresh_value'
CONF_REFRESH_DELAY = 'delay'
CONF_DEVICE_CONFIG = 'device_config'
@ -57,6 +58,7 @@ DATA_ZWAVE_CONFIG = 'zwave_config'
DEFAULT_CONF_IGNORED = False
DEFAULT_CONF_INVERT_OPENCLOSE_BUTTONS = False
DEFAULT_CONF_INVERT_PERCENT = False
DEFAULT_CONF_REFRESH_VALUE = False
DEFAULT_CONF_REFRESH_DELAY = 5
@ -146,6 +148,8 @@ DEVICE_CONFIG_SCHEMA_ENTRY = vol.Schema({
vol.Optional(CONF_IGNORED, default=DEFAULT_CONF_IGNORED): cv.boolean,
vol.Optional(CONF_INVERT_OPENCLOSE_BUTTONS,
default=DEFAULT_CONF_INVERT_OPENCLOSE_BUTTONS): cv.boolean,
vol.Optional(CONF_INVERT_PERCENT,
default=DEFAULT_CONF_INVERT_PERCENT): cv.boolean,
vol.Optional(CONF_REFRESH_VALUE, default=DEFAULT_CONF_REFRESH_VALUE):
cv.boolean,
vol.Optional(CONF_REFRESH_DELAY, default=DEFAULT_CONF_REFRESH_DELAY):

View file

@ -6,7 +6,8 @@ from homeassistant.components.cover import (
from homeassistant.components.cover import CoverDevice
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from . import (
ZWaveDeviceEntity, CONF_INVERT_OPENCLOSE_BUTTONS, workaround)
ZWaveDeviceEntity, CONF_INVERT_OPENCLOSE_BUTTONS, CONF_INVERT_PERCENT,
workaround)
from .const import (
COMMAND_CLASS_SWITCH_MULTILEVEL, COMMAND_CLASS_SWITCH_BINARY,
COMMAND_CLASS_BARRIER_OPERATOR, DATA_NETWORK)
@ -35,10 +36,11 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
def get_device(hass, values, node_config, **kwargs):
"""Create Z-Wave entity device."""
invert_buttons = node_config.get(CONF_INVERT_OPENCLOSE_BUTTONS)
invert_percent = node_config.get(CONF_INVERT_PERCENT)
if (values.primary.command_class ==
COMMAND_CLASS_SWITCH_MULTILEVEL
and values.primary.index == 0):
return ZwaveRollershutter(hass, values, invert_buttons)
return ZwaveRollershutter(hass, values, invert_buttons, invert_percent)
if values.primary.command_class == COMMAND_CLASS_SWITCH_BINARY:
return ZwaveGarageDoorSwitch(values)
if values.primary.command_class == \
@ -50,7 +52,7 @@ def get_device(hass, values, node_config, **kwargs):
class ZwaveRollershutter(ZWaveDeviceEntity, CoverDevice):
"""Representation of an Z-Wave cover."""
def __init__(self, hass, values, invert_buttons):
def __init__(self, hass, values, invert_buttons, invert_percent):
"""Initialize the Z-Wave rollershutter."""
ZWaveDeviceEntity.__init__(self, values, DOMAIN)
self._network = hass.data[DATA_NETWORK]
@ -58,6 +60,7 @@ class ZwaveRollershutter(ZWaveDeviceEntity, CoverDevice):
self._close_id = None
self._current_position = None
self._invert_buttons = invert_buttons
self._invert_percent = invert_percent
self._workaround = workaround.get_device_mapping(values.primary)
if self._workaround:
@ -92,12 +95,14 @@ class ZwaveRollershutter(ZWaveDeviceEntity, CoverDevice):
"""Return the current position of Zwave roller shutter."""
if self._workaround == workaround.WORKAROUND_NO_POSITION:
return None
if self._current_position is not None:
if self._current_position <= 5:
return 0
return 100 if self._invert_percent else 0
if self._current_position >= 95:
return 100
return self._current_position
return 0 if self._invert_percent else 100
return 100 - self._current_position if self._invert_percent \
else self._current_position
def open_cover(self, **kwargs):
"""Move the roller shutter up."""
@ -110,7 +115,9 @@ class ZwaveRollershutter(ZWaveDeviceEntity, CoverDevice):
def set_cover_position(self, **kwargs):
"""Move the roller shutter to a specific position."""
self.node.set_dimmer(self.values.primary.value_id,
kwargs.get(ATTR_POSITION))
(100 - kwargs.get(ATTR_POSITION))
if self._invert_percent
else kwargs.get(ATTR_POSITION))
def stop_cover(self, **kwargs):
"""Stop the roller shutter."""

View file

@ -3,7 +3,7 @@ from unittest.mock import MagicMock
from homeassistant.components.cover import SUPPORT_OPEN, SUPPORT_CLOSE
from homeassistant.components.zwave import (
const, cover, CONF_INVERT_OPENCLOSE_BUTTONS)
const, cover, CONF_INVERT_OPENCLOSE_BUTTONS, CONF_INVERT_PERCENT)
from tests.mock.zwave import (
MockNode, MockValue, MockEntityValues, value_changed)
@ -141,6 +141,34 @@ def test_roller_commands(hass, mock_openzwave):
assert value_id == open_value.value_id
def test_roller_invert_percent(hass, mock_openzwave):
"""Test position changed."""
mock_network = hass.data[const.DATA_NETWORK] = MagicMock()
node = MockNode()
value = MockValue(data=50, node=node,
command_class=const.COMMAND_CLASS_SWITCH_MULTILEVEL)
open_value = MockValue(data=False, node=node)
close_value = MockValue(data=False, node=node)
values = MockEntityValues(primary=value, open=open_value,
close=close_value, node=node)
device = cover.get_device(
hass=hass,
node=node,
values=values,
node_config={CONF_INVERT_PERCENT: True})
device.set_cover_position(position=25)
assert node.set_dimmer.called
value_id, brightness = node.set_dimmer.mock_calls[0][1]
assert value_id == value.value_id
assert brightness == 75
device.open_cover()
assert mock_network.manager.pressButton.called
value_id, = mock_network.manager.pressButton.mock_calls.pop(0)[1]
assert value_id == open_value.value_id
def test_roller_reverse_open_close(hass, mock_openzwave):
"""Test position changed."""
mock_network = hass.data[const.DATA_NETWORK] = MagicMock()