Add safety feature_safety_manager

Rename config attribute from security_ to safety_
This commit is contained in:
Jean-Marc Collin
2024-12-31 15:42:33 +00:00
parent 7ec7d3a26a
commit 6c91c197a1
42 changed files with 795 additions and 548 deletions

View File

@@ -29,6 +29,9 @@ from .const import (
CONF_AUTO_REGULATION_EXPERT, CONF_AUTO_REGULATION_EXPERT,
CONF_SHORT_EMA_PARAMS, CONF_SHORT_EMA_PARAMS,
CONF_SAFETY_MODE, CONF_SAFETY_MODE,
CONF_SAFETY_DELAY_MIN,
CONF_SAFETY_MIN_ON_PERCENT,
CONF_SAFETY_DEFAULT_ON_PERCENT,
CONF_THERMOSTAT_CENTRAL_CONFIG, CONF_THERMOSTAT_CENTRAL_CONFIG,
CONF_THERMOSTAT_TYPE, CONF_THERMOSTAT_TYPE,
CONF_USE_WINDOW_FEATURE, CONF_USE_WINDOW_FEATURE,
@@ -291,6 +294,20 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry):
]: ]:
new.pop(key, None) new.pop(key, None)
# Migration 2.0 to 2.1 -> rename security parameters into safety
if config_entry.version == CONFIG_VERSION and config_entry.minor_version == 0:
for key in [
"security_delay_min",
"security_min_on_percent",
"security_default_on_percent",
]:
new_key = key.replace("security_", "safety_")
old_value = config_entry.data.get(key, None)
if old_value is not None:
new[new_key] = old_value
new.pop(key, None)
hass.config_entries.async_update_entry( hass.config_entries.async_update_entry(
config_entry, config_entry,
data=new, data=new,

View File

@@ -70,6 +70,7 @@ from .feature_presence_manager import FeaturePresenceManager
from .feature_power_manager import FeaturePowerManager from .feature_power_manager import FeaturePowerManager
from .feature_motion_manager import FeatureMotionManager from .feature_motion_manager import FeatureMotionManager
from .feature_window_manager import FeatureWindowManager from .feature_window_manager import FeatureWindowManager
from .feature_safety_manager import FeatureSafetyManager
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@@ -102,9 +103,6 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
"saved_preset_mode", "saved_preset_mode",
"saved_target_temp", "saved_target_temp",
"saved_hvac_mode", "saved_hvac_mode",
"security_delay_min",
"security_min_on_percent",
"security_default_on_percent",
"last_temperature_datetime", "last_temperature_datetime",
"last_ext_temperature_datetime", "last_ext_temperature_datetime",
"minimal_activation_delay_sec", "minimal_activation_delay_sec",
@@ -170,11 +168,6 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
self._cur_ext_temp = None self._cur_ext_temp = None
self._should_relaunch_control_heating = None self._should_relaunch_control_heating = None
self._security_delay_min = None
self._security_min_on_percent = None
self._security_default_on_percent = None
self._security_state = None
self._thermostat_type = None self._thermostat_type = None
self._attr_translation_key = "versatile_thermostat" self._attr_translation_key = "versatile_thermostat"
@@ -224,11 +217,13 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
self._power_manager: FeaturePowerManager = FeaturePowerManager(self, hass) self._power_manager: FeaturePowerManager = FeaturePowerManager(self, hass)
self._motion_manager: FeatureMotionManager = FeatureMotionManager(self, hass) self._motion_manager: FeatureMotionManager = FeatureMotionManager(self, hass)
self._window_manager: FeatureWindowManager = FeatureWindowManager(self, hass) self._window_manager: FeatureWindowManager = FeatureWindowManager(self, hass)
self._safety_manager: FeatureSafetyManager = FeatureSafetyManager(self, hass)
self.register_manager(self._presence_manager) self.register_manager(self._presence_manager)
self.register_manager(self._power_manager) self.register_manager(self._power_manager)
self.register_manager(self._motion_manager) self.register_manager(self._motion_manager)
self.register_manager(self._window_manager) self.register_manager(self._window_manager)
self.register_manager(self._safety_manager)
self.post_init(entry_infos) self.post_init(entry_infos)
@@ -373,21 +368,9 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
) )
self._tpi_coef_ext = 0 self._tpi_coef_ext = 0
self._security_delay_min = entry_infos.get(CONF_SECURITY_DELAY_MIN)
self._security_min_on_percent = (
entry_infos.get(CONF_SECURITY_MIN_ON_PERCENT)
if entry_infos.get(CONF_SECURITY_MIN_ON_PERCENT) is not None
else DEFAULT_SECURITY_MIN_ON_PERCENT
)
self._security_default_on_percent = (
entry_infos.get(CONF_SECURITY_DEFAULT_ON_PERCENT)
if entry_infos.get(CONF_SECURITY_DEFAULT_ON_PERCENT) is not None
else DEFAULT_SECURITY_DEFAULT_ON_PERCENT
)
self._minimal_activation_delay = entry_infos.get(CONF_MINIMAL_ACTIVATION_DELAY) self._minimal_activation_delay = entry_infos.get(CONF_MINIMAL_ACTIVATION_DELAY)
self._last_temperature_measure = self.now self._last_temperature_measure = self.now
self._last_ext_temperature_measure = self.now self._last_ext_temperature_measure = self.now
self._security_state = False
# Initiate the ProportionalAlgorithm # Initiate the ProportionalAlgorithm
if self._prop_algorithm is not None: if self._prop_algorithm is not None:
@@ -619,6 +602,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
"saved_preset_mode", None "saved_preset_mode", None
) )
self._hvac_off_reason = old_state.attributes.get("hvac_mode_reason", None)
old_total_energy = old_state.attributes.get(ATTR_TOTAL_ENERGY) old_total_energy = old_state.attributes.get(ATTR_TOTAL_ENERGY)
self._total_energy = old_total_energy if old_total_energy is not None else 0 self._total_energy = old_total_energy if old_total_energy is not None else 0
_LOGGER.debug( _LOGGER.debug(
@@ -657,7 +642,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
self.send_event(EventType.HVAC_MODE_EVENT, {"hvac_mode": self._hvac_mode}) self.send_event(EventType.HVAC_MODE_EVENT, {"hvac_mode": self._hvac_mode})
_LOGGER.info( _LOGGER.info(
"%s - restored state is target_temp=%.1f, preset_mode=%s, hvac_mode=%s", "%s - restored state is target_temp=%s, preset_mode=%s, hvac_mode=%s",
self, self,
self._target_temp, self._target_temp,
self._attr_preset_mode, self._attr_preset_mode,
@@ -820,6 +805,11 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
"""Return the sensor temperature.""" """Return the sensor temperature."""
return self._cur_temp return self._cur_temp
@property
def current_outdoor_temperature(self) -> float | None:
"""Return the outdoor sensor temperature."""
return self._cur_ext_temp
@property @property
def is_aux_heat(self) -> bool | None: def is_aux_heat(self) -> bool | None:
"""Return true if aux heater. """Return true if aux heater.
@@ -861,6 +851,11 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
"""Get the window manager""" """Get the window manager"""
return self._window_manager return self._window_manager
@property
def safety_manager(self) -> FeatureSafetyManager | None:
"""Get the safety manager"""
return self._safety_manager
@property @property
def window_state(self) -> str | None: def window_state(self) -> str | None:
"""Get the window_state""" """Get the window_state"""
@@ -877,9 +872,9 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
return self._window_manager.is_window_bypass return self._window_manager.is_window_bypass
@property @property
def security_state(self) -> bool | None: def safety_state(self) -> str | None:
"""Get the security_state""" """Get the safety_state"""
return self._security_state return self._safety_manager.safety_state
@property @property
def motion_state(self) -> str | None: def motion_state(self) -> str | None:
@@ -1112,8 +1107,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
# I don't think we need to call async_write_ha_state if we didn't change the state # I don't think we need to call async_write_ha_state if we didn't change the state
return return
# In safety mode don't change preset but memorise the new expected preset when security will be off # In safety mode don't change preset but memorise the new expected preset when safety will be off
if preset_mode != PRESET_SECURITY and self._security_state: if preset_mode != PRESET_SAFETY and self._safety_manager.is_safety_detected:
_LOGGER.debug( _LOGGER.debug(
"%s - is in safety mode. Just memorise the new expected ", self "%s - is in safety mode. Just memorise the new expected ", self
) )
@@ -1182,10 +1177,10 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
else self._attr_min_temp else self._attr_min_temp
) )
if preset_mode == PRESET_SECURITY: if preset_mode == PRESET_SAFETY:
return ( return (
self._target_temp self._target_temp
) # in security just keep the current target temperature, the thermostat should be off ) # in safety just keep the current target temperature, the thermostat should be off
if preset_mode == PRESET_POWER: if preset_mode == PRESET_POWER:
return self._power_manager.power_temperature return self._power_manager.power_temperature
if preset_mode == PRESET_ACTIVITY: if preset_mode == PRESET_ACTIVITY:
@@ -1333,8 +1328,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
) )
# try to restart if we were in safety mode # try to restart if we were in safety mode
if self._security_state: if self._safety_manager.is_safety_detected:
await self.check_safety() await self._safety_manager.refresh_state()
except ValueError as err: except ValueError as err:
# La conversion a échoué, la chaîne n'est pas au format ISO 8601 # La conversion a échoué, la chaîne n'est pas au format ISO 8601
@@ -1399,8 +1394,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
) )
# try to restart if we were in safety mode # try to restart if we were in safety mode
if self._security_state: if self._safety_manager.is_safety_detected:
await self.check_safety() await self._safety_manager.refresh_state()
# check window_auto # check window_auto
return await self._window_manager.manage_window_auto() return await self._window_manager.manage_window_auto()
@@ -1426,8 +1421,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
) )
# try to restart if we were in safety mode # try to restart if we were in safety mode
if self._security_state: if self._safety_manager.is_safety_detected:
await self.check_safety() await self._safety_manager.refresh_state()
except ValueError as ex: except ValueError as ex:
_LOGGER.error("Unable to update external temperature from sensor: %s", ex) _LOGGER.error("Unable to update external temperature from sensor: %s", ex)
@@ -1572,163 +1567,6 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
"""Get now. The local datetime or the overloaded _set_now date""" """Get now. The local datetime or the overloaded _set_now date"""
return self._now if self._now is not None else NowClass.get_now(self._hass) return self._now if self._now is not None else NowClass.get_now(self._hass)
async def check_safety(self) -> bool:
"""Check if last temperature date is too long"""
now = self.now
delta_temp = (
now - self._last_temperature_measure.replace(tzinfo=self._current_tz)
).total_seconds() / 60.0
delta_ext_temp = (
now - self._last_ext_temperature_measure.replace(tzinfo=self._current_tz)
).total_seconds() / 60.0
mode_cond = self._hvac_mode != HVACMode.OFF
api: VersatileThermostatAPI = VersatileThermostatAPI.get_vtherm_api()
is_outdoor_checked = (
not api.safety_mode
or api.safety_mode.get("check_outdoor_sensor") is not False
)
temp_cond: bool = delta_temp > self._security_delay_min or (
is_outdoor_checked and delta_ext_temp > self._security_delay_min
)
climate_cond: bool = self.is_over_climate and self.hvac_action not in [
HVACAction.COOLING,
HVACAction.IDLE,
]
switch_cond: bool = (
not self.is_over_climate
and self._prop_algorithm is not None
and self._prop_algorithm.calculated_on_percent
>= self._security_min_on_percent
)
_LOGGER.debug(
"%s - checking security delta_temp=%.1f delta_ext_temp=%.1f mod_cond=%s temp_cond=%s climate_cond=%s switch_cond=%s",
self,
delta_temp,
delta_ext_temp,
mode_cond,
temp_cond,
climate_cond,
switch_cond,
)
# Issue 99 - a climate is regulated by the device itself and not by VTherm. So a VTherm should never be in security !
shouldClimateBeInSecurity = False # temp_cond and climate_cond
shouldSwitchBeInSecurity = temp_cond and switch_cond
shouldBeInSecurity = shouldClimateBeInSecurity or shouldSwitchBeInSecurity
shouldStartSecurity = (
mode_cond and not self._security_state and shouldBeInSecurity
)
# attr_preset_mode is not necessary normaly. It is just here to be sure
shouldStopSecurity = (
self._security_state
and not shouldBeInSecurity
and self._attr_preset_mode == PRESET_SECURITY
)
# Logging and event
if shouldStartSecurity:
if shouldClimateBeInSecurity:
_LOGGER.warning(
"%s - No temperature received for more than %.1f minutes (dt=%.1f, dext=%.1f) and underlying climate is %s. Setting it into safety mode",
self,
self._security_delay_min,
delta_temp,
delta_ext_temp,
self.hvac_action,
)
elif shouldSwitchBeInSecurity:
_LOGGER.warning(
"%s - No temperature received for more than %.1f minutes (dt=%.1f, dext=%.1f) and on_percent (%.2f %%) is over defined value (%.2f %%). Set it into safety mode",
self,
self._security_delay_min,
delta_temp,
delta_ext_temp,
self._prop_algorithm.on_percent * 100,
self._security_min_on_percent * 100,
)
self.send_event(
EventType.TEMPERATURE_EVENT,
{
"last_temperature_measure": self._last_temperature_measure.replace(
tzinfo=self._current_tz
).isoformat(),
"last_ext_temperature_measure": self._last_ext_temperature_measure.replace(
tzinfo=self._current_tz
).isoformat(),
"current_temp": self._cur_temp,
"current_ext_temp": self._cur_ext_temp,
"target_temp": self.target_temperature,
},
)
# Start safety mode
if shouldStartSecurity:
self._security_state = True
self.save_hvac_mode()
self.save_preset_mode()
if self._prop_algorithm:
self._prop_algorithm.set_security(self._security_default_on_percent)
await self.async_set_preset_mode_internal(PRESET_SECURITY)
# Turn off the underlying climate or heater if security default on_percent is 0
if self.is_over_climate or self._security_default_on_percent <= 0.0:
await self.async_set_hvac_mode(HVACMode.OFF, False)
self.send_event(
EventType.SECURITY_EVENT,
{
"type": "start",
"last_temperature_measure": self._last_temperature_measure.replace(
tzinfo=self._current_tz
).isoformat(),
"last_ext_temperature_measure": self._last_ext_temperature_measure.replace(
tzinfo=self._current_tz
).isoformat(),
"current_temp": self._cur_temp,
"current_ext_temp": self._cur_ext_temp,
"target_temp": self.target_temperature,
},
)
# Stop safety mode
if shouldStopSecurity:
_LOGGER.warning(
"%s - End of safety mode. restoring hvac_mode to %s and preset_mode to %s",
self,
self._saved_hvac_mode,
self._saved_preset_mode,
)
self._security_state = False
if self._prop_algorithm:
self._prop_algorithm.unset_security()
# Restore hvac_mode if previously saved
if self.is_over_climate or self._security_default_on_percent <= 0.0:
await self.restore_hvac_mode(False)
await self.restore_preset_mode()
self.send_event(
EventType.SECURITY_EVENT,
{
"type": "end",
"last_temperature_measure": self._last_temperature_measure.replace(
tzinfo=self._current_tz
).isoformat(),
"last_ext_temperature_measure": self._last_ext_temperature_measure.replace(
tzinfo=self._current_tz
).isoformat(),
"current_temp": self._cur_temp,
"current_ext_temp": self._cur_ext_temp,
"target_temp": self.target_temperature,
},
)
return shouldBeInSecurity
@property @property
def is_initialized(self) -> bool: def is_initialized(self) -> bool:
"""Check if all underlyings are initialized """Check if all underlyings are initialized
@@ -1740,10 +1578,10 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
"""The main function used to run the calculation at each cycle""" """The main function used to run the calculation at each cycle"""
_LOGGER.debug( _LOGGER.debug(
"%s - Checking new cycle. hvac_mode=%s, security_state=%s, preset_mode=%s", "%s - Checking new cycle. hvac_mode=%s, safety_state=%s, preset_mode=%s",
self, self,
self._hvac_mode, self._hvac_mode,
self._security_state, self._safety_manager.safety_state,
self._attr_preset_mode, self._attr_preset_mode,
) )
@@ -1763,9 +1601,9 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
_LOGGER.debug("%s - End of cycle (overpowering)", self) _LOGGER.debug("%s - End of cycle (overpowering)", self)
return True return True
security: bool = await self.check_safety() safety: bool = await self._safety_manager.refresh_state()
if security and self.is_over_climate: if safety and self.is_over_climate:
_LOGGER.debug("%s - End of cycle (security and over climate)", self) _LOGGER.debug("%s - End of cycle (safety and over climate)", self)
return True return True
# Stop here if we are off # Stop here if we are off
@@ -1834,16 +1672,12 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
"saved_preset_mode": self._saved_preset_mode, "saved_preset_mode": self._saved_preset_mode,
"saved_target_temp": self._saved_target_temp, "saved_target_temp": self._saved_target_temp,
"saved_hvac_mode": self._saved_hvac_mode, "saved_hvac_mode": self._saved_hvac_mode,
"security_delay_min": self._security_delay_min,
"security_min_on_percent": self._security_min_on_percent,
"security_default_on_percent": self._security_default_on_percent,
"last_temperature_datetime": self._last_temperature_measure.astimezone( "last_temperature_datetime": self._last_temperature_measure.astimezone(
self._current_tz self._current_tz
).isoformat(), ).isoformat(),
"last_ext_temperature_datetime": self._last_ext_temperature_measure.astimezone( "last_ext_temperature_datetime": self._last_ext_temperature_measure.astimezone(
self._current_tz self._current_tz
).isoformat(), ).isoformat(),
"security_state": self._security_state,
"minimal_activation_delay_sec": self._minimal_activation_delay, "minimal_activation_delay_sec": self._minimal_activation_delay,
ATTR_TOTAL_ENERGY: self.total_energy, ATTR_TOTAL_ENERGY: self.total_energy,
"last_update_datetime": self.now.isoformat(), "last_update_datetime": self.now.isoformat(),
@@ -1956,14 +1790,14 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
) )
await self.async_control_heating(force=True) await self.async_control_heating(force=True)
async def service_set_security( async def SERVICE_SET_SAFETY(
self, self,
delay_min: int | None, delay_min: int | None,
min_on_percent: float | None, min_on_percent: float | None,
default_on_percent: float | None, default_on_percent: float | None,
): ):
"""Called by a service call: """Called by a service call:
service: versatile_thermostat.set_security service: versatile_thermostat.set_safety
data: data:
delay_min: 15 delay_min: 15
min_on_percent: 0.5 min_on_percent: 0.5
@@ -1972,21 +1806,23 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
entity_id: climate.thermostat_2 entity_id: climate.thermostat_2
""" """
_LOGGER.info( _LOGGER.info(
"%s - Calling service_set_security, delay_min: %s, min_on_percent: %s %%, default_on_percent: %s %%", "%s - Calling SERVICE_SET_SAFETY, delay_min: %s, min_on_percent: %s %%, default_on_percent: %s %%",
self, self,
delay_min, delay_min,
min_on_percent * 100, min_on_percent * 100,
default_on_percent * 100, default_on_percent * 100,
) )
if delay_min: if delay_min:
self._security_delay_min = delay_min self._safety_manager.set_safety_delay_min(delay_min)
if min_on_percent: if min_on_percent:
self._security_min_on_percent = min_on_percent self._safety_manager.set_safety_min_on_percent(min_on_percent)
if default_on_percent: if default_on_percent:
self._security_default_on_percent = default_on_percent self._safety_manager.set_safety_default_on_percent(default_on_percent)
if self._prop_algorithm and self._security_state: if self._prop_algorithm:
self._prop_algorithm.set_security(self._security_default_on_percent) self._prop_algorithm.set_safety(
self._safety_manager.safety_default_on_percent
)
await self.async_control_heating() await self.async_control_heating()
self.update_custom_attributes() self.update_custom_attributes()
@@ -2070,7 +1906,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
self._support_flags = SUPPORT_FLAGS | ClimateEntityFeature.PRESET_MODE self._support_flags = SUPPORT_FLAGS | ClimateEntityFeature.PRESET_MODE
for key, _ in CONF_PRESETS.items(): for key, _ in CONF_PRESETS.items():
if self.find_preset_temp(key) > 0: preset_value = self.find_preset_temp(key)
if preset_value is not None and preset_value > 0:
self._attr_preset_modes.append(key) self._attr_preset_modes.append(key)
_LOGGER.debug( _LOGGER.debug(

View File

@@ -109,7 +109,7 @@ class SecurityBinarySensor(VersatileThermostatBaseEntity, BinarySensorEntity):
# _LOGGER.debug("%s - climate state change", self._attr_unique_id) # _LOGGER.debug("%s - climate state change", self._attr_unique_id)
old_state = self._attr_is_on old_state = self._attr_is_on
self._attr_is_on = self.my_climate.security_state is True self._attr_is_on = self.my_climate.safety_manager.is_safety_detected
if old_state != self._attr_is_on: if old_state != self._attr_is_on:
self.async_write_ha_state() self.async_write_ha_state()
return return

View File

@@ -97,13 +97,13 @@ async def async_setup_entry(
) )
platform.async_register_entity_service( platform.async_register_entity_service(
SERVICE_SET_SECURITY, SERVICE_SET_SAFETY,
{ {
vol.Optional("delay_min"): cv.positive_int, vol.Optional("delay_min"): cv.positive_int,
vol.Optional("min_on_percent"): vol.Coerce(float), vol.Optional("min_on_percent"): vol.Coerce(float),
vol.Optional("default_on_percent"): vol.Coerce(float), vol.Optional("default_on_percent"): vol.Coerce(float),
}, },
"service_set_security", "SERVICE_SET_SAFETY",
) )
platform.async_register_entity_service( platform.async_register_entity_service(

View File

@@ -6,7 +6,7 @@ from __future__ import annotations
from typing import Any from typing import Any
import logging import logging
import copy import copy
from collections.abc import Mapping from collections.abc import Mapping # pylint: disable=import-error
import voluptuous as vol import voluptuous as vol
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError

View File

@@ -368,13 +368,13 @@ STEP_PRESENCE_DATA_SCHEMA = vol.Schema( # pylint: disable=invalid-name
STEP_CENTRAL_ADVANCED_DATA_SCHEMA = vol.Schema( # pylint: disable=invalid-name STEP_CENTRAL_ADVANCED_DATA_SCHEMA = vol.Schema( # pylint: disable=invalid-name
{ {
vol.Required(CONF_MINIMAL_ACTIVATION_DELAY, default=10): cv.positive_int, vol.Required(CONF_MINIMAL_ACTIVATION_DELAY, default=10): cv.positive_int,
vol.Required(CONF_SECURITY_DELAY_MIN, default=60): cv.positive_int, vol.Required(CONF_SAFETY_DELAY_MIN, default=60): cv.positive_int,
vol.Required( vol.Required(
CONF_SECURITY_MIN_ON_PERCENT, CONF_SAFETY_MIN_ON_PERCENT,
default=DEFAULT_SECURITY_MIN_ON_PERCENT, default=DEFAULT_SECURITY_MIN_ON_PERCENT,
): vol.Coerce(float), ): vol.Coerce(float),
vol.Required( vol.Required(
CONF_SECURITY_DEFAULT_ON_PERCENT, CONF_SAFETY_DEFAULT_ON_PERCENT,
default=DEFAULT_SECURITY_DEFAULT_ON_PERCENT, default=DEFAULT_SECURITY_DEFAULT_ON_PERCENT,
): vol.Coerce(float), ): vol.Coerce(float),
} }

View File

@@ -29,7 +29,7 @@ from .prop_algorithm import (
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONFIG_VERSION = 2 CONFIG_VERSION = 2
CONFIG_MINOR_VERSION = 0 CONFIG_MINOR_VERSION = 1
PRESET_TEMP_SUFFIX = "_temp" PRESET_TEMP_SUFFIX = "_temp"
PRESET_AC_SUFFIX = "_ac" PRESET_AC_SUFFIX = "_ac"
@@ -42,10 +42,10 @@ DEVICE_MANUFACTURER = "JMCOLLIN"
DEVICE_MODEL = "Versatile Thermostat" DEVICE_MODEL = "Versatile Thermostat"
PRESET_POWER = "power" PRESET_POWER = "power"
PRESET_SECURITY = "security" PRESET_SAFETY = "security"
PRESET_FROST_PROTECTION = "frost" PRESET_FROST_PROTECTION = "frost"
HIDDEN_PRESETS = [PRESET_POWER, PRESET_SECURITY] HIDDEN_PRESETS = [PRESET_POWER, PRESET_SAFETY]
DOMAIN = "versatile_thermostat" DOMAIN = "versatile_thermostat"
@@ -84,9 +84,9 @@ CONF_PRESET_POWER = "power_temp"
CONF_MINIMAL_ACTIVATION_DELAY = "minimal_activation_delay" CONF_MINIMAL_ACTIVATION_DELAY = "minimal_activation_delay"
CONF_TEMP_MIN = "temp_min" CONF_TEMP_MIN = "temp_min"
CONF_TEMP_MAX = "temp_max" CONF_TEMP_MAX = "temp_max"
CONF_SECURITY_DELAY_MIN = "security_delay_min" CONF_SAFETY_DELAY_MIN = "safety_delay_min"
CONF_SECURITY_MIN_ON_PERCENT = "security_min_on_percent" CONF_SAFETY_MIN_ON_PERCENT = "safety_min_on_percent"
CONF_SECURITY_DEFAULT_ON_PERCENT = "security_default_on_percent" CONF_SAFETY_DEFAULT_ON_PERCENT = "safety_default_on_percent"
CONF_THERMOSTAT_TYPE = "thermostat_type" CONF_THERMOSTAT_TYPE = "thermostat_type"
CONF_THERMOSTAT_CENTRAL_CONFIG = "thermostat_central_config" CONF_THERMOSTAT_CENTRAL_CONFIG = "thermostat_central_config"
CONF_THERMOSTAT_SWITCH = "thermostat_over_switch" CONF_THERMOSTAT_SWITCH = "thermostat_over_switch"
@@ -286,9 +286,9 @@ ALL_CONF = (
CONF_MINIMAL_ACTIVATION_DELAY, CONF_MINIMAL_ACTIVATION_DELAY,
CONF_TEMP_MIN, CONF_TEMP_MIN,
CONF_TEMP_MAX, CONF_TEMP_MAX,
CONF_SECURITY_DELAY_MIN, CONF_SAFETY_DELAY_MIN,
CONF_SECURITY_MIN_ON_PERCENT, CONF_SAFETY_MIN_ON_PERCENT,
CONF_SECURITY_DEFAULT_ON_PERCENT, CONF_SAFETY_DEFAULT_ON_PERCENT,
CONF_THERMOSTAT_TYPE, CONF_THERMOSTAT_TYPE,
CONF_THERMOSTAT_SWITCH, CONF_THERMOSTAT_SWITCH,
CONF_THERMOSTAT_CLIMATE, CONF_THERMOSTAT_CLIMATE,
@@ -374,7 +374,7 @@ SUPPORT_FLAGS = (
SERVICE_SET_PRESENCE = "set_presence" SERVICE_SET_PRESENCE = "set_presence"
SERVICE_SET_PRESET_TEMPERATURE = "set_preset_temperature" SERVICE_SET_PRESET_TEMPERATURE = "set_preset_temperature"
SERVICE_SET_SECURITY = "set_security" SERVICE_SET_SAFETY = "set_safety"
SERVICE_SET_WINDOW_BYPASS = "set_window_bypass" SERVICE_SET_WINDOW_BYPASS = "set_window_bypass"
SERVICE_SET_AUTO_REGULATION_MODE = "set_auto_regulation_mode" SERVICE_SET_AUTO_REGULATION_MODE = "set_auto_regulation_mode"
SERVICE_SET_AUTO_FAN_MODE = "set_auto_fan_mode" SERVICE_SET_AUTO_FAN_MODE = "set_auto_fan_mode"

View File

@@ -211,7 +211,7 @@ class FeatureAutoStartStopManager(BaseFeatureManager):
@overrides @overrides
@property @property
def is_configured(self) -> bool: def is_configured(self) -> bool:
"""Return True of the window feature is configured""" """Return True of the aiuto-start/stop feature is configured"""
return self._is_configured return self._is_configured
@property @property

View File

@@ -0,0 +1,310 @@
# pylint: disable=line-too-long
""" Implements the Safety as a Feature Manager"""
import logging
from typing import Any
from homeassistant.const import (
STATE_ON,
STATE_OFF,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
)
from homeassistant.core import HomeAssistant
from homeassistant.components.climate import HVACMode, HVACAction
from .const import * # pylint: disable=wildcard-import, unused-wildcard-import
from .commons import ConfigData
from .base_manager import BaseFeatureManager
from .vtherm_api import VersatileThermostatAPI
_LOGGER = logging.getLogger(__name__)
class FeatureSafetyManager(BaseFeatureManager):
"""The implementation of the Safety feature"""
unrecorded_attributes = frozenset(
{
"safety_delay_min",
"safety_min_on_percent",
"safety_default_on_percent",
"is_safety_configured",
}
)
def __init__(self, vtherm: Any, hass: HomeAssistant):
"""Init of a featureManager"""
super().__init__(vtherm, hass)
self._is_configured: bool = False
self._safety_delay_min = None
self._safety_min_on_percent = None
self._safety_default_on_percent = None
self._safety_state = STATE_UNAVAILABLE
@overrides
def post_init(self, entry_infos: ConfigData):
"""Reinit of the manager"""
self._safety_delay_min = entry_infos.get(CONF_SAFETY_DELAY_MIN)
self._safety_min_on_percent = (
entry_infos.get(CONF_SAFETY_MIN_ON_PERCENT)
if entry_infos.get(CONF_SAFETY_MIN_ON_PERCENT) is not None
else DEFAULT_SECURITY_MIN_ON_PERCENT
)
self._safety_default_on_percent = (
entry_infos.get(CONF_SAFETY_DEFAULT_ON_PERCENT)
if entry_infos.get(CONF_SAFETY_DEFAULT_ON_PERCENT) is not None
else DEFAULT_SECURITY_DEFAULT_ON_PERCENT
)
self._safety_state = STATE_UNKNOWN
self._is_configured = True
@overrides
def start_listening(self):
"""Start listening the underlying entity"""
@overrides
def stop_listening(self):
"""Stop listening and remove the eventual timer still running"""
@overrides
async def refresh_state(self) -> bool:
"""Check the safety and an eventual action
Return True is safety should be active"""
if not self._is_configured:
_LOGGER.debug("%s - safety is disabled (or not configured)", self)
return False
now = self._vtherm.now
current_tz = dt_util.get_time_zone(self._hass.config.time_zone)
is_safety_detected = self.is_safety_detected
delta_temp = (
now - self._vtherm.last_temperature_measure.replace(tzinfo=current_tz)
).total_seconds() / 60.0
delta_ext_temp = (
now - self._vtherm.last_ext_temperature_measure.replace(tzinfo=current_tz)
).total_seconds() / 60.0
mode_cond = self._vtherm.hvac_mode != HVACMode.OFF
api: VersatileThermostatAPI = VersatileThermostatAPI.get_vtherm_api()
is_outdoor_checked = (
not api.safety_mode
or api.safety_mode.get("check_outdoor_sensor") is not False
)
temp_cond: bool = delta_temp > self._safety_delay_min or (
is_outdoor_checked and delta_ext_temp > self._safety_delay_min
)
climate_cond: bool = (
self._vtherm.is_over_climate
and self._vtherm.hvac_action
not in [
HVACAction.COOLING,
HVACAction.IDLE,
]
)
switch_cond: bool = (
not self._vtherm.is_over_climate
and self._vtherm.proportional_algorithm is not None
and self._vtherm.proportional_algorithm.calculated_on_percent
>= self._safety_min_on_percent
)
_LOGGER.debug(
"%s - checking safety delta_temp=%.1f delta_ext_temp=%.1f mod_cond=%s temp_cond=%s climate_cond=%s switch_cond=%s",
self,
delta_temp,
delta_ext_temp,
mode_cond,
temp_cond,
climate_cond,
switch_cond,
)
# Issue 99 - a climate is regulated by the device itself and not by VTherm. So a VTherm should never be in safety !
should_climate_be_in_security = False # temp_cond and climate_cond
should_switch_be_in_security = temp_cond and switch_cond
should_be_in_security = (
should_climate_be_in_security or should_switch_be_in_security
)
should_start_security = (
mode_cond and not is_safety_detected and should_be_in_security
)
# attr_preset_mode is not necessary normaly. It is just here to be sure
should_stop_security = (
is_safety_detected
and not should_be_in_security
and self._vtherm.preset_mode == PRESET_SAFETY
)
# Logging and event
if should_start_security:
if should_climate_be_in_security:
_LOGGER.warning(
"%s - No temperature received for more than %.1f minutes (dt=%.1f, dext=%.1f) and underlying climate is %s. Setting it into safety mode",
self,
self._safety_delay_min,
delta_temp,
delta_ext_temp,
self.hvac_action,
)
elif should_switch_be_in_security:
_LOGGER.warning(
"%s - No temperature received for more than %.1f minutes (dt=%.1f, dext=%.1f) and on_percent (%.2f %%) is over defined value (%.2f %%). Set it into safety mode",
self,
self._safety_delay_min,
delta_temp,
delta_ext_temp,
self._vtherm.proportional_algorithm.on_percent * 100,
self._safety_min_on_percent * 100,
)
self._vtherm.send_event(
EventType.TEMPERATURE_EVENT,
{
"last_temperature_measure": self._vtherm.last_temperature_measure.replace(
tzinfo=current_tz
).isoformat(),
"last_ext_temperature_measure": self._vtherm.last_ext_temperature_measure.replace(
tzinfo=current_tz
).isoformat(),
"current_temp": self._vtherm.current_temperature,
"current_ext_temp": self._vtherm.current_outdoor_temperature,
"target_temp": self._vtherm.target_temperature,
},
)
# Start safety mode
if should_start_security:
self._safety_state = STATE_ON
self._vtherm.save_hvac_mode()
self._vtherm.save_preset_mode()
if self._vtherm.proportional_algorithm:
self._vtherm.proportional_algorithm.set_safety(
self._safety_default_on_percent
)
await self._vtherm.async_set_preset_mode_internal(PRESET_SAFETY)
# Turn off the underlying climate or heater if safety default on_percent is 0
if self._vtherm.is_over_climate or self._safety_default_on_percent <= 0.0:
await self._vtherm.async_set_hvac_mode(HVACMode.OFF, False)
self._vtherm.send_event(
EventType.SECURITY_EVENT,
{
"type": "start",
"last_temperature_measure": self._vtherm.last_temperature_measure.replace(
tzinfo=current_tz
).isoformat(),
"last_ext_temperature_measure": self._vtherm.last_ext_temperature_measure.replace(
tzinfo=current_tz
).isoformat(),
"current_temp": self._vtherm.current_temperature,
"current_ext_temp": self._vtherm.current_outdoor_temperature,
"target_temp": self._vtherm.target_temperature,
},
)
# Stop safety mode
elif should_stop_security:
_LOGGER.warning(
"%s - End of safety mode. restoring hvac_mode to %s and preset_mode to %s",
self,
self._vtherm.saved_hvac_mode,
self._vtherm.saved_preset_mode,
)
self._safety_state = STATE_OFF
if self._vtherm.proportional_algorithm:
self._vtherm.proportional_algorithm.unset_safety()
# Restore hvac_mode if previously saved
if self._vtherm.is_over_climate or self._safety_default_on_percent <= 0.0:
await self._vtherm.restore_hvac_mode(False)
await self._vtherm.restore_preset_mode()
self._vtherm.send_event(
EventType.SECURITY_EVENT,
{
"type": "end",
"last_temperature_measure": self._vtherm.last_temperature_measure.replace(
tzinfo=current_tz
).isoformat(),
"last_ext_temperature_measure": self._vtherm.last_ext_temperature_measure.replace(
tzinfo=current_tz
).isoformat(),
"current_temp": self._vtherm.current_temperature,
"current_ext_temp": self._vtherm.current_outdoor_temperature,
"target_temp": self._vtherm.target_temperature,
},
)
# Initialize the safety_state if not already done
elif not should_be_in_security and self._safety_state in [STATE_UNKNOWN]:
self._safety_state = STATE_OFF
return should_be_in_security
def add_custom_attributes(self, extra_state_attributes: dict[str, Any]):
"""Add some custom attributes"""
extra_state_attributes.update(
{
"safety_delay_min": self._safety_delay_min,
"safety_min_on_percent": self._safety_min_on_percent,
"safety_default_on_percent": self._safety_default_on_percent,
"safety_state": self._safety_state,
"is_safety_configured": self._is_configured,
}
)
@overrides
@property
def is_configured(self) -> bool:
"""Return True of the safety feature is configured"""
return self._is_configured
def set_safety_delay_min(self, safety_delay_min):
"""Set the delay min"""
self._safety_delay_min = safety_delay_min
def set_safety_min_on_percent(self, safety_min_on_percent):
"""Set the min on percent"""
self._safety_min_on_percent = safety_min_on_percent
def set_safety_default_on_percent(self, safety_default_on_percent):
"""Set the default on_percent"""
self._safety_default_on_percent = safety_default_on_percent
@property
def is_safety_detected(self) -> bool:
"""Returns the is vtherm is in safety mode"""
return self._safety_state == STATE_ON
@property
def safety_state(self) -> str:
"""Returns the safety state: STATE_ON, STATE_OFF, STATE_UNKWNON, STATE_UNAVAILABLE"""
return self._safety_state
@property
def safety_delay_min(self) -> bool:
"""Returns the safety delay min"""
return self._safety_delay_min
@property
def safety_min_on_percent(self) -> bool:
"""Returns the safety min on percent"""
return self._safety_min_on_percent
@property
def safety_default_on_percent(self) -> bool:
"""Returns the safety safety_default_on_percent"""
return self._safety_default_on_percent
def __str__(self):
return f"SafetyManager-{self.name}"

View File

@@ -187,7 +187,7 @@ class PropAlgorithm:
self._off_time_sec = self._cycle_min * 60 - self._on_time_sec self._off_time_sec = self._cycle_min * 60 - self._on_time_sec
def set_security(self, default_on_percent: float): def set_safety(self, default_on_percent: float):
"""Set a default value for on_percent (used for safety mode)""" """Set a default value for on_percent (used for safety mode)"""
_LOGGER.info( _LOGGER.info(
"%s - Proportional Algo - set security to ON", self._vtherm_entity_id "%s - Proportional Algo - set security to ON", self._vtherm_entity_id
@@ -196,7 +196,7 @@ class PropAlgorithm:
self._default_on_percent = default_on_percent self._default_on_percent = default_on_percent
self._calculate_internal() self._calculate_internal()
def unset_security(self): def unset_safety(self):
"""Unset the safety mode""" """Unset the safety mode"""
_LOGGER.info( _LOGGER.info(
"%s - Proportional Algo - set security to OFF", self._vtherm_entity_id "%s - Proportional Algo - set security to OFF", self._vtherm_entity_id

View File

@@ -76,7 +76,7 @@ set_preset_temperature:
unit_of_measurement: ° unit_of_measurement: °
mode: slider mode: slider
set_security: set_safety:
name: Set safety name: Set safety
description: Change the safety parameters description: Change the safety parameters
target: target:

View File

@@ -413,7 +413,7 @@ class UnderlyingSwitch(UnderlyingEntity):
_LOGGER.debug("%s - End of cycle (3)", self) _LOGGER.debug("%s - End of cycle (3)", self)
return return
# safety mode could have change the on_time percent # safety mode could have change the on_time percent
await self._thermostat.check_safety() await self._thermostat.safety_manager.refresh_state()
time = self._on_time_sec time = self._on_time_sec
action_label = "start" action_label = "start"

View File

@@ -1053,7 +1053,7 @@ Si le thermostat est en mode ``security`` les nouveaux paramètres sont appliqu
Pour changer les paramètres de sécurité utilisez le code suivant : Pour changer les paramètres de sécurité utilisez le code suivant :
``` ```
service : versatile_thermostat.set_security service : versatile_thermostat.set_safety
data: data:
min_on_percent: "0.5" min_on_percent: "0.5"
default_on_percent: "0.1" default_on_percent: "0.1"

View File

@@ -175,7 +175,7 @@ If the thermostat is in ``security`` mode, the new settings are applied immediat
To change the security settings, use the following code: To change the security settings, use the following code:
```yaml ```yaml
service: versatile_thermostat.set_security service: versatile_thermostat.set_safety
data: data:
min_on_percent: "0.5" min_on_percent: "0.5"
default_on_percent: "0.1" default_on_percent: "0.1"

View File

@@ -1053,7 +1053,7 @@ Si le thermostat est en mode ``security`` les nouveaux paramètres sont appliqu
Pour changer les paramètres de sécurité utilisez le code suivant : Pour changer les paramètres de sécurité utilisez le code suivant :
``` ```
service : versatile_thermostat.set_security service : versatile_thermostat.set_safety
data: data:
min_on_percent: "0.5" min_on_percent: "0.5"
default_on_percent: "0.1" default_on_percent: "0.1"

View File

@@ -173,7 +173,7 @@ Si le thermostat est en mode ``security`` les nouveaux paramètres sont appliqu
Pour changer les paramètres de sécurité utilisez le code suivant : Pour changer les paramètres de sécurité utilisez le code suivant :
```yaml ```yaml
service : versatile_thermostat.set_security service : versatile_thermostat.set_safety
data: data:
min_on_percent: "0.5" min_on_percent: "0.5"
default_on_percent: "0.1" default_on_percent: "0.1"

View File

@@ -197,9 +197,9 @@ FULL_CENTRAL_CONFIG = {
CONF_PRESENCE_SENSOR: "binary_sensor.mock_presence_sensor", CONF_PRESENCE_SENSOR: "binary_sensor.mock_presence_sensor",
CONF_PRESET_POWER: 14, CONF_PRESET_POWER: 14,
CONF_MINIMAL_ACTIVATION_DELAY: 11, CONF_MINIMAL_ACTIVATION_DELAY: 11,
CONF_SECURITY_DELAY_MIN: 61, CONF_SAFETY_DELAY_MIN: 61,
CONF_SECURITY_MIN_ON_PERCENT: 0.5, CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
CONF_USE_CENTRAL_BOILER_FEATURE: False, CONF_USE_CENTRAL_BOILER_FEATURE: False,
} }
@@ -238,9 +238,9 @@ FULL_CENTRAL_CONFIG_WITH_BOILER = {
CONF_MAX_POWER_SENSOR: "sensor.mock_max_power_sensor", CONF_MAX_POWER_SENSOR: "sensor.mock_max_power_sensor",
CONF_PRESET_POWER: 14, CONF_PRESET_POWER: 14,
CONF_MINIMAL_ACTIVATION_DELAY: 11, CONF_MINIMAL_ACTIVATION_DELAY: 11,
CONF_SECURITY_DELAY_MIN: 61, CONF_SAFETY_DELAY_MIN: 61,
CONF_SECURITY_MIN_ON_PERCENT: 0.5, CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
CONF_USE_CENTRAL_BOILER_FEATURE: True, CONF_USE_CENTRAL_BOILER_FEATURE: True,
CONF_CENTRAL_BOILER_ACTIVATION_SRV: "switch.pompe_chaudiere/switch.turn_on", CONF_CENTRAL_BOILER_ACTIVATION_SRV: "switch.pompe_chaudiere/switch.turn_on",
CONF_CENTRAL_BOILER_DEACTIVATION_SRV: "switch.pompe_chaudiere/switch.turn_off", CONF_CENTRAL_BOILER_DEACTIVATION_SRV: "switch.pompe_chaudiere/switch.turn_off",

View File

@@ -89,7 +89,12 @@ MOCK_TH_OVER_SWITCH_AC_TYPE_CONFIG = {
} }
MOCK_TH_OVER_4SWITCH_TYPE_CONFIG = { MOCK_TH_OVER_4SWITCH_TYPE_CONFIG = {
CONF_UNDERLYING_LIST: ["switch.mock_4switch0", "switch.mock_4switch1","switch.mock_4switch2","switch.mock_4switch3"], CONF_UNDERLYING_LIST: [
"switch.mock_4switch0",
"switch.mock_4switch1",
"switch.mock_4switch2",
"switch.mock_4switch3",
],
CONF_HEATER_KEEP_ALIVE: 0, CONF_HEATER_KEEP_ALIVE: 0,
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI, CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
CONF_AC_MODE: False, CONF_AC_MODE: False,
@@ -195,9 +200,9 @@ MOCK_PRESENCE_AC_CONFIG = {
MOCK_ADVANCED_CONFIG = { MOCK_ADVANCED_CONFIG = {
CONF_MINIMAL_ACTIVATION_DELAY: 10, CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.4, CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
} }
MOCK_DEFAULT_FEATURE_CONFIG = { MOCK_DEFAULT_FEATURE_CONFIG = {

View File

@@ -53,8 +53,8 @@ async def test_over_climate_auto_fan_mode_turbo(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
}, },
) )
@@ -119,8 +119,8 @@ async def test_over_climate_auto_fan_mode_not_turbo(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
}, },
) )
@@ -189,8 +189,8 @@ async def test_over_climate_auto_fan_mode_turbo_activation(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
CONF_AC_MODE: True, CONF_AC_MODE: True,
}, },

View File

@@ -335,8 +335,8 @@ async def test_auto_start_stop_none_vtherm(
CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor", CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor",
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
CONF_AC_MODE: True, CONF_AC_MODE: True,
CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_NONE, CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_NONE,
@@ -426,8 +426,8 @@ async def test_auto_start_stop_medium_heat_vtherm(
CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor", CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor",
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
CONF_AC_MODE: True, CONF_AC_MODE: True,
CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_MEDIUM, CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_MEDIUM,
@@ -691,8 +691,8 @@ async def test_auto_start_stop_fast_ac_vtherm(
CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor", CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor",
CONF_UNDERLYING_LIST: ["climate.mock_climate"], CONF_UNDERLYING_LIST: ["climate.mock_climate"],
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
CONF_AC_MODE: True, CONF_AC_MODE: True,
CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST, CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST,
@@ -932,8 +932,8 @@ async def test_auto_start_stop_medium_heat_vtherm_preset_change(
CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor", CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor",
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
CONF_AC_MODE: True, CONF_AC_MODE: True,
CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST, CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST,
@@ -1145,8 +1145,8 @@ async def test_auto_start_stop_medium_heat_vtherm_preset_change_enable_false(
CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor", CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor",
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
CONF_AC_MODE: True, CONF_AC_MODE: True,
CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST, CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST,
@@ -1284,8 +1284,8 @@ async def test_auto_start_stop_fast_heat_window(
CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor", CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor",
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
CONF_AC_MODE: True, CONF_AC_MODE: True,
CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST, CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST,
@@ -1462,8 +1462,8 @@ async def test_auto_start_stop_fast_heat_window_mixed(
CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor", CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor",
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
CONF_AC_MODE: True, CONF_AC_MODE: True,
CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST, CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST,
@@ -1644,8 +1644,8 @@ async def test_auto_start_stop_disable_vtherm_off(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
CONF_AC_MODE: False, CONF_AC_MODE: False,
CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST, CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST,

View File

@@ -57,8 +57,8 @@ async def test_security_binary_sensors(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
}, },
) )
@@ -87,14 +87,14 @@ async def test_security_binary_sensors(
# set temperature to 15 so that on_percent will be > security_min_on_percent (0.2) # set temperature to 15 so that on_percent will be > security_min_on_percent (0.2)
await send_temperature_change_event(entity, 15, event_timestamp) await send_temperature_change_event(entity, 15, event_timestamp)
assert entity.security_state is True assert entity.safety_state is STATE_ON
# Simulate the event reception # Simulate the event reception
await security_binary_sensor.async_my_climate_changed() await security_binary_sensor.async_my_climate_changed()
assert security_binary_sensor.state == STATE_ON assert security_binary_sensor.state == STATE_ON
# set temperature now # set temperature now
await send_temperature_change_event(entity, 15, now) await send_temperature_change_event(entity, 15, now)
assert entity.security_state is False assert entity.safety_state is not STATE_ON
# Simulate the event reception # Simulate the event reception
await security_binary_sensor.async_my_climate_changed() await security_binary_sensor.async_my_climate_changed()
assert security_binary_sensor.state == STATE_OFF assert security_binary_sensor.state == STATE_OFF
@@ -134,8 +134,8 @@ async def test_overpowering_binary_sensors(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_POWER_SENSOR: "sensor.mock_power_sensor", CONF_POWER_SENSOR: "sensor.mock_power_sensor",
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor", CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
CONF_DEVICE_POWER: 100, CONF_DEVICE_POWER: 100,
@@ -218,8 +218,8 @@ async def test_window_binary_sensors(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
CONF_WINDOW_DELAY: 0, # important to not been obliged to wait CONF_WINDOW_DELAY: 0, # important to not been obliged to wait
}, },
@@ -306,8 +306,8 @@ async def test_motion_binary_sensors(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor", CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
CONF_MOTION_DELAY: 0, # important to not been obliged to wait CONF_MOTION_DELAY: 0, # important to not been obliged to wait
CONF_MOTION_PRESET: PRESET_BOOST, CONF_MOTION_PRESET: PRESET_BOOST,
@@ -399,8 +399,8 @@ async def test_presence_binary_sensors(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_PRESENCE_SENSOR: "binary_sensor.mock_presence_sensor", CONF_PRESENCE_SENSOR: "binary_sensor.mock_presence_sensor",
}, },
) )
@@ -482,8 +482,8 @@ async def test_binary_sensors_over_climate_minimal(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
}, },
) )

View File

@@ -63,9 +63,9 @@ async def test_bug_63(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.0, # !! here CONF_SAFETY_MIN_ON_PERCENT: 0.0, # !! here
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.0, # !! here CONF_SAFETY_DEFAULT_ON_PERCENT: 0.0, # !! here
CONF_DEVICE_POWER: 200, CONF_DEVICE_POWER: 200,
}, },
) )
@@ -75,8 +75,8 @@ async def test_bug_63(
) )
assert entity assert entity
assert entity._security_min_on_percent == 0 assert entity.safety_manager.safety_min_on_percent == 0
assert entity._security_default_on_percent == 0 assert entity.safety_manager.safety_default_on_percent == 0
# Waiting for answer in https://github.com/jmcollin78/versatile_thermostat/issues/64 # Waiting for answer in https://github.com/jmcollin78/versatile_thermostat/issues/64
@@ -115,9 +115,9 @@ async def test_bug_64(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.5, CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, # !! here CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1, # !! here
CONF_DEVICE_POWER: 200, CONF_DEVICE_POWER: 200,
}, },
) )
@@ -299,8 +299,8 @@ async def test_bug_407(hass: HomeAssistant, skip_hass_states_is_state):
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_POWER_SENSOR: "sensor.mock_power_sensor", CONF_POWER_SENSOR: "sensor.mock_power_sensor",
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor", CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
CONF_DEVICE_POWER: 100, CONF_DEVICE_POWER: 100,
@@ -510,8 +510,8 @@ async def test_bug_465(hass: HomeAssistant, skip_hass_states_is_state):
CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor", CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor",
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
CONF_AC_MODE: True, CONF_AC_MODE: True,
}, },

View File

@@ -111,9 +111,9 @@ async def test_update_central_boiler_state_simple(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
CONF_USE_MAIN_CENTRAL_CONFIG: True, CONF_USE_MAIN_CENTRAL_CONFIG: True,
CONF_USE_TPI_CENTRAL_CONFIG: True, CONF_USE_TPI_CENTRAL_CONFIG: True,
CONF_USE_PRESETS_CENTRAL_CONFIG: True, CONF_USE_PRESETS_CENTRAL_CONFIG: True,
@@ -298,9 +298,9 @@ async def test_update_central_boiler_state_multiple(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
CONF_USE_MAIN_CENTRAL_CONFIG: True, CONF_USE_MAIN_CENTRAL_CONFIG: True,
CONF_USE_TPI_CENTRAL_CONFIG: True, CONF_USE_TPI_CENTRAL_CONFIG: True,
CONF_USE_PRESETS_CENTRAL_CONFIG: True, CONF_USE_PRESETS_CENTRAL_CONFIG: True,
@@ -626,9 +626,9 @@ async def test_update_central_boiler_state_simple_valve(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
CONF_USE_MAIN_CENTRAL_CONFIG: True, CONF_USE_MAIN_CENTRAL_CONFIG: True,
CONF_USE_TPI_CENTRAL_CONFIG: True, CONF_USE_TPI_CENTRAL_CONFIG: True,
CONF_USE_PRESETS_CENTRAL_CONFIG: True, CONF_USE_PRESETS_CENTRAL_CONFIG: True,
@@ -800,9 +800,9 @@ async def test_update_central_boiler_state_simple_climate(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_UNDERLYING_LIST: [climate1.entity_id], CONF_UNDERLYING_LIST: [climate1.entity_id],
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
CONF_USE_MAIN_CENTRAL_CONFIG: True, CONF_USE_MAIN_CENTRAL_CONFIG: True,
CONF_USE_PRESETS_CENTRAL_CONFIG: True, CONF_USE_PRESETS_CENTRAL_CONFIG: True,
CONF_USE_ADVANCED_CENTRAL_CONFIG: True, CONF_USE_ADVANCED_CENTRAL_CONFIG: True,
@@ -990,9 +990,9 @@ async def test_update_central_boiler_state_simple_climate_valve_regulation(
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_HIGH, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_HIGH,
CONF_AUTO_REGULATION_USE_DEVICE_TEMP: False, CONF_AUTO_REGULATION_USE_DEVICE_TEMP: False,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
CONF_USE_MAIN_CENTRAL_CONFIG: True, CONF_USE_MAIN_CENTRAL_CONFIG: True,
CONF_USE_PRESETS_CENTRAL_CONFIG: True, CONF_USE_PRESETS_CENTRAL_CONFIG: True,
CONF_USE_ADVANCED_CENTRAL_CONFIG: True, CONF_USE_ADVANCED_CENTRAL_CONFIG: True,
@@ -1255,9 +1255,9 @@ async def test_bug_339(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: climate1.entity_id, CONF_CLIMATE: climate1.entity_id,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
CONF_USE_MAIN_CENTRAL_CONFIG: True, CONF_USE_MAIN_CENTRAL_CONFIG: True,
CONF_USE_PRESETS_CENTRAL_CONFIG: True, CONF_USE_PRESETS_CENTRAL_CONFIG: True,
CONF_USE_ADVANCED_CENTRAL_CONFIG: True, CONF_USE_ADVANCED_CENTRAL_CONFIG: True,

View File

@@ -67,9 +67,9 @@ async def test_add_a_central_config(hass: HomeAssistant, skip_hass_states_is_sta
CONF_MAX_POWER_SENSOR: "sensor.mock_central_max_power_sensor", CONF_MAX_POWER_SENSOR: "sensor.mock_central_max_power_sensor",
CONF_PRESET_POWER: 14, CONF_PRESET_POWER: 14,
CONF_MINIMAL_ACTIVATION_DELAY: 11, CONF_MINIMAL_ACTIVATION_DELAY: 11,
CONF_SECURITY_DELAY_MIN: 61, CONF_SAFETY_DELAY_MIN: 61,
CONF_SECURITY_MIN_ON_PERCENT: 0.5, CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
CONF_USE_CENTRAL_BOILER_FEATURE: False, CONF_USE_CENTRAL_BOILER_FEATURE: False,
}, },
) )
@@ -135,9 +135,9 @@ async def test_minimal_over_switch_wo_central_config(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
# CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1, # CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
# CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1, # CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1,
# CONF_WINDOW_AUTO_MAX_DURATION: 0, # Should be 0 for test # CONF_WINDOW_AUTO_MAX_DURATION: 0, # Should be 0 for test
@@ -174,9 +174,9 @@ async def test_minimal_over_switch_wo_central_config(
assert entity.proportional_algorithm._tpi_coef_int == 0.3 assert entity.proportional_algorithm._tpi_coef_int == 0.3
assert entity.proportional_algorithm._tpi_coef_ext == 0.01 assert entity.proportional_algorithm._tpi_coef_ext == 0.01
assert entity.proportional_algorithm._minimal_activation_delay == 30 assert entity.proportional_algorithm._minimal_activation_delay == 30
assert entity._security_delay_min == 5 assert entity.safety_manager.safety_delay_min == 5
assert entity._security_min_on_percent == 0.3 assert entity.safety_manager.safety_min_on_percent == 0.3
assert entity._security_default_on_percent == 0.1 assert entity.safety_manager.safety_default_on_percent == 0.1
assert entity.is_inversed assert entity.is_inversed
entity.remove_thermostat() entity.remove_thermostat()
@@ -220,9 +220,9 @@ async def test_full_over_switch_wo_central_config(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
CONF_WINDOW_DELAY: 30, CONF_WINDOW_DELAY: 30,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 3, CONF_WINDOW_AUTO_OPEN_THRESHOLD: 3,
@@ -274,9 +274,9 @@ async def test_full_over_switch_wo_central_config(
assert entity.proportional_algorithm._tpi_coef_int == 0.3 assert entity.proportional_algorithm._tpi_coef_int == 0.3
assert entity.proportional_algorithm._tpi_coef_ext == 0.01 assert entity.proportional_algorithm._tpi_coef_ext == 0.01
assert entity.proportional_algorithm._minimal_activation_delay == 30 assert entity.proportional_algorithm._minimal_activation_delay == 30
assert entity._security_delay_min == 5 assert entity.safety_manager.safety_delay_min == 5
assert entity._security_min_on_percent == 0.3 assert entity.safety_manager.safety_min_on_percent == 0.3
assert entity._security_default_on_percent == 0.1 assert entity.safety_manager.safety_default_on_percent == 0.1
assert entity.is_inversed is False assert entity.is_inversed is False
assert ( assert (
@@ -348,9 +348,9 @@ async def test_full_over_switch_with_central_config(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
CONF_WINDOW_DELAY: 30, CONF_WINDOW_DELAY: 30,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 3, CONF_WINDOW_AUTO_OPEN_THRESHOLD: 3,
@@ -401,9 +401,9 @@ async def test_full_over_switch_with_central_config(
assert entity.proportional_algorithm._tpi_coef_int == 0.5 assert entity.proportional_algorithm._tpi_coef_int == 0.5
assert entity.proportional_algorithm._tpi_coef_ext == 0.02 assert entity.proportional_algorithm._tpi_coef_ext == 0.02
assert entity.proportional_algorithm._minimal_activation_delay == 11 assert entity.proportional_algorithm._minimal_activation_delay == 11
assert entity._security_delay_min == 61 assert entity.safety_manager.safety_delay_min == 61
assert entity._security_min_on_percent == 0.5 assert entity.safety_manager.safety_min_on_percent == 0.5
assert entity._security_default_on_percent == 0.2 assert entity.safety_manager.safety_default_on_percent == 0.2
assert entity.is_inversed is False assert entity.is_inversed is False
# We have an entity so window auto is not enabled # We have an entity so window auto is not enabled
@@ -495,7 +495,7 @@ async def test_migration_of_central_config(
central_config_entry = MockConfigEntry( central_config_entry = MockConfigEntry(
version=CONFIG_VERSION, version=CONFIG_VERSION,
# An old minor version # An old minor version
minor_version=1, minor_version=0,
domain=DOMAIN, domain=DOMAIN,
title="TheCentralConfigMockName", title="TheCentralConfigMockName",
unique_id="centralConfigUniqueId", unique_id="centralConfigUniqueId",
@@ -509,9 +509,9 @@ async def test_migration_of_central_config(
CONF_TPI_COEF_INT: 0.5, CONF_TPI_COEF_INT: 0.5,
CONF_TPI_COEF_EXT: 0.02, CONF_TPI_COEF_EXT: 0.02,
CONF_MINIMAL_ACTIVATION_DELAY: 11, CONF_MINIMAL_ACTIVATION_DELAY: 11,
CONF_SECURITY_DELAY_MIN: 61, CONF_SAFETY_DELAY_MIN: 61,
CONF_SECURITY_MIN_ON_PERCENT: 0.5, CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
# The old central_boiler parameter # The old central_boiler parameter
"add_central_boiler_control": True, "add_central_boiler_control": True,
CONF_CENTRAL_BOILER_ACTIVATION_SRV: "switch.pompe_chaudiere/switch.turn_on", CONF_CENTRAL_BOILER_ACTIVATION_SRV: "switch.pompe_chaudiere/switch.turn_on",

View File

@@ -56,9 +56,9 @@ async def test_config_with_central_mode_true(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
}, },
) )
@@ -103,9 +103,9 @@ async def test_config_with_central_mode_false(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
}, },
) )
@@ -153,9 +153,9 @@ async def test_config_with_central_mode_none(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
}, },
) )
@@ -205,9 +205,9 @@ async def test_switch_change_central_mode_true(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
}, },
) )
@@ -347,9 +347,9 @@ async def test_switch_ac_change_central_mode_true(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
CONF_AC_MODE: True, CONF_AC_MODE: True,
}, },
) )
@@ -482,9 +482,9 @@ async def test_climate_ac_change_central_mode_false(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
}, },
) )
@@ -624,9 +624,9 @@ async def test_climate_ac_only_change_central_mode_true(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
}, },
) )
@@ -778,9 +778,9 @@ async def test_switch_change_central_mode_true_with_window(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
CONF_WINDOW_SENSOR: "binary_sensor.window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.window_sensor",
CONF_WINDOW_DELAY: 0, # To be not obliged to wait CONF_WINDOW_DELAY: 0, # To be not obliged to wait
CONF_MOTION_SENSOR: "input_boolean.motion_sensor", CONF_MOTION_SENSOR: "input_boolean.motion_sensor",
@@ -935,9 +935,9 @@ async def test_switch_change_central_mode_true_with_cool_only_and_window(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
CONF_WINDOW_SENSOR: "binary_sensor.window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.window_sensor",
CONF_WINDOW_DELAY: 0, # To be not obliged to wait CONF_WINDOW_DELAY: 0, # To be not obliged to wait
CONF_MOTION_SENSOR: "input_boolean.motion_sensor", CONF_MOTION_SENSOR: "input_boolean.motion_sensor",

View File

@@ -470,9 +470,9 @@ async def test_user_config_flow_over_climate(
result["flow_id"], result["flow_id"],
user_input={ user_input={
CONF_MINIMAL_ACTIVATION_DELAY: 10, CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.4, CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
}, },
) )
assert result["type"] == FlowResultType.MENU assert result["type"] == FlowResultType.MENU
@@ -496,9 +496,9 @@ async def test_user_config_flow_over_climate(
"data" "data"
] == MOCK_TH_OVER_CLIMATE_USER_CONFIG | MOCK_TH_OVER_CLIMATE_MAIN_CONFIG | MOCK_TH_OVER_CLIMATE_CENTRAL_MAIN_CONFIG | MOCK_TH_OVER_CLIMATE_TYPE_CONFIG | { ] == MOCK_TH_OVER_CLIMATE_USER_CONFIG | MOCK_TH_OVER_CLIMATE_MAIN_CONFIG | MOCK_TH_OVER_CLIMATE_CENTRAL_MAIN_CONFIG | MOCK_TH_OVER_CLIMATE_TYPE_CONFIG | {
CONF_MINIMAL_ACTIVATION_DELAY: 10, CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.4, CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
} | MOCK_DEFAULT_FEATURE_CONFIG | { } | MOCK_DEFAULT_FEATURE_CONFIG | {
CONF_USE_MAIN_CENTRAL_CONFIG: False, CONF_USE_MAIN_CENTRAL_CONFIG: False,
CONF_USE_PRESETS_CENTRAL_CONFIG: False, CONF_USE_PRESETS_CENTRAL_CONFIG: False,
@@ -1077,9 +1077,9 @@ async def test_user_config_flow_over_climate_auto_start_stop(
result["flow_id"], result["flow_id"],
user_input={ user_input={
CONF_MINIMAL_ACTIVATION_DELAY: 10, CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.4, CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
}, },
) )
assert result["type"] == FlowResultType.MENU assert result["type"] == FlowResultType.MENU
@@ -1104,9 +1104,9 @@ async def test_user_config_flow_over_climate_auto_start_stop(
"data" "data"
] == MOCK_TH_OVER_CLIMATE_USER_CONFIG | MOCK_TH_OVER_CLIMATE_MAIN_CONFIG | MOCK_TH_OVER_CLIMATE_CENTRAL_MAIN_CONFIG | MOCK_TH_OVER_CLIMATE_TYPE_CONFIG | { ] == MOCK_TH_OVER_CLIMATE_USER_CONFIG | MOCK_TH_OVER_CLIMATE_MAIN_CONFIG | MOCK_TH_OVER_CLIMATE_CENTRAL_MAIN_CONFIG | MOCK_TH_OVER_CLIMATE_TYPE_CONFIG | {
CONF_MINIMAL_ACTIVATION_DELAY: 10, CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.4, CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
} | MOCK_DEFAULT_FEATURE_CONFIG | { } | MOCK_DEFAULT_FEATURE_CONFIG | {
CONF_USE_MAIN_CENTRAL_CONFIG: False, CONF_USE_MAIN_CENTRAL_CONFIG: False,
CONF_USE_TPI_CENTRAL_CONFIG: False, CONF_USE_TPI_CENTRAL_CONFIG: False,
@@ -1274,9 +1274,9 @@ async def test_user_config_flow_over_switch_bug_552_tpi(
result["flow_id"], result["flow_id"],
user_input={ user_input={
CONF_MINIMAL_ACTIVATION_DELAY: 10, CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.4, CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
}, },
) )
@@ -1359,9 +1359,9 @@ async def test_user_config_flow_over_switch_bug_552_tpi(
CONF_TEMP_MAX: 30, CONF_TEMP_MAX: 30,
CONF_STEP_TEMPERATURE: 0.5, CONF_STEP_TEMPERATURE: 0.5,
CONF_MINIMAL_ACTIVATION_DELAY: 10, CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.4, CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
CONF_USE_MAIN_CENTRAL_CONFIG: False, CONF_USE_MAIN_CENTRAL_CONFIG: False,
CONF_USE_TPI_CENTRAL_CONFIG: False, CONF_USE_TPI_CENTRAL_CONFIG: False,
CONF_USE_PRESETS_CENTRAL_CONFIG: False, CONF_USE_PRESETS_CENTRAL_CONFIG: False,
@@ -1657,9 +1657,9 @@ async def test_user_config_flow_over_climate_valve(
result["flow_id"], result["flow_id"],
user_input={ user_input={
CONF_MINIMAL_ACTIVATION_DELAY: 10, CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.4, CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
}, },
) )
assert result["type"] == FlowResultType.MENU assert result["type"] == FlowResultType.MENU
@@ -1685,9 +1685,9 @@ async def test_user_config_flow_over_climate_valve(
"data" "data"
] == MOCK_TH_OVER_CLIMATE_USER_CONFIG | MOCK_TH_OVER_CLIMATE_MAIN_CONFIG | MOCK_TH_OVER_CLIMATE_CENTRAL_MAIN_CONFIG | MOCK_TH_OVER_CLIMATE_TYPE_CONFIG | { ] == MOCK_TH_OVER_CLIMATE_USER_CONFIG | MOCK_TH_OVER_CLIMATE_MAIN_CONFIG | MOCK_TH_OVER_CLIMATE_CENTRAL_MAIN_CONFIG | MOCK_TH_OVER_CLIMATE_TYPE_CONFIG | {
CONF_MINIMAL_ACTIVATION_DELAY: 10, CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.4, CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
} | MOCK_DEFAULT_FEATURE_CONFIG | { } | MOCK_DEFAULT_FEATURE_CONFIG | {
CONF_USE_MAIN_CENTRAL_CONFIG: False, CONF_USE_MAIN_CENTRAL_CONFIG: False,
CONF_USE_PRESETS_CENTRAL_CONFIG: False, CONF_USE_PRESETS_CENTRAL_CONFIG: False,

View File

@@ -42,8 +42,8 @@ async def test_inverted_switch(hass: HomeAssistant, skip_hass_states_is_state):
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1, CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1, CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1,
CONF_WINDOW_AUTO_MAX_DURATION: 0, # Should be 0 for test CONF_WINDOW_AUTO_MAX_DURATION: 0, # Should be 0 for test

View File

@@ -25,6 +25,12 @@ async def test_last_seen_feature(hass: HomeAssistant, skip_hass_states_is_state)
""" """
tz = get_tz(hass) # pylint: disable=invalid-name tz = get_tz(hass) # pylint: disable=invalid-name
temps = {
"frost": 7,
"eco": 17,
"comfort": 18,
"boost": 19,
}
entry = MockConfigEntry( entry = MockConfigEntry(
domain=DOMAIN, domain=DOMAIN,
@@ -39,22 +45,18 @@ async def test_last_seen_feature(hass: HomeAssistant, skip_hass_states_is_state)
"cycle_min": 5, "cycle_min": 5,
"temp_min": 15, "temp_min": 15,
"temp_max": 30, "temp_max": 30,
"frost_temp": 7,
"eco_temp": 17,
"comfort_temp": 18,
"boost_temp": 19,
"use_window_feature": False, "use_window_feature": False,
"use_motion_feature": False, "use_motion_feature": False,
"use_power_feature": False, "use_power_feature": False,
"use_presence_feature": False, "use_presence_feature": False,
"heater_entity_id": "switch.mock_switch", CONF_UNDERLYING_LIST: ["switch.mock_switch"],
"proportional_function": "tpi", "proportional_function": "tpi",
"tpi_coef_int": 0.3, "tpi_coef_int": 0.3,
"tpi_coef_ext": 0.01, "tpi_coef_ext": 0.01,
"minimal_activation_delay": 30, "minimal_activation_delay": 30,
"security_delay_min": 5, # 5 minutes CONF_SAFETY_DELAY_MIN: 5, # 5 minutes
"security_min_on_percent": 0.2, CONF_SAFETY_MIN_ON_PERCENT: 0.2,
"security_default_on_percent": 0.1, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
}, },
) )
@@ -65,8 +67,10 @@ async def test_last_seen_feature(hass: HomeAssistant, skip_hass_states_is_state)
) )
assert entity assert entity
assert entity._security_state is False await set_all_climate_preset_temp(hass, entity, temps, "theoverswitchmockname")
assert entity.preset_mode is not PRESET_SECURITY
assert entity.safety_manager.is_safety_detected is False
assert entity.preset_mode is not PRESET_SAFETY
assert entity._last_ext_temperature_measure is not None assert entity._last_ext_temperature_measure is not None
assert entity._last_temperature_measure is not None assert entity._last_temperature_measure is not None
assert (entity._last_temperature_measure.astimezone(tz) - now).total_seconds() < 1 assert (entity._last_temperature_measure.astimezone(tz) - now).total_seconds() < 1
@@ -96,13 +100,13 @@ async def test_last_seen_feature(hass: HomeAssistant, skip_hass_states_is_state)
# set temperature to 15 so that on_percent will be > security_min_on_percent (0.2) # set temperature to 15 so that on_percent will be > security_min_on_percent (0.2)
await send_temperature_change_event(entity, 15, event_timestamp) await send_temperature_change_event(entity, 15, event_timestamp)
assert entity.security_state is True assert entity.safety_state is STATE_ON
assert entity.preset_mode == PRESET_SECURITY assert entity.preset_mode == PRESET_SAFETY
assert mock_send_event.call_count == 3 assert mock_send_event.call_count == 3
mock_send_event.assert_has_calls( mock_send_event.assert_has_calls(
[ [
call.send_event(EventType.PRESET_EVENT, {"preset": PRESET_SECURITY}), call.send_event(EventType.PRESET_EVENT, {"preset": PRESET_SAFETY}),
call.send_event( call.send_event(
EventType.TEMPERATURE_EVENT, EventType.TEMPERATURE_EVENT,
{ {
@@ -135,7 +139,7 @@ async def test_last_seen_feature(hass: HomeAssistant, skip_hass_states_is_state)
# 3. change the last seen sensor # 3. change the last seen sensor
event_timestamp = now - timedelta(minutes=4) event_timestamp = now - timedelta(minutes=4)
await send_last_seen_temperature_change_event(entity, event_timestamp) await send_last_seen_temperature_change_event(entity, event_timestamp)
assert entity.security_state is False assert entity.safety_state is not STATE_ON
assert entity.preset_mode is PRESET_COMFORT assert entity.preset_mode is PRESET_COMFORT
assert entity._last_temperature_measure == event_timestamp assert entity._last_temperature_measure == event_timestamp

View File

@@ -305,8 +305,8 @@ async def test_motion_management_time_not_enough(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 10, CONF_SAFETY_DELAY_MIN: 10,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor", CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
CONF_MOTION_DELAY: 10, # important to not been obliged to wait CONF_MOTION_DELAY: 10, # important to not been obliged to wait
CONF_MOTION_OFF_DELAY: 30, CONF_MOTION_OFF_DELAY: 30,
@@ -522,8 +522,8 @@ async def test_motion_management_time_enough_and_presence(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor", CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
CONF_MOTION_DELAY: 0, # important to not been obliged to wait CONF_MOTION_DELAY: 0, # important to not been obliged to wait
CONF_MOTION_PRESET: "boost", CONF_MOTION_PRESET: "boost",
@@ -653,8 +653,8 @@ async def test_motion_management_time_enough_and_not_presence(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor", CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
CONF_MOTION_DELAY: 0, # important to not been obliged to wait CONF_MOTION_DELAY: 0, # important to not been obliged to wait
CONF_MOTION_PRESET: "boost", CONF_MOTION_PRESET: "boost",
@@ -785,8 +785,8 @@ async def test_motion_management_with_stop_during_condition(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor", CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
CONF_MOTION_DELAY: 10, CONF_MOTION_DELAY: 10,
CONF_MOTION_OFF_DELAY: 30, CONF_MOTION_OFF_DELAY: 30,
@@ -921,8 +921,8 @@ async def test_motion_management_with_stop_during_condition_last_state_on(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor", CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
CONF_MOTION_DELAY: 10, CONF_MOTION_DELAY: 10,
CONF_MOTION_OFF_DELAY: 30, CONF_MOTION_OFF_DELAY: 30,

View File

@@ -45,8 +45,8 @@ async def test_one_switch_cycle(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_HEATER: "switch.mock_switch1", CONF_HEATER: "switch.mock_switch1",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI, CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
@@ -262,8 +262,8 @@ async def test_multiple_switchs(
CONF_HEATER_4: "switch.mock_switch4", CONF_HEATER_4: "switch.mock_switch4",
CONF_HEATER_KEEP_ALIVE: 0, CONF_HEATER_KEEP_ALIVE: 0,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI, CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
@@ -402,8 +402,8 @@ async def test_multiple_climates(
CONF_CLIMATE_3: "switch.mock_climate3", CONF_CLIMATE_3: "switch.mock_climate3",
CONF_CLIMATE_4: "switch.mock_climate4", CONF_CLIMATE_4: "switch.mock_climate4",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
}, },
) )
@@ -503,8 +503,8 @@ async def test_multiple_climates_underlying_changes(
CONF_CLIMATE_3: "switch.mock_climate3", CONF_CLIMATE_3: "switch.mock_climate3",
CONF_CLIMATE_4: "switch.mock_climate4", CONF_CLIMATE_4: "switch.mock_climate4",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
}, },
) )
@@ -648,8 +648,8 @@ async def test_multiple_climates_underlying_changes_not_aligned(
CONF_CLIMATE_3: "switch.mock_climate3", CONF_CLIMATE_3: "switch.mock_climate3",
CONF_CLIMATE_4: "switch.mock_climate4", CONF_CLIMATE_4: "switch.mock_climate4",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
}, },
) )
@@ -750,8 +750,8 @@ async def test_multiple_switch_power_management(
CONF_HEATER_4: "switch.mock_switch4", CONF_HEATER_4: "switch.mock_switch4",
CONF_HEATER_KEEP_ALIVE: 0, CONF_HEATER_KEEP_ALIVE: 0,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI, CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,

View File

@@ -62,8 +62,8 @@ async def test_bug_56(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
}, },
) )
@@ -151,7 +151,7 @@ async def test_bug_82(
PRESET_BOOST, PRESET_BOOST,
] ]
assert entity.preset_mode is PRESET_NONE assert entity.preset_mode is PRESET_NONE
assert entity._security_state is False assert entity.safety_manager.is_safety_detected is False
# should have been called with EventType.PRESET_EVENT and EventType.HVAC_MODE_EVENT # should have been called with EventType.PRESET_EVENT and EventType.HVAC_MODE_EVENT
assert mock_send_event.call_count == 2 assert mock_send_event.call_count == 2
@@ -194,7 +194,7 @@ async def test_bug_82(
# set temperature to 15 so that on_percent will be > security_min_on_percent (0.2) # set temperature to 15 so that on_percent will be > security_min_on_percent (0.2)
await send_temperature_change_event(entity, 15, event_timestamp) await send_temperature_change_event(entity, 15, event_timestamp)
# Should stay False # Should stay False
assert entity.security_state is False assert entity.safety_state is not STATE_ON
assert entity.preset_mode == "none" assert entity.preset_mode == "none"
assert entity._saved_preset_mode == "none" assert entity._saved_preset_mode == "none"
@@ -641,8 +641,8 @@ async def test_bug_524(hass: HomeAssistant, skip_hass_states_is_state):
CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor", CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor",
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
CONF_AC_MODE: True, CONF_AC_MODE: True,
}, },
@@ -904,8 +904,8 @@ async def test_manual_hvac_off_should_take_the_lead_over_window(
CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor", CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor",
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
CONF_AC_MODE: True, CONF_AC_MODE: True,
CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST, CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST,
@@ -1081,8 +1081,8 @@ async def test_manual_hvac_off_should_take_the_lead_over_auto_start_stop(
CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor", CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor",
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO, CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
CONF_AC_MODE: True, CONF_AC_MODE: True,
CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST, CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST,

View File

@@ -111,7 +111,7 @@ async def test_over_climate_valve_mono(hass: HomeAssistant, skip_hass_states_get
PRESET_BOOST, PRESET_BOOST,
] ]
assert vtherm.preset_mode is PRESET_NONE assert vtherm.preset_mode is PRESET_NONE
assert vtherm._security_state is False assert vtherm.safety_manager.is_safety_detected is False
assert vtherm.window_state is STATE_UNAVAILABLE assert vtherm.window_state is STATE_UNAVAILABLE
assert vtherm.motion_state is STATE_UNAVAILABLE assert vtherm.motion_state is STATE_UNAVAILABLE
assert vtherm.presence_state is STATE_UNAVAILABLE assert vtherm.presence_state is STATE_UNAVAILABLE

View File

@@ -269,8 +269,8 @@ async def test_power_management_hvac_off(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_POWER_SENSOR: "sensor.mock_power_sensor", CONF_POWER_SENSOR: "sensor.mock_power_sensor",
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor", CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
CONF_DEVICE_POWER: 100, CONF_DEVICE_POWER: 100,
@@ -355,8 +355,8 @@ async def test_power_management_hvac_on(hass: HomeAssistant, skip_hass_states_is
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_POWER_SENSOR: "sensor.mock_power_sensor", CONF_POWER_SENSOR: "sensor.mock_power_sensor",
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor", CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
CONF_DEVICE_POWER: 100, CONF_DEVICE_POWER: 100,
@@ -491,8 +491,8 @@ async def test_power_management_energy_over_switch(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_POWER_SENSOR: "sensor.mock_power_sensor", CONF_POWER_SENSOR: "sensor.mock_power_sensor",
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor", CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
CONF_DEVICE_POWER: 100, CONF_DEVICE_POWER: 100,
@@ -620,8 +620,8 @@ async def test_power_management_energy_over_climate(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_POWER_SENSOR: "sensor.mock_power_sensor", CONF_POWER_SENSOR: "sensor.mock_power_sensor",
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor", CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
CONF_DEVICE_POWER: 100, CONF_DEVICE_POWER: 100,

View File

@@ -24,17 +24,26 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state):
1. creates a thermostat and check that security is off 1. creates a thermostat and check that security is off
2. activate security feature when date is expired 2. activate security feature when date is expired
3. change the preset to boost 3. change the preset to boost
4. check that security is still on
5. resolve the date issue 5. resolve the date issue
6. check that security is off and preset is changed to boost 6. check that security is off and preset is changed to boost
""" """
tz = get_tz(hass) # pylint: disable=invalid-name tz = get_tz(hass) # pylint: disable=invalid-name
temps = {
"frost": 7,
"eco": 17,
"comfort": 18,
"boost": 19,
}
entry = MockConfigEntry( entry = MockConfigEntry(
domain=DOMAIN, domain=DOMAIN,
title="TheOverSwitchMockName", title="TheOverSwitchMockName",
unique_id="uniqueId", unique_id="uniqueId",
# With migration
version=CONFIG_VERSION,
minor_version=0,
data={ data={
"name": "TheOverSwitchMockName", "name": "TheOverSwitchMockName",
"thermostat_type": "thermostat_over_switch", "thermostat_type": "thermostat_over_switch",
@@ -43,15 +52,11 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state):
"cycle_min": 5, "cycle_min": 5,
"temp_min": 15, "temp_min": 15,
"temp_max": 30, "temp_max": 30,
"frost_temp": 7,
"eco_temp": 17,
"comfort_temp": 18,
"boost_temp": 19,
"use_window_feature": False, "use_window_feature": False,
"use_motion_feature": False, "use_motion_feature": False,
"use_power_feature": False, "use_power_feature": False,
"use_presence_feature": False, "use_presence_feature": False,
"heater_entity_id": "switch.mock_switch", CONF_UNDERLYING_LIST: ["switch.mock_switch"],
"proportional_function": "tpi", "proportional_function": "tpi",
"tpi_coef_int": 0.3, "tpi_coef_int": 0.3,
"tpi_coef_ext": 0.01, "tpi_coef_ext": 0.01,
@@ -69,8 +74,11 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state):
) )
assert entity assert entity
assert entity._security_state is False await set_all_climate_preset_temp(hass, entity, temps, "theoverswitchmockname")
assert entity.preset_mode is not PRESET_SECURITY
assert entity.safety_manager.safety_state is not STATE_ON
assert entity.safety_manager.is_safety_detected is False
assert entity.preset_mode is not PRESET_SAFETY
assert entity.preset_modes == [ assert entity.preset_modes == [
PRESET_NONE, PRESET_NONE,
PRESET_FROST_PROTECTION, PRESET_FROST_PROTECTION,
@@ -105,8 +113,8 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state):
# set temperature to 15 so that on_percent will be > security_min_on_percent (0.2) # set temperature to 15 so that on_percent will be > security_min_on_percent (0.2)
await send_temperature_change_event(entity, 15, event_timestamp) await send_temperature_change_event(entity, 15, event_timestamp)
assert entity.security_state is True assert entity.safety_state is STATE_ON
assert entity.preset_mode == PRESET_SECURITY assert entity.preset_mode == PRESET_SAFETY
assert entity._saved_preset_mode == PRESET_COMFORT assert entity._saved_preset_mode == PRESET_COMFORT
assert entity._prop_algorithm.on_percent == 0.1 assert entity._prop_algorithm.on_percent == 0.1
assert entity._prop_algorithm.calculated_on_percent == 0.9 assert entity._prop_algorithm.calculated_on_percent == 0.9
@@ -114,7 +122,7 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state):
assert mock_send_event.call_count == 3 assert mock_send_event.call_count == 3
mock_send_event.assert_has_calls( mock_send_event.assert_has_calls(
[ [
call.send_event(EventType.PRESET_EVENT, {"preset": PRESET_SECURITY}), call.send_event(EventType.PRESET_EVENT, {"preset": PRESET_SAFETY}),
call.send_event( call.send_event(
EventType.TEMPERATURE_EVENT, EventType.TEMPERATURE_EVENT,
{ {
@@ -151,11 +159,13 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state):
await entity.async_set_preset_mode(PRESET_BOOST) await entity.async_set_preset_mode(PRESET_BOOST)
# 4. check that security is still on # 4. check that security is still on
assert entity._security_state is True assert entity.safety_manager.safety_state is STATE_ON
assert entity.safety_manager.is_safety_detected is True
assert entity._prop_algorithm.on_percent == 0.1 assert entity._prop_algorithm.on_percent == 0.1
assert entity._prop_algorithm.calculated_on_percent == 0.9 assert entity._prop_algorithm.calculated_on_percent == 0.9
assert entity._saved_preset_mode == PRESET_BOOST assert entity._saved_preset_mode == PRESET_BOOST
assert entity.preset_mode is PRESET_SECURITY assert entity.preset_mode is PRESET_SAFETY
# 5. resolve the datetime issue # 5. resolve the datetime issue
with patch( with patch(
@@ -168,7 +178,9 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state):
# set temperature to 15 so that on_percent will be > security_min_on_percent (0.2) # set temperature to 15 so that on_percent will be > security_min_on_percent (0.2)
await send_temperature_change_event(entity, 15.2, event_timestamp) await send_temperature_change_event(entity, 15.2, event_timestamp)
assert entity._security_state is False assert entity.safety_manager.safety_state is not STATE_ON
assert entity.safety_manager.is_safety_detected is False
assert entity.preset_mode == PRESET_BOOST assert entity.preset_mode == PRESET_BOOST
assert entity._saved_preset_mode == PRESET_BOOST assert entity._saved_preset_mode == PRESET_BOOST
assert entity._prop_algorithm.on_percent == 1.0 assert entity._prop_algorithm.on_percent == 1.0
@@ -215,6 +227,12 @@ async def test_security_feature_back_on_percent(
""" """
tz = get_tz(hass) # pylint: disable=invalid-name tz = get_tz(hass) # pylint: disable=invalid-name
temps = {
"eco": 17,
"comfort": 18,
"boost": 19,
"frost": 10,
}
entry = MockConfigEntry( entry = MockConfigEntry(
domain=DOMAIN, domain=DOMAIN,
@@ -228,21 +246,18 @@ async def test_security_feature_back_on_percent(
"cycle_min": 5, "cycle_min": 5,
"temp_min": 15, "temp_min": 15,
"temp_max": 30, "temp_max": 30,
"eco_temp": 17,
"comfort_temp": 18,
"boost_temp": 19,
"use_window_feature": False, "use_window_feature": False,
"use_motion_feature": False, "use_motion_feature": False,
"use_power_feature": False, "use_power_feature": False,
"use_presence_feature": False, "use_presence_feature": False,
"heater_entity_id": "switch.mock_switch", CONF_UNDERLYING_LIST: ["switch.mock_switch"],
"proportional_function": "tpi", "proportional_function": "tpi",
"tpi_coef_int": 0.3, "tpi_coef_int": 0.3,
"tpi_coef_ext": 0.01, "tpi_coef_ext": 0.01,
"minimal_activation_delay": 30, "minimal_activation_delay": 30,
"security_delay_min": 5, # 5 minutes "safety_delay_min": 5, # 5 minutes
"security_min_on_percent": 0.2, "safety_min_on_percent": 0.2,
"security_default_on_percent": 0.1, "safety_default_on_percent": 0.1,
}, },
) )
@@ -253,8 +268,12 @@ async def test_security_feature_back_on_percent(
) )
assert entity assert entity
assert entity._security_state is False await set_all_climate_preset_temp(hass, entity, temps, "theoverswitchmockname")
assert entity.preset_mode is not PRESET_SECURITY
assert entity.safety_manager.safety_state is not STATE_ON
assert entity.safety_manager.is_safety_detected is False
assert entity.preset_mode is not PRESET_SAFETY
assert entity._last_ext_temperature_measure is not None assert entity._last_ext_temperature_measure is not None
assert entity._last_temperature_measure is not None assert entity._last_temperature_measure is not None
assert (entity._last_temperature_measure.astimezone(tz) - now).total_seconds() < 1 assert (entity._last_temperature_measure.astimezone(tz) - now).total_seconds() < 1
@@ -285,7 +304,7 @@ async def test_security_feature_back_on_percent(
await send_temperature_change_event(entity, 17, event_timestamp) await send_temperature_change_event(entity, 17, event_timestamp)
assert entity._prop_algorithm.calculated_on_percent == 0.6 assert entity._prop_algorithm.calculated_on_percent == 0.6
assert entity.preset_mode == PRESET_BOOST assert entity.preset_mode == PRESET_BOOST
assert entity.security_state is False assert entity.safety_state is not STATE_ON
assert mock_send_event.call_count == 0 assert mock_send_event.call_count == 0
# 3. Set safety mode with a preset change # 3. Set safety mode with a preset change
@@ -302,14 +321,14 @@ async def test_security_feature_back_on_percent(
assert entity._prop_algorithm.calculated_on_percent == 0.6 assert entity._prop_algorithm.calculated_on_percent == 0.6
assert entity.security_state is True assert entity.safety_state is STATE_ON
assert entity.preset_mode == PRESET_SECURITY assert entity.preset_mode == PRESET_SAFETY
assert entity._saved_preset_mode == PRESET_BOOST assert entity._saved_preset_mode == PRESET_BOOST
assert mock_send_event.call_count == 3 assert mock_send_event.call_count == 3
mock_send_event.assert_has_calls( mock_send_event.assert_has_calls(
[ [
call.send_event(EventType.PRESET_EVENT, {"preset": PRESET_SECURITY}), call.send_event(EventType.PRESET_EVENT, {"preset": PRESET_SAFETY}),
call.send_event( call.send_event(
EventType.TEMPERATURE_EVENT, EventType.TEMPERATURE_EVENT,
{ {
@@ -343,8 +362,8 @@ async def test_security_feature_back_on_percent(
entity._set_now(event_timestamp) # pylint: disable=protected-access entity._set_now(event_timestamp) # pylint: disable=protected-access
await entity.async_set_preset_mode(PRESET_ECO) await entity.async_set_preset_mode(PRESET_ECO)
assert entity.security_state is True assert entity.safety_state is STATE_ON
assert entity.preset_mode == PRESET_SECURITY assert entity.preset_mode == PRESET_SAFETY
# 5. resolve the datetime issue # 5. resolve the datetime issue
with patch( with patch(
@@ -359,7 +378,9 @@ async def test_security_feature_back_on_percent(
# set temperature to 18.9 so that on_percent will be > security_min_on_percent (0.2) # set temperature to 18.9 so that on_percent will be > security_min_on_percent (0.2)
await send_temperature_change_event(entity, 18.92, event_timestamp) await send_temperature_change_event(entity, 18.92, event_timestamp)
assert entity._security_state is False assert entity.safety_manager.safety_state is not STATE_ON
assert entity.safety_manager.is_safety_detected is False
assert entity.preset_mode == PRESET_ECO assert entity.preset_mode == PRESET_ECO
assert entity._saved_preset_mode == PRESET_ECO assert entity._saved_preset_mode == PRESET_ECO
assert entity._prop_algorithm.on_percent == 0.0 assert entity._prop_algorithm.on_percent == 0.0
@@ -452,7 +473,8 @@ async def test_security_over_climate(
PRESET_BOOST, PRESET_BOOST,
] ]
assert entity.preset_mode is PRESET_NONE assert entity.preset_mode is PRESET_NONE
assert entity._security_state is False assert entity.safety_manager.safety_state is not STATE_ON
assert entity.safety_manager.is_safety_detected is False
# should have been called with EventType.PRESET_EVENT and EventType.HVAC_MODE_EVENT # should have been called with EventType.PRESET_EVENT and EventType.HVAC_MODE_EVENT
assert mock_send_event.call_count == 2 assert mock_send_event.call_count == 2
@@ -506,6 +528,56 @@ async def test_security_over_climate(
await send_temperature_change_event(entity, 15, event_timestamp) await send_temperature_change_event(entity, 15, event_timestamp)
# Should stay False because a climate is never in safety mode # Should stay False because a climate is never in safety mode
assert entity.security_state is False assert entity.safety_state is not STATE_ON
assert entity.preset_mode == "none" assert entity.preset_mode == "none"
assert entity._saved_preset_mode == "none" assert entity._saved_preset_mode == "none"
async def test_migration_security_safety(
hass: HomeAssistant,
skip_hass_states_is_state,
):
"""Tests the migration of security parameters to safety in English"""
central_config_entry = MockConfigEntry(
# Current is 2.1
version=CONFIG_VERSION,
# An old minor version
minor_version=0,
domain=DOMAIN,
title="TheCentralConfigMockName",
unique_id="centralConfigUniqueId",
data={
CONF_NAME: "migrationName",
CONF_THERMOSTAT_TYPE: CONF_THERMOSTAT_SWITCH,
CONF_UNDERLYING_LIST: ["switch.under1"],
"security_delay_min": 61,
"security_min_on_percent": 0.5,
"security_default_on_percent": 0.2,
CONF_TEMP_SENSOR: "sensor.mock_temp_sensor",
CONF_CYCLE_MIN: 5,
CONF_DEVICE_POWER: 1,
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.1,
CONF_USE_MAIN_CENTRAL_CONFIG: False,
CONF_USE_WINDOW_FEATURE: False,
CONF_USE_MOTION_FEATURE: False,
CONF_USE_POWER_FEATURE: False,
CONF_USE_PRESENCE_FEATURE: False,
CONF_MINIMAL_ACTIVATION_DELAY: 10,
},
)
central_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(central_config_entry.entry_id)
assert central_config_entry.state is ConfigEntryState.LOADED
entity: ThermostatOverSwitch = search_entity(
hass, "climate.migrationname", "climate"
)
assert entity is not None
assert entity.safety_manager.safety_min_on_percent == 0.5
assert entity.safety_manager.safety_default_on_percent == 0.2
assert entity.safety_manager.safety_delay_min == 61

View File

@@ -62,8 +62,8 @@ async def test_sensors_over_switch(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_DEVICE_POWER: 200, CONF_DEVICE_POWER: 200,
}, },
) )
@@ -222,8 +222,8 @@ async def test_sensors_over_climate(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_POWER_SENSOR: "sensor.mock_power_sensor", CONF_POWER_SENSOR: "sensor.mock_power_sensor",
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor", CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
CONF_DEVICE_POWER: 1.5, CONF_DEVICE_POWER: 1.5,
@@ -360,8 +360,8 @@ async def test_sensors_over_climate_minimal(
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
}, },
) )

View File

@@ -53,7 +53,7 @@ async def test_over_switch_full_start(hass: HomeAssistant, skip_hass_states_is_s
PRESET_ACTIVITY, PRESET_ACTIVITY,
] ]
assert entity.preset_mode is PRESET_NONE assert entity.preset_mode is PRESET_NONE
assert entity._security_state is False assert entity.safety_manager.is_safety_detected is False
assert entity.window_state is STATE_UNKNOWN assert entity.window_state is STATE_UNKNOWN
assert entity.motion_state is STATE_UNKNOWN assert entity.motion_state is STATE_UNKNOWN
assert entity.presence_state is STATE_UNKNOWN assert entity.presence_state is STATE_UNKNOWN
@@ -112,7 +112,7 @@ async def test_over_climate_full_start(hass: HomeAssistant, skip_hass_states_is_
PRESET_BOOST, PRESET_BOOST,
] ]
assert entity.preset_mode is PRESET_NONE assert entity.preset_mode is PRESET_NONE
assert entity._security_state is False assert entity.safety_manager.is_safety_detected is False
assert entity.window_state is STATE_UNAVAILABLE assert entity.window_state is STATE_UNAVAILABLE
assert entity.motion_state is STATE_UNAVAILABLE assert entity.motion_state is STATE_UNAVAILABLE
assert entity.presence_state is STATE_UNAVAILABLE assert entity.presence_state is STATE_UNAVAILABLE
@@ -168,7 +168,7 @@ async def test_over_4switch_full_start(hass: HomeAssistant, skip_hass_states_is_
PRESET_ACTIVITY, PRESET_ACTIVITY,
] ]
assert entity.preset_mode is PRESET_NONE assert entity.preset_mode is PRESET_NONE
assert entity._security_state is False assert entity.safety_manager.is_safety_detected is False
assert entity.window_state is STATE_UNKNOWN assert entity.window_state is STATE_UNKNOWN
assert entity.motion_state is STATE_UNKNOWN assert entity.motion_state is STATE_UNKNOWN
assert entity.presence_state is STATE_UNKNOWN assert entity.presence_state is STATE_UNKNOWN
@@ -230,7 +230,7 @@ async def test_over_switch_deactivate_preset(
CONF_HEATER_3: None, CONF_HEATER_3: None,
CONF_HEATER_4: None, CONF_HEATER_4: None,
CONF_HEATER_KEEP_ALIVE: 0, CONF_HEATER_KEEP_ALIVE: 0,
CONF_SECURITY_DELAY_MIN: 10, CONF_SAFETY_DELAY_MIN: 10,
CONF_MINIMAL_ACTIVATION_DELAY: 10, CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI, CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
CONF_TPI_COEF_INT: 0.6, CONF_TPI_COEF_INT: 0.6,

View File

@@ -89,7 +89,7 @@ async def test_over_switch_ac_full_start(
PRESET_ACTIVITY, PRESET_ACTIVITY,
] ]
assert entity.preset_mode is PRESET_NONE assert entity.preset_mode is PRESET_NONE
assert entity._security_state is False # pylint: disable=protected-access assert entity.safety_manager.is_safety_detected is False
assert entity.window_state is STATE_UNKNOWN assert entity.window_state is STATE_UNKNOWN
assert entity.motion_state is STATE_UNKNOWN assert entity.motion_state is STATE_UNKNOWN
assert entity.presence_state is STATE_UNKNOWN assert entity.presence_state is STATE_UNKNOWN

View File

@@ -39,8 +39,8 @@ def config_entry() -> MockConfigEntry:
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.1, CONF_SAFETY_MIN_ON_PERCENT: 0.1,
}, },
) )

View File

@@ -75,9 +75,9 @@ async def test_add_number_for_central_config(
CONF_MAX_POWER_SENSOR: "sensor.mock_central_max_power_sensor", CONF_MAX_POWER_SENSOR: "sensor.mock_central_max_power_sensor",
CONF_PRESET_POWER: 14, CONF_PRESET_POWER: 14,
CONF_MINIMAL_ACTIVATION_DELAY: 11, CONF_MINIMAL_ACTIVATION_DELAY: 11,
CONF_SECURITY_DELAY_MIN: 61, CONF_SAFETY_DELAY_MIN: 61,
CONF_SECURITY_MIN_ON_PERCENT: 0.5, CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
CONF_USE_CENTRAL_BOILER_FEATURE: False, CONF_USE_CENTRAL_BOILER_FEATURE: False,
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI, CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
} }
@@ -170,9 +170,9 @@ async def test_add_number_for_central_config_without_temp(
CONF_MAX_POWER_SENSOR: "sensor.mock_central_max_power_sensor", CONF_MAX_POWER_SENSOR: "sensor.mock_central_max_power_sensor",
CONF_PRESET_POWER: 14, CONF_PRESET_POWER: 14,
CONF_MINIMAL_ACTIVATION_DELAY: 11, CONF_MINIMAL_ACTIVATION_DELAY: 11,
CONF_SECURITY_DELAY_MIN: 61, CONF_SAFETY_DELAY_MIN: 61,
CONF_SECURITY_MIN_ON_PERCENT: 0.5, CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
CONF_USE_CENTRAL_BOILER_FEATURE: False, CONF_USE_CENTRAL_BOILER_FEATURE: False,
}, },
# | temps, # | temps,
@@ -265,9 +265,9 @@ async def test_add_number_for_central_config_without_temp_ac_mode(
CONF_MAX_POWER_SENSOR: "sensor.mock_central_max_power_sensor", CONF_MAX_POWER_SENSOR: "sensor.mock_central_max_power_sensor",
CONF_PRESET_POWER: 14, CONF_PRESET_POWER: 14,
CONF_MINIMAL_ACTIVATION_DELAY: 11, CONF_MINIMAL_ACTIVATION_DELAY: 11,
CONF_SECURITY_DELAY_MIN: 61, CONF_SAFETY_DELAY_MIN: 61,
CONF_SECURITY_MIN_ON_PERCENT: 0.5, CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
CONF_USE_CENTRAL_BOILER_FEATURE: False, CONF_USE_CENTRAL_BOILER_FEATURE: False,
}, },
# | temps, # | temps,
@@ -359,9 +359,9 @@ async def test_add_number_for_central_config_without_temp_restore(
CONF_MAX_POWER_SENSOR: "sensor.mock_central_max_power_sensor", CONF_MAX_POWER_SENSOR: "sensor.mock_central_max_power_sensor",
CONF_PRESET_POWER: 14, CONF_PRESET_POWER: 14,
CONF_MINIMAL_ACTIVATION_DELAY: 11, CONF_MINIMAL_ACTIVATION_DELAY: 11,
CONF_SECURITY_DELAY_MIN: 61, CONF_SAFETY_DELAY_MIN: 61,
CONF_SECURITY_MIN_ON_PERCENT: 0.5, CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
CONF_USE_CENTRAL_BOILER_FEATURE: False, CONF_USE_CENTRAL_BOILER_FEATURE: False,
}, },
# | temps, # | temps,

View File

@@ -38,8 +38,8 @@ async def test_tpi_calculation(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
# CONF_DEVICE_POWER: 100, # CONF_DEVICE_POWER: 100,
}, },
) )
@@ -66,14 +66,14 @@ async def test_tpi_calculation(
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_safety(0.1)
tpi_algo.calculate(15, 14, 5, HVACMode.HEAT) 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_safety()
tpi_algo.calculate(15, 14, 5, HVACMode.HEAT) 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
@@ -87,14 +87,14 @@ async def test_tpi_calculation(
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_safety(0.09)
tpi_algo.calculate(15, 14.7, 15, HVACMode.HEAT) 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_safety()
tpi_algo.calculate(25, 30, 35, HVACMode.COOL) 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
@@ -102,7 +102,7 @@ async def test_tpi_calculation(
assert tpi_algo.off_time_sec == 0 assert tpi_algo.off_time_sec == 0
assert entity.power_manager.mean_cycle_power is None # no device power configured assert entity.power_manager.mean_cycle_power is None # no device power configured
tpi_algo.set_security(0.09) tpi_algo.set_safety(0.09)
tpi_algo.calculate(25, 30, 35, HVACMode.COOL) 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
@@ -110,7 +110,7 @@ async def test_tpi_calculation(
assert tpi_algo.off_time_sec == 300 assert tpi_algo.off_time_sec == 300
assert entity.power_manager.mean_cycle_power is None # no device power configured assert entity.power_manager.mean_cycle_power is None # no device power configured
tpi_algo.unset_security() tpi_algo.unset_safety()
# The calculated values for HVACMode.OFF are the same as for HVACMode.HEAT. # The calculated values for HVACMode.OFF are the same as for HVACMode.HEAT.
tpi_algo.calculate(15, 10, 7, HVACMode.OFF) tpi_algo.calculate(15, 10, 7, HVACMode.OFF)
assert tpi_algo.on_percent == 1 assert tpi_algo.on_percent == 1

View File

@@ -60,8 +60,8 @@ async def test_over_valve_full_start(
PRESET_BOOST + PRESET_AWAY_SUFFIX + PRESET_TEMP_SUFFIX: 17.3, PRESET_BOOST + PRESET_AWAY_SUFFIX + PRESET_TEMP_SUFFIX: 17.3,
CONF_PRESET_POWER: 10, CONF_PRESET_POWER: 10,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_DEVICE_POWER: 100, CONF_DEVICE_POWER: 100,
CONF_AC_MODE: False, CONF_AC_MODE: False,
}, },
@@ -98,7 +98,9 @@ async def test_over_valve_full_start(
PRESET_ACTIVITY, PRESET_ACTIVITY,
] ]
assert entity.preset_mode is PRESET_NONE assert entity.preset_mode is PRESET_NONE
assert entity._security_state is False # pylint: disable=protected-access assert (
entity.safety_manager.is_safety_detected is False
) # pylint: disable=protected-access
assert entity.window_state is STATE_UNKNOWN assert entity.window_state is STATE_UNKNOWN
assert entity.motion_state is STATE_UNKNOWN assert entity.motion_state is STATE_UNKNOWN
assert entity.presence_state is STATE_UNKNOWN assert entity.presence_state is STATE_UNKNOWN
@@ -350,8 +352,8 @@ async def test_over_valve_regulation(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 60, CONF_SAFETY_DELAY_MIN: 60,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
# only send new valve open percent if dtemp is > 30% # only send new valve open percent if dtemp is > 30%
CONF_AUTO_REGULATION_DTEMP: 5, CONF_AUTO_REGULATION_DTEMP: 5,
# only send new valve open percent last mesure was more than 5 min ago # only send new valve open percent last mesure was more than 5 min ago
@@ -589,7 +591,7 @@ async def test_bug_533(
CONF_VALVE: "number.mock_valve", CONF_VALVE: "number.mock_valve",
CONF_AUTO_REGULATION_DTEMP: 10, # This parameter makes the bug CONF_AUTO_REGULATION_DTEMP: 10, # This parameter makes the bug
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 60, CONF_SAFETY_DELAY_MIN: 60,
}, },
# | temps, # | temps,
) )

View File

@@ -45,8 +45,8 @@ async def test_window_management_time_not_enough(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
CONF_WINDOW_DELAY: 0, # important to not been obliged to wait CONF_WINDOW_DELAY: 0, # important to not been obliged to wait
CONF_WINDOW_ACTION: CONF_WINDOW_TURN_OFF, CONF_WINDOW_ACTION: CONF_WINDOW_TURN_OFF,
@@ -134,8 +134,8 @@ async def test_window_management_time_enough(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
CONF_WINDOW_DELAY: 0, # important to not been obliged to wait CONF_WINDOW_DELAY: 0, # important to not been obliged to wait
CONF_WINDOW_ACTION: CONF_WINDOW_TURN_OFF, CONF_WINDOW_ACTION: CONF_WINDOW_TURN_OFF,
@@ -281,8 +281,8 @@ async def test_window_auto_fast(hass: HomeAssistant, skip_hass_states_is_state):
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1, CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1, CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1,
CONF_WINDOW_AUTO_MAX_DURATION: 10, # Should be 0 for test CONF_WINDOW_AUTO_MAX_DURATION: 10, # Should be 0 for test
@@ -490,8 +490,8 @@ async def test_window_auto_fast_and_sensor(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.fake_window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.fake_window_sensor",
CONF_WINDOW_DELAY: 10, CONF_WINDOW_DELAY: 10,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1, CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
@@ -615,8 +615,8 @@ async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_st
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "switch.mock_climate", CONF_CLIMATE: "switch.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 6, CONF_WINDOW_AUTO_OPEN_THRESHOLD: 6,
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 6, CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 6,
CONF_WINDOW_AUTO_MAX_DURATION: 1, # 0 will deactivate window auto detection CONF_WINDOW_AUTO_MAX_DURATION: 1, # 0 will deactivate window auto detection
@@ -783,8 +783,8 @@ async def test_window_auto_no_on_percent(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 6, CONF_WINDOW_AUTO_OPEN_THRESHOLD: 6,
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 6, CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 6,
CONF_WINDOW_AUTO_MAX_DURATION: 1, # Should be 0 for test but 0 is not possible CONF_WINDOW_AUTO_MAX_DURATION: 1, # Should be 0 for test but 0 is not possible
@@ -910,8 +910,8 @@ async def test_window_bypass(hass: HomeAssistant, skip_hass_states_is_state):
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
CONF_WINDOW_DELAY: 0, # important to not been obliged to wait CONF_WINDOW_DELAY: 0, # important to not been obliged to wait
}, },
@@ -1050,8 +1050,8 @@ async def test_window_auto_bypass(hass: HomeAssistant, skip_hass_states_is_state
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 6, CONF_WINDOW_AUTO_OPEN_THRESHOLD: 6,
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 6, CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 6,
CONF_WINDOW_AUTO_MAX_DURATION: 1, # Should be > 0 to activate window_auto CONF_WINDOW_AUTO_MAX_DURATION: 1, # Should be > 0 to activate window_auto
@@ -1178,8 +1178,8 @@ async def test_window_bypass_reactivate(hass: HomeAssistant, skip_hass_states_is
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
CONF_WINDOW_DELAY: 0, # important to not been obliged to wait CONF_WINDOW_DELAY: 0, # important to not been obliged to wait
}, },
@@ -1307,8 +1307,8 @@ async def test_window_action_fan_only(hass: HomeAssistant, skip_hass_states_is_s
CONF_USE_POWER_FEATURE: False, CONF_USE_POWER_FEATURE: False,
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
CONF_WINDOW_DELAY: 1, CONF_WINDOW_DELAY: 1,
CONF_WINDOW_ACTION: CONF_WINDOW_FAN_ONLY, CONF_WINDOW_ACTION: CONF_WINDOW_FAN_ONLY,
@@ -1464,8 +1464,8 @@ async def test_window_action_fan_only_ko(
CONF_USE_POWER_FEATURE: False, CONF_USE_POWER_FEATURE: False,
CONF_USE_PRESENCE_FEATURE: False, CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate", CONF_CLIMATE: "climate.mock_climate",
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
CONF_WINDOW_DELAY: 1, CONF_WINDOW_DELAY: 1,
CONF_WINDOW_ACTION: CONF_WINDOW_FAN_ONLY, CONF_WINDOW_ACTION: CONF_WINDOW_FAN_ONLY,
@@ -1615,8 +1615,8 @@ async def test_window_action_eco_temp(hass: HomeAssistant, skip_hass_states_is_s
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1, CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1, CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1,
CONF_WINDOW_AUTO_MAX_DURATION: 10, # Should be 0 for test CONF_WINDOW_AUTO_MAX_DURATION: 10, # Should be 0 for test
@@ -1812,8 +1812,8 @@ async def test_window_action_frost_temp(hass: HomeAssistant, skip_hass_states_is
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1, CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1, CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1,
CONF_WINDOW_AUTO_MAX_DURATION: 10, # Should be 0 for test CONF_WINDOW_AUTO_MAX_DURATION: 10, # Should be 0 for test
@@ -2016,9 +2016,9 @@ async def test_bug_66(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.5, CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, # !! here CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1, # !! here
CONF_DEVICE_POWER: 200, CONF_DEVICE_POWER: 200,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
CONF_WINDOW_DELAY: 0, # important to not been obliged to wait CONF_WINDOW_DELAY: 0, # important to not been obliged to wait
@@ -2167,8 +2167,8 @@ async def test_window_action_frost_temp_preset_change(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_ACTION: CONF_WINDOW_FROST_TEMP, CONF_WINDOW_ACTION: CONF_WINDOW_FROST_TEMP,
CONF_WINDOW_SENSOR: "binary_sensor.fake_window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.fake_window_sensor",
CONF_WINDOW_DELAY: 1, CONF_WINDOW_DELAY: 1,
@@ -2277,8 +2277,8 @@ async def test_window_action_frost_temp_temp_change(
CONF_TPI_COEF_INT: 0.3, CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01, CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30, CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_SECURITY_DELAY_MIN: 5, CONF_SAFETY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3, CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_ACTION: CONF_WINDOW_FROST_TEMP, CONF_WINDOW_ACTION: CONF_WINDOW_FROST_TEMP,
CONF_WINDOW_SENSOR: "binary_sensor.fake_window_sensor", CONF_WINDOW_SENSOR: "binary_sensor.fake_window_sensor",
CONF_WINDOW_DELAY: 1, CONF_WINDOW_DELAY: 1,