From 0c8d80f37840ed081e9c0b7647b020a641510712 Mon Sep 17 00:00:00 2001 From: Jean-Marc Collin Date: Mon, 6 Nov 2023 12:31:45 +0100 Subject: [PATCH] Issue #168 - Adds slow auto-new_slow_regulation (#170) Issue #169 - Adds support for Versatile Thermostat UI Card Co-authored-by: Jean-Marc Collin --- .devcontainer/configuration.yaml | 2 +- .devcontainer/devcontainer.json | 6 +- .gitignore | 3 +- .../versatile_thermostat/base_thermostat.py | 30 ++++---- .../versatile_thermostat/climate.py | 2 +- .../versatile_thermostat/const.py | 13 +++- .../versatile_thermostat/pi_algorithm.py | 3 +- .../versatile_thermostat/services.yaml | 1 + .../thermostat_climate.py | 13 ++++ tests/test_auto_regulation.py | 8 +-- tests/test_binary_sensors.py | 2 +- tests/test_bugs.py | 2 +- tests/test_multiple_switch.py | 10 +-- tests/test_pi.py | 68 +++++++++---------- tests/test_window.py | 16 ++--- 15 files changed, 104 insertions(+), 75 deletions(-) diff --git a/.devcontainer/configuration.yaml b/.devcontainer/configuration.yaml index aafd303..8906d69 100644 --- a/.devcontainer/configuration.yaml +++ b/.devcontainer/configuration.yaml @@ -213,7 +213,7 @@ switch: frontend: extra_module_url: - - /config/www/community/better-thermostat-ui-card/better-thermostat-ui-card.js + - /config/www/community/versatile-thermostat-ui-card/versatile-thermostat-ui-card.js themes: versatile_thermostat_theme: state-binary_sensor-safety-on-color: "#FF0B0B" diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 5628f0c..3409806 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -10,7 +10,9 @@ "postCreateCommand": "./container dev-setup", "mounts": [ - "source=/Users/jmcollin/.ssh,target=/home/vscode/.ssh,type=bind,consistency=cached" + "source=/Users/jmcollin/.ssh,target=/home/vscode/.ssh,type=bind,consistency=cached", + // uncomment this to get the versatile-thermostat-ui-card + "source=${localEnv:HOME}/SugarSync/Projets/home-assistant/versatile-thermostat-ui-card/dist,target=/workspaces/versatile_thermostat/config/www/community/versatile-thermostat-ui-card,type=bind,consistency=cached" ], "customizations": { @@ -22,7 +24,7 @@ "ms-python.vscode-pylance" ], // "mounts": [ - // "source=${localWorkspaceFolder}/.devcontainer/configuration.yaml,target=/home/vscode/core/config/configuration.yaml,type=bind,consistency=cached", + // "source=${localWorkspaceFolder}/.devcontainer/configuration.yaml,target=${localWorkspaceFolder}/config/www/community/,type=bind,consistency=cached", // "source=${localWorkspaceFolder}/custom_components,target=/home/vscode/core/config/custom_components,type=bind,consistency=cached" // ], "settings": { diff --git a/.gitignore b/.gitignore index c4a90ad..67d03c4 100644 --- a/.gitignore +++ b/.gitignore @@ -107,4 +107,5 @@ dist custom_components/__init__.py __pycache__ -config/** \ No newline at end of file +config/** +custom_components/hacs diff --git a/custom_components/versatile_thermostat/base_thermostat.py b/custom_components/versatile_thermostat/base_thermostat.py index 65bda14..91cab41 100644 --- a/custom_components/versatile_thermostat/base_thermostat.py +++ b/custom_components/versatile_thermostat/base_thermostat.py @@ -621,7 +621,7 @@ async def _async_startup_internal(*_): STATE_UNAVAILABLE, STATE_UNKNOWN, ): - self._window_state = window_state.state + self._window_state = (window_state.state == STATE_ON) _LOGGER.debug( "%s - Window state have been retrieved: %s", self, @@ -954,12 +954,12 @@ def overpowering_state(self) -> bool | None: return self._overpowering_state @property - def window_state(self) -> bool | None: + def window_state(self) -> str | None: """Get the window_state""" - return self._window_state + return STATE_ON if self._window_state else STATE_OFF @property - def window_auto_state(self) -> bool | None: + def window_auto_state(self) -> str | None: """Get the window_auto_state""" return STATE_ON if self._window_auto_state else STATE_OFF @@ -1307,33 +1307,33 @@ async def try_window_condition(_): _LOGGER.debug( "Window delay condition is not satisfied. Ignore window event" ) - self._window_state = old_state.state + self._window_state = (old_state.state == STATE_ON) return _LOGGER.debug("%s - Window delay condition is satisfied", self) # if not self._saved_hvac_mode: # self._saved_hvac_mode = self._hvac_mode - if self._window_state == new_state.state: + if self._window_state == (new_state.state == STATE_ON): _LOGGER.debug("%s - no change in window state. Forget the event") return - self._window_state = new_state.state + self._window_state = (new_state.state == STATE_ON) #PR - Adding Window ByPass _LOGGER.debug("%s - Window ByPass is : %s", self, self._window_bypass_state) if self._window_bypass_state: _LOGGER.info("%s - Window ByPass is activated. Ignore window event", self) else: - if self._window_state == STATE_OFF: + if not self._window_state: _LOGGER.info( "%s - Window is closed. Restoring hvac_mode '%s'", self, self._saved_hvac_mode, ) await self.restore_hvac_mode(True) - elif self._window_state == STATE_ON: + elif self._window_state: _LOGGER.info( "%s - Window is open. Set hvac_mode to '%s'", self, HVACMode.OFF ) @@ -1827,7 +1827,7 @@ async def check_overpowering(self) -> bool: self._device_power, ) - ret = self._current_power + self._device_power >= self._current_power_max + ret = (self._current_power + self._device_power) >= self._current_power_max if not self._overpowering_state and ret and self._hvac_mode != HVACMode.OFF: _LOGGER.warning( "%s - overpowering is detected. Heater preset will be set to 'power'", @@ -2124,11 +2124,11 @@ def update_custom_attributes(self): "saved_preset_mode": self._saved_preset_mode, "saved_target_temp": self._saved_target_temp, "saved_hvac_mode": self._saved_hvac_mode, - "window_state": self._window_state, + "window_state": self.window_state, "motion_state": self._motion_state, - "overpowering_state": self._overpowering_state, + "overpowering_state": self.overpowering_state, "presence_state": self._presence_state, - "window_auto_state": self._window_auto_state, + "window_auto_state": self.window_auto_state, #PR - Adding Window ByPass "window_bypass_state": self._window_bypass_state, "security_delay_min": self._security_delay_min, @@ -2258,11 +2258,11 @@ async def service_set_window_bypass_state(self, window_bypass): """ _LOGGER.info("%s - Calling service_set_window_bypass, window_bypass: %s", self, window_bypass) self._window_bypass_state = window_bypass - if not self._window_bypass_state and self._window_state == STATE_ON: + if not self._window_bypass_state and self._window_state: _LOGGER.info("%s - Last window state was open & ByPass is now off. Set hvac_mode to '%s'", self, HVACMode.OFF) self.save_hvac_mode() await self.async_set_hvac_mode(HVACMode.OFF) - if self._window_bypass_state and self._window_state == STATE_ON: + if self._window_bypass_state and self._window_state: _LOGGER.info("%s - Last window state was open & ByPass is now on. Set hvac_mode to last available mode", self) await self.restore_hvac_mode(True) self.update_custom_attributes() diff --git a/custom_components/versatile_thermostat/climate.py b/custom_components/versatile_thermostat/climate.py index 2baadc5..ea2dc1b 100644 --- a/custom_components/versatile_thermostat/climate.py +++ b/custom_components/versatile_thermostat/climate.py @@ -111,7 +111,7 @@ async def async_setup_entry( platform.async_register_entity_service( SERVICE_SET_AUTO_REGULATION_MODE, { - vol.Required("auto_regulation_mode"): vol.In(["None", "Light", "Medium", "Strong"]), + vol.Required("auto_regulation_mode"): vol.In(["None", "Light", "Medium", "Strong", "Slow"]), }, "service_set_auto_regulation_mode", ) diff --git a/custom_components/versatile_thermostat/const.py b/custom_components/versatile_thermostat/const.py index 929e2c8..64a9af7 100644 --- a/custom_components/versatile_thermostat/const.py +++ b/custom_components/versatile_thermostat/const.py @@ -85,6 +85,7 @@ CONF_VALVE_4 = "valve_entity4_id" CONF_AUTO_REGULATION_MODE= "auto_regulation_mode" CONF_AUTO_REGULATION_NONE= "auto_regulation_none" +CONF_AUTO_REGULATION_SLOW= "auto_regulation_slow" CONF_AUTO_REGULATION_LIGHT= "auto_regulation_light" CONF_AUTO_REGULATION_MEDIUM= "auto_regulation_medium" CONF_AUTO_REGULATION_STRONG= "auto_regulation_strong" @@ -207,7 +208,7 @@ PROPORTIONAL_FUNCTION_TPI, ] -CONF_AUTO_REGULATION_MODES = [CONF_AUTO_REGULATION_NONE, CONF_AUTO_REGULATION_LIGHT, CONF_AUTO_REGULATION_MEDIUM, CONF_AUTO_REGULATION_STRONG] +CONF_AUTO_REGULATION_MODES = [CONF_AUTO_REGULATION_NONE, CONF_AUTO_REGULATION_LIGHT, CONF_AUTO_REGULATION_MEDIUM, CONF_AUTO_REGULATION_STRONG, CONF_AUTO_REGULATION_SLOW] CONF_THERMOSTAT_TYPES = [CONF_THERMOSTAT_SWITCH, CONF_THERMOSTAT_CLIMATE, CONF_THERMOSTAT_VALVE] @@ -225,6 +226,16 @@ ATTR_TOTAL_ENERGY = "total_energy" ATTR_MEAN_POWER_CYCLE = "mean_cycle_power" +# A special regulation parameter suggested by @Maia here: https://github.com/jmcollin78/versatile_thermostat/discussions/154 +class RegulationParamSlow: + """ Light parameters for slow latency regulation""" + kp:float = 0.2 # 20% of the current internal regulation offset are caused by the current difference of target temperature and room temperature + ki:float = 0.8 / 288.0 # 80% of the current internal regulation offset are caused by the average offset of the past 24 hours + k_ext:float = 1.0 / 25.0 # this will add 1°C to the offset when it's 25°C colder outdoor than indoor + offset_max:float = 2.0 # limit to a final offset of -2°C to +2°C + stabilization_threshold:float = 0.0 # this needs to be disabled as otherwise the long term accumulated error will always be reset when the temp briefly crosses from/to below/above the target + accumulated_error_threshold:float = 2.0 * 288 # this allows up to 2°C long term offset in both directions + class RegulationParamLight: """ Light parameters for regulation""" kp:float = 0.2 diff --git a/custom_components/versatile_thermostat/pi_algorithm.py b/custom_components/versatile_thermostat/pi_algorithm.py index 05403cb..c214b1b 100644 --- a/custom_components/versatile_thermostat/pi_algorithm.py +++ b/custom_components/versatile_thermostat/pi_algorithm.py @@ -55,7 +55,8 @@ def calculate_regulated_temperature(self, internal_temp: float, external_temp:fl offset = self.kp * error + self.ki * self.accumulated_error # Calculate the exterior offset - offset_ext = self.k_ext * (self.target_temp - external_temp) + # For Maia tests - use the internal_temp vs external_temp and not target_temp - external_temp + offset_ext = self.k_ext * (internal_temp - external_temp) # Capping of offset_ext total_offset = offset + offset_ext diff --git a/custom_components/versatile_thermostat/services.yaml b/custom_components/versatile_thermostat/services.yaml index 6899cb1..0a56d44 100644 --- a/custom_components/versatile_thermostat/services.yaml +++ b/custom_components/versatile_thermostat/services.yaml @@ -159,3 +159,4 @@ set_auto_regulation_mode: - "Light" - "Medium" - "Strong" + - "Slow" diff --git a/custom_components/versatile_thermostat/thermostat_climate.py b/custom_components/versatile_thermostat/thermostat_climate.py index a064d57..145ec3d 100644 --- a/custom_components/versatile_thermostat/thermostat_climate.py +++ b/custom_components/versatile_thermostat/thermostat_climate.py @@ -20,11 +20,13 @@ CONF_CLIMATE_4, CONF_AUTO_REGULATION_MODE, CONF_AUTO_REGULATION_NONE, + CONF_AUTO_REGULATION_SLOW, CONF_AUTO_REGULATION_LIGHT, CONF_AUTO_REGULATION_MEDIUM, CONF_AUTO_REGULATION_STRONG, CONF_AUTO_REGULATION_DTEMP, CONF_AUTO_REGULATION_PERIOD_MIN, + RegulationParamSlow, RegulationParamLight, RegulationParamMedium, RegulationParamStrong @@ -176,6 +178,15 @@ def choose_auto_regulation_mode(self, auto_regulation_mode): RegulationParamStrong.offset_max, RegulationParamStrong.stabilization_threshold, RegulationParamStrong.accumulated_error_threshold) + elif self._auto_regulation_mode == CONF_AUTO_REGULATION_SLOW: + self._regulation_algo = PITemperatureRegulator( + self.target_temperature, + RegulationParamSlow.kp, + RegulationParamSlow.ki, + RegulationParamSlow.k_ext, + RegulationParamSlow.offset_max, + RegulationParamSlow.stabilization_threshold, + RegulationParamSlow.accumulated_error_threshold) else: # A default empty algo (which does nothing) self._regulation_algo = PITemperatureRegulator( @@ -666,6 +677,8 @@ async def service_set_auto_regulation_mode(self, auto_regulation_mode): self.choose_auto_regulation_mode(CONF_AUTO_REGULATION_MEDIUM) elif auto_regulation_mode == "Strong": self.choose_auto_regulation_mode(CONF_AUTO_REGULATION_STRONG) + elif auto_regulation_mode == "Slow": + self.choose_auto_regulation_mode(CONF_AUTO_REGULATION_SLOW) await self._send_regulated_temperature() self.update_custom_attributes() diff --git a/tests/test_auto_regulation.py b/tests/test_auto_regulation.py index 2d74532..f572353 100644 --- a/tests/test_auto_regulation.py +++ b/tests/test_auto_regulation.py @@ -110,7 +110,7 @@ def find_my_entity(entity_id) -> ClimateEntity: with patch( "custom_components.versatile_thermostat.commons.NowClass.get_now", return_value=event_timestamp ): - await send_temperature_change_event(entity, 22, event_timestamp) + await send_temperature_change_event(entity, 23, event_timestamp) await send_ext_temperature_change_event(entity, 19, event_timestamp) # the regulated temperature should be under @@ -212,14 +212,14 @@ def find_my_entity(entity_id) -> ClimateEntity: # the regulated temperature should be under assert entity.regulated_target_temp < entity.target_temperature - assert entity.regulated_target_temp == 25-2.5 # +2.3 without round_to_nearest + assert entity.regulated_target_temp == 25-2 # +2.3 without round_to_nearest # change temperature so that the regulated temperature should slow down event_timestamp = now - timedelta(minutes=3) with patch( "custom_components.versatile_thermostat.commons.NowClass.get_now", return_value=event_timestamp ): - await send_temperature_change_event(entity, 20, event_timestamp) + await send_temperature_change_event(entity, 18, event_timestamp) await send_ext_temperature_change_event(entity, 25, event_timestamp) # the regulated temperature should be greater @@ -331,4 +331,4 @@ def find_my_entity(entity_id) -> ClimateEntity: # 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 + 1 # 0.7 without round_to_nearest \ No newline at end of file + assert entity.regulated_target_temp == 17 + 1.5 # 0.7 without round_to_nearest \ No newline at end of file diff --git a/tests/test_binary_sensors.py b/tests/test_binary_sensors.py index 7a5d834..64852f7 100644 --- a/tests/test_binary_sensors.py +++ b/tests/test_binary_sensors.py @@ -241,7 +241,7 @@ async def test_window_binary_sensors( await entity.async_set_preset_mode(PRESET_COMFORT) await entity.async_set_hvac_mode(HVACMode.HEAT) await send_temperature_change_event(entity, 15, now) - assert entity.window_state is None + assert entity.window_state is STATE_OFF await window_binary_sensor.async_my_climate_changed() assert window_binary_sensor.state is STATE_OFF diff --git a/tests/test_bugs.py b/tests/test_bugs.py index 4291227..23ae0e9 100644 --- a/tests/test_bugs.py +++ b/tests/test_bugs.py @@ -243,7 +243,7 @@ async def test_bug_66( assert entity.hvac_mode is HVACMode.HEAT assert entity.preset_mode is PRESET_BOOST assert entity.target_temperature == 19 - assert entity.window_state is None + assert entity.window_state is STATE_OFF # Open the window and let the thermostat shut down with patch( diff --git a/tests/test_multiple_switch.py b/tests/test_multiple_switch.py index f1bf7fc..b1f37bc 100644 --- a/tests/test_multiple_switch.py +++ b/tests/test_multiple_switch.py @@ -69,7 +69,7 @@ async def test_one_switch_cycle( assert entity.hvac_mode is HVACMode.HEAT assert entity.preset_mode is PRESET_BOOST assert entity.target_temperature == 19 - assert entity.window_state is None + assert entity.window_state is STATE_OFF event_timestamp = now - timedelta(minutes=4) await send_temperature_change_event(entity, 15, event_timestamp) @@ -282,7 +282,7 @@ async def test_multiple_switchs( assert entity.hvac_mode is HVACMode.HEAT assert entity.preset_mode is PRESET_BOOST assert entity.target_temperature == 19 - assert entity.window_state is None + assert entity.window_state is STATE_OFF event_timestamp = now - timedelta(minutes=4) await send_temperature_change_event(entity, 15, event_timestamp) @@ -418,7 +418,7 @@ async def test_multiple_climates( assert entity.hvac_mode is HVACMode.HEAT assert entity.preset_mode is PRESET_BOOST assert entity.target_temperature == 19 - assert entity.window_state is None + assert entity.window_state is STATE_OFF event_timestamp = now - timedelta(minutes=4) await send_temperature_change_event(entity, 15, event_timestamp) @@ -443,7 +443,7 @@ async def test_multiple_climates( assert entity.hvac_mode is HVACMode.OFF assert entity.preset_mode is PRESET_BOOST assert entity.target_temperature == 19 - assert entity.window_state is None + assert entity.window_state is STATE_OFF event_timestamp = now - timedelta(minutes=4) await send_temperature_change_event(entity, 15, event_timestamp) @@ -518,7 +518,7 @@ async def test_multiple_climates_underlying_changes( assert entity.hvac_mode is HVACMode.HEAT assert entity.preset_mode is PRESET_BOOST assert entity.target_temperature == 19 - assert entity.window_state is None + assert entity.window_state is STATE_OFF event_timestamp = now - timedelta(minutes=4) await send_temperature_change_event(entity, 15, event_timestamp) diff --git a/tests/test_pi.py b/tests/test_pi.py index 0e35b22..246add2 100644 --- a/tests/test_pi.py +++ b/tests/test_pi.py @@ -26,15 +26,15 @@ def test_pi_algorithm_basics(): # to reset the accumulated error the_algo.reset_accumulated_error() - assert the_algo.calculate_regulated_temperature(18, 10) == 21.5 # +1.5 - assert the_algo.calculate_regulated_temperature(18.1, 10) == 21.6 # +1.6 - assert the_algo.calculate_regulated_temperature(18.3, 10) == 21.6 # +1.6 - assert the_algo.calculate_regulated_temperature(18.5, 10) == 21.7 # +1.7 - assert the_algo.calculate_regulated_temperature(18.7, 10) == 21.7 # +1.7 - assert the_algo.calculate_regulated_temperature(19, 10) == 21.7 # +1.7 + assert the_algo.calculate_regulated_temperature(18, 10) == 21.3 # +1.5 + assert the_algo.calculate_regulated_temperature(18.1, 10) == 21.4 # +1.6 + assert the_algo.calculate_regulated_temperature(18.3, 10) == 21.4 # +1.6 + assert the_algo.calculate_regulated_temperature(18.5, 10) == 21.5 # +1.7 + assert the_algo.calculate_regulated_temperature(18.7, 10) == 21.6 # +1.7 + assert the_algo.calculate_regulated_temperature(19, 10) == 21.6 # +1.7 assert the_algo.calculate_regulated_temperature(20, 10) == 21.5 # +1.5 - assert the_algo.calculate_regulated_temperature(21, 10) == 20.8 # +0.8 - assert the_algo.calculate_regulated_temperature(21, 10) == 20.7 # +0.7 + assert the_algo.calculate_regulated_temperature(21, 10) == 20.9 # +0.8 + assert the_algo.calculate_regulated_temperature(21, 10) == 20.8 # +0.7 assert the_algo.calculate_regulated_temperature(20, 10) == 20.9 # +0.7 # Test temperature external @@ -54,15 +54,15 @@ def test_pi_algorithm_light(): # to reset the accumulated erro the_algo.set_target_temp(20) - assert the_algo.calculate_regulated_temperature(18, 10) == 21.5 # +1.5 - assert the_algo.calculate_regulated_temperature(18.1, 10) == 21.6 # +1.6 - assert the_algo.calculate_regulated_temperature(18.3, 10) == 21.6 # +1.6 - assert the_algo.calculate_regulated_temperature(18.5, 10) == 21.7 # +1.7 - assert the_algo.calculate_regulated_temperature(18.7, 10) == 21.7 # +1.7 - assert the_algo.calculate_regulated_temperature(19, 10) == 21.7 # +1.7 + assert the_algo.calculate_regulated_temperature(18, 10) == 21.3 # +1.5 + assert the_algo.calculate_regulated_temperature(18.1, 10) == 21.4 # +1.6 + assert the_algo.calculate_regulated_temperature(18.3, 10) == 21.4 # +1.6 + assert the_algo.calculate_regulated_temperature(18.5, 10) == 21.5 # +1.7 + assert the_algo.calculate_regulated_temperature(18.7, 10) == 21.6 # +1.7 + assert the_algo.calculate_regulated_temperature(19, 10) == 21.6 # +1.7 assert the_algo.calculate_regulated_temperature(20, 10) == 21.5 # +1.5 - assert the_algo.calculate_regulated_temperature(21, 10) == 20.8 # +0.8 - assert the_algo.calculate_regulated_temperature(21, 10) == 20.7 # +0.7 + assert the_algo.calculate_regulated_temperature(21, 10) == 20.9 # +0.8 + assert the_algo.calculate_regulated_temperature(21, 10) == 20.8 # +0.7 assert the_algo.calculate_regulated_temperature(20, 10) == 20.9 # +0.7 # Test temperature external @@ -81,15 +81,15 @@ def test_pi_algorithm_medium(): # to reset the accumulated erro the_algo.set_target_temp(20) - assert the_algo.calculate_regulated_temperature(18, 10) == 22.2 - assert the_algo.calculate_regulated_temperature(18.1, 10) == 22.3 - assert the_algo.calculate_regulated_temperature(18.3, 10) == 22.4 - assert the_algo.calculate_regulated_temperature(18.5, 10) == 22.5 - assert the_algo.calculate_regulated_temperature(18.7, 10) == 22.5 - assert the_algo.calculate_regulated_temperature(19, 10) == 22.4 + assert the_algo.calculate_regulated_temperature(18, 10) == 22.0 + assert the_algo.calculate_regulated_temperature(18.1, 10) == 22.1 + assert the_algo.calculate_regulated_temperature(18.3, 10) == 22.2 + assert the_algo.calculate_regulated_temperature(18.5, 10) == 22.3 + assert the_algo.calculate_regulated_temperature(18.7, 10) == 22.4 + assert the_algo.calculate_regulated_temperature(19, 10) == 22.3 assert the_algo.calculate_regulated_temperature(20, 10) == 21.9 + assert the_algo.calculate_regulated_temperature(21, 10) == 20.5 assert the_algo.calculate_regulated_temperature(21, 10) == 20.4 - assert the_algo.calculate_regulated_temperature(21, 10) == 20.3 assert the_algo.calculate_regulated_temperature(20, 10) == 20.8 # Test temperature external @@ -107,6 +107,7 @@ def test_pi_algorithm_medium(): the_algo.set_target_temp(20) the_algo.reset_accumulated_error() # Test the error acculation effect + assert the_algo.calculate_regulated_temperature(19, 5) == 22.0 assert the_algo.calculate_regulated_temperature(19, 5) == 22.1 assert the_algo.calculate_regulated_temperature(19, 5) == 22.2 assert the_algo.calculate_regulated_temperature(19, 5) == 22.3 @@ -119,7 +120,6 @@ def test_pi_algorithm_medium(): assert the_algo.calculate_regulated_temperature(19, 5) == 23 assert the_algo.calculate_regulated_temperature(19, 5) == 23 assert the_algo.calculate_regulated_temperature(19, 5) == 23 - assert the_algo.calculate_regulated_temperature(19, 5) == 23 def test_pi_algorithm_strong(): """ Test the PI algorithm """ @@ -131,20 +131,20 @@ def test_pi_algorithm_strong(): # to reset the accumulated erro the_algo.set_target_temp(20) - assert the_algo.calculate_regulated_temperature(18, 10) == 23.6 - assert the_algo.calculate_regulated_temperature(18.1, 10) == 23.9 - assert the_algo.calculate_regulated_temperature(18.3, 10) == 24.0 + assert the_algo.calculate_regulated_temperature(18, 10) == 23.2 + assert the_algo.calculate_regulated_temperature(18.1, 10) == 23.5 + assert the_algo.calculate_regulated_temperature(18.3, 10) == 23.8 assert the_algo.calculate_regulated_temperature(18.5, 10) == 24 assert the_algo.calculate_regulated_temperature(18.7, 10) == 24 assert the_algo.calculate_regulated_temperature(19, 10) == 24 assert the_algo.calculate_regulated_temperature(20, 10) == 23.9 + assert the_algo.calculate_regulated_temperature(21, 10) == 21.4 assert the_algo.calculate_regulated_temperature(21, 10) == 21.2 assert the_algo.calculate_regulated_temperature(21, 10) == 21 assert the_algo.calculate_regulated_temperature(21, 10) == 20.8 assert the_algo.calculate_regulated_temperature(21, 10) == 20.6 assert the_algo.calculate_regulated_temperature(21, 10) == 20.4 assert the_algo.calculate_regulated_temperature(21, 10) == 20.2 - assert the_algo.calculate_regulated_temperature(21, 10) == 20 # Test temperature external assert the_algo.calculate_regulated_temperature(20, 8) == 21.0 @@ -161,14 +161,14 @@ def test_pi_algorithm_strong(): the_algo.set_target_temp(20) the_algo.reset_accumulated_error() # Test the error acculation effect + assert the_algo.calculate_regulated_temperature(19, 10) == 22.6 assert the_algo.calculate_regulated_temperature(19, 10) == 22.8 - assert the_algo.calculate_regulated_temperature(19, 10) == 23 + assert the_algo.calculate_regulated_temperature(19, 10) == 23.0 assert the_algo.calculate_regulated_temperature(19, 10) == 23.2 assert the_algo.calculate_regulated_temperature(19, 10) == 23.4 assert the_algo.calculate_regulated_temperature(19, 10) == 23.6 assert the_algo.calculate_regulated_temperature(19, 10) == 23.8 - assert the_algo.calculate_regulated_temperature(19, 10) == 24 - assert the_algo.calculate_regulated_temperature(19, 10) == 24 - assert the_algo.calculate_regulated_temperature(19, 10) == 24 - assert the_algo.calculate_regulated_temperature(19, 10) == 24 - assert the_algo.calculate_regulated_temperature(19, 10) == 24 + assert the_algo.calculate_regulated_temperature(19, 10) == 24.0 + assert the_algo.calculate_regulated_temperature(19, 10) == 24.0 + assert the_algo.calculate_regulated_temperature(19, 10) == 24.0 + assert the_algo.calculate_regulated_temperature(19, 10) == 24.0 diff --git a/tests/test_window.py b/tests/test_window.py index 0a5f826..fd87722 100644 --- a/tests/test_window.py +++ b/tests/test_window.py @@ -64,7 +64,7 @@ async def test_window_management_time_not_enough( assert entity.overpowering_state is None assert entity.target_temperature == 19 - assert entity.window_state is None + assert entity.window_state is STATE_OFF # Open the window, but condition of time is not satisfied and check the thermostat don't turns off with patch( @@ -152,7 +152,7 @@ async def test_window_management_time_enough( assert entity.overpowering_state is None assert entity.target_temperature == 19 - assert entity.window_state is None + assert entity.window_state is STATE_OFF # change temperature to force turning on the heater with patch( @@ -294,7 +294,7 @@ async def test_window_auto_fast(hass: HomeAssistant, skip_hass_states_is_state): assert entity.overpowering_state is None assert entity.target_temperature == 21 - assert entity.window_state is None + assert entity.window_state is STATE_OFF # Make the temperature down with patch( @@ -478,7 +478,7 @@ async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_st assert entity.overpowering_state is None assert entity.target_temperature == 21 - assert entity.window_state is None + assert entity.window_state is STATE_OFF # Make the temperature down with patch( @@ -623,7 +623,7 @@ async def test_window_auto_no_on_percent( assert entity.overpowering_state is None assert entity.target_temperature == 21 - assert entity.window_state is None + assert entity.window_state is STATE_OFF # Make the temperature down with patch( @@ -728,7 +728,7 @@ async def test_window_bypass( assert entity.overpowering_state is None assert entity.target_temperature == 19 - assert entity.window_state is None + assert entity.window_state is STATE_OFF # change temperature to force turning on the heater with patch( @@ -866,7 +866,7 @@ async def test_window_auto_bypass(hass: HomeAssistant, skip_hass_states_is_state assert entity.overpowering_state is None assert entity.target_temperature == 21 - assert entity.window_state is None + assert entity.window_state is STATE_OFF # Make the temperature down with patch( @@ -973,7 +973,7 @@ async def test_window_bypass_reactivate(hass: HomeAssistant, skip_hass_states_is assert entity.overpowering_state is None assert entity.target_temperature == 19 - assert entity.window_state is None + assert entity.window_state is STATE_OFF # change temperature to force turning on the heater with patch(