Prevent disabled heating warning loop while HVACMode is OFF (#374)

This commit is contained in:
Paulo Ferreira de Castro
2024-02-04 19:58:22 +00:00
committed by GitHub
parent e52666b9d9
commit a440b35815
5 changed files with 40 additions and 18 deletions

View File

@@ -799,7 +799,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
self._target_temp, self._target_temp,
self._cur_temp, self._cur_temp,
self._cur_ext_temp, self._cur_ext_temp,
self._hvac_mode == HVACMode.COOL, self._hvac_mode or HVACMode.OFF,
) )
self.hass.create_task(self._check_initial_state()) self.hass.create_task(self._check_initial_state())

View File

@@ -1,6 +1,8 @@
""" The TPI calculation module """ """ The TPI calculation module """
import logging import logging
from homeassistant.components.climate import HVACMode
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
PROPORTIONAL_FUNCTION_ATAN = "atan" PROPORTIONAL_FUNCTION_ATAN = "atan"
@@ -46,19 +48,20 @@ class PropAlgorithm:
def calculate( def calculate(
self, self,
target_temp: float, target_temp: float | None,
current_temp: float, current_temp: float | None,
ext_current_temp: float, ext_current_temp: float | None,
cooling=False, hvac_mode: HVACMode,
): ):
"""Do the calculation of the duration""" """Do the calculation of the duration"""
if target_temp is None or current_temp is None: if target_temp is None or current_temp is None:
_LOGGER.warning( log = _LOGGER.debug if hvac_mode == HVACMode.OFF else _LOGGER.warning
log(
"Proportional algorithm: calculation is not possible cause target_temp or current_temp is null. Heating/cooling will be disabled" # pylint: disable=line-too-long "Proportional algorithm: calculation is not possible cause target_temp or current_temp is null. Heating/cooling will be disabled" # pylint: disable=line-too-long
) )
self._calculated_on_percent = 0 self._calculated_on_percent = 0
else: else:
if cooling: if hvac_mode == HVACMode.COOL:
delta_temp = current_temp - target_temp delta_temp = current_temp - target_temp
delta_ext_temp = ( delta_ext_temp = (
ext_current_temp ext_current_temp

View File

@@ -183,7 +183,7 @@ class ThermostatOverSwitch(BaseThermostat):
self._target_temp, self._target_temp,
self._cur_temp, self._cur_temp,
self._cur_ext_temp, self._cur_ext_temp,
self._hvac_mode == HVACMode.COOL, self._hvac_mode or HVACMode.OFF,
) )
self.update_custom_attributes() self.update_custom_attributes()
self.async_write_ha_state() self.async_write_ha_state()

View File

@@ -234,7 +234,7 @@ class ThermostatOverValve(BaseThermostat):
self._target_temp, self._target_temp,
self._cur_temp, self._cur_temp,
self._cur_ext_temp, self._cur_ext_temp,
self._hvac_mode == HVACMode.COOL, self._hvac_mode or HVACMode.OFF,
) )
new_valve_percent = round( new_valve_percent = round(

View File

@@ -1,6 +1,9 @@
""" Test the TPI algorithm """ """ Test the TPI algorithm """
from homeassistant.components.climate import HVACMode
from custom_components.versatile_thermostat.base_thermostat import BaseThermostat from custom_components.versatile_thermostat.base_thermostat import BaseThermostat
from custom_components.versatile_thermostat.prop_algorithm import PropAlgorithm
from .commons import * # pylint: disable=wildcard-import, unused-wildcard-import from .commons import * # pylint: disable=wildcard-import, unused-wildcard-import
@@ -42,53 +45,54 @@ async def test_tpi_calculation(
hass, entry, "climate.theoverswitchmockname" hass, entry, "climate.theoverswitchmockname"
) )
assert entity assert entity
assert entity._prop_algorithm # pylint: disable=protected-access
tpi_algo = entity._prop_algorithm # pylint: disable=protected-access tpi_algo: PropAlgorithm = entity._prop_algorithm # pylint: disable=protected-access
assert tpi_algo assert tpi_algo
tpi_algo.calculate(15, 10, 7) tpi_algo.calculate(15, 10, 7, HVACMode.HEAT)
assert tpi_algo.on_percent == 1 assert tpi_algo.on_percent == 1
assert tpi_algo.calculated_on_percent == 1 assert tpi_algo.calculated_on_percent == 1
assert tpi_algo.on_time_sec == 300 assert tpi_algo.on_time_sec == 300
assert tpi_algo.off_time_sec == 0 assert tpi_algo.off_time_sec == 0
assert entity.mean_cycle_power is None # no device power configured assert entity.mean_cycle_power is None # no device power configured
tpi_algo.calculate(15, 14, 5, False) tpi_algo.calculate(15, 14, 5, HVACMode.HEAT)
assert tpi_algo.on_percent == 0.4 assert tpi_algo.on_percent == 0.4
assert tpi_algo.calculated_on_percent == 0.4 assert tpi_algo.calculated_on_percent == 0.4
assert tpi_algo.on_time_sec == 120 assert tpi_algo.on_time_sec == 120
assert tpi_algo.off_time_sec == 180 assert tpi_algo.off_time_sec == 180
tpi_algo.set_security(0.1) tpi_algo.set_security(0.1)
tpi_algo.calculate(15, 14, 5, False) tpi_algo.calculate(15, 14, 5, HVACMode.HEAT)
assert tpi_algo.on_percent == 0.1 assert tpi_algo.on_percent == 0.1
assert tpi_algo.calculated_on_percent == 0.4 assert tpi_algo.calculated_on_percent == 0.4
assert tpi_algo.on_time_sec == 30 # >= minimal_activation_delay (=30) assert tpi_algo.on_time_sec == 30 # >= minimal_activation_delay (=30)
assert tpi_algo.off_time_sec == 270 assert tpi_algo.off_time_sec == 270
tpi_algo.unset_security() tpi_algo.unset_security()
tpi_algo.calculate(15, 14, 5, False) tpi_algo.calculate(15, 14, 5, HVACMode.HEAT)
assert tpi_algo.on_percent == 0.4 assert tpi_algo.on_percent == 0.4
assert tpi_algo.calculated_on_percent == 0.4 assert tpi_algo.calculated_on_percent == 0.4
assert tpi_algo.on_time_sec == 120 assert tpi_algo.on_time_sec == 120
assert tpi_algo.off_time_sec == 180 assert tpi_algo.off_time_sec == 180
# Test minimal activation delay # Test minimal activation delay
tpi_algo.calculate(15, 14.7, 15, False) tpi_algo.calculate(15, 14.7, 15, HVACMode.HEAT)
assert tpi_algo.on_percent == 0.09 assert tpi_algo.on_percent == 0.09
assert tpi_algo.calculated_on_percent == 0.09 assert tpi_algo.calculated_on_percent == 0.09
assert tpi_algo.on_time_sec == 0 assert tpi_algo.on_time_sec == 0
assert tpi_algo.off_time_sec == 300 assert tpi_algo.off_time_sec == 300
tpi_algo.set_security(0.09) tpi_algo.set_security(0.09)
tpi_algo.calculate(15, 14.7, 15, False) tpi_algo.calculate(15, 14.7, 15, HVACMode.HEAT)
assert tpi_algo.on_percent == 0.09 assert tpi_algo.on_percent == 0.09
assert tpi_algo.calculated_on_percent == 0.09 assert tpi_algo.calculated_on_percent == 0.09
assert tpi_algo.on_time_sec == 0 assert tpi_algo.on_time_sec == 0
assert tpi_algo.off_time_sec == 300 assert tpi_algo.off_time_sec == 300
tpi_algo.unset_security() tpi_algo.unset_security()
tpi_algo.calculate(25, 30, 35, True) tpi_algo.calculate(25, 30, 35, HVACMode.COOL)
assert tpi_algo.on_percent == 1 assert tpi_algo.on_percent == 1
assert tpi_algo.calculated_on_percent == 1 assert tpi_algo.calculated_on_percent == 1
assert tpi_algo.on_time_sec == 300 assert tpi_algo.on_time_sec == 300
@@ -96,9 +100,24 @@ async def test_tpi_calculation(
assert entity.mean_cycle_power is None # no device power configured assert entity.mean_cycle_power is None # no device power configured
tpi_algo.set_security(0.09) tpi_algo.set_security(0.09)
tpi_algo.calculate(25, 30, 35, True) tpi_algo.calculate(25, 30, 35, HVACMode.COOL)
assert tpi_algo.on_percent == 0.09 assert tpi_algo.on_percent == 0.09
assert tpi_algo.calculated_on_percent == 1 assert tpi_algo.calculated_on_percent == 1
assert tpi_algo.on_time_sec == 0 assert tpi_algo.on_time_sec == 0
assert tpi_algo.off_time_sec == 300 assert tpi_algo.off_time_sec == 300
assert entity.mean_cycle_power is None # no device power configured assert entity.mean_cycle_power is None # no device power configured
tpi_algo.unset_security()
# The calculated values for HVACMode.OFF are the same as for HVACMode.HEAT.
tpi_algo.calculate(15, 10, 7, HVACMode.OFF)
assert tpi_algo.on_percent == 1
assert tpi_algo.calculated_on_percent == 1
assert tpi_algo.on_time_sec == 300
assert tpi_algo.off_time_sec == 0
# If target_temp or current_temp are None, _calculated_on_percent is set to 0.
tpi_algo.calculate(15, None, 7, HVACMode.OFF)
assert tpi_algo.on_percent == 0
assert tpi_algo.calculated_on_percent == 0
assert tpi_algo.on_time_sec == 0
assert tpi_algo.off_time_sec == 300