From e3e014bccca3e3f505eabaf7574ee495d5ed05a7 Mon Sep 17 00:00:00 2001 From: cdce8p <30130371+cdce8p@users.noreply.github.com> Date: Fri, 29 Jun 2018 16:09:46 +0200 Subject: [PATCH] Fix zwave climate operation mode mappings (#15162) --- homeassistant/components/climate/zwave.py | 33 ++++++++++++--- tests/components/climate/test_zwave.py | 49 ++++++++++++++++++++++- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/climate/zwave.py b/homeassistant/components/climate/zwave.py index c87d1507e92..52c544256b6 100644 --- a/homeassistant/components/climate/zwave.py +++ b/homeassistant/components/climate/zwave.py @@ -7,12 +7,13 @@ https://home-assistant.io/components/climate.zwave/ # Because we do not compile openzwave on CI import logging from homeassistant.components.climate import ( - DOMAIN, ClimateDevice, SUPPORT_TARGET_TEMPERATURE, SUPPORT_FAN_MODE, + DOMAIN, ClimateDevice, STATE_AUTO, STATE_COOL, STATE_HEAT, + SUPPORT_TARGET_TEMPERATURE, SUPPORT_FAN_MODE, SUPPORT_OPERATION_MODE, SUPPORT_SWING_MODE) from homeassistant.components.zwave import ZWaveDeviceEntity from homeassistant.components.zwave import async_setup_platform # noqa # pylint: disable=unused-import from homeassistant.const import ( - TEMP_CELSIUS, TEMP_FAHRENHEIT, ATTR_TEMPERATURE) + STATE_OFF, TEMP_CELSIUS, TEMP_FAHRENHEIT, ATTR_TEMPERATURE) _LOGGER = logging.getLogger(__name__) @@ -31,6 +32,15 @@ DEVICE_MAPPINGS = { REMOTEC_ZXT_120_THERMOSTAT: WORKAROUND_ZXT_120 } +STATE_MAPPINGS = { + 'Off': STATE_OFF, + 'Heat': STATE_HEAT, + 'Heat Mode': STATE_HEAT, + 'Heat (Default)': STATE_HEAT, + 'Cool': STATE_COOL, + 'Auto': STATE_AUTO, +} + def get_device(hass, values, **kwargs): """Create Z-Wave entity device.""" @@ -48,6 +58,7 @@ class ZWaveClimate(ZWaveDeviceEntity, ClimateDevice): self._current_temperature = None self._current_operation = None self._operation_list = None + self._operation_mapping = None self._operating_state = None self._current_fan_mode = None self._fan_list = None @@ -86,10 +97,21 @@ class ZWaveClimate(ZWaveDeviceEntity, ClimateDevice): """Handle the data changes for node values.""" # Operation Mode if self.values.mode: - self._current_operation = self.values.mode.data + self._operation_list = [] + self._operation_mapping = {} operation_list = self.values.mode.data_items if operation_list: - self._operation_list = list(operation_list) + for mode in operation_list: + ha_mode = STATE_MAPPINGS.get(mode) + if ha_mode and ha_mode not in self._operation_mapping: + self._operation_mapping[ha_mode] = mode + self._operation_list.append(ha_mode) + continue + self._operation_list.append(mode) + current_mode = self.values.mode.data + self._current_operation = next( + (key for key, value in self._operation_mapping.items() + if value == current_mode), current_mode) _LOGGER.debug("self._operation_list=%s", self._operation_list) _LOGGER.debug("self._current_operation=%s", self._current_operation) @@ -205,7 +227,8 @@ class ZWaveClimate(ZWaveDeviceEntity, ClimateDevice): def set_operation_mode(self, operation_mode): """Set new target operation mode.""" if self.values.mode: - self.values.mode.data = operation_mode + self.values.mode.data = self._operation_mapping.get( + operation_mode, operation_mode) def set_swing_mode(self, swing_mode): """Set new target swing mode.""" diff --git a/tests/components/climate/test_zwave.py b/tests/components/climate/test_zwave.py index fbd6ea7f798..39a85ab493f 100644 --- a/tests/components/climate/test_zwave.py +++ b/tests/components/climate/test_zwave.py @@ -1,9 +1,9 @@ """Test Z-Wave climate devices.""" import pytest -from homeassistant.components.climate import zwave +from homeassistant.components.climate import zwave, STATE_COOL, STATE_HEAT from homeassistant.const import ( - TEMP_CELSIUS, TEMP_FAHRENHEIT, ATTR_TEMPERATURE) + STATE_OFF, TEMP_CELSIUS, TEMP_FAHRENHEIT, ATTR_TEMPERATURE) from tests.mock.zwave import ( MockNode, MockValue, MockEntityValues, value_changed) @@ -46,6 +46,24 @@ def device_zxt_120(hass, mock_openzwave): yield device +@pytest.fixture +def device_mapping(hass, mock_openzwave): + """Fixture to provide a precreated climate device. Test state mapping.""" + node = MockNode() + values = MockEntityValues( + primary=MockValue(data=1, node=node), + temperature=MockValue(data=5, node=node, units=None), + mode=MockValue(data='Off', data_items=['Off', 'Cool', 'Heat'], + node=node), + fan_mode=MockValue(data='test2', data_items=[3, 4, 5], node=node), + operating_state=MockValue(data=6, node=node), + fan_state=MockValue(data=7, node=node), + ) + device = zwave.get_device(hass, node=node, values=values, node_config={}) + + yield device + + def test_zxt_120_swing_mode(device_zxt_120): """Test operation of the zxt 120 swing mode.""" device = device_zxt_120 @@ -109,6 +127,18 @@ def test_operation_value_set(device): assert device.values.mode.data == 'test_set' +def test_operation_value_set_mapping(device_mapping): + """Test values changed for climate device. Mapping.""" + device = device_mapping + assert device.values.mode.data == 'Off' + device.set_operation_mode(STATE_HEAT) + assert device.values.mode.data == 'Heat' + device.set_operation_mode(STATE_COOL) + assert device.values.mode.data == 'Cool' + device.set_operation_mode(STATE_OFF) + assert device.values.mode.data == 'Off' + + def test_fan_mode_value_set(device): """Test values changed for climate device.""" assert device.values.fan_mode.data == 'test2' @@ -140,6 +170,21 @@ def test_operation_value_changed(device): assert device.current_operation == 'test_updated' +def test_operation_value_changed_mapping(device_mapping): + """Test values changed for climate device. Mapping.""" + device = device_mapping + assert device.current_operation == 'off' + device.values.mode.data = 'Heat' + value_changed(device.values.mode) + assert device.current_operation == STATE_HEAT + device.values.mode.data = 'Cool' + value_changed(device.values.mode) + assert device.current_operation == STATE_COOL + device.values.mode.data = 'Off' + value_changed(device.values.mode) + assert device.current_operation == STATE_OFF + + def test_fan_mode_value_changed(device): """Test values changed for climate device.""" assert device.current_fan_mode == 'test2'