From dc71b7421c075283703f7a40badc3ceef8cd282d Mon Sep 17 00:00:00 2001 From: Robert Svensson <Kane610@users.noreply.github.com> Date: Tue, 13 Oct 2020 22:11:09 +0200 Subject: [PATCH] Improve deCONZ climate platform handling unsupported commands (#41780) * Improve deCONZ climate platform * Raise valueerror if missing input * Fix linting --- homeassistant/components/deconz/climate.py | 34 ++++++++++------------ tests/components/deconz/test_climate.py | 30 +++++++++++++++++++ 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/homeassistant/components/deconz/climate.py b/homeassistant/components/deconz/climate.py index e4de5badb61..e79ed1dfb0c 100644 --- a/homeassistant/components/deconz/climate.py +++ b/homeassistant/components/deconz/climate.py @@ -16,7 +16,7 @@ from .const import ATTR_OFFSET, ATTR_VALVE, NEW_SENSOR from .deconz_device import DeconzDevice from .gateway import get_gateway_from_config_entry -SUPPORT_HVAC = [HVAC_MODE_AUTO, HVAC_MODE_HEAT, HVAC_MODE_OFF] +HVAC_MODES = {HVAC_MODE_AUTO: "auto", HVAC_MODE_HEAT: "heat", HVAC_MODE_OFF: "off"} async def async_setup_entry(hass, config_entry, async_add_entities): @@ -72,19 +72,19 @@ class DeconzThermostat(DeconzDevice, ClimateEntity): Need to be one of HVAC_MODE_*. """ - if self._device.mode in SUPPORT_HVAC: - return self._device.mode + for hass_hvac_mode, device_mode in HVAC_MODES.items(): + if self._device.mode == device_mode: + return hass_hvac_mode + if self._device.state_on: return HVAC_MODE_HEAT + return HVAC_MODE_OFF @property - def hvac_modes(self): - """Return the list of available hvac operation modes. - - Need to be a subset of HVAC_MODES. - """ - return SUPPORT_HVAC + def hvac_modes(self) -> list: + """Return the list of available hvac operation modes.""" + return list(HVAC_MODES) @property def current_temperature(self): @@ -98,21 +98,19 @@ class DeconzThermostat(DeconzDevice, ClimateEntity): async def async_set_temperature(self, **kwargs): """Set new target temperature.""" - data = {} + if ATTR_TEMPERATURE not in kwargs: + raise ValueError(f"Expected attribute {ATTR_TEMPERATURE}") - if ATTR_TEMPERATURE in kwargs: - data["heatsetpoint"] = kwargs[ATTR_TEMPERATURE] * 100 + data = {"heatsetpoint": kwargs[ATTR_TEMPERATURE] * 100} await self._device.async_set_config(data) async def async_set_hvac_mode(self, hvac_mode): """Set new target hvac mode.""" - if hvac_mode == HVAC_MODE_AUTO: - data = {"mode": "auto"} - elif hvac_mode == HVAC_MODE_HEAT: - data = {"mode": "heat"} - elif hvac_mode == HVAC_MODE_OFF: - data = {"mode": "off"} + if hvac_mode not in HVAC_MODES: + raise ValueError(f"Unsupported mode {hvac_mode}") + + data = {"mode": HVAC_MODES[hvac_mode]} await self._device.async_set_config(data) diff --git a/tests/components/deconz/test_climate.py b/tests/components/deconz/test_climate.py index 3eb893d8a6e..7e49dd3c907 100644 --- a/tests/components/deconz/test_climate.py +++ b/tests/components/deconz/test_climate.py @@ -1,6 +1,8 @@ """deCONZ climate platform tests.""" from copy import deepcopy +import pytest + from homeassistant.components import deconz import homeassistant.components.climate as climate from homeassistant.components.deconz.gateway import get_gateway_from_config_entry @@ -155,6 +157,18 @@ async def test_climate_devices(hass): "put", "/sensors/1/config", json={"mode": "off"} ) + # Service set HVAC mode to unsupported value + + with patch.object( + thermostat_device, "_request", return_value=True + ) as set_callback, pytest.raises(ValueError): + await hass.services.async_call( + climate.DOMAIN, + climate.SERVICE_SET_HVAC_MODE, + {"entity_id": "climate.thermostat", "hvac_mode": "cool"}, + blocking=True, + ) + # Service set temperature to 20 with patch.object(thermostat_device, "_request", return_value=True) as set_callback: @@ -168,6 +182,22 @@ async def test_climate_devices(hass): "put", "/sensors/1/config", json={"heatsetpoint": 2000.0} ) + # Service set temperature without providing temperature attribute + + with patch.object( + thermostat_device, "_request", return_value=True + ) as set_callback, pytest.raises(ValueError): + await hass.services.async_call( + climate.DOMAIN, + climate.SERVICE_SET_TEMPERATURE, + { + "entity_id": "climate.thermostat", + "target_temp_high": 30, + "target_temp_low": 10, + }, + blocking=True, + ) + await hass.config_entries.async_unload(config_entry.entry_id) assert len(hass.states.async_all()) == 0 -- GitLab