Compare commits

...

10 Commits
7.2.1 ... main

Author SHA1 Message Date
Jean-Marc Collin
cc7b7f43b9 Fix test and default value for minimal_deactivation_delay 2025-02-12 14:38:50 +00:00
Jean-Marc Collin
2a125db73f Fix fr.json translations for minimal_deactivation_delay 2025-02-12 13:46:16 +00:00
Tomasz Madycki
bb4d3a59a9 Add minimal_deactivation_delay (#905)
* Add minimal_deactivation_delay

In some cases users may want to keep the equipment on if it will deactivate for a short time.
This could help reduce wear on gas boilers.

* fix(prop_algorithm): correct the log message for minimal_deactivation_delay

* fix(translations): correct the translations for minimal_deactivation_delay
2025-02-12 14:41:13 +01:00
Jean-Marc Collin
15a48105b0 Add quickstart over_climate 2025-02-10 17:44:25 +00:00
Jean-Marc Collin
ea0d66f0c6 Vack to HA 2025.1.4. It doesn't work on Github. 2025-02-10 16:53:28 +00:00
adi90x
641801084d Correct window bypass (#899) 2025-02-10 17:44:28 +01:00
adi90x
1576e9c189 Add bypass to the window open check and correct description (#897) 2025-02-10 17:42:06 +01:00
adi90x
313fa26160 Save & Recover Window Bypass state (#898)
* Remove windows_bypass state from unrecorded

* Recover bypass_state
2025-02-10 17:29:53 +01:00
Jean-Marc Collin
832ea78a12 FIX select_option 2025-02-10 08:33:40 +01:00
Jean-Marc Collin
5f167af331 Fix select_option 2025-02-10 08:33:06 +01:00
44 changed files with 329 additions and 27 deletions

View File

@@ -104,6 +104,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
"last_temperature_datetime",
"last_ext_temperature_datetime",
"minimal_activation_delay_sec",
"minimal_deactivation_delay_sec",
"last_update_datetime",
"timezone",
"temperature_unit",
@@ -370,6 +371,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
self._tpi_coef_ext = 0
self._minimal_activation_delay = entry_infos.get(CONF_MINIMAL_ACTIVATION_DELAY)
self._minimal_deactivation_delay = entry_infos.get(CONF_MINIMAL_DEACTIVATION_DELAY, 0)
self._last_temperature_measure = self.now
self._last_ext_temperature_measure = self.now
@@ -1684,6 +1686,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
self._current_tz
).isoformat(),
"minimal_activation_delay_sec": self._minimal_activation_delay,
"minimal_deactivation_delay_sec": self._minimal_deactivation_delay,
ATTR_TOTAL_ENERGY: self.total_energy,
"last_update_datetime": self.now.isoformat(),
"timezone": str(self._current_tz),

View File

@@ -371,6 +371,12 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
):
return False
if (
infos.get(CONF_USE_ADVANCED_CENTRAL_CONFIG, False) is False
and infos.get(CONF_MINIMAL_DEACTIVATION_DELAY, -1) == -1
):
return False
if (
infos.get(CONF_PROP_FUNCTION, None) == PROPORTIONAL_FUNCTION_TPI
and infos.get(CONF_USE_TPI_CENTRAL_CONFIG, False) is False

View File

@@ -374,6 +374,7 @@ 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_MINIMAL_DEACTIVATION_DELAY, default=0): cv.positive_int,
vol.Required(CONF_SAFETY_DELAY_MIN, default=60): cv.positive_int,
vol.Required(
CONF_SAFETY_MIN_ON_PERCENT,

View File

@@ -83,6 +83,7 @@ CONF_TPI_COEF_EXT = "tpi_coef_ext"
CONF_PRESENCE_SENSOR = "presence_sensor_entity_id"
CONF_PRESET_POWER = "power_temp"
CONF_MINIMAL_ACTIVATION_DELAY = "minimal_activation_delay"
CONF_MINIMAL_DEACTIVATION_DELAY = "minimal_deactivation_delay"
CONF_TEMP_MIN = "temp_min"
CONF_TEMP_MAX = "temp_max"
CONF_SAFETY_DELAY_MIN = "safety_delay_min"
@@ -289,6 +290,7 @@ ALL_CONF = (
CONF_TPI_COEF_EXT,
CONF_PRESENCE_SENSOR,
CONF_MINIMAL_ACTIVATION_DELAY,
CONF_MINIMAL_DEACTIVATION_DELAY,
CONF_TEMP_MIN,
CONF_TEMP_MAX,
CONF_SAFETY_DELAY_MIN,

View File

@@ -44,7 +44,6 @@ class FeatureWindowManager(BaseFeatureManager):
{
"window_sensor_entity_id",
"is_window_configured",
"is_window_bypass",
"window_delay_sec",
"window_off_delay_sec",
"window_auto_configured",
@@ -130,6 +129,11 @@ class FeatureWindowManager(BaseFeatureManager):
@overrides
async def start_listening(self):
"""Start listening the underlying entity"""
#Try to get last window bypass state
old_state = await self._vtherm.async_get_last_state()
self._is_window_bypass = True if old_state and old_state.attributes and old_state.attributes.get("is_window_bypass") == True else False
if self._is_configured:
self.stop_listening()
if self._window_sensor_entity_id:
@@ -449,22 +453,23 @@ class FeatureWindowManager(BaseFeatureManager):
"""Set the window bypass flag
Return True if state have been changed"""
self._is_window_bypass = window_bypass
if not self._is_window_bypass and self._window_state:
_LOGGER.info(
"%s - Last window state was open & ByPass is now off. Set hvac_mode to '%s'",
self,
HVACMode.OFF,
)
self._vtherm.save_hvac_mode()
await self._vtherm.async_set_hvac_mode(HVACMode.OFF)
return True
if self._window_state == STATE_ON:
if not self._is_window_bypass:
_LOGGER.info(
"%s - Last window state was open & ByPass is now off. Set hvac_mode to '%s'",
self,
HVACMode.OFF,
)
self._vtherm.save_hvac_mode()
await self._vtherm.async_set_hvac_mode(HVACMode.OFF)
if self._is_window_bypass and self._window_state:
_LOGGER.info(
"%s - Last window state was open & ByPass is now on. Set hvac_mode to last available mode",
self,
)
await self._vtherm.restore_hvac_mode(True)
if self._is_window_bypass:
_LOGGER.info(
"%s - Last window state was open & ByPass is now on. Set hvac_mode to last available mode",
self,
)
await self._vtherm.restore_hvac_mode(True)
return True
return False
@@ -504,10 +509,10 @@ class FeatureWindowManager(BaseFeatureManager):
@property
def is_window_detected(self) -> bool:
"""Return true if the presence is configured and presence sensor is OFF"""
"""Return true if the window is configured and open and bypass is not ON"""
return self._is_configured and (
self._window_state == STATE_ON or self._window_auto_state == STATE_ON
)
) and not self._is_window_bypass
@property
def window_sensor_entity_id(self) -> bool:

View File

@@ -30,18 +30,20 @@ class PropAlgorithm:
tpi_coef_ext,
cycle_min: int,
minimal_activation_delay: int,
minimal_deactivation_delay: int,
vtherm_entity_id: str = None,
max_on_percent: float = None,
) -> None:
"""Initialisation of the Proportional Algorithm"""
_LOGGER.debug(
"%s - Creation new PropAlgorithm function_type: %s, tpi_coef_int: %s, tpi_coef_ext: %s, cycle_min:%d, minimal_activation_delay:%d", # pylint: disable=line-too-long
"%s - Creation new PropAlgorithm function_type: %s, tpi_coef_int: %s, tpi_coef_ext: %s, cycle_min:%d, minimal_activation_delay:%d, minimal_deactivation_delay:%d", # pylint: disable=line-too-long
vtherm_entity_id,
function_type,
tpi_coef_int,
tpi_coef_ext,
cycle_min,
minimal_activation_delay,
minimal_deactivation_delay,
)
# Issue 506 - check parameters
@@ -51,10 +53,11 @@ class PropAlgorithm:
or not is_number(tpi_coef_ext)
or not is_number(cycle_min)
or not is_number(minimal_activation_delay)
or not is_number(minimal_deactivation_delay)
or function_type != PROPORTIONAL_FUNCTION_TPI
):
_LOGGER.error(
"%s - configuration is wrong. function_type=%s, entity_id is %s, tpi_coef_int is %s, tpi_coef_ext is %s, cycle_min is %s, minimal_activation_delay is %s",
"%s - configuration is wrong. function_type=%s, entity_id is %s, tpi_coef_int is %s, tpi_coef_ext is %s, cycle_min is %s, minimal_activation_delay is %s, minimal_deactivation_delay is %s",
vtherm_entity_id,
function_type,
vtherm_entity_id,
@@ -62,6 +65,7 @@ class PropAlgorithm:
tpi_coef_ext,
cycle_min,
minimal_activation_delay,
minimal_deactivation_delay,
)
raise TypeError(
"TPI parameters are not set correctly. VTherm will not work as expected. Please reconfigure it correctly. See previous log for values"
@@ -73,6 +77,7 @@ class PropAlgorithm:
self._tpi_coef_ext = tpi_coef_ext
self._cycle_min = cycle_min
self._minimal_activation_delay = minimal_activation_delay
self._minimal_deactivation_delay = minimal_deactivation_delay
self._on_percent = 0
self._calculated_on_percent = 0
self._on_time_sec = 0
@@ -187,6 +192,18 @@ class PropAlgorithm:
self._off_time_sec = self._cycle_min * 60 - self._on_time_sec
# Do not stop heating when off time less than xx sec
if self._off_time_sec < self._minimal_deactivation_delay:
if self._off_time_sec > 0:
_LOGGER.info(
"%s - Force 100%% heating cycle since the off duration (%f) is shorter than minimal_deactivation_delay (%f)",
self._vtherm_entity_id,
self._off_time_sec,
self._minimal_deactivation_delay,
)
self._on_time_sec = self._cycle_min * 60
self._off_time_sec = 0
def set_safety(self, default_on_percent: float):
"""Set a default value for on_percent (used for safety mode)"""
_LOGGER.info(

View File

@@ -199,6 +199,7 @@
"description": "Configuration of advanced parameters. Leave the default values if you don't know what you are doing.\nThese parameters can lead to very poor temperature control or bad power regulation&nbsp;[![?](https://img.icons8.com/color/18/help.png)](https://github.com/jmcollin78/versatile_thermostat/blob/main/documentation/en/feature-advanced.md)",
"data": {
"minimal_activation_delay": "Minimum activation delay",
"minimal_deactivation_delay": "Minimum deactivation delay",
"safety_delay_min": "Safety delay (in minutes)",
"safety_min_on_percent": "Minimum power percent to enable safety mode",
"safety_default_on_percent": "Power percent to use in safety mode",
@@ -206,6 +207,7 @@
},
"data_description": {
"minimal_activation_delay": "Delay in seconds under which the equipment will not be activated",
"minimal_deactivation_delay": "Delay in seconds under which the equipment will be kept active",
"safety_delay_min": "Maximum allowed delay in minutes between two temperature measurements. Above this delay the thermostat will turn to a safety off state",
"safety_min_on_percent": "Minimum heating percent value for safety preset activation. Below this amount of power percent the thermostat won't go into safety preset",
"safety_default_on_percent": "The default heating power percent value in safety preset. Set to 0 to switch off heater in safety preset",
@@ -451,6 +453,7 @@
"description": "Configuration of advanced parameters. Leave the default values if you don't know what you are doing.\nThese parameters can lead to very poor temperature control or bad power regulation&nbsp;[![?](https://img.icons8.com/color/18/help.png)](https://github.com/jmcollin78/versatile_thermostat/blob/main/documentation/en/feature-advanced.md)",
"data": {
"minimal_activation_delay": "Minimum activation delay",
"minimal_deactivation_delay": "Minimum deactivation delay",
"safety_delay_min": "Safety delay (in minutes)",
"safety_min_on_percent": "Minimum power percent to enable safety mode",
"safety_default_on_percent": "Power percent to use in safety mode",
@@ -458,6 +461,7 @@
},
"data_description": {
"minimal_activation_delay": "Delay in seconds under which the equipment will not be activated",
"minimal_deactivation_delay": "Delay in seconds under which the equipment will be kept active",
"safety_delay_min": "Maximum allowed delay in minutes between two temperature measurements. Above this delay the thermostat will turn to a safety off state",
"safety_min_on_percent": "Minimum heating percent value for safety preset activation. Below this amount of power percent the thermostat won't go into safety preset",
"safety_default_on_percent": "The default heating power percent value in safety preset. Set to 0 to switch off heater in safety preset",

View File

@@ -82,6 +82,7 @@ class ThermostatOverClimateValve(ThermostatOverClimate):
self._tpi_coef_ext,
self._cycle_min,
self._minimal_activation_delay,
self._minimal_deactivation_delay,
self.name,
)

View File

@@ -77,6 +77,7 @@ class ThermostatOverSwitch(BaseThermostat[UnderlyingSwitch]):
self._tpi_coef_ext,
self._cycle_min,
self._minimal_activation_delay,
self._minimal_deactivation_delay,
self.name,
max_on_percent=self._max_on_percent,
)

View File

@@ -96,6 +96,7 @@ class ThermostatOverValve(BaseThermostat[UnderlyingValve]): # pylint: disable=a
self._tpi_coef_ext,
self._cycle_min,
self._minimal_activation_delay,
self._minimal_deactivation_delay,
self.name,
max_on_percent=self._max_on_percent,
)

View File

@@ -199,6 +199,7 @@
"description": "Configuration of advanced parameters. Leave the default values if you don't know what you are doing.\nThese parameters can lead to very poor temperature control or bad power regulation&nbsp;[![?](https://img.icons8.com/color/18/help.png)](https://github.com/jmcollin78/versatile_thermostat/blob/main/documentation/en/feature-advanced.md)",
"data": {
"minimal_activation_delay": "Minimum activation delay",
"minimal_deactivation_delay": "Minimal deactivation delay",
"safety_delay_min": "Safety delay (in minutes)",
"safety_min_on_percent": "Minimum power percent to enable safety mode",
"safety_default_on_percent": "Power percent to use in safety mode",
@@ -206,6 +207,7 @@
},
"data_description": {
"minimal_activation_delay": "Delay in seconds under which the equipment will not be activated",
"minimal_deactivation_delay": "Delay in seconds under which the equipment will be kept active",
"safety_delay_min": "Maximum allowed delay in minutes between two temperature measurements. Above this delay the thermostat will turn to a safety off state",
"safety_min_on_percent": "Minimum heating percent value for safety preset activation. Below this amount of power percent the thermostat won't go into safety preset",
"safety_default_on_percent": "The default heating power percent value in safety preset. Set to 0 to switch off heater in safety preset",

View File

@@ -200,6 +200,7 @@
"description": "Configuration des paramètres avancés. Laissez les valeurs par défaut si vous ne savez pas ce que vous faites.\nCes paramètres peuvent induire des mauvais comportements du thermostat&nbsp;[![?](https://img.icons8.com/color/18/help.png)](https://github.com/jmcollin78/versatile_thermostat/blob/main/documentation/fr/feature-advanced.md)",
"data": {
"minimal_activation_delay": "Délai minimal d'activation",
"minimal_deactivation_delay": "Délai de désactivation minimal",
"safety_delay_min": "Délai maximal entre 2 mesures de températures",
"safety_min_on_percent": "Pourcentage minimal de puissance",
"safety_default_on_percent": "Pourcentage de puissance a utiliser en mode securité",
@@ -207,6 +208,7 @@
},
"data_description": {
"minimal_activation_delay": "Délai en secondes en-dessous duquel l'équipement ne sera pas activé",
"minimal_deactivation_delay": "Délai en secondes en-dessous duquel l'équipement se laissé actif",
"safety_delay_min": "Délai maximal autorisé en minutes entre 2 mesures de températures. Au-dessus de ce délai, le thermostat se mettra en position de sécurité",
"safety_min_on_percent": "Seuil minimal de pourcentage de chauffage en-dessous duquel le préréglage sécurité ne sera jamais activé",
"safety_default_on_percent": "Valeur par défaut pour le pourcentage de chauffage en mode sécurité. Mettre 0 pour éteindre le radiateur en mode sécurité",
@@ -448,13 +450,15 @@
"description": "Configuration des paramètres avancés. Laissez les valeurs par défaut si vous ne savez pas ce que vous faites.\nCes paramètres peuvent induire des mauvais comportements du thermostat&nbsp;[![?](https://img.icons8.com/color/18/help.png)](https://github.com/jmcollin78/versatile_thermostat/blob/main/documentation/fr/feature-advanced.md)",
"data": {
"minimal_activation_delay": "Délai minimal d'activation",
"minimal_deactivation_delay": "Délai de désactivation minimal",
"safety_delay_min": "Délai maximal entre 2 mesures de températures",
"safety_min_on_percent": "Pourcentage minimal de puissance",
"safety_default_on_percent": "Pourcentage de puissance a utiliser en mode securité",
"use_advanced_central_config": "Utiliser la configuration centrale avancée"
},
"data_description": {
"minimal_activation_delay": "Délai en seondes en-dessous duquel l'équipement ne sera pas activé",
"minimal_activation_delay": "Délai en secondes en-dessous duquel l'équipement ne sera pas activé",
"minimal_deactivation_delay": "Délai en secondes en-dessous duquel l'équipement se laissé actif",
"safety_delay_min": "Délai maximal autorisé en minutes entre 2 mesures de températures. Au-dessus de ce délai, le thermostat se mettra en position de sécurité",
"safety_min_on_percent": "Seuil minimal de pourcentage de chauffage en-dessous duquel le préréglage sécurité ne sera jamais activé",
"safety_default_on_percent": "Valeur par défaut pour le pourcentage de chauffage en mode sécurité. Mettre 0 pour éteindre le radiateur en mode sécurité",

View File

@@ -25,6 +25,10 @@ The advanced configuration form looks like this:
The first delay (`minimal_activation_delay_sec`) in seconds is the minimum acceptable delay to turn on the heating. If the calculated activation time is shorter than this value, the heating remains off. This parameter only applies to _VTherm_ with cyclic triggering `over_switch`. If the activation time is too short, rapid switching will not allow the device to heat up properly.
### Minimum Deactivation Delay
The delay (`minimal_deactivation_delay_sec`) in seconds is the minimum acceptable delay to turn off the heating. If the calculated deactivation time is shorter than this value, the heating remains on.
### Safety Mode
The second delay (`safety_delay_min`) is the maximum time between two temperature measurements before the _VTherm_ switches to Safety Mode.

View File

@@ -74,7 +74,7 @@ The available commands depend on the type of underlying device:
| Underlying Device Type | Possible On Commands | Possible Off Commands | Applies To |
| --------------------------- | ------------------------------------- | ---------------------------------------------- | ----------------------------- |
| `switch` or `input_boolean` | `turn_on` | `turn_off` | All switches |
| `select` or `input_select` | `select_option/option:comfort` | `set_option/option:frost_protection` | Nodon SIN-4-FP-21 and similar |
| `select` or `input_select` | `select_option/option:comfort` | `select_option/option:frost_protection` | Nodon SIN-4-FP-21 and similar |
| `climate` (hvac_mode) | `set_hvac_mode/hvac_mode:heat` | `set_hvac_mode/hvac_mode:off` | eCosy (via Tuya Local) |
| `climate` (preset) | `set_preset_mode/preset_mode:comfort` | `set_preset_mode/preset_mode:frost_protection` | Heatzy |

View File

@@ -7,6 +7,7 @@ This page outlines the steps to quickly set up a basic yet operational _VTherm_.
- [Heatzy, eCosy, or similar (`climate` entity)](#heatzy-ecosy-or-similar-climate-entity)
- [Simple switch such as Aqara T1, Nous B2Z, Sonoff ZBMini, Sonoff POW, ...](#simple-switch-such-as-aqara-t1-nous-b2z-sonoff-zbmini-sonoff-pow-)
- [Sonoff TRVZB or similar (TRV with valve control)](#sonoff-trvzb-or-similar-trv-with-valve-control)
- [Reversible HP Units, Air Conditioning, or Devices Controlled via a `climate` Entity](#reversible-hp-units-air-conditioning-or-devices-controlled-via-a-climate-entity)
- [Next Steps](#next-steps)
- [Call for Contributions](#call-for-contributions)
@@ -70,6 +71,21 @@ For this to work, the `closing degree` must be set to the maximum (100%). Do not
After completing these five steps, you will have a fully functional _VTherm_ that controls your Sonoff TRVZB or similar device.
## Reversible HP Units, Air Conditioning, or Devices Controlled via a `climate` Entity
Reversible heat pumps (HP) or similar devices are represented in _HA_ as a `climate` entity, allowing you to select the heating preset or mode (Heat / Cool / Off).)
_VTherm_ will regulate the temperature by controlling the target temperature and mode of the device through commands sent to the underlying `climate` entity.
To integrate it into _VTherm_, you need to:
1. Create a _VTherm_ of type `over_climate`. See [creating a _VTherm_](creation.md),
2. Assign it the main attributes (name, room temperature sensor, and outdoor temperature sensor at minimum). See [main attributes](base-attributes.md),
3. Define one or more underlying devices to control. The underlying entity here is the `climate` entity that manages the heat pump or air conditioner. See [underlying devices](over-climate.md),
After these three steps, you will have a fully operational _VTherm_ to control your heat pump, air conditioner, or similar device.
To go further, self-regulation may be necessary depending on how well your device operates. Self-regulation involves _VTherm_ slightly adjusting the target temperature to encourage the device to heat or cool more or less until the desired setpoint is reached. Self-regulation is explained in detail here: [self-regulation](self-regulation.md).
# Next Steps
Once created, you need to configure the preset temperatures. See [presets](feature-presets.md) for a minimal configuration.

View File

@@ -61,6 +61,7 @@
| ``power_temp`` | Temperature during load shedding | X | X | X | X |
| ``presence_sensor_entity_id`` | Presence sensor entity id (true if someone is present) | X | X | X | - |
| ``minimal_activation_delay`` | Minimum activation delay | X | - | - | X |
| ``minimal_deactivation_delay`` | Minimum deactivation delay | X | - | - | X |
| ``safety_delay_min`` | Maximum delay between two temperature measurements | X | - | X | X |
| ``safety_min_on_percent`` | Minimum power percentage to enter security mode | X | - | X | X |
| ``auto_regulation_mode`` | Auto-regulation mode | - | X | - | - |
@@ -259,6 +260,7 @@ The custom attributes are as follows:
| ``last_ext_temperature_datetime`` | The date and time in ISO8866 format of the last external temperature reception |
| ``security_state`` | The security state. True or false |
| ``minimal_activation_delay_sec`` | The minimal activation delay in seconds |
| ``minimal_deactivation_delay_sec``| The minimal deactivation delay in seconds |
| ``last_update_datetime`` | The date and time in ISO8866 format of this state |
| ``friendly_name`` | The name of the thermostat |
| ``supported_features`` | A combination of all features supported by this thermostat. See the official climate integration documentation for more information |

View File

@@ -72,7 +72,7 @@ Les commandes possibles dépendent du type de sous-jacents :
| type de sous-jacent | commandes d'allumage possibles | commandes d'extinction possibles | S'applique à |
| --------------------------- | ------------------------------------- | ---------------------------------------------- | ------------------------------ |
| `switch` ou `input_boolean` | `turn_on` | `turn_off` | tous les switchs |
| `select` ou `input_select` | `select_option/option:comfort` | `set_option/option:frost_protection` | Nodon SIN-4-FP-21 et assimilés |
| `select` ou `input_select` | `select_option/option:comfort` | `select_option/option:frost_protection` | Nodon SIN-4-FP-21 et assimilés |
| `climate` (hvac_mode) | `set_hvac_mode/hvac_mode:heat` | `set_hvac_mode/hvac_mode:off` | eCosy (via Tuya Local) |
| `climate` (preset) | `set_preset_mode/preset_mode:comfort` | `set_preset_mode/preset_mode:frost_protection` | Heatzy |
@@ -90,4 +90,4 @@ Si l'erreur suivante se produit :
Cela signifie que une des commandes saisies est invalide. Les règles à respecter sont les suivantes :
1. chaque commande doit avoir le format `commande[/attribut[:valeur]]` (ex: `select_option/option:comfort` ou `turn_on`) sans blanc et sans caractères spéciaux sauf '_',
2. il doit y avoir autant de commandes qu'il y a de sous-jacents déclarés sauf si tous les sous-jacents sont des `switchs` auquel cas il n'est pas nécessaire de paramétrer les commandes,
3. si plusieurs sous-jacents sont configurés, les commandes doivent être dans le même ordre. Le nombre de commandes d'allumage doit être égal au nombre de commandes d'extinction et de sous-jacents (dans l'ordre donc). Il est possible de mettre des sous-jacents de type différent. À partir du moment où un sous-jacent n'est pas un `switch`, il faut paramétrer toutes les commandes de tous les sous-jacents y compris des éventuels switchs.
3. si plusieurs sous-jacents sont configurés, les commandes doivent être dans le même ordre. Le nombre de commandes d'allumage doit être égal au nombre de commandes d'extinction et de sous-jacents (dans l'ordre donc). Il est possible de mettre des sous-jacents de type différent. À partir du moment où un sous-jacent n'est pas un `switch`, il faut paramétrer toutes les commandes de tous les sous-jacents y compris des éventuels switchs.

View File

@@ -7,6 +7,7 @@ Cette page présente les étapes à suivre pour avoir un _VTherm_ basique mais o
- [Heatzy ou eCosy ou assimilé (entité `climate`)](#heatzy-ou-ecosy-ou-assimilé-entité-climate)
- [Simple switch comme Aqara T1, Nous B2Z, Sonoff ZBMini, Sonoff POW, ...](#simple-switch-comme-aqara-t1-nous-b2z-sonoff-zbmini-sonoff-pow-)
- [Sonoff TRVZB ou assimilé (TRV avec contrôle de la vanne)](#sonoff-trvzb-ou-assimilé-trv-avec-contrôle-de-la-vanne)
- [_PAC_ reversibles ou climatisation ou équipements commandables à travers une entité `climate`](#pac-reversibles-ou-climatisation-ou-équipements-commandables-à-travers-une-entité-climate)
- [La suite](#la-suite)
- [Appel à contribution](#appel-à-contribution)
@@ -71,6 +72,19 @@ Pour que cela fonctionne, il faut que le `closing degree` soit réglé au maximu
A l'issue de ces 5 étapes vous avez un _VTherm_ opérationnel ultra simple qui commande votre équipement Sonoff TRVZB ou assimilé.
## _PAC_ reversibles ou climatisation ou équipements commandables à travers une entité `climate`
Les _PAC_ ou assimilés sont visibles sous _HA_ sous la forme d'une entité `climate` qui permet de choisir le preset de chauffage à appliquer ou le mode (Chauffe / Froid / éteint).
_VTherm_ va réguler la température en commandant la consigne de l'équipement et son mode à l'aide de commandes envoyée à l'entité `climate` sous-jacente.
Pour l'intégrer dans _VTherm_ vous devez :
1. Créer un _VTherm_ de type `over_climate`. Cf. [création d'un _VTherm_](creation.md),
2. Lui donner des principaux attributs (nom, capteur de température de la pièce et capteur de température extérieure au minimium). Cf. [principaux attributs](base-attributes.md),
3. Lui donner un ou plusieurs équipements sous-jacents à contrôler. Le sous-jacent est ici l'entité `climate` qui contrôle la _PAC_ ou la clim... . Cf. [sous-jacent](over-climate.md),
A l'issue de ces 3 étapes vous avez un _VTherm_ opérationnel ultra simple qui commande votre _PAC_, climatisation ou assimilé. Pour aller plus loin, une auto-régulation peut êrte nécessaire en fonction du bon fonctionnement de votre équipement. L'auto-régulation consiste à envoyer des consignes légèrement modifiées par _VTherm_ pour forcer l'équipement à chauffer plus ou moins jusqu'à ce que la consigne soit atteinte. L'auto-régulation est détaillée ici : [auto-régulation](self-regulation.md).
# La suite
Uen fois créé, vous devez paramétrer les températures des presets. Cf. [presets](feature-presets.md) pour avoir une configuration minimale.

View File

@@ -1 +1 @@
homeassistant==2025.2.1
homeassistant==2025.1.4

View File

@@ -181,6 +181,7 @@ FULL_CENTRAL_CONFIG = {
CONF_PRESENCE_SENSOR: "binary_sensor.mock_presence_sensor",
CONF_PRESET_POWER: 14,
CONF_MINIMAL_ACTIVATION_DELAY: 11,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 61,
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
@@ -222,6 +223,7 @@ FULL_CENTRAL_CONFIG_WITH_BOILER = {
CONF_MAX_POWER_SENSOR: "sensor.mock_max_power_sensor",
CONF_PRESET_POWER: 14,
CONF_MINIMAL_ACTIVATION_DELAY: 11,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 61,
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,

View File

@@ -185,6 +185,7 @@ MOCK_PRESENCE_AC_CONFIG = {
MOCK_ADVANCED_CONFIG = {
CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,

View File

@@ -53,6 +53,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
@@ -119,6 +120,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
@@ -189,6 +191,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,

View File

@@ -335,6 +335,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
@@ -426,6 +427,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
@@ -691,6 +693,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
@@ -932,6 +935,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
@@ -1145,6 +1149,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
@@ -1284,6 +1289,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
@@ -1462,6 +1468,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
@@ -1644,6 +1651,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,

View File

@@ -57,6 +57,7 @@ async def test_security_binary_sensors(
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 30,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
},
@@ -138,6 +139,7 @@ async def test_overpowering_binary_sensors(
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_DEVICE_POWER: 100,
@@ -240,6 +242,7 @@ async def test_window_binary_sensors(
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
@@ -328,6 +331,7 @@ async def test_motion_binary_sensors(
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
@@ -421,6 +425,7 @@ async def test_presence_binary_sensors(
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_PRESENCE_SENSOR: "binary_sensor.mock_presence_sensor",
@@ -504,6 +509,7 @@ async def test_binary_sensors_over_climate_minimal(
CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
},
@@ -539,3 +545,4 @@ async def test_binary_sensors_over_climate_minimal(
hass, "binary_sensor.theoverclimatemockname_presence_state", "binary_sensor"
)
assert presence_binary_sensor is None

View File

@@ -63,6 +63,7 @@ async def test_bug_63(
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.0, # !! here
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.0, # !! here
@@ -115,6 +116,7 @@ async def test_bug_64(
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1, # !! here
@@ -304,6 +306,7 @@ async def test_bug_407(
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_DEVICE_POWER: 100,
@@ -545,6 +548,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,

View File

@@ -111,6 +111,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -298,6 +299,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -626,6 +628,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -800,6 +803,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -990,6 +994,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -1255,6 +1260,7 @@ async def test_bug_339(
CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: climate1.entity_id,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,

View File

@@ -67,6 +67,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 61,
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
@@ -135,6 +136,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -224,6 +226,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -349,6 +352,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -511,6 +515,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 61,
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,

View File

@@ -56,6 +56,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -103,6 +104,7 @@ async def test_config_with_central_mode_false(
CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -153,6 +155,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -205,6 +208,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -347,6 +351,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -482,6 +487,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -624,6 +630,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -778,6 +785,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,
@@ -935,6 +943,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,

View File

@@ -741,6 +741,7 @@ async def test_central_power_manager_start_vtherm_power(hass: HomeAssistant, ski
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_DEVICE_POWER: 1000,
@@ -811,6 +812,7 @@ async def test_central_power_manager_start_vtherm_power(hass: HomeAssistant, ski
CONF_USE_PRESENCE_FEATURE: False,
CONF_UNDERLYING_LIST: ["switch.mock_climate"],
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_DEVICE_POWER: 150,

View File

@@ -471,6 +471,7 @@ async def test_user_config_flow_over_climate(
result["flow_id"],
user_input={
CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
@@ -495,6 +496,7 @@ async def test_user_config_flow_over_climate(
assert result.get("errors") is None
assert result["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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
@@ -1077,6 +1079,7 @@ async def test_user_config_flow_over_climate_auto_start_stop(
result["flow_id"],
user_input={
CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
@@ -1104,6 +1107,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
@@ -1274,6 +1278,7 @@ async def test_user_config_flow_over_switch_bug_552_tpi(
result["flow_id"],
user_input={
CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
@@ -1359,6 +1364,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
@@ -1658,6 +1664,7 @@ async def test_user_config_flow_over_climate_valve(
result["flow_id"],
user_input={
CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,
@@ -1684,6 +1691,7 @@ async def test_user_config_flow_over_climate_valve(
assert result.get("errors") is None
assert result["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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.4,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.3,

View File

@@ -45,6 +45,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,

View File

@@ -54,6 +54,7 @@ async def test_last_seen_feature(hass: HomeAssistant, skip_hass_states_is_state)
"tpi_coef_int": 0.3,
"tpi_coef_ext": 0.01,
"minimal_activation_delay": 30,
"minimal_deactivation_delay": 0,
CONF_SAFETY_DELAY_MIN: 5, # 5 minutes
CONF_SAFETY_MIN_ON_PERCENT: 0.2,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1,

View File

@@ -305,6 +305,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 10,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
@@ -506,6 +507,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
@@ -631,6 +633,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
@@ -757,6 +760,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
@@ -890,6 +894,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",

View File

@@ -45,6 +45,7 @@ async def test_one_switch_cycle(
CONF_USE_PRESENCE_FEATURE: False,
CONF_HEATER: "switch.mock_switch1",
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
@@ -248,6 +249,7 @@ async def test_multiple_switchs(
CONF_HEATER_4: "switch.mock_switch4",
CONF_HEATER_KEEP_ALIVE: 0,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
@@ -383,6 +385,7 @@ async def test_multiple_climates(
CONF_CLIMATE_3: "switch.mock_climate3",
CONF_CLIMATE_4: "switch.mock_climate4",
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
},
@@ -484,6 +487,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
},
@@ -629,6 +633,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
},
@@ -734,6 +739,7 @@ async def test_multiple_switch_power_management(
],
CONF_HEATER_KEEP_ALIVE: 0,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,

View File

@@ -62,6 +62,7 @@ async def test_bug_56(
CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
},
@@ -653,6 +654,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
@@ -923,6 +925,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
@@ -1100,6 +1103,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_TURBO,
@@ -1267,6 +1271,7 @@ async def test_underlying_from_comes_back_to_life(
CONF_USE_PRESENCE_FEATURE: False,
CONF_UNDERLYING_LIST: ["climate.mock_climate"],
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_AUTO_FAN_MODE: CONF_AUTO_FAN_NONE,

View File

@@ -130,7 +130,7 @@ async def test_power_feature_manager(
# fmt:on
# Finish the mock configuration
tpi_algo = PropAlgorithm(PROPORTIONAL_FUNCTION_TPI, 0.6, 0.01, 5, 0, "climate.vtherm")
tpi_algo = PropAlgorithm(PROPORTIONAL_FUNCTION_TPI, 0.6, 0.01, 5, 0, 0, "climate.vtherm")
tpi_algo._on_percent = 1 # pylint: disable="protected-access"
type(fake_vtherm).hvac_mode = PropertyMock(return_value=HVACMode.HEAT)
type(fake_vtherm).is_device_active = PropertyMock(return_value=is_device_active)
@@ -354,6 +354,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_DEVICE_POWER: 100,
@@ -462,6 +463,7 @@ async def test_power_management_hvac_on(
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_DEVICE_POWER: 100,
@@ -629,6 +631,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_DEVICE_POWER: 100,
@@ -761,6 +764,7 @@ async def test_power_management_energy_over_climate(
CONF_USE_PRESENCE_FEATURE: False,
CONF_UNDERLYING_LIST: ["climate.mock_climate"],
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_DEVICE_POWER: 100,
@@ -860,6 +864,7 @@ async def test_power_management_turn_off_while_shedding(hass: HomeAssistant, ski
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_DEVICE_POWER: 100,

View File

@@ -152,6 +152,7 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state):
"tpi_coef_int": 0.3,
"tpi_coef_ext": 0.01,
"minimal_activation_delay": 30,
"minimal_deactivation_delay": 0,
"security_delay_min": 5, # 5 minutes
"security_min_on_percent": 0.2,
"security_default_on_percent": 0.1,
@@ -346,6 +347,7 @@ async def test_security_feature_back_on_percent(
"tpi_coef_int": 0.3,
"tpi_coef_ext": 0.01,
"minimal_activation_delay": 30,
"minimal_deactivation_delay": 0,
"safety_delay_min": 5, # 5 minutes
"safety_min_on_percent": 0.2,
"safety_default_on_percent": 0.1,
@@ -657,6 +659,7 @@ async def test_migration_security_safety(
CONF_USE_POWER_FEATURE: False,
CONF_USE_PRESENCE_FEATURE: False,
CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
},
)

View File

@@ -62,6 +62,7 @@ async def test_sensors_over_switch(
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_DEVICE_POWER: 200,
@@ -222,6 +223,7 @@ async def test_sensors_over_climate(
CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_DEVICE_POWER: 1.5,
@@ -358,6 +360,7 @@ async def test_sensors_over_climate_minimal(
CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "climate.mock_climate",
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
},

View File

@@ -232,6 +232,7 @@ async def test_over_switch_deactivate_preset(
CONF_HEATER_KEEP_ALIVE: 0,
CONF_SAFETY_DELAY_MIN: 10,
CONF_MINIMAL_ACTIVATION_DELAY: 10,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
CONF_TPI_COEF_INT: 0.6,
CONF_TPI_COEF_EXT: 0.01,

View File

@@ -39,6 +39,7 @@ def config_entry() -> MockConfigEntry:
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.1,
},

View File

@@ -75,6 +75,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 61,
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
@@ -170,6 +171,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 61,
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
@@ -265,6 +267,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 61,
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
@@ -359,6 +362,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 61,
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.2,
@@ -700,7 +704,7 @@ async def test_add_number_for_over_switch_use_central_presets_and_restore(
assert vtherm.use_central_config_temperature is True
# We should try to restore all 4 temp entities and the VTherm itself
assert mock_restore_state.call_count == 4 + 1
assert mock_restore_state.call_count == 4 + 2
# 1. We search for NumberEntities
for preset_name, value in temps.items():

View File

@@ -38,6 +38,7 @@ async def test_tpi_calculation(
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
# CONF_DEVICE_POWER: 100,
@@ -159,6 +160,94 @@ async def test_tpi_calculation(
assert tpi_algo.off_time_sec == 60
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize("expected_lingering_timers", [True])
async def test_minimal_deactivation_delay(
hass: HomeAssistant, skip_hass_states_is_state: None
): # pylint: disable=unused-argument
"""Test the minimal deactivation delay"""
entry = MockConfigEntry(
domain=DOMAIN,
title="TheOverSwitchMockName",
unique_id="uniqueId",
data={
CONF_NAME: "TheOverSwitchMockName",
CONF_THERMOSTAT_TYPE: CONF_THERMOSTAT_SWITCH,
CONF_TEMP_SENSOR: "sensor.mock_temp_sensor",
CONF_EXTERNAL_TEMP_SENSOR: "sensor.mock_ext_temp_sensor",
CONF_CYCLE_MIN: 5,
CONF_TEMP_MIN: 15,
CONF_TEMP_MAX: 30,
CONF_USE_WINDOW_FEATURE: False,
CONF_USE_MOTION_FEATURE: False,
CONF_USE_POWER_FEATURE: False,
CONF_USE_PRESENCE_FEATURE: False,
CONF_HEATER: "switch.mock_switch",
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 60,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
},
)
entity: BaseThermostat = await create_thermostat(
hass, entry, "climate.theoverswitchmockname"
)
assert entity
assert entity._prop_algorithm # pylint: disable=protected-access
tpi_algo: PropAlgorithm = entity._prop_algorithm # pylint: disable=protected-access
assert tpi_algo
# off_time is less than minimal_deactivation_delay
tpi_algo.calculate(9, 6, 10, HVACMode.HEAT)
assert tpi_algo.on_percent == 0.89
assert tpi_algo.calculated_on_percent == 0.89
assert tpi_algo.on_time_sec == 300
assert tpi_algo.off_time_sec == 0
# off_time is less than minimal_deactivation_delay
tpi_algo.calculate(6, 0, 104, HVACMode.HEAT)
assert tpi_algo.on_percent == 0.82
assert tpi_algo.calculated_on_percent == 0.82
assert tpi_algo.on_time_sec == 300
assert tpi_algo.off_time_sec == 0
# off_time is exactly minimal_deactivation_delay
tpi_algo.calculate(10, 8, -10, HVACMode.HEAT)
assert tpi_algo.on_percent == 0.8
assert tpi_algo.calculated_on_percent == 0.8
assert tpi_algo.on_time_sec == 240
assert tpi_algo.off_time_sec == 60 # Equal to minimal_deactivation_delay
# off_time is greater than minimal_deactivation_delay
tpi_algo.calculate(10, 9, 0, HVACMode.HEAT)
assert tpi_algo.on_percent == 0.4
assert tpi_algo.calculated_on_percent == 0.4
assert tpi_algo.on_time_sec == 120
assert tpi_algo.off_time_sec == 180
# with safety mode
tpi_algo.set_safety(0.2)
tpi_algo.calculate(10, 8, -10, HVACMode.HEAT)
assert tpi_algo.on_percent == 0.2
assert tpi_algo.calculated_on_percent == 0.8
assert tpi_algo.on_time_sec == 60
assert tpi_algo.off_time_sec == 240
tpi_algo.unset_safety()
# with cooling mode
tpi_algo.calculate(10, 10, 90, HVACMode.COOL)
assert tpi_algo.on_percent == 0.8
assert tpi_algo.calculated_on_percent == 0.8
assert tpi_algo.on_time_sec == 240
assert tpi_algo.off_time_sec == 60
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize("expected_lingering_timers", [True])
async def test_wrong_tpi_parameters(
@@ -174,6 +263,7 @@ async def test_wrong_tpi_parameters(
0.01,
5,
1,
1,
"entity_id",
)
# We should not be there
@@ -190,6 +280,7 @@ async def test_wrong_tpi_parameters(
0,
2,
3,
3,
"entity_id",
)
# We should not be there
@@ -206,6 +297,7 @@ async def test_wrong_tpi_parameters(
0,
2,
3,
3,
"entity_id",
)
# We should not be there
@@ -222,6 +314,7 @@ async def test_wrong_tpi_parameters(
None,
2,
3,
3,
"entity_id",
)
# We should not be there
@@ -238,6 +331,7 @@ async def test_wrong_tpi_parameters(
0.00001,
None,
3,
3,
"entity_id",
)
# We should not be there
@@ -262,6 +356,23 @@ async def test_wrong_tpi_parameters(
# the normal case
pass
# Test minimal_activation_delay
try:
algo = PropAlgorithm(
PROPORTIONAL_FUNCTION_TPI,
0.6,
0.00001,
0,
3,
None,
"entity_id",
)
# We should not be there
assert False
except TypeError as e:
# the normal case
pass
# Test vtherm_entity_id
try:
algo = PropAlgorithm(
@@ -270,6 +381,7 @@ async def test_wrong_tpi_parameters(
0.00001,
0,
12,
12,
None,
)
# We should not be there

View File

@@ -58,6 +58,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_DEVICE_POWER: 100,
@@ -350,6 +351,7 @@ async def test_over_valve_regulation(
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 60,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
# only send new valve open percent if dtemp is > 30%
@@ -589,6 +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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 60,
},
# | temps,

View File

@@ -45,6 +45,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
@@ -134,6 +135,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
@@ -281,6 +283,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
@@ -490,6 +493,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.fake_window_sensor",
@@ -615,6 +619,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 6,
@@ -783,6 +788,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 6,
@@ -910,6 +916,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
@@ -1050,6 +1057,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 6,
@@ -1178,6 +1186,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
@@ -1615,6 +1624,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
@@ -1812,6 +1822,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
@@ -2016,6 +2027,7 @@ async def test_bug_66(
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
CONF_MINIMAL_ACTIVATION_DELAY: 30,
CONF_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.5,
CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1, # !! here
@@ -2155,6 +2167,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_ACTION: CONF_WINDOW_FROST_TEMP,
@@ -2265,6 +2278,7 @@ 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_MINIMAL_DEACTIVATION_DELAY: 0,
CONF_SAFETY_DELAY_MIN: 5,
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_ACTION: CONF_WINDOW_FROST_TEMP,