From 5ee2f4f438f8acb119308738639169138b15662c Mon Sep 17 00:00:00 2001 From: G Johansson Date: Fri, 3 Jun 2022 21:11:57 +0200 Subject: [PATCH] Sensibo Set temperature improvement (#72992) --- homeassistant/components/sensibo/climate.py | 25 ++++++------- tests/components/sensibo/fixtures/data.json | 8 ++--- tests/components/sensibo/test_climate.py | 39 +++++++++++++++------ 3 files changed, 43 insertions(+), 29 deletions(-) diff --git a/homeassistant/components/sensibo/climate.py b/homeassistant/components/sensibo/climate.py index 4b0e797a5b7..c7967d05be0 100644 --- a/homeassistant/components/sensibo/climate.py +++ b/homeassistant/components/sensibo/climate.py @@ -1,6 +1,7 @@ """Support for Sensibo wifi-enabled home thermostats.""" from __future__ import annotations +from bisect import bisect_left from typing import TYPE_CHECKING, Any import voluptuous as vol @@ -54,6 +55,14 @@ AC_STATE_TO_DATA = { } +def _find_valid_target_temp(target: int, valid_targets: list[int]) -> int: + if target <= valid_targets[0]: + return valid_targets[0] + if target >= valid_targets[-1]: + return valid_targets[-1] + return valid_targets[bisect_left(valid_targets, target)] + + async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: @@ -203,20 +212,8 @@ class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity): if temperature == self.target_temperature: return - if temperature not in self.device_data.temp_list: - # Requested temperature is not supported. - if temperature > self.device_data.temp_list[-1]: - temperature = self.device_data.temp_list[-1] - - elif temperature < self.device_data.temp_list[0]: - temperature = self.device_data.temp_list[0] - - else: - raise ValueError( - f"Target temperature has to be one off {str(self.device_data.temp_list)}" - ) - - await self._async_set_ac_state_property("targetTemperature", int(temperature)) + new_temp = _find_valid_target_temp(temperature, self.device_data.temp_list) + await self._async_set_ac_state_property("targetTemperature", new_temp) async def async_set_fan_mode(self, fan_mode: str) -> None: """Set new target fan mode.""" diff --git a/tests/components/sensibo/fixtures/data.json b/tests/components/sensibo/fixtures/data.json index c787ea5592c..6c44b44821f 100644 --- a/tests/components/sensibo/fixtures/data.json +++ b/tests/components/sensibo/fixtures/data.json @@ -251,7 +251,7 @@ }, "C": { "isNative": true, - "values": [18, 19, 20] + "values": [10, 16, 17, 18, 19, 20] } }, "fanLevels": ["quiet", "low", "medium"], @@ -267,7 +267,7 @@ }, "C": { "isNative": true, - "values": [17, 18, 19, 20] + "values": [10, 16, 17, 18, 19, 20] } }, "fanLevels": ["quiet", "low", "medium"], @@ -283,7 +283,7 @@ }, "C": { "isNative": true, - "values": [18, 19, 20] + "values": [10, 16, 17, 18, 19, 20] } }, "swing": ["stopped", "fixedTop", "fixedMiddleTop"], @@ -298,7 +298,7 @@ }, "C": { "isNative": true, - "values": [18, 19, 20, 21] + "values": [10, 16, 17, 18, 19, 20] } }, "fanLevels": ["quiet", "low", "medium"], diff --git a/tests/components/sensibo/test_climate.py b/tests/components/sensibo/test_climate.py index 79813727c15..ead4fb02d88 100644 --- a/tests/components/sensibo/test_climate.py +++ b/tests/components/sensibo/test_climate.py @@ -20,7 +20,10 @@ from homeassistant.components.climate.const import ( SERVICE_SET_SWING_MODE, SERVICE_SET_TEMPERATURE, ) -from homeassistant.components.sensibo.climate import SERVICE_ASSUME_STATE +from homeassistant.components.sensibo.climate import ( + SERVICE_ASSUME_STATE, + _find_valid_target_temp, +) from homeassistant.components.sensibo.const import DOMAIN from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( @@ -37,6 +40,21 @@ from homeassistant.util import dt from tests.common import async_fire_time_changed +async def test_climate_find_valid_targets(): + """Test function to return temperature from valid targets.""" + + valid_targets = [10, 16, 17, 18, 19, 20] + + assert _find_valid_target_temp(7, valid_targets) == 10 + assert _find_valid_target_temp(10, valid_targets) == 10 + assert _find_valid_target_temp(11, valid_targets) == 16 + assert _find_valid_target_temp(15, valid_targets) == 16 + assert _find_valid_target_temp(16, valid_targets) == 16 + assert _find_valid_target_temp(18.5, valid_targets) == 19 + assert _find_valid_target_temp(20, valid_targets) == 20 + assert _find_valid_target_temp(25, valid_targets) == 20 + + async def test_climate( hass: HomeAssistant, load_int: ConfigEntry, get_data: SensiboData ) -> None: @@ -55,7 +73,7 @@ async def test_climate( "fan_only", "off", ], - "min_temp": 17, + "min_temp": 10, "max_temp": 20, "target_temp_step": 1, "fan_modes": ["quiet", "low", "medium"], @@ -244,23 +262,22 @@ async def test_climate_temperatures( await hass.async_block_till_done() state2 = hass.states.get("climate.hallway") - assert state2.attributes["temperature"] == 17 + assert state2.attributes["temperature"] == 16 with patch( "homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property", return_value={"result": {"status": "Success"}}, ): - with pytest.raises(ValueError): - await hass.services.async_call( - CLIMATE_DOMAIN, - SERVICE_SET_TEMPERATURE, - {ATTR_ENTITY_ID: state1.entity_id, ATTR_TEMPERATURE: 18.5}, - blocking=True, - ) + await hass.services.async_call( + CLIMATE_DOMAIN, + SERVICE_SET_TEMPERATURE, + {ATTR_ENTITY_ID: state1.entity_id, ATTR_TEMPERATURE: 18.5}, + blocking=True, + ) await hass.async_block_till_done() state2 = hass.states.get("climate.hallway") - assert state2.attributes["temperature"] == 17 + assert state2.attributes["temperature"] == 19 with patch( "homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property",