Add safety feature_safety_manager
Rename config attribute from security_ to safety_
This commit is contained in:
@@ -29,6 +29,9 @@ from .const import (
|
||||
CONF_AUTO_REGULATION_EXPERT,
|
||||
CONF_SHORT_EMA_PARAMS,
|
||||
CONF_SAFETY_MODE,
|
||||
CONF_SAFETY_DELAY_MIN,
|
||||
CONF_SAFETY_MIN_ON_PERCENT,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT,
|
||||
CONF_THERMOSTAT_CENTRAL_CONFIG,
|
||||
CONF_THERMOSTAT_TYPE,
|
||||
CONF_USE_WINDOW_FEATURE,
|
||||
@@ -291,6 +294,20 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry):
|
||||
]:
|
||||
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(
|
||||
config_entry,
|
||||
data=new,
|
||||
|
||||
@@ -70,6 +70,7 @@ from .feature_presence_manager import FeaturePresenceManager
|
||||
from .feature_power_manager import FeaturePowerManager
|
||||
from .feature_motion_manager import FeatureMotionManager
|
||||
from .feature_window_manager import FeatureWindowManager
|
||||
from .feature_safety_manager import FeatureSafetyManager
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -102,9 +103,6 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
"saved_preset_mode",
|
||||
"saved_target_temp",
|
||||
"saved_hvac_mode",
|
||||
"security_delay_min",
|
||||
"security_min_on_percent",
|
||||
"security_default_on_percent",
|
||||
"last_temperature_datetime",
|
||||
"last_ext_temperature_datetime",
|
||||
"minimal_activation_delay_sec",
|
||||
@@ -170,11 +168,6 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
self._cur_ext_temp = 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._attr_translation_key = "versatile_thermostat"
|
||||
@@ -224,11 +217,13 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
self._power_manager: FeaturePowerManager = FeaturePowerManager(self, hass)
|
||||
self._motion_manager: FeatureMotionManager = FeatureMotionManager(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._power_manager)
|
||||
self.register_manager(self._motion_manager)
|
||||
self.register_manager(self._window_manager)
|
||||
self.register_manager(self._safety_manager)
|
||||
|
||||
self.post_init(entry_infos)
|
||||
|
||||
@@ -373,21 +368,9 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
)
|
||||
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._last_temperature_measure = self.now
|
||||
self._last_ext_temperature_measure = self.now
|
||||
self._security_state = False
|
||||
|
||||
# Initiate the ProportionalAlgorithm
|
||||
if self._prop_algorithm is not None:
|
||||
@@ -619,6 +602,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
"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)
|
||||
self._total_energy = old_total_energy if old_total_energy is not None else 0
|
||||
_LOGGER.debug(
|
||||
@@ -657,7 +642,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
self.send_event(EventType.HVAC_MODE_EVENT, {"hvac_mode": self._hvac_mode})
|
||||
|
||||
_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._target_temp,
|
||||
self._attr_preset_mode,
|
||||
@@ -820,6 +805,11 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
"""Return the sensor temperature."""
|
||||
return self._cur_temp
|
||||
|
||||
@property
|
||||
def current_outdoor_temperature(self) -> float | None:
|
||||
"""Return the outdoor sensor temperature."""
|
||||
return self._cur_ext_temp
|
||||
|
||||
@property
|
||||
def is_aux_heat(self) -> bool | None:
|
||||
"""Return true if aux heater.
|
||||
@@ -861,6 +851,11 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
"""Get the window manager"""
|
||||
return self._window_manager
|
||||
|
||||
@property
|
||||
def safety_manager(self) -> FeatureSafetyManager | None:
|
||||
"""Get the safety manager"""
|
||||
return self._safety_manager
|
||||
|
||||
@property
|
||||
def window_state(self) -> str | None:
|
||||
"""Get the window_state"""
|
||||
@@ -877,9 +872,9 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
return self._window_manager.is_window_bypass
|
||||
|
||||
@property
|
||||
def security_state(self) -> bool | None:
|
||||
"""Get the security_state"""
|
||||
return self._security_state
|
||||
def safety_state(self) -> str | None:
|
||||
"""Get the safety_state"""
|
||||
return self._safety_manager.safety_state
|
||||
|
||||
@property
|
||||
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
|
||||
return
|
||||
|
||||
# In safety mode don't change preset but memorise the new expected preset when security will be off
|
||||
if preset_mode != PRESET_SECURITY and self._security_state:
|
||||
# In safety mode don't change preset but memorise the new expected preset when safety will be off
|
||||
if preset_mode != PRESET_SAFETY and self._safety_manager.is_safety_detected:
|
||||
_LOGGER.debug(
|
||||
"%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
|
||||
)
|
||||
|
||||
if preset_mode == PRESET_SECURITY:
|
||||
if preset_mode == PRESET_SAFETY:
|
||||
return (
|
||||
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:
|
||||
return self._power_manager.power_temperature
|
||||
if preset_mode == PRESET_ACTIVITY:
|
||||
@@ -1333,8 +1328,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
)
|
||||
|
||||
# try to restart if we were in safety mode
|
||||
if self._security_state:
|
||||
await self.check_safety()
|
||||
if self._safety_manager.is_safety_detected:
|
||||
await self._safety_manager.refresh_state()
|
||||
|
||||
except ValueError as err:
|
||||
# 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
|
||||
if self._security_state:
|
||||
await self.check_safety()
|
||||
if self._safety_manager.is_safety_detected:
|
||||
await self._safety_manager.refresh_state()
|
||||
|
||||
# check 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
|
||||
if self._security_state:
|
||||
await self.check_safety()
|
||||
if self._safety_manager.is_safety_detected:
|
||||
await self._safety_manager.refresh_state()
|
||||
except ValueError as 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"""
|
||||
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
|
||||
def is_initialized(self) -> bool:
|
||||
"""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"""
|
||||
|
||||
_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._hvac_mode,
|
||||
self._security_state,
|
||||
self._safety_manager.safety_state,
|
||||
self._attr_preset_mode,
|
||||
)
|
||||
|
||||
@@ -1763,9 +1601,9 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
_LOGGER.debug("%s - End of cycle (overpowering)", self)
|
||||
return True
|
||||
|
||||
security: bool = await self.check_safety()
|
||||
if security and self.is_over_climate:
|
||||
_LOGGER.debug("%s - End of cycle (security and over climate)", self)
|
||||
safety: bool = await self._safety_manager.refresh_state()
|
||||
if safety and self.is_over_climate:
|
||||
_LOGGER.debug("%s - End of cycle (safety and over climate)", self)
|
||||
return True
|
||||
|
||||
# Stop here if we are off
|
||||
@@ -1834,16 +1672,12 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
"saved_preset_mode": self._saved_preset_mode,
|
||||
"saved_target_temp": self._saved_target_temp,
|
||||
"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(
|
||||
self._current_tz
|
||||
).isoformat(),
|
||||
"last_ext_temperature_datetime": self._last_ext_temperature_measure.astimezone(
|
||||
self._current_tz
|
||||
).isoformat(),
|
||||
"security_state": self._security_state,
|
||||
"minimal_activation_delay_sec": self._minimal_activation_delay,
|
||||
ATTR_TOTAL_ENERGY: self.total_energy,
|
||||
"last_update_datetime": self.now.isoformat(),
|
||||
@@ -1956,14 +1790,14 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
)
|
||||
await self.async_control_heating(force=True)
|
||||
|
||||
async def service_set_security(
|
||||
async def SERVICE_SET_SAFETY(
|
||||
self,
|
||||
delay_min: int | None,
|
||||
min_on_percent: float | None,
|
||||
default_on_percent: float | None,
|
||||
):
|
||||
"""Called by a service call:
|
||||
service: versatile_thermostat.set_security
|
||||
service: versatile_thermostat.set_safety
|
||||
data:
|
||||
delay_min: 15
|
||||
min_on_percent: 0.5
|
||||
@@ -1972,21 +1806,23 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
entity_id: climate.thermostat_2
|
||||
"""
|
||||
_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,
|
||||
delay_min,
|
||||
min_on_percent * 100,
|
||||
default_on_percent * 100,
|
||||
)
|
||||
if delay_min:
|
||||
self._security_delay_min = delay_min
|
||||
self._safety_manager.set_safety_delay_min(delay_min)
|
||||
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:
|
||||
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:
|
||||
self._prop_algorithm.set_security(self._security_default_on_percent)
|
||||
if self._prop_algorithm:
|
||||
self._prop_algorithm.set_safety(
|
||||
self._safety_manager.safety_default_on_percent
|
||||
)
|
||||
|
||||
await self.async_control_heating()
|
||||
self.update_custom_attributes()
|
||||
@@ -2070,7 +1906,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
self._support_flags = SUPPORT_FLAGS | ClimateEntityFeature.PRESET_MODE
|
||||
|
||||
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)
|
||||
|
||||
_LOGGER.debug(
|
||||
|
||||
@@ -109,7 +109,7 @@ class SecurityBinarySensor(VersatileThermostatBaseEntity, BinarySensorEntity):
|
||||
# _LOGGER.debug("%s - climate state change", self._attr_unique_id)
|
||||
|
||||
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:
|
||||
self.async_write_ha_state()
|
||||
return
|
||||
|
||||
@@ -97,13 +97,13 @@ async def async_setup_entry(
|
||||
)
|
||||
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_SET_SECURITY,
|
||||
SERVICE_SET_SAFETY,
|
||||
{
|
||||
vol.Optional("delay_min"): cv.positive_int,
|
||||
vol.Optional("min_on_percent"): vol.Coerce(float),
|
||||
vol.Optional("default_on_percent"): vol.Coerce(float),
|
||||
},
|
||||
"service_set_security",
|
||||
"SERVICE_SET_SAFETY",
|
||||
)
|
||||
|
||||
platform.async_register_entity_service(
|
||||
|
||||
@@ -6,7 +6,7 @@ from __future__ import annotations
|
||||
from typing import Any
|
||||
import logging
|
||||
import copy
|
||||
from collections.abc import Mapping
|
||||
from collections.abc import Mapping # pylint: disable=import-error
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
@@ -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
|
||||
{
|
||||
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(
|
||||
CONF_SECURITY_MIN_ON_PERCENT,
|
||||
CONF_SAFETY_MIN_ON_PERCENT,
|
||||
default=DEFAULT_SECURITY_MIN_ON_PERCENT,
|
||||
): vol.Coerce(float),
|
||||
vol.Required(
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT,
|
||||
default=DEFAULT_SECURITY_DEFAULT_ON_PERCENT,
|
||||
): vol.Coerce(float),
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ from .prop_algorithm import (
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONFIG_VERSION = 2
|
||||
CONFIG_MINOR_VERSION = 0
|
||||
CONFIG_MINOR_VERSION = 1
|
||||
|
||||
PRESET_TEMP_SUFFIX = "_temp"
|
||||
PRESET_AC_SUFFIX = "_ac"
|
||||
@@ -42,10 +42,10 @@ DEVICE_MANUFACTURER = "JMCOLLIN"
|
||||
DEVICE_MODEL = "Versatile Thermostat"
|
||||
|
||||
PRESET_POWER = "power"
|
||||
PRESET_SECURITY = "security"
|
||||
PRESET_SAFETY = "security"
|
||||
PRESET_FROST_PROTECTION = "frost"
|
||||
|
||||
HIDDEN_PRESETS = [PRESET_POWER, PRESET_SECURITY]
|
||||
HIDDEN_PRESETS = [PRESET_POWER, PRESET_SAFETY]
|
||||
|
||||
DOMAIN = "versatile_thermostat"
|
||||
|
||||
@@ -84,9 +84,9 @@ CONF_PRESET_POWER = "power_temp"
|
||||
CONF_MINIMAL_ACTIVATION_DELAY = "minimal_activation_delay"
|
||||
CONF_TEMP_MIN = "temp_min"
|
||||
CONF_TEMP_MAX = "temp_max"
|
||||
CONF_SECURITY_DELAY_MIN = "security_delay_min"
|
||||
CONF_SECURITY_MIN_ON_PERCENT = "security_min_on_percent"
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT = "security_default_on_percent"
|
||||
CONF_SAFETY_DELAY_MIN = "safety_delay_min"
|
||||
CONF_SAFETY_MIN_ON_PERCENT = "safety_min_on_percent"
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT = "safety_default_on_percent"
|
||||
CONF_THERMOSTAT_TYPE = "thermostat_type"
|
||||
CONF_THERMOSTAT_CENTRAL_CONFIG = "thermostat_central_config"
|
||||
CONF_THERMOSTAT_SWITCH = "thermostat_over_switch"
|
||||
@@ -286,9 +286,9 @@ ALL_CONF = (
|
||||
CONF_MINIMAL_ACTIVATION_DELAY,
|
||||
CONF_TEMP_MIN,
|
||||
CONF_TEMP_MAX,
|
||||
CONF_SECURITY_DELAY_MIN,
|
||||
CONF_SECURITY_MIN_ON_PERCENT,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT,
|
||||
CONF_SAFETY_DELAY_MIN,
|
||||
CONF_SAFETY_MIN_ON_PERCENT,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT,
|
||||
CONF_THERMOSTAT_TYPE,
|
||||
CONF_THERMOSTAT_SWITCH,
|
||||
CONF_THERMOSTAT_CLIMATE,
|
||||
@@ -374,7 +374,7 @@ SUPPORT_FLAGS = (
|
||||
|
||||
SERVICE_SET_PRESENCE = "set_presence"
|
||||
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_AUTO_REGULATION_MODE = "set_auto_regulation_mode"
|
||||
SERVICE_SET_AUTO_FAN_MODE = "set_auto_fan_mode"
|
||||
|
||||
@@ -211,7 +211,7 @@ class FeatureAutoStartStopManager(BaseFeatureManager):
|
||||
@overrides
|
||||
@property
|
||||
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
|
||||
|
||||
@property
|
||||
|
||||
310
custom_components/versatile_thermostat/feature_safety_manager.py
Normal file
310
custom_components/versatile_thermostat/feature_safety_manager.py
Normal 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}"
|
||||
@@ -187,7 +187,7 @@ class PropAlgorithm:
|
||||
|
||||
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)"""
|
||||
_LOGGER.info(
|
||||
"%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._calculate_internal()
|
||||
|
||||
def unset_security(self):
|
||||
def unset_safety(self):
|
||||
"""Unset the safety mode"""
|
||||
_LOGGER.info(
|
||||
"%s - Proportional Algo - set security to OFF", self._vtherm_entity_id
|
||||
|
||||
@@ -76,7 +76,7 @@ set_preset_temperature:
|
||||
unit_of_measurement: °
|
||||
mode: slider
|
||||
|
||||
set_security:
|
||||
set_safety:
|
||||
name: Set safety
|
||||
description: Change the safety parameters
|
||||
target:
|
||||
|
||||
@@ -413,7 +413,7 @@ class UnderlyingSwitch(UnderlyingEntity):
|
||||
_LOGGER.debug("%s - End of cycle (3)", self)
|
||||
return
|
||||
# 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
|
||||
|
||||
action_label = "start"
|
||||
|
||||
@@ -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 :
|
||||
```
|
||||
service : versatile_thermostat.set_security
|
||||
service : versatile_thermostat.set_safety
|
||||
data:
|
||||
min_on_percent: "0.5"
|
||||
default_on_percent: "0.1"
|
||||
|
||||
@@ -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:
|
||||
```yaml
|
||||
service: versatile_thermostat.set_security
|
||||
service: versatile_thermostat.set_safety
|
||||
data:
|
||||
min_on_percent: "0.5"
|
||||
default_on_percent: "0.1"
|
||||
|
||||
@@ -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 :
|
||||
```
|
||||
service : versatile_thermostat.set_security
|
||||
service : versatile_thermostat.set_safety
|
||||
data:
|
||||
min_on_percent: "0.5"
|
||||
default_on_percent: "0.1"
|
||||
|
||||
@@ -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 :
|
||||
```yaml
|
||||
service : versatile_thermostat.set_security
|
||||
service : versatile_thermostat.set_safety
|
||||
data:
|
||||
min_on_percent: "0.5"
|
||||
default_on_percent: "0.1"
|
||||
|
||||
@@ -197,9 +197,9 @@ FULL_CENTRAL_CONFIG = {
|
||||
CONF_PRESENCE_SENSOR: "binary_sensor.mock_presence_sensor",
|
||||
CONF_PRESET_POWER: 14,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 11,
|
||||
CONF_SECURITY_DELAY_MIN: 61,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2,
|
||||
CONF_SAFETY_DELAY_MIN: 61,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
|
||||
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_PRESET_POWER: 14,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 11,
|
||||
CONF_SECURITY_DELAY_MIN: 61,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2,
|
||||
CONF_SAFETY_DELAY_MIN: 61,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
|
||||
CONF_USE_CENTRAL_BOILER_FEATURE: True,
|
||||
CONF_CENTRAL_BOILER_ACTIVATION_SRV: "switch.pompe_chaudiere/switch.turn_on",
|
||||
CONF_CENTRAL_BOILER_DEACTIVATION_SRV: "switch.pompe_chaudiere/switch.turn_off",
|
||||
|
||||
@@ -89,7 +89,12 @@ MOCK_TH_OVER_SWITCH_AC_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_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
|
||||
CONF_AC_MODE: False,
|
||||
@@ -195,9 +200,9 @@ MOCK_PRESENCE_AC_CONFIG = {
|
||||
|
||||
MOCK_ADVANCED_CONFIG = {
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 10,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
|
||||
}
|
||||
|
||||
MOCK_DEFAULT_FEATURE_CONFIG = {
|
||||
|
||||
@@ -53,8 +53,8 @@ async def test_over_climate_auto_fan_mode_turbo(
|
||||
CONF_USE_PRESENCE_FEATURE: False,
|
||||
CONF_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
|
||||
CONF_AC_MODE: True,
|
||||
},
|
||||
|
||||
@@ -335,8 +335,8 @@ async def test_auto_start_stop_none_vtherm(
|
||||
CONF_PRESENCE_SENSOR: "binary_sensor.presence_sensor",
|
||||
CONF_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
|
||||
CONF_AC_MODE: True,
|
||||
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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
|
||||
CONF_AC_MODE: True,
|
||||
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_UNDERLYING_LIST: ["climate.mock_climate"],
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
|
||||
CONF_AC_MODE: True,
|
||||
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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
|
||||
CONF_AC_MODE: True,
|
||||
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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
|
||||
CONF_AC_MODE: True,
|
||||
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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
|
||||
CONF_AC_MODE: True,
|
||||
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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
|
||||
CONF_AC_MODE: True,
|
||||
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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
|
||||
CONF_AC_MODE: False,
|
||||
CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST,
|
||||
|
||||
@@ -57,8 +57,8 @@ async def test_security_binary_sensors(
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
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)
|
||||
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
|
||||
await security_binary_sensor.async_my_climate_changed()
|
||||
assert security_binary_sensor.state == STATE_ON
|
||||
|
||||
# set temperature 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
|
||||
await security_binary_sensor.async_my_climate_changed()
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_POWER_SENSOR: "sensor.mock_power_sensor",
|
||||
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
|
||||
CONF_DEVICE_POWER: 100,
|
||||
@@ -218,8 +218,8 @@ async def test_window_binary_sensors(
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
|
||||
CONF_MOTION_DELAY: 0, # important to not been obliged to wait
|
||||
CONF_MOTION_PRESET: PRESET_BOOST,
|
||||
@@ -399,8 +399,8 @@ async def test_presence_binary_sensors(
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -63,9 +63,9 @@ async def test_bug_63(
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.0, # !! here
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.0, # !! here
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.0, # !! here
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.0, # !! here
|
||||
CONF_DEVICE_POWER: 200,
|
||||
},
|
||||
)
|
||||
@@ -75,8 +75,8 @@ async def test_bug_63(
|
||||
)
|
||||
assert entity
|
||||
|
||||
assert entity._security_min_on_percent == 0
|
||||
assert entity._security_default_on_percent == 0
|
||||
assert entity.safety_manager.safety_min_on_percent == 0
|
||||
assert entity.safety_manager.safety_default_on_percent == 0
|
||||
|
||||
|
||||
# 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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, # !! here
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1, # !! here
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_POWER_SENSOR: "sensor.mock_power_sensor",
|
||||
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
|
||||
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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
|
||||
CONF_AC_MODE: True,
|
||||
},
|
||||
|
||||
@@ -111,9 +111,9 @@ async def test_update_central_boiler_state_simple(
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_USE_MAIN_CENTRAL_CONFIG: True,
|
||||
CONF_USE_TPI_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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_USE_MAIN_CENTRAL_CONFIG: True,
|
||||
CONF_USE_TPI_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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_USE_MAIN_CENTRAL_CONFIG: True,
|
||||
CONF_USE_TPI_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_UNDERLYING_LIST: [climate1.entity_id],
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_USE_MAIN_CENTRAL_CONFIG: True,
|
||||
CONF_USE_PRESETS_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_REGULATION_USE_DEVICE_TEMP: False,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_USE_MAIN_CENTRAL_CONFIG: True,
|
||||
CONF_USE_PRESETS_CENTRAL_CONFIG: True,
|
||||
CONF_USE_ADVANCED_CENTRAL_CONFIG: True,
|
||||
@@ -1255,9 +1255,9 @@ async def test_bug_339(
|
||||
CONF_USE_PRESENCE_FEATURE: False,
|
||||
CONF_CLIMATE: climate1.entity_id,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_USE_MAIN_CENTRAL_CONFIG: True,
|
||||
CONF_USE_PRESETS_CENTRAL_CONFIG: True,
|
||||
CONF_USE_ADVANCED_CENTRAL_CONFIG: True,
|
||||
|
||||
@@ -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_PRESET_POWER: 14,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 11,
|
||||
CONF_SECURITY_DELAY_MIN: 61,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2,
|
||||
CONF_SAFETY_DELAY_MIN: 61,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
|
||||
# CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
|
||||
# CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1,
|
||||
# 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_ext == 0.01
|
||||
assert entity.proportional_algorithm._minimal_activation_delay == 30
|
||||
assert entity._security_delay_min == 5
|
||||
assert entity._security_min_on_percent == 0.3
|
||||
assert entity._security_default_on_percent == 0.1
|
||||
assert entity.safety_manager.safety_delay_min == 5
|
||||
assert entity.safety_manager.safety_min_on_percent == 0.3
|
||||
assert entity.safety_manager.safety_default_on_percent == 0.1
|
||||
assert entity.is_inversed
|
||||
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
|
||||
CONF_WINDOW_DELAY: 30,
|
||||
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_ext == 0.01
|
||||
assert entity.proportional_algorithm._minimal_activation_delay == 30
|
||||
assert entity._security_delay_min == 5
|
||||
assert entity._security_min_on_percent == 0.3
|
||||
assert entity._security_default_on_percent == 0.1
|
||||
assert entity.safety_manager.safety_delay_min == 5
|
||||
assert entity.safety_manager.safety_min_on_percent == 0.3
|
||||
assert entity.safety_manager.safety_default_on_percent == 0.1
|
||||
assert entity.is_inversed is False
|
||||
|
||||
assert (
|
||||
@@ -348,9 +348,9 @@ async def test_full_over_switch_with_central_config(
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
|
||||
CONF_WINDOW_DELAY: 30,
|
||||
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_ext == 0.02
|
||||
assert entity.proportional_algorithm._minimal_activation_delay == 11
|
||||
assert entity._security_delay_min == 61
|
||||
assert entity._security_min_on_percent == 0.5
|
||||
assert entity._security_default_on_percent == 0.2
|
||||
assert entity.safety_manager.safety_delay_min == 61
|
||||
assert entity.safety_manager.safety_min_on_percent == 0.5
|
||||
assert entity.safety_manager.safety_default_on_percent == 0.2
|
||||
assert entity.is_inversed is False
|
||||
|
||||
# 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(
|
||||
version=CONFIG_VERSION,
|
||||
# An old minor version
|
||||
minor_version=1,
|
||||
minor_version=0,
|
||||
domain=DOMAIN,
|
||||
title="TheCentralConfigMockName",
|
||||
unique_id="centralConfigUniqueId",
|
||||
@@ -509,9 +509,9 @@ async def test_migration_of_central_config(
|
||||
CONF_TPI_COEF_INT: 0.5,
|
||||
CONF_TPI_COEF_EXT: 0.02,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 11,
|
||||
CONF_SECURITY_DELAY_MIN: 61,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2,
|
||||
CONF_SAFETY_DELAY_MIN: 61,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
|
||||
# The old central_boiler parameter
|
||||
"add_central_boiler_control": True,
|
||||
CONF_CENTRAL_BOILER_ACTIVATION_SRV: "switch.pompe_chaudiere/switch.turn_on",
|
||||
|
||||
@@ -56,9 +56,9 @@ async def test_config_with_central_mode_true(
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_AC_MODE: True,
|
||||
},
|
||||
)
|
||||
@@ -482,9 +482,9 @@ async def test_climate_ac_change_central_mode_false(
|
||||
CONF_USE_PRESENCE_FEATURE: False,
|
||||
CONF_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.window_sensor",
|
||||
CONF_WINDOW_DELAY: 0, # To be not obliged to wait
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.window_sensor",
|
||||
CONF_WINDOW_DELAY: 0, # To be not obliged to wait
|
||||
CONF_MOTION_SENSOR: "input_boolean.motion_sensor",
|
||||
|
||||
@@ -470,9 +470,9 @@ async def test_user_config_flow_over_climate(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 10,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
|
||||
},
|
||||
)
|
||||
assert result["type"] == FlowResultType.MENU
|
||||
@@ -496,9 +496,9 @@ async def test_user_config_flow_over_climate(
|
||||
"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 | {
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 10,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
|
||||
} | MOCK_DEFAULT_FEATURE_CONFIG | {
|
||||
CONF_USE_MAIN_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"],
|
||||
user_input={
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 10,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
|
||||
},
|
||||
)
|
||||
assert result["type"] == FlowResultType.MENU
|
||||
@@ -1104,9 +1104,9 @@ async def test_user_config_flow_over_climate_auto_start_stop(
|
||||
"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 | {
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 10,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
|
||||
} | MOCK_DEFAULT_FEATURE_CONFIG | {
|
||||
CONF_USE_MAIN_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"],
|
||||
user_input={
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 10,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
|
||||
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_STEP_TEMPERATURE: 0.5,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 10,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
|
||||
CONF_USE_MAIN_CENTRAL_CONFIG: False,
|
||||
CONF_USE_TPI_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"],
|
||||
user_input={
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 10,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
|
||||
},
|
||||
)
|
||||
assert result["type"] == FlowResultType.MENU
|
||||
@@ -1685,9 +1685,9 @@ async def test_user_config_flow_over_climate_valve(
|
||||
"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 | {
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 10,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
|
||||
} | MOCK_DEFAULT_FEATURE_CONFIG | {
|
||||
CONF_USE_MAIN_CENTRAL_CONFIG: False,
|
||||
CONF_USE_PRESETS_CENTRAL_CONFIG: False,
|
||||
|
||||
@@ -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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
|
||||
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1,
|
||||
CONF_WINDOW_AUTO_MAX_DURATION: 0, # Should be 0 for test
|
||||
|
||||
@@ -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
|
||||
temps = {
|
||||
"frost": 7,
|
||||
"eco": 17,
|
||||
"comfort": 18,
|
||||
"boost": 19,
|
||||
}
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
@@ -39,22 +45,18 @@ async def test_last_seen_feature(hass: HomeAssistant, skip_hass_states_is_state)
|
||||
"cycle_min": 5,
|
||||
"temp_min": 15,
|
||||
"temp_max": 30,
|
||||
"frost_temp": 7,
|
||||
"eco_temp": 17,
|
||||
"comfort_temp": 18,
|
||||
"boost_temp": 19,
|
||||
"use_window_feature": False,
|
||||
"use_motion_feature": False,
|
||||
"use_power_feature": False,
|
||||
"use_presence_feature": False,
|
||||
"heater_entity_id": "switch.mock_switch",
|
||||
CONF_UNDERLYING_LIST: ["switch.mock_switch"],
|
||||
"proportional_function": "tpi",
|
||||
"tpi_coef_int": 0.3,
|
||||
"tpi_coef_ext": 0.01,
|
||||
"minimal_activation_delay": 30,
|
||||
"security_delay_min": 5, # 5 minutes
|
||||
"security_min_on_percent": 0.2,
|
||||
"security_default_on_percent": 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5, # 5 minutes
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.2,
|
||||
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._security_state is False
|
||||
assert entity.preset_mode is not PRESET_SECURITY
|
||||
await set_all_climate_preset_temp(hass, entity, temps, "theoverswitchmockname")
|
||||
|
||||
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_temperature_measure is not None
|
||||
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)
|
||||
await send_temperature_change_event(entity, 15, event_timestamp)
|
||||
assert entity.security_state is True
|
||||
assert entity.preset_mode == PRESET_SECURITY
|
||||
assert entity.safety_state is STATE_ON
|
||||
assert entity.preset_mode == PRESET_SAFETY
|
||||
|
||||
assert mock_send_event.call_count == 3
|
||||
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(
|
||||
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
|
||||
event_timestamp = now - timedelta(minutes=4)
|
||||
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._last_temperature_measure == event_timestamp
|
||||
|
||||
|
||||
@@ -305,8 +305,8 @@ async def test_motion_management_time_not_enough(
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 10,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 10,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
|
||||
CONF_MOTION_DELAY: 10, # important to not been obliged to wait
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
|
||||
CONF_MOTION_DELAY: 0, # important to not been obliged to wait
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
|
||||
CONF_MOTION_DELAY: 0, # important to not been obliged to wait
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
|
||||
CONF_MOTION_DELAY: 10,
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
|
||||
CONF_MOTION_DELAY: 10,
|
||||
CONF_MOTION_OFF_DELAY: 30,
|
||||
|
||||
@@ -45,8 +45,8 @@ async def test_one_switch_cycle(
|
||||
CONF_USE_PRESENCE_FEATURE: False,
|
||||
CONF_HEATER: "switch.mock_switch1",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
@@ -262,8 +262,8 @@ async def test_multiple_switchs(
|
||||
CONF_HEATER_4: "switch.mock_switch4",
|
||||
CONF_HEATER_KEEP_ALIVE: 0,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
@@ -402,8 +402,8 @@ async def test_multiple_climates(
|
||||
CONF_CLIMATE_3: "switch.mock_climate3",
|
||||
CONF_CLIMATE_4: "switch.mock_climate4",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
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_4: "switch.mock_climate4",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
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_4: "switch.mock_climate4",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
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_KEEP_ALIVE: 0,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
|
||||
@@ -62,8 +62,8 @@ async def test_bug_56(
|
||||
CONF_USE_PRESENCE_FEATURE: False,
|
||||
CONF_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -151,7 +151,7 @@ async def test_bug_82(
|
||||
PRESET_BOOST,
|
||||
]
|
||||
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
|
||||
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)
|
||||
await send_temperature_change_event(entity, 15, event_timestamp)
|
||||
# Should stay False
|
||||
assert entity.security_state is False
|
||||
assert entity.safety_state is not STATE_ON
|
||||
assert entity.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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
|
||||
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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
|
||||
CONF_AC_MODE: True,
|
||||
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_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
|
||||
CONF_AC_MODE: True,
|
||||
CONF_AUTO_START_STOP_LEVEL: AUTO_START_STOP_LEVEL_FAST,
|
||||
|
||||
@@ -111,7 +111,7 @@ async def test_over_climate_valve_mono(hass: HomeAssistant, skip_hass_states_get
|
||||
PRESET_BOOST,
|
||||
]
|
||||
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.motion_state is STATE_UNAVAILABLE
|
||||
assert vtherm.presence_state is STATE_UNAVAILABLE
|
||||
|
||||
@@ -269,8 +269,8 @@ async def test_power_management_hvac_off(
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_POWER_SENSOR: "sensor.mock_power_sensor",
|
||||
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_POWER_SENSOR: "sensor.mock_power_sensor",
|
||||
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_POWER_SENSOR: "sensor.mock_power_sensor",
|
||||
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
|
||||
CONF_DEVICE_POWER: 100,
|
||||
@@ -620,8 +620,8 @@ async def test_power_management_energy_over_climate(
|
||||
CONF_USE_PRESENCE_FEATURE: False,
|
||||
CONF_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_POWER_SENSOR: "sensor.mock_power_sensor",
|
||||
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
|
||||
CONF_DEVICE_POWER: 100,
|
||||
|
||||
@@ -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
|
||||
2. activate security feature when date is expired
|
||||
3. change the preset to boost
|
||||
4. check that security is still on
|
||||
5. resolve the date issue
|
||||
6. check that security is off and preset is changed to boost
|
||||
"""
|
||||
|
||||
tz = get_tz(hass) # pylint: disable=invalid-name
|
||||
|
||||
temps = {
|
||||
"frost": 7,
|
||||
"eco": 17,
|
||||
"comfort": 18,
|
||||
"boost": 19,
|
||||
}
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title="TheOverSwitchMockName",
|
||||
unique_id="uniqueId",
|
||||
# With migration
|
||||
version=CONFIG_VERSION,
|
||||
minor_version=0,
|
||||
data={
|
||||
"name": "TheOverSwitchMockName",
|
||||
"thermostat_type": "thermostat_over_switch",
|
||||
@@ -43,15 +52,11 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state):
|
||||
"cycle_min": 5,
|
||||
"temp_min": 15,
|
||||
"temp_max": 30,
|
||||
"frost_temp": 7,
|
||||
"eco_temp": 17,
|
||||
"comfort_temp": 18,
|
||||
"boost_temp": 19,
|
||||
"use_window_feature": False,
|
||||
"use_motion_feature": False,
|
||||
"use_power_feature": False,
|
||||
"use_presence_feature": False,
|
||||
"heater_entity_id": "switch.mock_switch",
|
||||
CONF_UNDERLYING_LIST: ["switch.mock_switch"],
|
||||
"proportional_function": "tpi",
|
||||
"tpi_coef_int": 0.3,
|
||||
"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._security_state is False
|
||||
assert entity.preset_mode is not PRESET_SECURITY
|
||||
await set_all_climate_preset_temp(hass, entity, temps, "theoverswitchmockname")
|
||||
|
||||
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 == [
|
||||
PRESET_NONE,
|
||||
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)
|
||||
await send_temperature_change_event(entity, 15, event_timestamp)
|
||||
assert entity.security_state is True
|
||||
assert entity.preset_mode == PRESET_SECURITY
|
||||
assert entity.safety_state is STATE_ON
|
||||
assert entity.preset_mode == PRESET_SAFETY
|
||||
assert entity._saved_preset_mode == PRESET_COMFORT
|
||||
assert entity._prop_algorithm.on_percent == 0.1
|
||||
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
|
||||
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(
|
||||
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)
|
||||
|
||||
# 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.calculated_on_percent == 0.9
|
||||
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
|
||||
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)
|
||||
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._saved_preset_mode == PRESET_BOOST
|
||||
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
|
||||
temps = {
|
||||
"eco": 17,
|
||||
"comfort": 18,
|
||||
"boost": 19,
|
||||
"frost": 10,
|
||||
}
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
@@ -228,21 +246,18 @@ async def test_security_feature_back_on_percent(
|
||||
"cycle_min": 5,
|
||||
"temp_min": 15,
|
||||
"temp_max": 30,
|
||||
"eco_temp": 17,
|
||||
"comfort_temp": 18,
|
||||
"boost_temp": 19,
|
||||
"use_window_feature": False,
|
||||
"use_motion_feature": False,
|
||||
"use_power_feature": False,
|
||||
"use_presence_feature": False,
|
||||
"heater_entity_id": "switch.mock_switch",
|
||||
CONF_UNDERLYING_LIST: ["switch.mock_switch"],
|
||||
"proportional_function": "tpi",
|
||||
"tpi_coef_int": 0.3,
|
||||
"tpi_coef_ext": 0.01,
|
||||
"minimal_activation_delay": 30,
|
||||
"security_delay_min": 5, # 5 minutes
|
||||
"security_min_on_percent": 0.2,
|
||||
"security_default_on_percent": 0.1,
|
||||
"safety_delay_min": 5, # 5 minutes
|
||||
"safety_min_on_percent": 0.2,
|
||||
"safety_default_on_percent": 0.1,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -253,8 +268,12 @@ async def test_security_feature_back_on_percent(
|
||||
)
|
||||
assert entity
|
||||
|
||||
assert entity._security_state is False
|
||||
assert entity.preset_mode is not PRESET_SECURITY
|
||||
await set_all_climate_preset_temp(hass, entity, temps, "theoverswitchmockname")
|
||||
|
||||
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_temperature_measure is not None
|
||||
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)
|
||||
assert entity._prop_algorithm.calculated_on_percent == 0.6
|
||||
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
|
||||
|
||||
# 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.security_state is True
|
||||
assert entity.preset_mode == PRESET_SECURITY
|
||||
assert entity.safety_state is STATE_ON
|
||||
assert entity.preset_mode == PRESET_SAFETY
|
||||
assert entity._saved_preset_mode == PRESET_BOOST
|
||||
|
||||
assert mock_send_event.call_count == 3
|
||||
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(
|
||||
EventType.TEMPERATURE_EVENT,
|
||||
{
|
||||
@@ -343,8 +362,8 @@ async def test_security_feature_back_on_percent(
|
||||
entity._set_now(event_timestamp) # pylint: disable=protected-access
|
||||
|
||||
await entity.async_set_preset_mode(PRESET_ECO)
|
||||
assert entity.security_state is True
|
||||
assert entity.preset_mode == PRESET_SECURITY
|
||||
assert entity.safety_state is STATE_ON
|
||||
assert entity.preset_mode == PRESET_SAFETY
|
||||
|
||||
# 5. resolve the datetime issue
|
||||
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)
|
||||
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._saved_preset_mode == PRESET_ECO
|
||||
assert entity._prop_algorithm.on_percent == 0.0
|
||||
@@ -452,7 +473,8 @@ async def test_security_over_climate(
|
||||
PRESET_BOOST,
|
||||
]
|
||||
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
|
||||
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)
|
||||
# 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._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
|
||||
@@ -62,8 +62,8 @@ async def test_sensors_over_switch(
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_DEVICE_POWER: 200,
|
||||
},
|
||||
)
|
||||
@@ -222,8 +222,8 @@ async def test_sensors_over_climate(
|
||||
CONF_USE_PRESENCE_FEATURE: False,
|
||||
CONF_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_POWER_SENSOR: "sensor.mock_power_sensor",
|
||||
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
|
||||
CONF_DEVICE_POWER: 1.5,
|
||||
@@ -360,8 +360,8 @@ async def test_sensors_over_climate_minimal(
|
||||
CONF_USE_PRESENCE_FEATURE: False,
|
||||
CONF_CLIMATE: "climate.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ async def test_over_switch_full_start(hass: HomeAssistant, skip_hass_states_is_s
|
||||
PRESET_ACTIVITY,
|
||||
]
|
||||
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.motion_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,
|
||||
]
|
||||
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.motion_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,
|
||||
]
|
||||
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.motion_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_4: None,
|
||||
CONF_HEATER_KEEP_ALIVE: 0,
|
||||
CONF_SECURITY_DELAY_MIN: 10,
|
||||
CONF_SAFETY_DELAY_MIN: 10,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 10,
|
||||
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
|
||||
CONF_TPI_COEF_INT: 0.6,
|
||||
|
||||
@@ -89,7 +89,7 @@ async def test_over_switch_ac_full_start(
|
||||
PRESET_ACTIVITY,
|
||||
]
|
||||
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.motion_state is STATE_UNKNOWN
|
||||
assert entity.presence_state is STATE_UNKNOWN
|
||||
|
||||
@@ -39,8 +39,8 @@ def config_entry() -> MockConfigEntry:
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.1,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.1,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -75,9 +75,9 @@ async def test_add_number_for_central_config(
|
||||
CONF_MAX_POWER_SENSOR: "sensor.mock_central_max_power_sensor",
|
||||
CONF_PRESET_POWER: 14,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 11,
|
||||
CONF_SECURITY_DELAY_MIN: 61,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2,
|
||||
CONF_SAFETY_DELAY_MIN: 61,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
|
||||
CONF_USE_CENTRAL_BOILER_FEATURE: False,
|
||||
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_PRESET_POWER: 14,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 11,
|
||||
CONF_SECURITY_DELAY_MIN: 61,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2,
|
||||
CONF_SAFETY_DELAY_MIN: 61,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
|
||||
CONF_USE_CENTRAL_BOILER_FEATURE: False,
|
||||
},
|
||||
# | 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_PRESET_POWER: 14,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 11,
|
||||
CONF_SECURITY_DELAY_MIN: 61,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2,
|
||||
CONF_SAFETY_DELAY_MIN: 61,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
|
||||
CONF_USE_CENTRAL_BOILER_FEATURE: False,
|
||||
},
|
||||
# | 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_PRESET_POWER: 14,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 11,
|
||||
CONF_SECURITY_DELAY_MIN: 61,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.2,
|
||||
CONF_SAFETY_DELAY_MIN: 61,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
|
||||
CONF_USE_CENTRAL_BOILER_FEATURE: False,
|
||||
},
|
||||
# | temps,
|
||||
|
||||
@@ -38,8 +38,8 @@ async def test_tpi_calculation(
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
# CONF_DEVICE_POWER: 100,
|
||||
},
|
||||
)
|
||||
@@ -66,14 +66,14 @@ async def test_tpi_calculation(
|
||||
assert tpi_algo.on_time_sec == 120
|
||||
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)
|
||||
assert tpi_algo.on_percent == 0.1
|
||||
assert tpi_algo.calculated_on_percent == 0.4
|
||||
assert tpi_algo.on_time_sec == 30 # >= minimal_activation_delay (=30)
|
||||
assert tpi_algo.off_time_sec == 270
|
||||
|
||||
tpi_algo.unset_security()
|
||||
tpi_algo.unset_safety()
|
||||
tpi_algo.calculate(15, 14, 5, HVACMode.HEAT)
|
||||
assert tpi_algo.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.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)
|
||||
assert tpi_algo.on_percent == 0.09
|
||||
assert tpi_algo.calculated_on_percent == 0.09
|
||||
assert tpi_algo.on_time_sec == 0
|
||||
assert tpi_algo.off_time_sec == 300
|
||||
|
||||
tpi_algo.unset_security()
|
||||
tpi_algo.unset_safety()
|
||||
tpi_algo.calculate(25, 30, 35, HVACMode.COOL)
|
||||
assert tpi_algo.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 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)
|
||||
assert tpi_algo.on_percent == 0.09
|
||||
assert tpi_algo.calculated_on_percent == 1
|
||||
@@ -110,7 +110,7 @@ async def test_tpi_calculation(
|
||||
assert tpi_algo.off_time_sec == 300
|
||||
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.
|
||||
tpi_algo.calculate(15, 10, 7, HVACMode.OFF)
|
||||
assert tpi_algo.on_percent == 1
|
||||
|
||||
@@ -60,8 +60,8 @@ async def test_over_valve_full_start(
|
||||
PRESET_BOOST + PRESET_AWAY_SUFFIX + PRESET_TEMP_SUFFIX: 17.3,
|
||||
CONF_PRESET_POWER: 10,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_DEVICE_POWER: 100,
|
||||
CONF_AC_MODE: False,
|
||||
},
|
||||
@@ -98,7 +98,9 @@ async def test_over_valve_full_start(
|
||||
PRESET_ACTIVITY,
|
||||
]
|
||||
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.motion_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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 60,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 60,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
# only send new valve open percent if dtemp is > 30%
|
||||
CONF_AUTO_REGULATION_DTEMP: 5,
|
||||
# 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_AUTO_REGULATION_DTEMP: 10, # This parameter makes the bug
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 60,
|
||||
CONF_SAFETY_DELAY_MIN: 60,
|
||||
},
|
||||
# | temps,
|
||||
)
|
||||
|
||||
@@ -45,8 +45,8 @@ async def test_window_management_time_not_enough(
|
||||
CONF_TPI_COEF_INT: 0.3,
|
||||
CONF_TPI_COEF_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
|
||||
CONF_WINDOW_DELAY: 0, # important to not been obliged to wait
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
|
||||
CONF_WINDOW_DELAY: 0, # important to not been obliged to wait
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
|
||||
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1,
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.fake_window_sensor",
|
||||
CONF_WINDOW_DELAY: 10,
|
||||
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_CLIMATE: "switch.mock_climate",
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 6,
|
||||
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 6,
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 6,
|
||||
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 6,
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 6,
|
||||
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 6,
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
|
||||
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_PRESENCE_FEATURE: False,
|
||||
CONF_CLIMATE: "climate.mock_climate",
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
|
||||
CONF_WINDOW_DELAY: 1,
|
||||
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_PRESENCE_FEATURE: False,
|
||||
CONF_CLIMATE: "climate.mock_climate",
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
|
||||
CONF_WINDOW_DELAY: 1,
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
|
||||
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1,
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
|
||||
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1,
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.1, # !! here
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
|
||||
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1, # !! here
|
||||
CONF_DEVICE_POWER: 200,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_ACTION: CONF_WINDOW_FROST_TEMP,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.fake_window_sensor",
|
||||
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_EXT: 0.01,
|
||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||
CONF_SECURITY_DELAY_MIN: 5,
|
||||
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_SAFETY_DELAY_MIN: 5,
|
||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||
CONF_WINDOW_ACTION: CONF_WINDOW_FROST_TEMP,
|
||||
CONF_WINDOW_SENSOR: "binary_sensor.fake_window_sensor",
|
||||
CONF_WINDOW_DELAY: 1,
|
||||
|
||||
Reference in New Issue
Block a user