diff --git a/custom_components/versatile_thermostat/commons.py b/custom_components/versatile_thermostat/commons.py index d799080..4c99eff 100644 --- a/custom_components/versatile_thermostat/commons.py +++ b/custom_components/versatile_thermostat/commons.py @@ -26,10 +26,26 @@ class NowClass: def get_now(hass: HomeAssistant) -> datetime: """ A test function to get the now. For testing purpose this method can be overriden to get a specific - timestamp + timestamp. """ return datetime.now( get_tz(hass)) +def round_to_nearest(n:float, x: float)->float: + """ Round a number to the nearest x (which should be decimal but not null) + Example: + nombre1 = 3.2 + nombre2 = 4.7 + x = 0.3 + + nombre_arrondi1 = round_to_nearest(nombre1, x) + nombre_arrondi2 = round_to_nearest(nombre2, x) + + print(nombre_arrondi1) # Output: 3.3 + print(nombre_arrondi2) # Output: 4.6 + """ + assert x > 0 + return round(n * (1/x)) / (1/x) + class VersatileThermostatBaseEntity(Entity): """A base class for all entities""" diff --git a/custom_components/versatile_thermostat/thermostat_climate.py b/custom_components/versatile_thermostat/thermostat_climate.py index 347e55b..f929ba4 100644 --- a/custom_components/versatile_thermostat/thermostat_climate.py +++ b/custom_components/versatile_thermostat/thermostat_climate.py @@ -8,7 +8,7 @@ from homeassistant.helpers.event import async_track_state_change_event, async_tr from homeassistant.components.climate import HVACAction, HVACMode -from .commons import NowClass +from .commons import NowClass, round_to_nearest from .base_thermostat import BaseThermostat from .pi_algorithm import PITemperatureRegulator @@ -94,11 +94,13 @@ class ThermostatOverClimate(BaseThermostat): if not self._regulated_target_temp: self._regulated_target_temp = self.target_temperature - new_regulated_temp = self._regulation_algo.calculate_regulated_temperature(self.current_temperature, self._cur_ext_temp) + new_regulated_temp = round_to_nearest( + self._regulation_algo.calculate_regulated_temperature(self.current_temperature, self._cur_ext_temp), + self._auto_regulation_dtemp) dtemp = new_regulated_temp - self._regulated_target_temp if abs(dtemp) < self._auto_regulation_dtemp: - _LOGGER.info("!!!!! %s - dtemp (%.1f) is < %.1f -> forget the regulation send", self, dtemp, self._auto_regulation_dtemp) + _LOGGER.debug("%s - dtemp (%.1f) is < %.1f -> forget the regulation send", self, dtemp, self._auto_regulation_dtemp) return now:datetime = NowClass.get_now(self._hass) @@ -109,7 +111,7 @@ class ThermostatOverClimate(BaseThermostat): self._regulated_target_temp = new_regulated_temp - _LOGGER.info("!!!!! %s - Regulated temp have changed to %.1f. Resend it to underlyings", self, new_regulated_temp) + _LOGGER.info("%s - Regulated temp have changed to %.1f. Resend it to underlyings", self, new_regulated_temp) self._last_regulation_change = now for under in self._underlyings: diff --git a/tests/test_auto_regulation.py b/tests/test_auto_regulation.py index f9c333c..39d877a 100644 --- a/tests/test_auto_regulation.py +++ b/tests/test_auto_regulation.py @@ -100,7 +100,9 @@ async def test_over_climate_regulation(hass: HomeAssistant, skip_hass_states_is_ # the regulated temperature should be greater assert entity.regulated_target_temp > entity.target_temperature - assert entity.regulated_target_temp == 18+2.2 # In medium we could go up to +3 degre + # In medium we could go up to +3 degre + # normally the calcul gives 18 + 2.2 but we round the result to the nearest 0.5 which is 2.0 + assert entity.regulated_target_temp == 18+2.0 assert entity.hvac_action == HVACAction.HEATING # change temperature so that the regulated temperature should slow down @@ -113,7 +115,7 @@ async def test_over_climate_regulation(hass: HomeAssistant, skip_hass_states_is_ # the regulated temperature should be under assert entity.regulated_target_temp < entity.target_temperature - assert entity.regulated_target_temp == 18-0.6 + assert entity.regulated_target_temp == 18-0.5 # normally 0.6 but round_to_nearest gives 0.5 @pytest.mark.parametrize("expected_lingering_tasks", [True]) @pytest.mark.parametrize("expected_lingering_timers", [True]) @@ -210,7 +212,7 @@ async def test_over_climate_regulation_ac_mode(hass: HomeAssistant, skip_hass_st # the regulated temperature should be under assert entity.regulated_target_temp < entity.target_temperature - assert entity.regulated_target_temp == 25-2.3 + assert entity.regulated_target_temp == 25-2.5 # +2.3 without round_to_nearest # change temperature so that the regulated temperature should slow down event_timestamp = now - timedelta(minutes=3) @@ -222,7 +224,7 @@ async def test_over_climate_regulation_ac_mode(hass: HomeAssistant, skip_hass_st # the regulated temperature should be greater assert entity.regulated_target_temp > entity.target_temperature - assert entity.regulated_target_temp == 25+0.4 + assert entity.regulated_target_temp == 25+0.5 # +0.4 without round_to_nearest @pytest.mark.parametrize("expected_lingering_tasks", [True]) @pytest.mark.parametrize("expected_lingering_timers", [True]) @@ -304,7 +306,7 @@ async def test_over_climate_regulation_limitations(hass: HomeAssistant, skip_has ): await entity.async_set_temperature(temperature=17) assert entity.regulated_target_temp > entity.target_temperature - assert entity.regulated_target_temp == 18+0.7 # In medium we could go up to +3 degre + assert entity.regulated_target_temp == 18+0.5 # In medium we could go up to +3 degre. 0.7 without round_to_nearest old_regulated_temp = entity.regulated_target_temp # change temperature so that dtemp < 0.5 and time is > period_min (+ 3min) @@ -329,4 +331,4 @@ async def test_over_climate_regulation_limitations(hass: HomeAssistant, skip_has # the regulated should have been done assert entity.regulated_target_temp != old_regulated_temp assert entity.regulated_target_temp > entity.target_temperature - assert entity.regulated_target_temp == 17 + 0.7 \ No newline at end of file + assert entity.regulated_target_temp == 17 + 0.5 # 0.7 without round_to_nearest \ No newline at end of file