Compare commits

..

1 Commits

Author SHA1 Message Date
Jean-Marc Collin
a17aba45fa Normal algo working and testu ok 2024-01-03 09:57:18 +00:00
25 changed files with 189 additions and 1017 deletions

View File

@@ -1,8 +1,5 @@
default_config:
# ffmeg
ffmpeg:
logger:
default: info
logs:

View File

@@ -4,8 +4,6 @@ about: Create a report to help us improve
---
<!-- This template will allow the maintainer to be efficient and post the more accurante response as possible. There is many types / modes / configuration possible, so the analysis can be very tricky. If don't follow this template, your issue could be rejected without any message. Please help me to help you. -->
<!-- Before you open a new issue, search through the existing issues to see if others have had the same problem.
If you have a simple question or you are not sure this is an issue, don't open an issue but open a new discussion [here](https://github.com/jmcollin78/versatile_thermostat/discussions).
@@ -15,7 +13,7 @@ Check also in the [Troubleshooting](#troubleshooting) paragrah of the README if
Issues not containing the minimum requirements will be closed:
- Issues without a description (using the header is not good enough) will be closed.
- Issues that don't follow this template could be closed
- Issues without configuration will be closed
-->

View File

@@ -17,7 +17,6 @@
- [HACS installation (recommendé)](#hacs-installation-recommendé)
- [Installation manuelle](#installation-manuelle)
- [Configuration](#configuration)
- [Création d'un nouveau Versatile Thermostat](#création-dun-nouveau-versatile-thermostat)
- [Choix des attributs de base](#choix-des-attributs-de-base)
- [Sélectionnez des entités pilotées](#sélectionnez-des-entités-pilotées)
- [Pour un thermostat de type ```thermostat_over_switch```](#pour-un-thermostat-de-type-thermostat_over_switch)
@@ -35,7 +34,6 @@
- [Configurer la gestion de la puissance](#configurer-la-gestion-de-la-puissance)
- [Configurer la présence ou l'occupation](#configurer-la-présence-ou-loccupation)
- [Configuration avancée](#configuration-avancée)
- [Le contrôle centralisé](#le-contrôle-centralisé)
- [Synthèse des paramètres](#synthèse-des-paramètres)
- [Exemples de réglage](#exemples-de-réglage)
- [Chauffage électrique](#chauffage-électrique)
@@ -65,9 +63,6 @@
- [Utilisation d'un Heatzy](#utilisation-dun-heatzy)
- [Utilisation d'un radiateur avec un fil pilote](#utilisation-dun-radiateur-avec-un-fil-pilote)
- [Seul le premier radiateur chauffe](#seul-le-premier-radiateur-chauffe)
- [Le radiateur chauffe alors que la température de consigne est dépassée ou ne chauffe pas alors que la température de la pièce est bien en-dessous de la consigne](#le-radiateur-chauffe-alors-que-la-température-de-consigne-est-dépassée-ou-ne-chauffe-pas-alors-que-la-température-de-la-pièce-est-bien-en-dessous-de-la-consigne)
- [Type `over_switch` ou `over_valve`](#type-over_switch-ou-over_valve)
- [Type `over_climate`](#type-over_climate)
- [Régler les paramètres de détection d'ouverture de fenêtre en mode auto](#régler-les-paramètres-de-détection-douverture-de-fenêtre-en-mode-auto)
- [Pourquoi mon Versatile Thermostat se met en Securite ?](#pourquoi-mon-versatile-thermostat-se-met-en-securite-)
- [Comment détecter le mode sécurité ?](#comment-détecter-le-mode-sécurité-)
@@ -79,16 +74,14 @@ Ce composant personnalisé pour Home Assistant est une mise à niveau et est une
> ![Nouveau](https://github.com/jmcollin78/versatile_thermostat/blob/main/images/new-icon.png?raw=true) _*Nouveautés*_
> * **Release 5.2** : Ajout d'un `central_mode` permettant de piloter tous les VTherms de façon centralisée [#158](https://github.com/jmcollin78/versatile_thermostat/issues/158).
> * **Release 5.1** : Limitation des valeurs envoyées aux valves et au température envoyées au climate sous-jacent.
> * **Release 5.0** : Ajout d'une configuration centrale permettant de mettre en commun les attributs qui peuvent l'être [#239](https://github.com/jmcollin78/versatile_thermostat/issues/239).
> * **Release 4.3** : Ajout d'un mode auto-fan pour le type `over_climate` permettant d'activer la ventilation si l'écart de température est important [#223](https://github.com/jmcollin78/versatile_thermostat/issues/223).
> * **Release 4.2** : Le calcul de la pente de la courbe de température se fait maintenant en °/heure et non plus en °/min [#242](https://github.com/jmcollin78/versatile_thermostat/issues/242). Correction de la détection automatique des ouvertures par l'ajout d'un lissage de la courbe de température .
> * **Release 4.1** : Ajout d'un mode de régulation **Expert** dans lequel l'utilisateur peut spécifier ses propres paramètres d'auto-régulation au lieu d'utiliser les pre-programmés [#194](https://github.com/jmcollin78/versatile_thermostat/issues/194).
> * **Release 4.0** : Ajout de la prise en charge de la **Versatile Thermostat UI Card**. Voir [Versatile Thermostat UI Card](https://github.com/jmcollin78/versatile-thermostat-ui-card). Ajout d'un mode de régulation **Slow** pour les appareils de chauffage à latence lente [#168](https://github.com/jmcollin78/versatile_thermostat/issues/168). Changement de la façon dont **la puissance est calculée** dans le cas de VTherm avec des équipements multi-sous-jacents [#146](https://github.com/jmcollin78/versatile_thermostat/issues/146). Ajout de la prise en charge de AC et Heat pour VTherm via un interrupteur également [#144](https://github.com/jmcollin78/versatile_thermostat/pull/144)
<details>
<summary>Autres versions</summary>
> * **Release 4.1** : Ajout d'un mode de régulation **Expert** dans lequel l'utilisateur peut spécifier ses propres paramètres d'auto-régulation au lieu d'utiliser les pre-programmés [#194](https://github.com/jmcollin78/versatile_thermostat/issues/194).
> * **Release 4.0** : Ajout de la prise en charge de la **Versatile Thermostat UI Card**. Voir [Versatile Thermostat UI Card](https://github.com/jmcollin78/versatile-thermostat-ui-card). Ajout d'un mode de régulation **Slow** pour les appareils de chauffage à latence lente [#168](https://github.com/jmcollin78/versatile_thermostat/issues/168). Changement de la façon dont **la puissance est calculée** dans le cas de VTherm avec des équipements multi-sous-jacents [#146](https://github.com/jmcollin78/versatile_thermostat/issues/146). Ajout de la prise en charge de AC et Heat pour VTherm via un interrupteur également [#144](https://github.com/jmcollin78/versatile_thermostat/pull/144)
> * **Release 3.8**: Ajout d'une **fonction d'auto-régulation** pour les thermostats `over climate` dont la régulation est faite par le climate sous-jacent. Cf. [L'auto-régulation](#lauto-régulation) et [#129](https://github.com/jmcollin78/versatile_thermostat/issues/129). Ajout de la **possibilité d'inverser la commande** pour un thermostat `over switch` pour adresser les installations avec fil pilote et diode [#124](https://github.com/jmcollin78/versatile_thermostat/issues/124).
> * **Release 3.7**: Ajout du type de **Versatile Thermostat `over valve`** pour piloter une vanne TRV directement ou tout autre équipement type gradateur pour le chauffage. La régulation se fait alors directement en agissant sur le pourcentage d'ouverture de l'entité sous-jacente : 0 la vanne est coupée, 100 : la vanne est ouverte à fond. Cf. [#131](https://github.com/jmcollin78/versatile_thermostat/issues/131). Ajout d'une fonction permettant le bypass de la détection d'ouverture [#138](https://github.com/jmcollin78/versatile_thermostat/issues/138). Ajout de la langue Slovaque
> * **Release 3.6**: Ajout du paramètre `motion_off_delay` pour améliorer la gestion de des mouvements [#116](https://github.com/jmcollin78/versatile_thermostat/issues/116), [#128](https://github.com/jmcollin78/versatile_thermostat/issues/128). Ajout du mode AC (air conditionné) pour un VTherm over switch. Préparation du projet Github pour faciliter les contributions [#127](https://github.com/jmcollin78/versatile_thermostat/issues/127)
@@ -157,8 +150,7 @@ Ce composant nommé __Versatile thermostat__ gère les cas d'utilisation suivant
- Ajouter une **gestion de délestage** ou une régulation pour ne pas dépasser une puissance totale définie. Lorsque la puissance maximale est dépassée, un préréglage caché de « puissance » est défini sur l'entité climatique. Lorsque la puissance passe en dessous du maximum, le préréglage précédent est restauré.
- La **gestion de la présence à domicile**. Cette fonctionnalité vous permet de modifier dynamiquement la température du préréglage en tenant compte d'un capteur de présence de votre maison.
- Des **services pour interagir avec le thermostat** à partir d'autres intégrations : vous pouvez forcer la présence / la non-présence à l'aide d'un service, et vous pouvez modifier dynamiquement la température des préréglages et changer les paramètres de sécurité.
- Ajouter des capteurs pour voir les états internes du thermostat,
- Contrôle centralisé de tous les Versatile Thermostat pour les stopper tous, les passer tous en hors-gel, les forcer en mode Chauffage (l'hiver), les forcer en mode Climatisation (l'été).
- Ajouter des capteurs pour voir les états internes du thermostat.
# Comment installer cet incroyable Thermostat Versatile ?
@@ -183,17 +175,8 @@ Ce composant nommé __Versatile thermostat__ gère les cas d'utilisation suivant
# Configuration
-- VTherm = Versatile Thermostat dans la suite de ce document --
Note: aucune configuration dans configuration.yaml n'est nécessaire car toute la configuration est effectuée via l'interface graphique standard lors de l'ajout de l'intégration.
> ![Astuce](/images/tips.png?raw=true) _*Notes*_
>
> Trois façons de configurer les VTherms sont disponibles :
> 1. Chaque Versatile Thermostat est entièrement configurée de manière indépendante. Choisissez cette option si vous ne souhaitez avoir aucune configuration ou gestion centrale.
> 2. Certains aspects sont configurés de manière centralisée. Cela permet par ex. définir la température min/max, la détection de fenêtre ouverte,… au niveau d'une instance centrale et unique. Pour chaque VTherm que vous configurez, vous pouvez alors choisir d'utiliser la configuration centrale ou de la remplacer par des paramètres personnalisés.
> 3. En plus de cette configuration centralisée, tous les VTherm peuvent être contrôlées par une seule entité de type `select`. Cette fonction est nommé `central_mode`. Cela permet de stopper / démarrer / mettre en hors gel / etc tous les VTherms en une seule fois. Pour chaque VTherm, l'utilisateur indique si il est concerné par ce `central_mode`.
## Création d'un nouveau Versatile Thermostat
Cliquez sur le bouton Ajouter une intégration dans la page d'intégration
![image](https://github.com/jmcollin78/versatile_thermostat/blob/main/images/add-an-integration.png?raw=true)
@@ -204,9 +187,7 @@ Suivez ensuite les étapes de configuration comme suit :
## Choix des attributs de base
![image](/images/config-main0.png?raw=true)
![image](/images/config-main.png?raw=true)
![image](https://github.com/jmcollin78/versatile_thermostat/blob/main/images/config-main.png?raw=true)
Donnez les principaux attributs obligatoires :
1. un nom (sera le nom de l'intégration et aussi le nom de l'entité climate)
@@ -216,8 +197,7 @@ Donnez les principaux attributs obligatoires :
6. une durée de cycle en minutes. A chaque cycle, le radiateur s'allumera puis s'éteindra pendant une durée calculée afin d'atteindre la température ciblée (voir [preset](#configure-the-preset-temperature) ci-dessous). En mode ```over_climate```, le cycle ne sert qu'à faire des controles de base mais ne régule pas directement la température. C'est le ```climate``` sous-jacent qui le fait,
7. les températures minimales et maximales du thermostat,
8. une puissance de l'équipement ce qui va activer les capteurs de puissance et énergie consommée par l'appareil,
9. la possibilité de controler le thermostat de façon centralisée. Cf [controle centralisé](#le-contrôle-centralisé),
10. la liste des fonctionnalités qui seront utilisées pour ce thermostat. En fonction de vos choix, les écrans de configuration suivants s'afficheront ou pas.
9. la liste des fonctionnalités qui seront utilisées pour ce thermostat. En fonction de vos choix, les écrans de configuration suivants s'afficheront ou pas.
> ![Astuce](https://github.com/jmcollin78/versatile_thermostat/blob/main/images/tips.png?raw=true) _*Notes*_
> 1. avec les types ```over_switch``` et ```over_valve```, les calculs sont effectués à chaque cycle. Donc en cas de changement de conditions, il faudra attendre le prochain cycle pour voir un changement. Pour cette raison, le cycle ne doit pas être trop long. **5 min est une bonne valeur**,
@@ -535,21 +515,6 @@ Voir [exemple de réglages](#examples-tuning) pour avoir des exemples de réglag
> 4. Pour un usage naturel, le ``security_default_on_percent`` doit être inférieur à ``security_min_on_percent``,
> 5. Les thermostats de type ``thermostat_over_climate`` ne sont pas concernés par le mode security.
## Le contrôle centralisé
Depuis la release 5.2, si vous avez défini une configuration centralisée, vous avez une nouvelle entité nommée `select.central_mode` qui permet de piloter tous les VTherms avec une seule action. Pour qu'un VTherm soit contrôlable de façon centralisée, il faut que son attribut de configuration nommé `use_central_mode` soit vrai.
Cette entité se présente sous la forme d'une liste de choix qui contient les choix suivants :
1. `Auto` : le mode 'normal' dans lequel chaque VTherm se comporte comme dans les versions précédentes,
2. `Stooped` : tous les VTherms sont mis à l'arrêt (`hvac_off`),
3. `Heat only` : tous les VTherms sont mis en mode chauffage lorsque ce mode est supporté par le VTherm, sinon il est stoppé,
3. `Cool only` : tous les VTherms sont mis en mode climatisation lorsque ce mode est supporté par le VTherm, sinon il est stoppé,
4. `Frost protection` : tous les VTherms sont mis en preset hors-gel lorsque ce preset est supporté par le VTherm, sinon il est stoppé.
Il est donc possible de contrôler tous les VTherms (que ceux que l'on désigne explicitement) avec un seul contrôle.
Exemple de rendu :
![central_mode](/images/central_mode.png?raw=true)
## Synthèse des paramètres
| Paramètre | Libellé | "over switch" | "over climate" | "over valve" | "configuration centrale" |
@@ -562,7 +527,6 @@ Exemple de rendu :
| ``temp_min`` | Température minimale permise | X | X | X | X |
| ``temp_max`` | Température maximale permise | X | X | X | X |
| ``device_power`` | Puissance de l'équipement | X | X | X | - |
| ``use_central_mode`` | Autorisation du contrôle centralisé | X | X | X | - |
| ``use_window_feature`` | Avec détection des ouvertures | X | X | X | - |
| ``use_motion_feature`` | Avec détection de mouvement | X | X | X | - |
| ``use_power_feature`` | Avec gestion de la puissance | X | X | X | - |
@@ -871,8 +835,6 @@ Les attributs personnalisés sont les suivants :
| ``valve_open_percent`` | Le pourcentage d'ouverture de la vanne |
| ``regulated_target_temperature`` | La température de consigne calculée par l'auto-régulation |
| ``is_inversed`` | True si la commande est inversée (fil pilote avec diode) |
| ``is_controlled_by_central_mode`` | True si le VTherm peut être controlé de façon centrale |
| ``last_central_mode`` | Le dernier mode central utilisé (None si le VTherm n'est pas controlé en central) |
# Quelques résultats
@@ -1046,10 +1008,6 @@ Remplacez les valeurs entre [[ ]] par les votres.
step: day
```
Exemple de courbes obtenues avec Plotly :
![image](/images/plotly-curves.png?raw=true)
## Et toujours de mieux en mieux avec l'AappDaemon NOTIFIER pour notifier les évènements
Cette automatisation utilise l'excellente App Daemon nommée NOTIFIER développée par Horizon Domotique que vous trouverez en démonstration [ici](https://www.youtube.com/watch?v=chJylIK0ASo&ab_channel=HorizonDomotique) et le code est [ici](https://github.com/jlpouffier/home-assistant-config/blob/master/appdaemon/apps/notifier.py). Elle permet de notifier les utilisateurs du logement lorsqu'un des évènements touchant à la sécurité survient sur un des Versatile Thermostats.
@@ -1198,19 +1156,6 @@ Exemple :
En mode `over_switch` si plusieurs radiateurs sont configurés pour un même VTherm, l'alllumage va se faire de façon séquentiel pour lisser au plus possible les pics de consommation.
Cela est tout à fait normal et voulu. C'est décrit ici : [Pour un thermostat de type ```thermostat_over_switch```](#pour-un-thermostat-de-type-thermostat_over_switch)
## Le radiateur chauffe alors que la température de consigne est dépassée ou ne chauffe pas alors que la température de la pièce est bien en-dessous de la consigne
### Type `over_switch` ou `over_valve`
Avec un VTherm de type `over_switch` ou `over_valve`, ce défaut montre juste que les paramètres de l'algorithme TPI sont mal réglés. Voir [Algorithme TPI](#algorithme-tpi) pour optimiser les réglages.
### Type `over_climate`
Avec un VTherm de type `over_climate`, la régulation est faite par le `climate` sous-jacent directement et VTherm se contente de lui transmettre les consignes. Donc si le radiateur chauffe alors que la température de consigne est dépassée, c'est certainement que sa mesure de température interne est biaisée. Ca arrive très souvent avec les TRV et les clims réversibles qui ont un capteur de température interne, soit trop près de l'élément de chauffe (donc trop froid l'hiver).
Exemple de discussion autour de ces sujets: [#316](https://github.com/jmcollin78/versatile_thermostat/issues/316), [#312](https://github.com/jmcollin78/versatile_thermostat/discussions/312), [#278](https://github.com/jmcollin78/versatile_thermostat/discussions/278)
Pour s'en sortir, VTherm est équipé d'une fonction nommée auto-régulation qui permet d'adapter la consigne envoyée au sous-jacent jusqu'à ce que la consigne soit respectée. Cette fonction permet de compenser le biais de mesure des thermomètres internes. Si le biais est important la régulation doit être importante. Voir [L'auto-régulation](#lauto-régulation) pour configurer l'auto-régulation.
## Régler les paramètres de détection d'ouverture de fenêtre en mode auto
Si vous n'arrivez pas à régler la fonction de détection des ouvertures en mode auto (cf. [auto](#le-mode-auto)), vous pouvez essayer de modifier les paramètres de l'algorithme de lissage de la température.

View File

@@ -17,7 +17,6 @@
- [HACS installation (recommended)](#hacs-installation-recommended)
- [Manual installation](#manual-installation)
- [Configuration](#configuration)
- [Creation of a new Versatile Thermostat](#creation-of-a-new-versatile-thermostat)
- [Minimal configuration update](#minimal-configuration-update)
- [Select the driven entity](#select-the-driven-entity)
- [For a ```thermostat_over_switch``` type thermostat](#for-a-thermostat_over_switch-type-thermostat)
@@ -35,7 +34,6 @@
- [Configure the power management](#configure-the-power-management)
- [Configure presence or occupancy](#configure-presence-or-occupancy)
- [Advanced configuration](#advanced-configuration)
- [Centralized control](#centralized-control)
- [Parameters synthesis](#parameters-synthesis)
- [Examples tuning](#examples-tuning)
- [Electrical heater](#electrical-heater)
@@ -65,9 +63,6 @@
- [Using a Heatzy](#using-a-heatzy)
- [Using a Heatsink with a Pilot Wire](#using-a-heatsink-with-a-pilot-wire)
- [Only the first radiator heats](#only-the-first-radiator-heats)
- [The radiator heats up even though the setpoint temperature is exceeded or does not heat up even though the room temperature is well below the setpoint](#the-radiator-heats-up-even-though-the-setpoint-temperature-is-exceeded-or-does-not-heat-up-even-though-the-room-temperature-is-well-below-the-setpoint)
- [Type `over_switch` or `over_valve`](#type-over_switch-or-over_valve)
- [Type `over_climate`](#type-over_climate)
- [Adjust window opening detection parameters in auto mode](#adjust-window-opening-detection-parameters-in-auto-mode)
- [Why does my Versatile Thermostat go into Safety?](#why-does-my-versatile-thermostat-go-into-safety)
- [How to detect safety mode?](#how-to-detect-safety-mode)
@@ -79,18 +74,16 @@
This custom component for Home Assistant is an upgrade and is a complete rewrite of the component "Awesome thermostat" (see [Github](https://github.com/dadge/awesome_thermostat)) with addition of features.
>![New](https://github.com/jmcollin78/versatile_thermostat/blob/main/images/new-icon.png?raw=true) _*News*_
> * **Release 5.2**: Added a `central_mode` allowing all VTherms to be controlled centrally [#158](https://github.com/jmcollin78/versatile_thermostat/issues/158).
> * **Release 5.1**: Limitation of the values sent to the valves and the temperature sent to the underlying climate.
> * **Release 5.0**: Added a central configuration allowing the sharing of attributes that can be shared [#239](https://github.com/jmcollin78/versatile_thermostat/issues/239).
> * **Release 4.3**: Added an auto-fan mode for the `over_climate` type allowing ventilation to be activated if the temperature difference is significant [#223](https://github.com/jmcollin78/versatile_thermostat/issues/223).
> * **Release 4.2**: The calculation of the slope of the temperature curve is now done in °/hour and no longer in °/min [#242](https://github.com/jmcollin78/versatile_thermostat/issues/242). Correction of automatic detection of openings by adding smoothing of the temperature curve.
<details>
<summary>Others releases</summary>
> * **Release 4.1**: Added an **Expert** regulation mode in which the user can specify their own auto-regulation parameters instead of using the pre-programmed ones [#194]( https://github.com/jmcollin78/versatile_thermostat/issues/194).
> * **Release 4.0**: Added the support of **Versatile Thermostat UI Card**. See [Versatile Thermostat UI Card](https://github.com/jmcollin78/versatile-thermostat-ui-card). Added a **Slow** regulation mode for slow latency heating devices [#168](https://github.com/jmcollin78/versatile_thermostat/issues/168). Change the way **the power is calculated** in case of VTherm with multi-underlying equipements [#146](https://github.com/jmcollin78/versatile_thermostat/issues/146). Added the support of AC and Heat for VTherm over switch alse [#144](https://github.com/jmcollin78/versatile_thermostat/pull/144)
> * **Release 3.8**: Added a **self-regulation function** for `over climate` thermostats whose regulation is done by the underlying climate. See [Self-regulation](#self-regulation) and [#129](https://github.com/jmcollin78/versatile_thermostat/issues/129). Added the possibility of **inverting the command** for an `over switch` thermostat to address installations with pilot wire and diode [#124](https://github.com/jmcollin78/versatile_thermostat/issues/124).
> * **Release 3.7**: Addition of the **Versatile Thermostat type `over valve`** to control a TRV valve directly or any other dimmer type equipment for heating. Regulation is then done directly by acting on the opening percentage of the underlying entity: 0 the valve is cut off, 100: the valve is fully opened. See [#131](https://github.com/jmcollin78/versatile_thermostat/issues/131). Added a function allowing the bypass of opening detection [#138](https://github.com/jmcollin78/versatile_thermostat/issues/138). Added Slovak language
<details>
<summary>Others releases</summary>
> * **Release 3.6**: Added the `motion_off_delay` parameter to improve motion management [#116](https://github.com/jmcollin78/versatile_thermostat/issues/116), [#128](https://github.com/jmcollin78/versatile_thermostat/issues/128). Added AC (air conditioning) mode for a VTherm over switch. Preparing the Github project to facilitate contributions [#127](https://github.com/jmcollin78/versatile_thermostat/issues/127)
> * **Release 3.5**: Multiple thermostats when using "thermostat over another thermostat" mode [#113](https://github.com/jmcollin78/versatile_thermostat/issues/113)
> * **Release 3.4**: bug fixes and expose preset temperatures for AC mode [#103](https://github.com/jmcollin78/versatile_thermostat/issues/103)
@@ -157,8 +150,7 @@ This component named __Versatile thermostat__ manage the following use cases :
- Add **power shedding management** or regulation to avoid exceeding a defined total power. When max power is exceeded, a hidden 'power' preset is set on the climate entity. When power goes below the max, the previous preset is restored.
- Add **home presence management**. This feature allows you to dynamically change the temperature of preset considering a occupancy sensor of your home.
- Add **services to interact with the thermostat** from others integration: you can force the presence / un-presence using a service, and you can dynamically change the temperature of the presets and change dynamically the safety parameters.
- Add sensors to see the internal states of the thermostat,
- Centralized control of all Versatile Thermostats to stop them all, switch them all to frost protection, force them into Heating mode (winter), force them into Cooling mode (summer).
- Add sensors to see the internal states of the thermostat
# How to install this incredible Versatile Thermostat ?
@@ -183,17 +175,8 @@ This component named __Versatile thermostat__ manage the following use cases :
# Configuration
-- VTherm = Versatile Thermostat in the remainder of this document --
Note: no configuration in configuration.yaml is needed because all configuration is done through the standard GUI when adding the integration.
> ![Tip](https://github.com/jmcollin78/versatile_thermostat/blob/main/images/tips.png?raw=true) _*Notes*_
>
> Three ways to configure VTherms are available:
> 1. Each Versatile Thermostat is completely independently configured. Choose this option if you do not want to have any central configuration or management.
> 2. Some aspects are configured centrally. This allows e.g. define the min/max temperature, open window detection, etc. at the level of a single central instance. For each VTherm you configure, you can then choose to use the central configuration or override it with custom settings.
> 3. In addition to this centralized configuration, all VTherms can be controlled by a single entity of type `select`. This function is named `central_mode`. This allows you to stop / start / freeze / etc. all VTherms at once. For each VTherm, the user indicates whether he is affected by this `central_mode`.
## Creation of a new Versatile Thermostat
Click on Add integration button in the integration page
![image](https://github.com/jmcollin78/versatile_thermostat/blob/main/images/add-an-integration.png?raw=true)
@@ -202,10 +185,7 @@ The configuration can be change through the same interface. Simply select the th
Then follow the configurations steps as follow:
## Minimal configuration update
![image](/images/config-main0.png?raw=true)
![image](/images/config-main.png?raw=true)
![image](https://github.com/jmcollin78/versatile_thermostat/blob/main/images/config-main.png?raw=true)
Give the main mandatory attributes:
1. a name (will be the name of the integration and also the name of the climate entity)
@@ -215,8 +195,7 @@ Give the main mandatory attributes:
6. a cycle duration in minutes. On each cycle, the heater will cycle on and then off for a calculated time to reach the target temperature (see [preset](#configure-the-preset-temperature) below). In ```over_climate``` mode, the cycle is only used to carry out basic controls but does not directly regulate the temperature. It's the underlying climate that does it,
7. minimum and maximum thermostat temperatures,
8. the power of the l'équipement which will activate the power and energy sensors of the device,
9. the possibility of controlling the thermostat centrally. Cf [centralized control](#centralized-control),
10. the list of features that will be used for this thermostat. Depending on your choices, the following configuration screens will appear or not.
9. the list of features that will be used for this thermostat. Depending on your choices, the following configuration screens will appear or not.
> ![Tip](https://github.com/jmcollin78/versatile_thermostat/blob/main/images/tips.png?raw=true) _*Notes*_
> 1. With the ```thermostat_over_switch``` type, calculation are done at each cycle. So in case of conditions change, you will have to wait for the next cycle to see a change. For this reason, the cycle should not be too long. **5 min is a good value**,
@@ -521,21 +500,6 @@ See [example tuning](#examples-tuning) for common tuning examples
> 4. For natural usage, the ``security_default_on_percent`` should be less than ``security_min_on_percent``,
> 5. Thermostat of type ``thermostat_over_climate`` are not concerned by the safety feature.
## Centralized control
Since release 5.2, if you have defined a centralized configuration, you have a new entity named `select.central_mode` which allows you to control all VTherms with a single action. For a VTherm to be centrally controllable, its configuration attribute named `use_central_mode` must be true.
This entity is presented in the form of a list of choices which contains the following choices:
1. `Auto`: the 'normal' mode in which each VTherm behaves as in previous versions,
2. `Stooped`: all VTherms are turned off (`hvac_off`),
3. `Heat only`: all VTherms are put in heating mode when this mode is supported by the VTherm, otherwise it is stopped,
3. `Cool only`: all VTherms are put in cooling mode when this mode is supported by the VTherm, otherwise it is stopped,
4. `Frost protection`: all VTherms are put in frost protection preset when this preset is supported by the VTherm, otherwise it is stopped.
It is therefore possible to control all VTherms (only those explicitly designated) with a single control.
Example rendering:
![central_mode](/images/central_mode.png?raw=true)
## Parameters synthesis
| Paramètre | Libellé | "over switch" | "over climate" | "over valve" | "central configuration" |
@@ -548,7 +512,6 @@ Example rendering:
| ``temp_min`` | Minimal temperature allowed | X | X | X | X |
| ``temp_max`` | Maximal temperature allowed | X | X | X | X |
| ``device_power`` | Total device power | X | X | X | - |
| ``use_central_mode`` | Allow the centralized control | X | X | X | - |
| ``use_window_feature`` | Use window detection | X | X | X | - |
| ``use_motion_feature`` | Use motion detection | X | X | X | - |
| ``use_power_feature`` | Use power management | X | X | X | - |
@@ -856,8 +819,6 @@ Custom attributes are the following:
| ``valve_open_percent`` | The opening percentage of the valve |
| ``regulated_target_temperature`` | The self-regulated target temperature calculated |
| ``is_inversed`` | True if the command is inversed (pilot wire with diode) |
| ``is_controlled_by_central_mode`` | True if the VTherm can be centrally controlled |
| ``last_central_mode`` | The last central mode used (None if the VTherm is not centrally controlled) |
# Some results
@@ -1030,11 +991,6 @@ Replace values in [[ ]] by yours.
step: day
```
Example of graph obtained with Plotly :
![image](/images/plotly-curves.png?raw=true)
## And always better and better with the NOTIFIER daemon app to notify events
This automation uses the excellent App Daemon named NOTIFIER developed by Horizon Domotique that you will find in demonstration [here](https://www.youtube.com/watch?v=chJylIK0ASo&ab_channel=HorizonDomotique) and the code is [here](https ://github.com/jlpouffier/home-assistant-config/blob/master/appdaemon/apps/notifier.py). It allows you to notify the users of the accommodation when one of the events affecting safety occurs on one of the Versatile Thermostats.
@@ -1180,19 +1136,7 @@ Example :
## Only the first radiator heats
In `over_switch` mode if several radiators are configured for the same VTherm, switching on will be done sequentially to smooth out consumption peaks as much as possible.
This is completely normal and desired. It is described here: [For a thermostat of type ``thermostat_over_switch```](#for-a-thermostat-of-type-thermostat_over_switch)v
## The radiator heats up even though the setpoint temperature is exceeded or does not heat up even though the room temperature is well below the setpoint
### Type `over_switch` or `over_valve`
With a VTherm of type `over_switch` or `over_valve`, this fault just shows that the parameters of the TPI algorithm are incorrectly set. See [TPI Algorithm](#tpi-algorithm) to optimize the settings.
### Type `over_climate`
With an `over_climate` type VTherm, the regulation is done by the underlying `climate` directly and VTherm simply transmits the instructions to it. So if the radiator heats up when the set temperature is exceeded, it is certainly because its internal temperature measurement is biased. This happens very often with TRVs and reversible air conditioning units which have an internal temperature sensor, or too close to the heating element (therefore too cold in winter).
Example of discussion around these topics: [#316](https://github.com/jmcollin78/versatile_thermostat/issues/316), [#312](https://github.com/jmcollin78/versatile_thermostat/discussions/312 ), [#278](https://github.com/jmcollin78/versatile_thermostat/discussions/278)
To get around this, VTherm is equipped with a function called self-regulation which allows the instruction sent to the underlying to be adapted until the target temperature is respected. This function compensates for the measurement bias of internal thermometers. If the bias is important the regulation must be important. See [Self-regulation](#self-regulation) to configure self-regulation.
This is completely normal and desired. It is described here: [For a thermostat of type ``thermostat_over_switch```](#for-a-thermostat-of-type-thermostat_over_switch)
## Adjust window opening detection parameters in auto mode

View File

@@ -410,8 +410,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
)
self._window_auto_max_duration = entry_infos.get(CONF_WINDOW_AUTO_MAX_DURATION)
self._window_auto_on = (
self._window_sensor_entity_id is None
and self._window_auto_open_threshold is not None
self._window_auto_open_threshold is not None
and self._window_auto_open_threshold > 0.0
and self._window_auto_close_threshold is not None
and self._window_auto_max_duration is not None
@@ -1248,10 +1247,10 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
# 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
# In security 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:
_LOGGER.debug(
"%s - is in safety mode. Just memorise the new expected ", self
"%s - is in security mode. Just memorise the new expected ", self
)
if preset_mode not in HIDDEN_PRESETS:
self._saved_preset_mode = preset_mode
@@ -1406,10 +1405,9 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
if new_state is None or new_state.state in (STATE_UNAVAILABLE, STATE_UNKNOWN):
return
dearm_window_auto = await self._async_update_temp(new_state)
await self._async_update_temp(new_state)
self.recalculate()
await self.async_control_heating(force=False)
return dearm_window_auto
async def _async_ext_temperature_changed(self, event: Event):
"""Handle external temperature opf the sensor changes."""
@@ -1477,19 +1475,16 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
else:
if not self._window_state:
_LOGGER.info(
"%s - Window is closed. Restoring hvac_mode '%s' if central_mode is not STOPPED",
"%s - Window is closed. Restoring hvac_mode '%s'",
self,
self._saved_hvac_mode,
)
if self.last_central_mode != CENTRAL_MODE_STOPPED:
await self.restore_hvac_mode(True)
await self.restore_hvac_mode(True)
elif self._window_state:
_LOGGER.info(
"%s - Window is open. Set hvac_mode to '%s'", self, HVACMode.OFF
)
if self.last_central_mode in [CENTRAL_MODE_AUTO, None]:
self.save_hvac_mode()
self.save_hvac_mode()
await self.async_set_hvac_mode(HVACMode.OFF)
self.update_custom_attributes()
@@ -1642,12 +1637,12 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
state.last_changed.astimezone(self._current_tz),
)
# try to restart if we were in safety mode
# try to restart if we were in security mode
if self._security_state:
await self.check_security()
# check window_auto
return await self._async_manage_window_auto()
await self._async_manage_window_auto()
except ValueError as ex:
_LOGGER.error("Unable to update temperature from sensor: %s", ex)
@@ -1669,7 +1664,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
state.last_changed.astimezone(self._current_tz),
)
# try to restart if we were in safety mode
# try to restart if we were in security mode
if self._security_state:
await self.check_security()
except ValueError as ex:
@@ -1854,8 +1849,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
slope if slope is not None else 0.0,
)
if self.window_bypass_state or not self.is_window_auto_enabled:
_LOGGER.info("%s - Window auto event is ignored because bypass is ON or window auto detection is disabled", self)
if self.window_bypass_state:
_LOGGER.info("%s - Window auto event is ignored because bypass is ON", self)
return
if (
@@ -2057,13 +2052,12 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
self.save_hvac_mode()
if new_central_mode == CENTRAL_MODE_AUTO:
if self.window_state is not STATE_ON:
await self.restore_hvac_mode()
await self.restore_preset_mode()
await self.restore_hvac_mode()
await self.restore_preset_mode()
return
if old_central_mode == CENTRAL_MODE_AUTO and self.window_state is not STATE_ON:
if old_central_mode == CENTRAL_MODE_AUTO:
save_all()
if new_central_mode == CENTRAL_MODE_STOPPED:
@@ -2163,7 +2157,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
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",
"%s - No temperature received for more than %.1f minutes (dt=%.1f, dext=%.1f) and underlying climate is %s. Set it into security mode",
self,
self._security_delay_min,
delta_temp,
@@ -2172,13 +2166,13 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
)
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",
"%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 security mode",
self,
self._security_delay_min,
delta_temp,
delta_ext_temp,
self._prop_algorithm.on_percent * 100,
self._security_min_on_percent * 100,
self._prop_algorithm.on_percent,
self._security_min_on_percent,
)
self.send_event(
@@ -2196,7 +2190,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
},
)
# Start safety mode
# Start security mode
if shouldStartSecurity:
self._security_state = True
self.save_hvac_mode()
@@ -2224,10 +2218,10 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
},
)
# Stop safety mode
# Stop security mode
if shouldStopSecurity:
_LOGGER.warning(
"%s - End of safety mode. restoring hvac_mode to %s and preset_mode to %s",
"%s - End of security mode. restoring hvac_mode to %s and preset_mode to %s",
self,
self._saved_hvac_mode,
self._saved_preset_mode,
@@ -2475,11 +2469,11 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
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_security, delay_min: %s, min_on_percent: %s, default_on_percent: %s",
self,
delay_min,
min_on_percent * 100,
default_on_percent * 100,
min_on_percent,
default_on_percent,
)
if delay_min:
self._security_delay_min = delay_min

View File

@@ -14,6 +14,6 @@
"quality_scale": "silver",
"requirements": [],
"ssdp": [],
"version": "5.2.2",
"version": "4.3.0",
"zeroconf": []
}
}

View File

@@ -140,27 +140,27 @@ class PropAlgorithm:
self._off_time_sec = self._cycle_min * 60 - self._on_time_sec
def set_security(self, default_on_percent: float):
"""Set a default value for on_percent (used for safety mode)"""
"""Set a default value for on_percent (used for security mode)"""
self._security = True
self._default_on_percent = default_on_percent
self._calculate_internal()
def unset_security(self):
"""Unset the safety mode"""
"""Unset the security mode"""
self._security = False
self._calculate_internal()
@property
def on_percent(self) -> float:
"""Returns the percentage the heater must be ON
In safety mode this value is overriden with the _default_on_percent
In security mode this value is overriden with the _default_on_percent
(1 means the heater will be always on, 0 never on)""" # pylint: disable=line-too-long
return round(self._on_percent, 2)
@property
def calculated_on_percent(self) -> float:
"""Returns the calculated percentage the heater must be ON
Calculated means NOT overriden even in safety mode
Calculated means NOT overriden even in security mode
(1 means the heater will be always on, 0 never on)""" # pylint: disable=line-too-long
return round(self._calculated_on_percent, 2)

View File

@@ -90,7 +90,7 @@ class CentralModeSelect(SelectEntity, RestoreEntity):
"%s - Calling async_added_to_hass old_state is %s", self, old_state
)
if old_state is not None:
self._attr_current_option = old_state.state
self.async_select_option = old_state.state
@callback
async def _async_startup_internal(*_):

View File

@@ -24,7 +24,7 @@
"temp_min": "Minimal temperature allowed",
"temp_max": "Maximal temperature allowed",
"device_power": "Device power",
"use_central_mode": "Enable the control by central entity (need central config)",
"use_central_mode": "Enable the control by central mode ('central_mode')",
"use_window_feature": "Use window detection",
"use_motion_feature": "Use motion detection",
"use_power_feature": "Use power management",
@@ -123,7 +123,7 @@
},
"window": {
"title": "Window management",
"description": "Open window management.\nYou can also configure automatic window open detection based on temperature decrease",
"description": "Open window management.\nLeave corresponding entity_id empty if not used\nYou can also configure automatic window open detection based on temperature decrease",
"data": {
"window_sensor_entity_id": "Window sensor entity id",
"window_delay": "Window sensor delay (seconds)",
@@ -133,7 +133,7 @@
"use_window_central_config": "Use central window configuration"
},
"data_description": {
"window_sensor_entity_id": "Leave empty if no window sensor should be used and to use the automatic detection",
"window_sensor_entity_id": "Leave empty if no window sensor should be used",
"window_delay": "The delay in seconds before sensor detection is taken into account",
"window_auto_open_threshold": "Recommended value: between 3 and 10. Leave empty if automatic window open detection is not used",
"window_auto_close_threshold": "Recommended value: 0. Leave empty if automatic window open detection is not used",
@@ -143,7 +143,7 @@
},
"motion": {
"title": "Motion management",
"description": "Motion sensor management. Preset can switch automatically depending on motion detection\nmotion_preset and no_motion_preset should be set to the corresponding preset name",
"description": "Motion sensor management. Preset can switch automatically depending on motion detection\nLeave corresponding entity_id empty if not used.\nmotion_preset and no_motion_preset should be set to the corresponding preset name",
"data": {
"motion_sensor_entity_id": "Motion sensor entity id",
"motion_delay": "Activation delay",
@@ -163,7 +163,7 @@
},
"power": {
"title": "Power management",
"description": "Power management attributes.\nGives the power and max power sensor of your home.\nThen specify the power consumption of the heater when on.\nAll sensors and device power should have the same unit (kW or W).",
"description": "Power management attributes.\nGives the power and max power sensor of your home.\nThen specify the power consumption of the heater when on.\nAll sensors and device power should have the same unit (kW or W).\nLeave corresponding entity_id empty if not used.",
"data": {
"power_sensor_entity_id": "Power",
"max_power_sensor_entity_id": "Max power",
@@ -179,7 +179,7 @@
},
"presence": {
"title": "Presence management",
"description": "Presence management attributes.\nGives the a presence sensor of your home (true is someone is present) and give the corresponding temperature preset setting.",
"description": "Presence management attributes.\nGives the a presence sensor of your home (true is someone is present).\nThen specify either the preset to use when presence sensor is false or the offset in temperature to apply.\nIf preset is given, the offset will not be used.\nLeave corresponding entity_id empty if not used.",
"data": {
"presence_sensor_entity_id": "Presence sensor",
"eco_away_temp": "Eco preset",
@@ -256,7 +256,7 @@
"temp_min": "Minimal temperature allowed",
"temp_max": "Maximal temperature allowed",
"device_power": "Device power",
"use_central_mode": "Enable the control by central entity (need central config)",
"use_central_mode": "Enable the control by central mode ('central_mode')",
"use_window_feature": "Use window detection",
"use_motion_feature": "Use motion detection",
"use_power_feature": "Use power management",
@@ -365,7 +365,7 @@
"use_window_central_config": "Use central window configuration"
},
"data_description": {
"window_sensor_entity_id": "Leave empty if no window sensor should be used and to use the automatic detection",
"window_sensor_entity_id": "Leave empty if no window sensor should be used",
"window_delay": "The delay in seconds before sensor detection is taken into account",
"window_auto_open_threshold": "Recommended value: between 3 and 10. Leave empty if automatic window open detection is not used",
"window_auto_close_threshold": "Recommended value: 0. Leave empty if automatic window open detection is not used",
@@ -375,7 +375,7 @@
},
"motion": {
"title": "Motion - {name}",
"description": "Motion management. Preset can switch automatically depending of a motion detection\nmotion_preset and no_motion_preset should be set to the corresponding preset name",
"description": "Motion management. Preset can switch automatically depending of a motion detection\nLeave corresponding entity_id empty if not used.\nmotion_preset and no_motion_preset should be set to the corresponding preset name",
"data": {
"motion_sensor_entity_id": "Motion sensor entity id",
"motion_delay": "Activation delay",
@@ -395,7 +395,7 @@
},
"power": {
"title": "Power - {name}",
"description": "Power management attributes.\nGives the power and max power sensor of your home.\nThen specify the power consumption of the heater when on.\nAll sensors and device power should have the same unit (kW or W).",
"description": "Power management attributes.\nGives the power and max power sensor of your home.\nThen specify the power consumption of the heater when on.\nAll sensors and device power should have the same unit (kW or W).\nLeave corresponding entity_id empty if not used.",
"data": {
"power_sensor_entity_id": "Power",
"max_power_sensor_entity_id": "Max power",
@@ -411,7 +411,7 @@
},
"presence": {
"title": "Presence - {name}",
"description": "Presence management attributes.\nGives the a presence sensor of your home (true is someone is present) and give the corresponding temperature preset setting.",
"description": "Presence management attributes.\nGives the a presence sensor of your home (true is someone is present).\nThen specify either the preset to use when presence sensor is false or the offset in temperature to apply.\nIf preset is given, the offset will not be used.\nLeave corresponding entity_id empty if not used.",
"data": {
"presence_sensor_entity_id": "Presence sensor",
"eco_away_temp": "Eco away preset",

View File

@@ -601,9 +601,8 @@ class ThermostatOverClimate(BaseThermostat):
# new_hvac_mode = HVACMode.OFF
_LOGGER.info(
"%s - Underlying climate %s changed. Event.new_hvac_mode is %s, current_hvac_mode=%s, new_hvac_action=%s, old_hvac_action=%s",
"%s - Underlying climate changed. Event.new_hvac_mode is %s, current_hvac_mode=%s, new_hvac_action=%s, old_hvac_action=%s",
self,
new_state.entity_id,
new_hvac_mode,
self._hvac_mode,
new_hvac_action,
@@ -659,7 +658,7 @@ class ThermostatOverClimate(BaseThermostat):
)
changes = True
# Issue #120 - Some TRV are changing target temperature a very long time (6 sec) after the change.
# Issue #120 - Some TRV are chaning target temperature a very long time (6 sec) after the change.
# In that case a loop is possible if a user change multiple times during this 6 sec.
if new_state_date_updated and self._last_change_time:
delta = (new_state_date_updated - self._last_change_time).total_seconds()
@@ -685,31 +684,12 @@ class ThermostatOverClimate(BaseThermostat):
]
and self._hvac_mode != new_hvac_mode
):
# Update all underlyings state
# Issue #334 - if all underlyings are not aligned with the same hvac_mode don't change the underlying and wait they are aligned
if self.is_over_climate:
for under in self._underlyings:
if (
under.entity_id != new_state.entity_id
and under.hvac_mode != self._hvac_mode
):
_LOGGER.info(
"%s - the underlying's hvac_mode %s is not aligned with VTherm hvac_mode %s. So we don't diffuse the change to all other underlyings to avoid loops",
under,
under.hvac_mode,
self._hvac_mode,
)
return
_LOGGER.debug(
"%s - All underlyings have the same hvac_mode, so VTherm will send the new hvac mode %s",
self,
new_hvac_mode,
)
for under in self._underlyings:
await under.set_hvac_mode(new_hvac_mode)
changes = True
self._hvac_mode = new_hvac_mode
# Update all underlyings state
if self.is_over_climate:
for under in self._underlyings:
await under.set_hvac_mode(new_hvac_mode)
# A quick win to known if it has change by using the self._attr_fan_mode and not only underlying[0].fan_mode
if new_fan_mode != self._attr_fan_mode:

View File

@@ -24,7 +24,7 @@
"temp_min": "Minimal temperature allowed",
"temp_max": "Maximal temperature allowed",
"device_power": "Device power",
"use_central_mode": "Enable the control by central entity (need central config)",
"use_central_mode": "Enable the control by central mode ('central_mode')",
"use_window_feature": "Use window detection",
"use_motion_feature": "Use motion detection",
"use_power_feature": "Use power management",
@@ -123,7 +123,7 @@
},
"window": {
"title": "Window management",
"description": "Open window management.\nYou can also configure automatic window open detection based on temperature decrease",
"description": "Open window management.\nLeave corresponding entity_id empty if not used\nYou can also configure automatic window open detection based on temperature decrease",
"data": {
"window_sensor_entity_id": "Window sensor entity id",
"window_delay": "Window sensor delay (seconds)",
@@ -133,7 +133,7 @@
"use_window_central_config": "Use central window configuration"
},
"data_description": {
"window_sensor_entity_id": "Leave empty if no window sensor should be used and to use the automatic detection",
"window_sensor_entity_id": "Leave empty if no window sensor should be used",
"window_delay": "The delay in seconds before sensor detection is taken into account",
"window_auto_open_threshold": "Recommended value: between 3 and 10. Leave empty if automatic window open detection is not used",
"window_auto_close_threshold": "Recommended value: 0. Leave empty if automatic window open detection is not used",
@@ -143,7 +143,7 @@
},
"motion": {
"title": "Motion management",
"description": "Motion sensor management. Preset can switch automatically depending on motion detection\nmotion_preset and no_motion_preset should be set to the corresponding preset name",
"description": "Motion sensor management. Preset can switch automatically depending on motion detection\nLeave corresponding entity_id empty if not used.\nmotion_preset and no_motion_preset should be set to the corresponding preset name",
"data": {
"motion_sensor_entity_id": "Motion sensor entity id",
"motion_delay": "Activation delay",
@@ -163,7 +163,7 @@
},
"power": {
"title": "Power management",
"description": "Power management attributes.\nGives the power and max power sensor of your home.\nThen specify the power consumption of the heater when on.\nAll sensors and device power should have the same unit (kW or W).",
"description": "Power management attributes.\nGives the power and max power sensor of your home.\nThen specify the power consumption of the heater when on.\nAll sensors and device power should have the same unit (kW or W).\nLeave corresponding entity_id empty if not used.",
"data": {
"power_sensor_entity_id": "Power",
"max_power_sensor_entity_id": "Max power",
@@ -179,7 +179,7 @@
},
"presence": {
"title": "Presence management",
"description": "Presence management attributes.\nGives the a presence sensor of your home (true is someone is present) and give the corresponding temperature preset setting.",
"description": "Presence management attributes.\nGives the a presence sensor of your home (true is someone is present).\nThen specify either the preset to use when presence sensor is false or the offset in temperature to apply.\nIf preset is given, the offset will not be used.\nLeave corresponding entity_id empty if not used.",
"data": {
"presence_sensor_entity_id": "Presence sensor",
"eco_away_temp": "Eco preset",
@@ -256,7 +256,7 @@
"temp_min": "Minimal temperature allowed",
"temp_max": "Maximal temperature allowed",
"device_power": "Device power",
"use_central_mode": "Enable the control by central entity (need central config)",
"use_central_mode": "Enable the control by central mode ('central_mode')",
"use_window_feature": "Use window detection",
"use_motion_feature": "Use motion detection",
"use_power_feature": "Use power management",
@@ -365,7 +365,7 @@
"use_window_central_config": "Use central window configuration"
},
"data_description": {
"window_sensor_entity_id": "Leave empty if no window sensor should be used and to use the automatic detection",
"window_sensor_entity_id": "Leave empty if no window sensor should be used",
"window_delay": "The delay in seconds before sensor detection is taken into account",
"window_auto_open_threshold": "Recommended value: between 3 and 10. Leave empty if automatic window open detection is not used",
"window_auto_close_threshold": "Recommended value: 0. Leave empty if automatic window open detection is not used",
@@ -375,7 +375,7 @@
},
"motion": {
"title": "Motion - {name}",
"description": "Motion management. Preset can switch automatically depending of a motion detection\nmotion_preset and no_motion_preset should be set to the corresponding preset name",
"description": "Motion management. Preset can switch automatically depending of a motion detection\nLeave corresponding entity_id empty if not used.\nmotion_preset and no_motion_preset should be set to the corresponding preset name",
"data": {
"motion_sensor_entity_id": "Motion sensor entity id",
"motion_delay": "Activation delay",
@@ -395,7 +395,7 @@
},
"power": {
"title": "Power - {name}",
"description": "Power management attributes.\nGives the power and max power sensor of your home.\nThen specify the power consumption of the heater when on.\nAll sensors and device power should have the same unit (kW or W).",
"description": "Power management attributes.\nGives the power and max power sensor of your home.\nThen specify the power consumption of the heater when on.\nAll sensors and device power should have the same unit (kW or W).\nLeave corresponding entity_id empty if not used.",
"data": {
"power_sensor_entity_id": "Power",
"max_power_sensor_entity_id": "Max power",
@@ -411,7 +411,7 @@
},
"presence": {
"title": "Presence - {name}",
"description": "Presence management attributes.\nGives the a presence sensor of your home (true is someone is present) and give the corresponding temperature preset setting.",
"description": "Presence management attributes.\nGives the a presence sensor of your home (true is someone is present).\nThen specify either the preset to use when presence sensor is false or the offset in temperature to apply.\nIf preset is given, the offset will not be used.\nLeave corresponding entity_id empty if not used.",
"data": {
"presence_sensor_entity_id": "Presence sensor",
"eco_away_temp": "Eco away preset",

View File

@@ -24,7 +24,7 @@
"temp_min": "Température minimale permise",
"temp_max": "Température maximale permise",
"device_power": "Puissance de l'équipement",
"use_central_mode": "Autoriser le controle par une entity centrale ('nécessite une config. centrale`)",
"use_central_mode": "Autoriser le controle par le mode central ('central_mode`)",
"use_window_feature": "Avec détection des ouvertures",
"use_motion_feature": "Avec détection de mouvement",
"use_power_feature": "Avec gestion de la puissance",
@@ -33,7 +33,7 @@
},
"data_description": {
"use_central_mode": "Cochez pour autoriser le contrôle du VTherm par la liste déroulante 'central_mode' de l'entité configuration centrale",
"external_temperature_sensor_entity_id": "Entity id du capteur de température extérieure.",
"external_temperature_sensor_entity_id": "Entity id du capteur de température extérieure. N'est pas utilisé si la configuration centrale est utilisée",
"use_main_central_config": "Cochez pour utiliser la configuration centrale principale. Décochez et saisissez les attributs pour utiliser une configuration spécifique principale"
}
},
@@ -123,7 +123,7 @@
},
"window": {
"title": "Gestion d'une ouverture",
"description": "Coupe le radiateur si l'ouverture est ouverte.\nLaissez l'id d'entité vide pour utiliser la détection automatique.",
"description": "Coupe le radiateur si l'ouverture est ouverte.\nLaissez l'entity id vide si non utilisé.",
"data": {
"window_sensor_entity_id": "Détecteur d'ouverture (entity id)",
"window_delay": "Délai avant extinction (secondes)",
@@ -133,7 +133,7 @@
"use_window_central_config": "Utiliser la configuration centrale des ouvertures"
},
"data_description": {
"window_sensor_entity_id": "Laissez vide si vous n'avez de détecteur et pour utiliser la détection automatique",
"window_sensor_entity_id": "Laissez vide si vous n'avez de détecteur",
"window_delay": "Le délai (en secondes) avant que le changement du détecteur soit pris en compte",
"window_auto_open_threshold": "Valeur recommandée: entre 3 et 10. Laissez vide si vous n'utilisez pas la détection automatique",
"window_auto_close_threshold": "Valeur recommandée: 0. Laissez vide si vous n'utilisez pas la détection automatique",
@@ -143,17 +143,17 @@
},
"motion": {
"title": "Gestion de la détection de mouvement",
"description": "Le preset s'ajuste automatiquement si un mouvement est détecté\n'Preset mouvement' et 'Preset sans mouvement' doivent être choisis avec les preset à utiliser.",
"description": "Le preset s'ajuste automatiquement si un mouvement est détecté\nLaissez l'entity id vide si non utilisé.\n'Preset mouvement' et 'Preset sans mouvement' doivent être choisis avec les preset à utiliser.",
"data": {
"motion_sensor_entity_id": "Détecteur de mouvement",
"motion_delay": "Délai d'activation",
"motion_off_delay": "Délai de désactivation",
"motion_preset": "Preset si mouvement",
"no_motion_preset": "Preset sans mouvement",
"no_motion_preset": "Preset si pas de mouvement",
"use_motion_central_config": "Utiliser la condfiguration centrale du mouvement"
},
"data_description": {
"motion_sensor_entity_id": "Id d'entité du détecteur de mouvement",
"motion_sensor_entity_id": "Détecteur de mouvement entity id",
"motion_delay": "Délai avant activation lorsqu'un mouvement est détecté (secondss)",
"motion_off_delai": "Délai avant désactivation lorsqu'aucun mouvement n'est détecté (secondes)",
"motion_preset": "Preset à utiliser si mouvement détecté",
@@ -179,7 +179,7 @@
},
"presence": {
"title": "Gestion de la présence",
"description": "Donnez un capteur de présence (true si quelqu'un est présent) et les températures cibles à utiliser en cas d'absence.",
"description": "Donnez un capteur de présence (true si quelqu'un est présent).\nEnsuite spécifiez soit un preset à utiliser, soit un offset de température à appliquer lorsque personne n'est présent.\nSi le préset est utilisé, l'offset ne sera pas pris en compte.\nLaissez l'entity id vide si la gestion de la présence est non utilisée.",
"data": {
"presence_sensor_entity_id": "Capteur de présence",
"eco_away_temp": "preset Eco",
@@ -192,7 +192,7 @@
"use_presence_central_config": "Utiliser la configuration centrale de la présence"
},
"data_description": {
"presence_sensor_entity_id": "Id d'entité du capteur de présence",
"presence_sensor_entity_id": "Capteur de présence entity id (true si quelqu'un est présent)",
"eco_away_temp": "Température en preset Eco en cas d'absence",
"comfort_away_temp": "Température en preset Comfort en cas d'absence",
"boost_away_temp": "Température en preset Boost en cas d'absence",
@@ -256,7 +256,7 @@
"temp_min": "Température minimale permise",
"temp_max": "Température maximale permise",
"device_power": "Puissance de l'équipement",
"use_central_mode": "Autoriser le controle par une entity centrale ('nécessite une config. centrale`)",
"use_central_mode": "Autoriser le controle par le mode central ('central_mode`)",
"use_window_feature": "Avec détection des ouvertures",
"use_motion_feature": "Avec détection de mouvement",
"use_power_feature": "Avec gestion de la puissance",
@@ -349,7 +349,7 @@
},
"window": {
"title": "Ouverture - {name}",
"description": "Coupe le radiateur si l'ouverture est ouverte.\nLaissez l'id d'entité vide pour utiliser la détection automatique.",
"description": "Gestion des ouvertures. Coupe le radiateur si l'ouverture est ouverte.",
"data": {
"window_sensor_entity_id": "Détecteur d'ouverture (entity id)",
"window_delay": "Délai avant extinction (secondes)",
@@ -359,7 +359,7 @@
"use_window_central_config": "Utiliser la configuration centrale des ouvertures"
},
"data_description": {
"window_sensor_entity_id": "Laissez vide si vous n'avez de détecteur et pour utiliser la détection automatique",
"window_sensor_entity_id": "Laissez vide si vous n'avez de détecteur",
"window_delay": "Le délai (en secondes) avant que le changement du détecteur soit pris en compte",
"window_auto_open_threshold": "Valeur recommandée: entre 3 et 10. Laissez vide si vous n'utilisez pas la détection automatique",
"window_auto_close_threshold": "Valeur recommandée: 0. Laissez vide si vous n'utilisez pas la détection automatique",
@@ -375,11 +375,11 @@
"motion_delay": "Délai d'activation",
"motion_off_delay": "Délai de désactivation",
"motion_preset": "Preset si mouvement",
"no_motion_preset": "Preset sans mouvement",
"no_motion_preset": "Preset si pas de mouvement",
"use_motion_central_config": "Utiliser la condfiguration centrale du mouvement"
},
"data_description": {
"motion_sensor_entity_id": "Id d'entité du détecteur de mouvement",
"motion_sensor_entity_id": "Détecteur de mouvement entity id",
"motion_delay": "Délai avant activation lorsqu'un mouvement est détecté (secondss)",
"motion_off_delai": "Délai avant désactivation lorsqu'aucun mouvement n'est détecté (secondes)",
"motion_preset": "Preset à utiliser si mouvement détecté",
@@ -405,7 +405,7 @@
},
"presence": {
"title": "Présence - {name}",
"description": "Donnez un capteur de présence (true si quelqu'un est présent) et les températures cibles à utiliser en cas d'absence.",
"description": "Gestion de la présence. Le capteur de présence doit être true ou home si quelqu'un est présent.",
"data": {
"presence_sensor_entity_id": "Capteur de présence",
"eco_away_temp": "preset Eco",
@@ -418,7 +418,7 @@
"use_presence_central_config": "Utiliser la configuration centrale de la présence"
},
"data_description": {
"presence_sensor_entity_id": "Id d'entité du capteur de présence",
"presence_sensor_entity_id": "Capteur de présence entity id (true si quelqu'un est présent)",
"eco_away_temp": "Température en preset Eco en cas d'absence",
"comfort_away_temp": "Température en preset Comfort en cas d'absence",
"boost_away_temp": "Température en preset Boost en cas d'absence",

View File

@@ -4,15 +4,6 @@
"flow_title": "Všestranná konfigurácia termostatu",
"step": {
"user": {
"title": "Typ všestranného termostatu",
"data": {
"thermostat_type": "Typ termostatu"
},
"data_description": {
"thermostat_type": "Len jeden centrálny typ konfigurácie je možný"
}
},
"main": {
"title": "Pridajte nový všestranný termostat",
"description": "Hlavné povinné atribúty",
"data": {
@@ -24,17 +15,10 @@
"temp_min": "Minimálna povolená teplota",
"temp_max": "Maximálna povolená teplota",
"device_power": "Napájanie zariadenia",
"use_central_mode": "Povoliť ovládanie centrálnou entitou (potrebná centrálna konfigurácia)",
"use_window_feature": "Použite detekciu okien",
"use_motion_feature": "Použite detekciu pohybu",
"use_power_feature": "Použite správu napájania",
"use_presence_feature": "Použite detekciu prítomnosti",
"use_main_central_config": "Použite centrálnu hlavnú konfiguráciu"
},
"data_description": {
"use_central_mode": "Zaškrtnutím povolíte ovládanie VTherm pomocou vybraných entít central_mode",
"use_main_central_config": "Začiarknite, ak chcete použiť centrálnu hlavnú konfiguráciu. Zrušte začiarknutie, ak chcete použiť špecifickú hlavnú konfiguráciu pre tento VTherm",
"external_temperature_sensor_entity_id": "ID entity snímača vonkajšej teploty. Nepoužíva sa, ak je zvolená centrálna konfigurácia"
"use_presence_feature": "Použite detekciu prítomnosti"
}
},
"type": {
@@ -55,11 +39,11 @@
"valve_entity2_id": "2. ventil číslo",
"valve_entity3_id": "3. ventil číslo",
"valve_entity4_id": "4. ventil číslo",
"auto_regulation_mode": "Samoregulácia",
"auto_regulation_dtemp": "Regulačný prah",
"auto_regulation_periode_min": "Regulačné minimálne obdobie",
"inverse_switch_command": "Inverzný prepínací príkaz",
"auto_fan_mode": "Režim automatického ventilátora"
"auto_regulation_mode": "Self-regulation",
"auto_regulation_dtemp": "Regulation threshold",
"auto_regulation_periode_min": "Regulation minimal period",
"inverse_switch_command": "Inverse switch command",
"auto_fan_mode": " Auto fan mode"
},
"data_description": {
"heater_entity_id": "ID entity povinného ohrievača",
@@ -76,11 +60,11 @@
"valve_entity2_id": "2. ventil číslo entity id",
"valve_entity3_id": "3. ventil číslo entity id",
"valve_entity4_id": "4. ventil číslo entity id",
"auto_regulation_mode": "Automatické nastavenie cieľovej teploty",
"auto_regulation_dtemp": "Hranica v °, pod ktorou sa zmena teploty neodošle",
"auto_regulation_periode_min": "Trvanie v minútach medzi dvoma aktualizáciami predpisov",
"inverse_switch_command": "V prípade spínača s pilotným vodičom a diódou možno budete musieť príkaz invertovať",
"auto_fan_mode": "Automaticky aktivujte ventilátor, keď je potrebné veľké vykurovanie/chladenie"
"auto_regulation_mode": "Auto adjustment of the target temperature",
"auto_regulation_dtemp": "The threshold in ° under which the temperature change will not be send",
"auto_regulation_periode_min": "Duration in minutes between two regulation update",
"inverse_switch_command": "For switch with pilot wire and diode you may need to inverse the command",
"auto_fan_mode": " Automatically activate fan when huge heating/cooling is necessary"
}
},
"tpi": {
@@ -88,13 +72,7 @@
"description": "Časovo proporcionálne integrálne atribúty",
"data": {
"tpi_coef_int": "Koeficient na použitie pre vnútornú teplotnú deltu",
"tpi_coef_ext": "Koeficient na použitie pre deltu vonkajšej teploty",
"use_tpi_central_config": "Použite centrálnu konfiguráciu TPI"
},
"data_description": {
"tpi_coef_int": "Koeficient na použitie pre vnútornú teplotnú deltu",
"tpi_coef_ext": "Koeficient na použitie pre deltu vonkajšej teploty",
"use_tpi_central_config": "Začiarknite, ak chcete použiť centrálnu konfiguráciu TPI. Zrušte začiarknutie, ak chcete použiť špecifickú konfiguráciu TPI pre tento VTherm"
"tpi_coef_ext": "Koeficient na použitie pre deltu vonkajšej teploty"
}
},
"presets": {
@@ -107,18 +85,7 @@
"frost_temp": "Teplota v prednastavení Frost protection",
"eco_ac_temp": "Teplota v režime Eco prednastavená pre režim AC",
"comfort_ac_temp": "Teplota v režime Comfort je prednastavená pre režim AC",
"boost_ac_temp": "Prednastavená teplota v režime Boost pre režim AC",
"use_presets_central_config": "Použite konfiguráciu centrálnych predvolieb"
},
"data_description": {
"eco_temp": "Teplota v predvoľbe Eco",
"comfort_temp": "Prednastavená teplota v komfortnom režime",
"boost_temp": "Teplota v prednastavení Boost",
"frost_temp": "Teplota v prednastavenej ochrane proti mrazu",
"eco_ac_temp": "Teplota v režime Eco prednastavená pre režim AC",
"comfort_ac_temp": "Teplota v režime Comfort je prednastavená pre režim AC",
"boost_ac_temp": "Prednastavená teplota v režime Boost pre režim AC",
"use_presets_central_config": "Začiarknite, ak chcete použiť konfiguráciu centrálnych predvolieb. Zrušte začiarknutie, ak chcete použiť špecifickú konfiguráciu predvolieb pre tento VTherm"
"boost_ac_temp": "Prednastavená teplota v režime Boost pre režim AC"
}
},
"window": {
@@ -129,16 +96,14 @@
"window_delay": "Oneskorenie snímača okna (sekundy)",
"window_auto_open_threshold": "Prah poklesu teploty pre automatickú detekciu otvoreného okna (v °/hodina)",
"window_auto_close_threshold": "Prahová hodnota zvýšenia teploty pre koniec automatickej detekcie (v °/hodina)",
"window_auto_max_duration": "Maximálne trvanie automatickej detekcie otvoreného okna (v min)",
"use_window_central_config": "Použite centrálnu konfiguráciu okna"
"window_auto_max_duration": "Maximálne trvanie automatickej detekcie otvoreného okna (v min)"
},
"data_description": {
"window_sensor_entity_id": "Nechajte prázdne, ak nemáte použiť žiadny okenný senzor",
"window_delay": "Zohľadňuje sa oneskorenie v sekundách pred detekciou snímača",
"window_auto_open_threshold": "Odporúčaná hodnota: medzi 3 a 10. Ak sa nepoužíva automatická detekcia otvoreného okna, nechajte prázdne",
"window_auto_close_threshold": "Odporúčaná hodnota: 0. Ak sa nepoužíva automatická detekcia otvoreného okna, nechajte prázdne",
"window_auto_max_duration": "Odporúčaná hodnota: 60 (jedna hodina). Ak sa nepoužíva automatická detekcia otvoreného okna, nechajte prázdne",
"use_window_central_config": "Začiarknite, ak chcete použiť konfiguráciu centrálneho okna. Zrušte začiarknutie, ak chcete použiť špecifickú konfiguráciu okna pre tento VTherm"
"window_auto_max_duration": "Odporúčaná hodnota: 60 (jedna hodina). Ak sa nepoužíva automatická detekcia otvoreného okna, nechajte prázdne"
}
},
"motion": {
@@ -149,16 +114,14 @@
"motion_delay": "Oneskorenie aktivácie",
"motion_off_delay": "Oneskorenie deaktivácie",
"motion_preset": "Prednastavený pohyb",
"no_motion_preset": "Žiadna predvoľba pohybu",
"use_motion_central_config": "Použite centrálnu konfiguráciu pohybu"
"no_motion_preset": "Žiadna predvoľba pohybu"
},
"data_description": {
"motion_sensor_entity_id": "ID entity snímača pohybu",
"motion_delay": "Oneskorenie aktivácie pohybu (sekundy)",
"motion_off_delay": "Oneskorenie deaktivácie pohybu (sekundy)",
"motion_preset": "Prednastavené na použitie pri detekcii pohybu",
"no_motion_preset": "Prednastavené na použitie, keď nie je detekovaný žiadny pohyb",
"use_motion_central_config": "Začiarknite, ak chcete použiť konfiguráciu centrálneho pohybu. Zrušte začiarknutie, ak chcete použiť špecifickú konfiguráciu pohybu pre tento VTherm"
"no_motion_preset": "Prednastavené na použitie, keď nie je detekovaný žiadny pohyb"
}
},
"power": {
@@ -167,14 +130,7 @@
"data": {
"power_sensor_entity_id": "ID entity snímača výkonu",
"max_power_sensor_entity_id": "ID entity snímača maximálneho výkonu",
"power_temp": "Teplota pre zníženie výkonu",
"use_power_central_config": "Použite centrálnu konfiguráciu napájania"
},
"data_description": {
"power_sensor_entity_id": "ID entity snímača výkonu",
"max_power_sensor_entity_id": "ID entity snímača maximálneho výkonu",
"power_temp": "Teplota pre zníženie výkonu",
"use_power_central_config": "Začiarknite, ak chcete použiť konfiguráciu centrálneho napájania. Zrušte začiarknutie, ak chcete použiť špecifickú konfiguráciu napájania pre tento VTherm"
"power_temp": "Teplota pre zníženie výkonu"
}
},
"presence": {
@@ -188,19 +144,7 @@
"frost_away_temp": "Prednastavená teplota v režime Frost protection, keď nie je prítomný",
"eco_ac_away_temp": "Teplota v prednastavenej Eco, keď nie je prítomná v režime AC",
"comfort_ac_away_temp": "Teplota v režime Comfort je prednastavená, keď nie je prítomný v režime AC",
"boost_ac_away_temp": "Teplota v prednastavenom Boost, keď nie je prítomný v režime AC",
"use_presence_central_config": "Použite centrálnu konfiguráciu prítomnosti"
},
"data_description": {
"presence_sensor_entity_id": "ID entity senzora prítomnosti",
"eco_away_temp": "Teplota v prednastavenej Eco, keď nie je žiadna prítomnosť",
"comfort_away_temp": "Teplota v režime Comfort je prednastavená, keď nie je prítomný",
"boost_away_temp": "Prednastavená teplota v režime Boost, keď nie je prítomný",
"frost_away_temp": "Teplota v Prednastavená ochrana pred mrazom, keď nie je prítomný",
"eco_ac_away_temp": "Teplota v prednastavenej Eco, keď nie je prítomná v režime AC",
"comfort_ac_away_temp": "Teplota v režime Comfort je prednastavená, keď nie je prítomný v režime AC",
"boost_ac_away_temp": "Teplota v prednastavenom Boost, keď nie je prítomný v režime AC",
"use_presence_central_config": "Začiarknite, ak chcete použiť konfiguráciu centrálnej prítomnosti. Zrušte začiarknutie, ak chcete použiť špecifickú konfiguráciu prítomnosti pre tento VTherm"
"boost_ac_away_temp": "Teplota v prednastavenom Boost, keď nie je prítomný v režime AC"
}
},
"advanced": {
@@ -210,23 +154,20 @@
"minimal_activation_delay": "Minimálne oneskorenie aktivácie",
"security_delay_min": "Bezpečnostné oneskorenie (v minútach)",
"security_min_on_percent": "Minimálne percento výkonu na aktiváciu bezpečnostného režimu",
"security_default_on_percent": "Percento výkonu na použitie v bezpečnostnom režime",
"use_advanced_central_config": "Použite centrálnu rozšírenú konfiguráciu"
"security_default_on_percent": "Percento výkonu na použitie v bezpečnostnom režime"
},
"data_description": {
"minimal_activation_delay": "Oneskorenie v sekundách, pri ktorom sa zariadenie neaktivuje",
"security_delay_min": "Maximálne povolené oneskorenie v minútach medzi dvoma meraniami teploty. Po uplynutí tohto oneskorenia sa termostat prepne do bezpečnostného vypnutého stavu",
"security_min_on_percent": "Minimálna percentuálna hodnota ohrevu pre aktiváciu prednastavenej bezpečnosti. Pod týmto percentom výkonu termostat neprejde do prednastavenia zabezpečenia",
"security_default_on_percent": "Predvolená percentuálna hodnota vykurovacieho výkonu v bezpečnostnej predvoľbe. Nastavte na 0, ak chcete vypnúť ohrievač v zabezpečenom stave",
"use_advanced_central_config": "Začiarknite, ak chcete použiť centrálnu rozšírenú konfiguráciu. Zrušte začiarknutie, ak chcete použiť špecifickú rozšírenú konfiguráciu pre tento VTherm"
"security_default_on_percent": "Predvolená percentuálna hodnota vykurovacieho výkonu v bezpečnostnej predvoľbe. Nastavte na 0, ak chcete vypnúť ohrievač v zabezpečenom stave"
}
}
},
"error": {
"unknown": "Neočakávaná chyba",
"unknown_entity": "Neznáme ID entity",
"window_open_detection_method": "Mala by sa použiť iba jedna metóda detekcie otvoreného okna. Použite senzor alebo automatickú detekciu cez teplotný prah, ale nie oboje",
"no_central_config": "Nemôžete zaškrtnúť „použiť centrálnu konfiguráciu“, pretože sa nenašla žiadna centrálna konfigurácia. Aby ste ho mohli používať, musíte si vytvoriť všestranný termostat typu „Central Configuration“."
"window_open_detection_method": "Mala by sa použiť iba jedna metóda detekcie otvoreného okna. Použite senzor alebo automatickú detekciu cez teplotný prah, ale nie oboje"
},
"abort": {
"already_configured": "Zariadenie je už nakonfigurované"
@@ -236,16 +177,7 @@
"flow_title": "Všestranná konfigurácia termostatu",
"step": {
"user": {
"title": "Typ - {name}",
"data": {
"thermostat_type": "Typ termostatu"
},
"data_description": {
"thermostat_type": "Je možný len jeden centrálny typ konfigurácie"
}
},
"main": {
"title": "Hlavný - {name}",
"title": "Pridajte nový všestranný termostat",
"description": "Hlavné povinné atribúty",
"data": {
"name": "Názov",
@@ -256,21 +188,14 @@
"temp_min": "Minimálna povolená teplota",
"temp_max": "Maximálna povolená teplota",
"device_power": "Výkon zariadenia (kW)",
"use_central_mode": "Povoliť ovládanie centrálnou entitou (potrebná centrálna konfigurácia)",
"use_window_feature": "Použite detekciu okien",
"use_motion_feature": "Použite detekciu pohybu",
"use_power_feature": "Použite správu napájania",
"use_presence_feature": "Použite detekciu prítomnosti",
"use_main_central_config": "Použite centrálnu hlavnú konfiguráciu"
},
"data_description": {
"use_central_mode": "Zaškrtnutím povolíte ovládanie VTherm pomocou vybraných entít central_mode",
"use_main_central_config": "Začiarknite, ak chcete použiť centrálnu hlavnú konfiguráciu. Ak chcete použiť špecifickú konfiguráciu pre tento VTherm, zrušte začiarknutie",
"external_temperature_sensor_entity_id": "ID entity snímača vonkajšej teploty. Nepoužíva sa, ak je zvolená centrálna konfigurácia"
"use_presence_feature": "Použite detekciu prítomnosti"
}
},
"type": {
"title": "Prepojené entity - {name}",
"title": "Prepojené entity",
"description": "Atribúty prepojených entít",
"data": {
"heater_entity_id": "Spínač ohrievača",
@@ -287,11 +212,11 @@
"valve_entity2_id": "2. ventil číslo",
"valve_entity3_id": "3. ventil číslo",
"valve_entity4_id": "4. ventil číslo",
"auto_regulation_mode": "Samoregulácia",
"auto_regulation_dtemp": "Regulačný prah",
"auto_regulation_periode_min": "Regulačné minimálne obdobie",
"inverse_switch_command": "Inverzný prepínací príkaz",
"auto_fan_mode": "Režim automatického ventilátora"
"auto_regulation_mode": "Self-regulation",
"auto_regulation_dtemp": "Regulation threshold",
"auto_regulation_periode_min": "Regulation minimal period",
"inverse_switch_command": "Inverse switch command",
"auto_fan_mode": " Auto fan mode"
},
"data_description": {
"heater_entity_id": "ID entity povinného ohrievača",
@@ -308,29 +233,23 @@
"valve_entity2_id": "2. ventil číslo entity id",
"valve_entity3_id": "3. ventil číslo entity id",
"valve_entity4_id": "4. ventil číslo entity id",
"auto_regulation_mode": "Automatické nastavenie cieľovej teploty",
"auto_regulation_dtemp": "Hranica v °, pod ktorou sa zmena teploty neodošle",
"auto_regulation_periode_min": "Trvanie v minútach medzi dvoma aktualizáciami predpisov",
"inverse_switch_command": "V prípade spínača s pilotným vodičom a diódou možno budete musieť príkaz invertovať",
"auto_fan_mode": "Automaticky aktivujte ventilátor, keď je potrebné veľké vykurovanie/chladenie"
"auto_regulation_mode": "Auto adjustment of the target temperature",
"auto_regulation_dtemp": "The threshold in ° under which the temperature change will not be send",
"auto_regulation_periode_min": "Duration in minutes between two regulation update",
"inverse_switch_command": "For switch with pilot wire and diode you may need to inverse the command",
"auto_fan_mode": " Automatically activate fan when huge heating/cooling is necessary"
}
},
"tpi": {
"title": "TPI - {name}",
"title": "TPI",
"description": "Časovo proporcionálne integrálne atribúty",
"data": {
"tpi_coef_int": "Koeficient na použitie pre vnútornú teplotnú deltu",
"tpi_coef_ext": "Koeficient na použitie pre vonkajšiu teplotnú deltu",
"use_tpi_central_config": "Použite centrálnu konfiguráciu TPI"
},
"data_description": {
"tpi_coef_int": "Koeficient na použitie pre vnútornú teplotnú deltu",
"tpi_coef_ext": "Koeficient na použitie pre deltu vonkajšej teploty",
"use_tpi_central_config": "Začiarknite, ak chcete použiť centrálnu konfiguráciu TPI. Zrušte začiarknutie, ak chcete použiť špecifickú konfiguráciu TPI pre tento VTherm"
"tpi_coef_ext": "Koeficient na použitie pre vonkajšiu teplotnú deltu"
}
},
"presets": {
"title": "Predvoľby - {name}",
"title": "Predvoľby",
"description": "Pre každú predvoľbu zadajte cieľovú teplotu (0, ak chcete predvoľbu ignorovať)",
"data": {
"eco_temp": "Teplota v predvoľbe Eco",
@@ -339,74 +258,52 @@
"frost_temp": "Teplota v prednastavení Frost protection",
"eco_ac_temp": "Teplota v režime Eco prednastavená pre režim AC",
"comfort_ac_temp": "Teplota v režime Comfort je prednastavená pre režim AC",
"boost_ac_temp": "Prednastavená teplota v režime Boost pre režim AC",
"use_presets_central_config": "Použite konfiguráciu centrálnych predvolieb"
},
"data_description": {
"eco_temp": "Teplota v predvoľbe Eco",
"comfort_temp": "Prednastavená teplota v komfortnom režime",
"boost_temp": "Teplota v prednastavení Boost",
"frost_temp": "Teplota v prednastavenej ochrane proti mrazu",
"eco_ac_temp": "Teplota v režime Eco prednastavená pre režim AC",
"comfort_ac_temp": "Teplota v režime Comfort je prednastavená pre režim AC",
"boost_ac_temp": "Prednastavená teplota v režime Boost pre režim AC",
"use_presets_central_config": "Začiarknite, ak chcete použiť konfiguráciu centrálnych predvolieb. Zrušte začiarknutie, ak chcete použiť špecifickú konfiguráciu predvolieb pre tento VTherm"
"boost_ac_temp": "Prednastavená teplota v režime Boost pre režim AC"
}
},
"window": {
"title": "Správa okien - {name}",
"title": "Správa okien",
"description": "Otvoriť správu okien.\nAk sa príslušné entity_id nepoužíva, ponechajte prázdne\nMôžete tiež nakonfigurovať automatickú detekciu otvoreného okna na základe poklesu teploty",
"data": {
"window_sensor_entity_id": "ID entity snímača okna",
"window_delay": "Oneskorenie snímača okna (sekundy)",
"window_auto_open_threshold": "Prah poklesu teploty pre automatickú detekciu otvoreného okna (v °/hodina)",
"window_auto_close_threshold": "Prahová hodnota zvýšenia teploty pre koniec automatickej detekcie (v °/hodina)",
"window_auto_max_duration": "Maximálne trvanie automatickej detekcie otvoreného okna (v min)",
"use_window_central_config": "Použite centrálnu konfiguráciu okna"
"window_auto_max_duration": "Maximálne trvanie automatickej detekcie otvoreného okna (v min)"
},
"data_description": {
"window_sensor_entity_id": "Nechajte prázdne, ak nemáte použiť žiadny okenný senzor",
"window_delay": "Zohľadňuje sa oneskorenie v sekundách pred detekciou snímača",
"window_auto_open_threshold": "Odporúčaná hodnota: medzi 3 a 10. Ak sa nepoužíva automatická detekcia otvoreného okna, nechajte prázdne",
"window_auto_close_threshold": "Odporúčaná hodnota: 0. Ak sa nepoužíva automatická detekcia otvoreného okna, nechajte prázdne",
"window_auto_max_duration": "Odporúčaná hodnota: 60 (jedna hodina). Ak sa nepoužíva automatická detekcia otvoreného okna, nechajte prázdne",
"use_window_central_config": "Začiarknite, ak chcete použiť konfiguráciu centrálneho okna. Zrušte začiarknutie, ak chcete použiť špecifickú konfiguráciu okna pre tento VTherm"
"window_auto_max_duration": "Odporúčaná hodnota: 60 (jedna hodina). Ak sa nepoužíva automatická detekcia otvoreného okna, nechajte prázdne"
}
},
"motion": {
"title": "Riadenie pohybu - {name}",
"title": "Riadenie pohybu",
"description": "Správa snímača pohybu. Predvoľba sa môže automaticky prepínať v závislosti od detekcie pohybu\nAk sa nepoužíva, ponechajte zodpovedajúce entity_id prázdne.\nmotion_preset a no_motion_preset by mali byť nastavené na zodpovedajúci názov predvoľby",
"data": {
"motion_sensor_entity_id": "ID entity snímača pohybu",
"motion_delay": "Oneskorenie aktivácie",
"motion_off_delay": "Oneskorenie deaktivácie",
"motion_preset": "Prednastavený pohyb",
"no_motion_preset": "Žiadna predvoľba pohybu",
"use_motion_central_config": "Použite centrálnu konfiguráciu pohybu"
"no_motion_preset": "Žiadna predvoľba pohybu"
},
"data_description": {
"motion_sensor_entity_id": "ID entity snímača pohybu",
"motion_delay": "Oneskorenie aktivácie pohybu (sekundy)",
"motion_off_delay": "Oneskorenie deaktivácie pohybu (sekundy)",
"motion_preset": "Prednastavené na použitie pri detekcii pohybu",
"no_motion_preset": "Prednastavené na použitie, keď nie je detekovaný žiadny pohyb",
"use_motion_central_config": "Začiarknite, ak chcete použiť konfiguráciu centrálneho pohybu. Zrušte začiarknutie, ak chcete použiť špecifickú konfiguráciu pohybu pre tento VTherm"
"no_motion_preset": "Prednastavené na použitie, keď nie je detekovaný žiadny pohyb"
}
},
"power": {
"title": "Správa napájania - {name}",
"title": "Správa napájania",
"description": "Atribúty správy napájania.\nPoskytuje senzor výkonu a maximálneho výkonu vášho domova.\nPotom zadajte spotrebu energie ohrievača, keď je zapnutý.\nVšetky senzory a výkon zariadenia by mali mať rovnakú jednotku (kW alebo W).\nPonechajte zodpovedajúce entity_id prázdne ak sa nepoužíva.",
"data": {
"power_sensor_entity_id": "ID entity snímača výkonu",
"max_power_sensor_entity_id": "ID entity snímača maximálneho výkonu",
"power_temp": "Teplota pre zníženie výkonu",
"use_power_central_config": "Použite centrálnu konfiguráciu napájania"
},
"data_description": {
"power_sensor_entity_id": "ID entity snímača výkonu",
"max_power_sensor_entity_id": "ID entity snímača maximálneho výkonu",
"power_temp": "Teplota pre zníženie výkonu",
"use_power_central_config": "Začiarknite, ak chcete použiť konfiguráciu centrálneho napájania. Zrušte začiarknutie, ak chcete použiť špecifickú konfiguráciu napájania pre tento VTherm"
"power_temp": "Teplota pre zníženie výkonu"
}
},
"presence": {
@@ -420,45 +317,30 @@
"frost_away_temp": "Prednastavená teplota v režime Frost protection, keď nie je prítomný",
"eco_ac_away_temp": "Teplota v prednastavenej Eco, keď nie je prítomná v režime AC",
"comfort_ac_away_temp": "Teplota v režime Comfort je prednastavená, keď nie je prítomný v režime AC",
"boost_ac_away_temp": "Teplota v prednastavenom Boost, keď nie je prítomný v režime AC",
"use_presence_central_config": "Použite centrálnu konfiguráciu prítomnosti"
},
"data_description": {
"presence_sensor_entity_id": "ID entity senzora prítomnosti",
"eco_away_temp": "Teplota v prednastavenej Eco, keď nie je žiadna prítomnosť",
"comfort_away_temp": "Teplota v režime Comfort je prednastavená, keď nie je prítomný",
"boost_away_temp": "Prednastavená teplota v režime Boost, keď nie je prítomný",
"frost_away_temp": "Teplota v Prednastavená ochrana pred mrazom, keď nie je prítomný",
"eco_ac_away_temp": "Teplota v prednastavenej Eco, keď nie je prítomná v režime AC",
"comfort_ac_away_temp": "Teplota v režime Comfort je prednastavená, keď nie je prítomný v režime AC",
"boost_ac_away_temp": "Teplota v prednastavenom Boost, keď nie je prítomný v režime AC",
"use_presence_central_config": "Začiarknite, ak chcete použiť konfiguráciu centrálnej prítomnosti. Zrušte začiarknutie, ak chcete použiť špecifickú konfiguráciu prítomnosti pre tento VTherm"
"boost_ac_away_temp": "Teplota v prednastavenom Boost, keď nie je prítomný v režime AC"
}
},
"advanced": {
"title": "Pokročilé parametre - {name}",
"title": "Pokročilé parametre",
"description": "Konfigurácia pokročilých parametrov. Ak neviete, čo robíte, ponechajte predvolené hodnoty.\nTento parameter môže viesť k veľmi zlej regulácii teploty alebo výkonu.",
"data": {
"minimal_activation_delay": "Minimálne oneskorenie aktivácie",
"security_delay_min": "Bezpečnostné oneskorenie (v minútach)",
"security_min_on_percent": "Minimálne percento výkonu pre bezpečnostný režim",
"security_default_on_percent": "Percento výkonu na použitie v bezpečnostnom režime",
"use_advanced_central_config": "Použite centrálnu rozšírenú konfiguráciu"
"security_default_on_percent": "Percento výkonu na použitie v bezpečnostnom režime"
},
"data_description": {
"minimal_activation_delay": "Oneskorenie v sekundách, pri ktorom sa zariadenie neaktivuje",
"security_delay_min": "Maximálne povolené oneskorenie v minútach medzi dvoma meraniami teploty. Po uplynutí tohto oneskorenia sa termostat prepne do bezpečnostného vypnutého stavu",
"security_min_on_percent": "Minimálna percentuálna hodnota ohrevu pre aktiváciu prednastavenej bezpečnosti. Pod týmto percentom výkonu termostat neprejde do prednastavenia zabezpečenia",
"security_default_on_percent": "Predvolená percentuálna hodnota vykurovacieho výkonu v bezpečnostnej predvoľbe. Nastavte na 0, ak chcete vypnúť ohrievač v zabezpečenom stave",
"use_advanced_central_config": "Začiarknite, ak chcete použiť centrálnu rozšírenú konfiguráciu. Zrušte začiarknutie, ak chcete použiť špecifickú rozšírenú konfiguráciu pre tento VTherm"
"security_default_on_percent": "Predvolená percentuálna hodnota vykurovacieho výkonu v bezpečnostnej predvoľbe. Nastavte na 0, ak chcete vypnúť ohrievač v zabezpečenom stave"
}
}
},
"error": {
"unknown": "Neočakávaná chyba",
"unknown_entity": "Neznáme ID entity",
"window_open_detection_method": "Mala by sa použiť iba jedna metóda detekcie otvoreného okna. Použite senzor alebo automatickú detekciu cez teplotný prah, ale nie oboje",
"no_central_config": "Nemôžete zaškrtnúť „použiť centrálnu konfiguráciu“, pretože sa nenašla žiadna centrálna konfigurácia. Aby ste ho mohli používať, musíte si vytvoriť všestranný termostat typu „Central Configuration“."
"window_open_detection_method": "Mala by sa použiť iba jedna metóda detekcie otvoreného okna. Použite senzor alebo automatickú detekciu cez teplotný prah, ale nie oboje"
},
"abort": {
"already_configured": "Zariadenie je už nakonfigurované"
@@ -467,28 +349,27 @@
"selector": {
"thermostat_type": {
"options": {
"thermostat_central_config": "Centrálna konfigurácia",
"thermostat_over_switch": "Termostat nad spínačom",
"thermostat_over_climate": "Termostat nad iným termostatom",
"thermostat_over_valve": "Termostat nad ventilom"
"thermostat_over_valve": "Thermostat over a valve"
}
},
"auto_regulation_mode": {
"options": {
"auto_regulation_slow": "Pomalé",
"auto_regulation_strong": "Silné",
"auto_regulation_medium": "Stredné",
"auto_regulation_light": "Jemné",
"auto_regulation_expert": "Expert",
"auto_regulation_none": "Nie auto-regulácia"
"auto_regulation_slow": "Slow",
"auto_regulation_strong": "Strong",
"auto_regulation_medium": "Medium",
"auto_regulation_light": "Light",
"auto_regulation_expert": "Expert",
"auto_regulation_none": "No auto-regulation"
}
},
"auto_fan_mode": {
"options": {
"auto_fan_none": "Žiadny automatický ventilátor",
"auto_fan_low": "Nízky",
"auto_fan_medium": "Stredný",
"auto_fan_high": "Vysoký",
"auto_fan_none": "No auto-fan",
"auto_fan_low": "Low",
"auto_fan_medium": "Medium",
"auto_fan_high": "High",
"auto_fan_turbo": "Turbo"
}
}
@@ -508,4 +389,4 @@
}
}
}
}
}

View File

@@ -141,9 +141,8 @@ class UnderlyingEntity:
await self.set_hvac_mode(hvac_mode)
elif hvac_mode != HVACMode.OFF and not self.is_device_active:
_LOGGER.warning(
"%s - The hvac mode is %s, but the underlying device is not ON. Turning on device %s if needed",
"%s - The hvac mode is ON, but the underlying device is not ON. Turning on device %s",
self,
hvac_mode,
self._entity_id,
)
await self.set_hvac_mode(hvac_mode)
@@ -355,7 +354,7 @@ class UnderlyingSwitch(UnderlyingEntity):
if await self._thermostat.check_overpowering():
_LOGGER.debug("%s - End of cycle (3)", self)
return
# safety mode could have change the on_time percent
# Security mode could have change the on_time percent
await self._thermostat.check_security()
time = self._on_time_sec
@@ -484,14 +483,6 @@ class UnderlyingClimate(UnderlyingEntity):
if not self.is_initialized:
return False
if self._underlying_climate.hvac_mode == hvac_mode:
_LOGGER.debug(
"%s - hvac_mode is already is requested state %s. Do not send any command",
self,
self._underlying_climate.hvac_mode,
)
return False
data = {ATTR_ENTITY_ID: self._entity_id, "hvac_mode": hvac_mode}
await self._hass.services.async_call(
CLIMATE_DOMAIN,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

View File

@@ -428,12 +428,10 @@ async def send_temperature_change_event(
)
},
)
dearm_window_auto = await entity._async_temperature_changed(temp_event)
await entity._async_temperature_changed(temp_event)
if sleep:
await asyncio.sleep(0.1)
return dearm_window_auto
async def send_ext_temperature_change_event(
entity: BaseThermostat, new_temp, date, sleep=True
@@ -621,7 +619,6 @@ async def send_climate_change_event(
old_hvac_action: HVACAction,
date,
sleep=True,
underlying_entity_id: str = None,
):
"""Sending a new climate event simulating a change on the underlying climate state"""
_LOGGER.info(
@@ -633,23 +630,18 @@ async def send_climate_change_event(
date,
entity,
)
send_from_entity_id = (
underlying_entity_id if underlying_entity_id is not None else entity.entity_id
)
climate_event = Event(
EVENT_STATE_CHANGED,
{
"new_state": State(
entity_id=send_from_entity_id,
entity_id=entity.entity_id,
state=new_hvac_mode,
attributes={"hvac_action": new_hvac_action},
last_changed=date,
last_updated=date,
),
"old_state": State(
entity_id=send_from_entity_id,
entity_id=entity.entity_id,
state=old_hvac_mode,
attributes={"hvac_action": old_hvac_action},
last_changed=date,

View File

@@ -358,7 +358,7 @@ async def test_bug_82(
skip_turn_on_off_heater,
skip_send_event,
):
"""Test that when a underlying climate is not available the VTherm doesn't go into safety mode"""
"""Test that when a underlying climate is not available the VTherm doesn't go into security mode"""
tz = get_tz(hass) # pylint: disable=invalid-name
now: datetime = datetime.now(tz=tz)
@@ -427,7 +427,7 @@ async def test_bug_82(
assert mock_find_climate.mock_calls[0] == call()
mock_find_climate.assert_has_calls([call.find_underlying_entity()])
# Force safety mode
# Force security mode
assert entity._last_ext_temperature_measure is not None
assert entity._last_temperature_measure is not None
assert (
@@ -633,16 +633,14 @@ async def test_bug_272(
# In the accepted interval
await entity.async_set_temperature(temperature=17.5)
# MagicMock climate is already HEAT by default. So there is no SET_HAVC_MODE call
assert mock_service_call.call_count == 1
assert mock_service_call.call_count == 2
mock_service_call.assert_has_calls(
[
# call.async_call(
# "climate",
# SERVICE_SET_HVAC_MODE,
# {"entity_id": "climate.mock_climate", "hvac_mode": HVACMode.HEAT},
# ),
call.async_call(
"climate",
SERVICE_SET_HVAC_MODE,
{"entity_id": "climate.mock_climate", "hvac_mode": HVACMode.HEAT},
),
call.async_call(
"climate",
SERVICE_SET_TEMPERATURE,

View File

@@ -268,7 +268,7 @@ async def test_full_over_switch_wo_central_config(
assert entity._security_default_on_percent == 0.1
assert entity.is_inversed is False
assert entity.is_window_auto_enabled is False # we have an entity_id
assert entity.is_window_auto_enabled is True
assert entity._window_sensor_entity_id == "binary_sensor.mock_window_sensor"
assert entity._window_delay_sec == 30
assert entity._window_auto_close_threshold == 0.1
@@ -377,8 +377,7 @@ async def test_full_over_switch_with_central_config(
assert entity._security_default_on_percent == 0.2
assert entity.is_inversed is False
# We have an entity so window auto is not enabled
assert entity.is_window_auto_enabled is False
assert entity.is_window_auto_enabled is True
assert entity._window_sensor_entity_id == "binary_sensor.mock_window_sensor"
assert entity._window_delay_sec == 15
assert entity._window_auto_close_threshold == 1

View File

@@ -1,9 +1,9 @@
# pylint: disable=wildcard-import, unused-wildcard-import, protected-access, unused-argument, line-too-long, too-many-lines
# pylint: disable=wildcard-import, unused-wildcard-import, protected-access, unused-argument, line-too-long
""" Test the central_configuration """
from unittest.mock import patch, call
from unittest.mock import patch # , call
from datetime import datetime, timedelta
# from datetime import datetime # , timedelta
from homeassistant.core import HomeAssistant
@@ -732,309 +732,3 @@ async def test_climate_ac_only_change_central_mode_true(
# No change
assert entity.hvac_mode == HVACMode.COOL
assert entity.preset_mode == PRESET_ECO
async def test_switch_change_central_mode_true_with_window(
hass: HomeAssistant, skip_hass_states_is_state, init_central_config
):
"""test that changes with over_switch config with central_mode True are
taken into account"""
# Add a Switch VTherm
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_USE_CENTRAL_MODE: True,
CONF_CYCLE_MIN: 5,
CONF_TEMP_MIN: 8,
CONF_TEMP_MAX: 18,
"frost_temp": 10,
"eco_temp": 17,
"comfort_temp": 18,
"boost_temp": 21,
CONF_USE_WINDOW_FEATURE: True,
CONF_USE_MOTION_FEATURE: True,
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_SECURITY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_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",
CONF_MOTION_DELAY: 10,
CONF_MOTION_OFF_DELAY: 30,
CONF_MOTION_PRESET: PRESET_BOOST,
CONF_NO_MOTION_PRESET: PRESET_ECO,
},
)
tz = get_tz(hass) # pylint: disable=invalid-name
event_timestamp = datetime.now(tz)
# 1 initialize entity and find select entity
with patch("homeassistant.core.ServiceRegistry.async_call"):
entity: ThermostatOverSwitch = await create_thermostat(
hass, entry, "climate.theoverswitchmockname"
)
assert entity
assert entity.is_controlled_by_central_mode
assert entity.last_central_mode is None
# Find the select entity
select_entity = search_entity(hass, "select.central_mode", SELECT_DOMAIN)
assert select_entity
assert select_entity.current_option == CENTRAL_MODE_AUTO
assert select_entity.options == CENTRAL_MODES
# start entity
await entity.async_set_hvac_mode(HVACMode.HEAT)
await entity.async_set_preset_mode(PRESET_ACTIVITY)
assert entity.hvac_mode == HVACMode.HEAT
assert entity.preset_mode == PRESET_ACTIVITY
assert entity.window_state is STATE_OFF
# 2 Open the window
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
) as mock_send_event, patch(
"homeassistant.helpers.condition.state", return_value=True
):
event_timestamp = event_timestamp + timedelta(minutes=1)
try_function = await send_window_change_event(
entity, True, False, event_timestamp
)
await try_function(None)
assert mock_send_event.call_count == 1
mock_send_event.assert_has_calls(
[call.send_event(EventType.HVAC_MODE_EVENT, {"hvac_mode": HVACMode.OFF})]
)
assert entity.hvac_mode == HVACMode.OFF
assert entity.preset_mode == PRESET_ACTIVITY
assert entity._saved_hvac_mode == HVACMode.HEAT
assert entity._saved_preset_mode == PRESET_ACTIVITY
assert entity.window_state is STATE_ON
# 3 Change central_mode to STOPPED
with patch("homeassistant.core.ServiceRegistry.async_call"):
event_timestamp = event_timestamp + timedelta(minutes=1)
entity._set_now(event_timestamp)
await select_entity.async_select_option(CENTRAL_MODE_STOPPED)
assert entity.last_central_mode is CENTRAL_MODE_STOPPED
# No change
assert entity.hvac_mode == HVACMode.OFF
assert entity.preset_mode == PRESET_ACTIVITY
assert entity._saved_hvac_mode == HVACMode.HEAT
assert entity._saved_preset_mode == PRESET_ACTIVITY
# 4 Close the window
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
) as mock_send_event, patch(
"homeassistant.helpers.condition.state", return_value=True
):
event_timestamp = event_timestamp + timedelta(minutes=1)
try_function = await send_window_change_event(
entity, False, True, event_timestamp
)
await try_function(None)
# No hvac_mode change cause the central mode is STOPPED
assert mock_send_event.call_count == 0
# We should stay off because central is STOPPED
assert entity.hvac_mode == HVACMode.OFF
assert entity.preset_mode == PRESET_ACTIVITY
assert entity._saved_hvac_mode == HVACMode.HEAT
assert entity._saved_preset_mode == PRESET_ACTIVITY
assert entity.window_state is STATE_OFF
# 5 Back to Auto
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
) as mock_send_event:
event_timestamp = event_timestamp + timedelta(minutes=1)
await select_entity.async_select_option(CENTRAL_MODE_AUTO)
assert mock_send_event.call_count == 1
mock_send_event.assert_has_calls(
[call.send_event(EventType.HVAC_MODE_EVENT, {"hvac_mode": HVACMode.HEAT})]
)
# We should switch back to HEAT
assert entity.hvac_mode == HVACMode.HEAT
assert entity.preset_mode == PRESET_ACTIVITY
assert entity._saved_hvac_mode == HVACMode.HEAT
assert entity._saved_preset_mode == PRESET_ACTIVITY
assert entity.window_state is STATE_OFF
async def test_switch_change_central_mode_true_with_cool_only_and_window(
hass: HomeAssistant, skip_hass_states_is_state, init_central_config
):
"""test that changes with over_switch config with central_mode True are
taken into account"""
# Add a Switch VTherm
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_USE_CENTRAL_MODE: True,
CONF_CYCLE_MIN: 5,
CONF_TEMP_MIN: 8,
CONF_TEMP_MAX: 18,
"frost_temp": 10,
"eco_temp": 17,
"comfort_temp": 18,
"boost_temp": 21,
CONF_USE_WINDOW_FEATURE: True,
CONF_USE_MOTION_FEATURE: True,
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_SECURITY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
CONF_SECURITY_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",
CONF_MOTION_DELAY: 10,
CONF_MOTION_OFF_DELAY: 30,
CONF_MOTION_PRESET: PRESET_BOOST,
CONF_NO_MOTION_PRESET: PRESET_ECO,
},
)
tz = get_tz(hass) # pylint: disable=invalid-name
event_timestamp = datetime.now(tz)
# 1 initialize entity and find select entity
with patch("homeassistant.core.ServiceRegistry.async_call"):
entity: ThermostatOverSwitch = await create_thermostat(
hass, entry, "climate.theoverswitchmockname"
)
assert entity
assert entity.is_controlled_by_central_mode
assert entity.last_central_mode is None
# Find the select entity
select_entity = search_entity(hass, "select.central_mode", SELECT_DOMAIN)
assert select_entity
assert select_entity.current_option == CENTRAL_MODE_AUTO
assert select_entity.options == CENTRAL_MODES
# start entity
await entity.async_set_hvac_mode(HVACMode.HEAT)
await entity.async_set_preset_mode(PRESET_ACTIVITY)
assert entity.hvac_mode == HVACMode.HEAT
assert entity.preset_mode == PRESET_ACTIVITY
assert entity.window_state is STATE_OFF
# 2 Change central_mode to COOL_ONLY
with patch("homeassistant.core.ServiceRegistry.async_call"):
event_timestamp = event_timestamp + timedelta(minutes=1)
entity._set_now(event_timestamp)
await select_entity.async_select_option(CENTRAL_MODE_COOL_ONLY)
assert entity.last_central_mode is CENTRAL_MODE_COOL_ONLY
await entity.async_set_hvac_mode(HVACMode.OFF)
await entity.async_set_preset_mode(PRESET_ACTIVITY)
assert entity._saved_hvac_mode == HVACMode.HEAT
assert entity._saved_preset_mode == PRESET_ACTIVITY
# 3 Open the window
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
) as mock_send_event, patch(
"homeassistant.helpers.condition.state", return_value=True
):
event_timestamp = event_timestamp + timedelta(minutes=1)
try_function = await send_window_change_event(
entity, True, False, event_timestamp
)
await try_function(None)
assert mock_send_event.call_count == 1
mock_send_event.assert_has_calls(
[call.send_event(EventType.HVAC_MODE_EVENT, {"hvac_mode": HVACMode.OFF})]
)
assert entity.hvac_mode == HVACMode.OFF
assert entity.preset_mode == PRESET_ACTIVITY
assert entity._saved_hvac_mode == HVACMode.HEAT
assert entity._saved_preset_mode == PRESET_ACTIVITY
assert entity.window_state is STATE_ON
# 4 Change central_mode to AUTO
with patch("homeassistant.core.ServiceRegistry.async_call"):
event_timestamp = event_timestamp + timedelta(minutes=1)
entity._set_now(event_timestamp)
await select_entity.async_select_option(CENTRAL_MODE_AUTO)
assert entity.last_central_mode is CENTRAL_MODE_AUTO
# No change
assert entity.hvac_mode == HVACMode.OFF
assert entity.preset_mode == PRESET_ACTIVITY
assert entity._saved_hvac_mode == HVACMode.HEAT
assert entity._saved_preset_mode == PRESET_ACTIVITY
# 5 Close the window
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
) as mock_send_event, patch(
"homeassistant.helpers.condition.state", return_value=True
):
event_timestamp = event_timestamp + timedelta(minutes=1)
try_function = await send_window_change_event(
entity, False, True, event_timestamp
)
await try_function(None)
# hvac_mode change to HEAT
assert mock_send_event.call_count == 1
mock_send_event.assert_has_calls(
[call.send_event(EventType.HVAC_MODE_EVENT, {"hvac_mode": HVACMode.HEAT})]
)
# We should stay off because central is STOPPED
assert entity.hvac_mode == HVACMode.HEAT
assert entity.preset_mode == PRESET_ACTIVITY
assert entity._saved_hvac_mode == HVACMode.HEAT
assert entity._saved_preset_mode == PRESET_ACTIVITY
assert entity.window_state is STATE_OFF

View File

@@ -472,7 +472,7 @@ async def test_multiple_climates_underlying_changes(
skip_hass_states_is_state,
skip_send_event,
): # pylint: disable=unused-argument
"""Test that when multiple climate are configured the activation of one underlying
"""Test that when multiple switch are configured the activation of one underlying
climate activate the others"""
tz = get_tz(hass) # pylint: disable=invalid-name
@@ -541,15 +541,11 @@ async def test_multiple_climates_underlying_changes(
assert entity.is_device_active is False # pylint: disable=protected-access
# Stop heating on one underlying climate
# All underlying supposed to be aligned with the hvac_mode now
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.async_control_heating"
), patch(
"custom_components.versatile_thermostat.underlyings.UnderlyingClimate.set_hvac_mode"
) as mock_underlying_set_hvac_mode, patch(
"custom_components.versatile_thermostat.underlyings.UnderlyingClimate.hvac_mode",
HVACMode.HEAT,
):
) as mock_underlying_set_hvac_mode:
# Wait 11 sec so that the event will not be discarded
event_timestamp = now + timedelta(seconds=11)
await send_climate_change_event(
@@ -559,7 +555,6 @@ async def test_multiple_climates_underlying_changes(
HVACAction.OFF,
HVACAction.HEATING,
event_timestamp,
underlying_entity_id="switch.mock_climate3",
)
# Should be call for all Switch
@@ -582,9 +577,6 @@ async def test_multiple_climates_underlying_changes(
# a function but a property
"custom_components.versatile_thermostat.underlyings.UnderlyingClimate.hvac_action",
HVACAction.IDLE,
), patch(
"custom_components.versatile_thermostat.underlyings.UnderlyingClimate.hvac_mode",
HVACMode.OFF,
):
# Wait 11 sec so that the event will not be discarded
event_timestamp = now + timedelta(seconds=11)
@@ -609,113 +601,6 @@ async def test_multiple_climates_underlying_changes(
assert entity.is_device_active is False # pylint: disable=protected-access
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize("expected_lingering_timers", [True])
async def test_multiple_climates_underlying_changes_not_aligned(
hass: HomeAssistant,
skip_hass_states_is_state,
skip_send_event,
): # pylint: disable=unused-argument
"""Test that when multiple climate are configured the activation of one underlying
climate don't activate the others if their havc_mode are not aligned"""
tz = get_tz(hass) # pylint: disable=invalid-name
now: datetime = datetime.now(tz=tz)
entry = MockConfigEntry(
domain=DOMAIN,
title="TheOver4ClimateMockName",
unique_id="uniqueId",
data={
CONF_NAME: "TheOver4ClimateMockName",
CONF_THERMOSTAT_TYPE: CONF_THERMOSTAT_CLIMATE,
CONF_TEMP_SENSOR: "sensor.mock_temp_sensor",
CONF_EXTERNAL_TEMP_SENSOR: "sensor.mock_ext_temp_sensor",
CONF_CYCLE_MIN: 8,
CONF_TEMP_MIN: 15,
CONF_TEMP_MAX: 30,
"eco_temp": 17,
"comfort_temp": 18,
"boost_temp": 19,
CONF_USE_WINDOW_FEATURE: False,
CONF_USE_MOTION_FEATURE: False,
CONF_USE_POWER_FEATURE: False,
CONF_USE_PRESENCE_FEATURE: False,
CONF_CLIMATE: "switch.mock_climate1",
CONF_CLIMATE_2: "switch.mock_climate2",
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,
},
)
entity: BaseThermostat = await create_thermostat(
hass, entry, "climate.theover4climatemockname"
)
assert entity
assert entity.is_over_climate is True
assert entity.nb_underlying_entities == 4
# start heating, in boost mode. We block the control_heating to avoid running a cycle
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.async_control_heating"
), patch(
"custom_components.versatile_thermostat.underlyings.UnderlyingClimate.set_hvac_mode"
) as mock_underlying_set_hvac_mode:
await entity.async_set_hvac_mode(HVACMode.HEAT)
await entity.async_set_preset_mode(PRESET_BOOST)
assert entity.hvac_mode is HVACMode.HEAT
assert entity.preset_mode is PRESET_BOOST
assert entity.target_temperature == 19
assert entity.window_state is STATE_OFF
event_timestamp = now - timedelta(minutes=4)
await send_temperature_change_event(entity, 15, event_timestamp)
# Should be call for all Switch
assert mock_underlying_set_hvac_mode.call_count == 4
mock_underlying_set_hvac_mode.assert_has_calls(
[
call.set_hvac_mode(HVACMode.HEAT),
]
)
# Stop heating on one underlying climate
# All underlying supposed to be aligned with the hvac_mode now
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.async_control_heating"
), patch(
"custom_components.versatile_thermostat.underlyings.UnderlyingClimate.set_hvac_mode"
) as mock_underlying_set_hvac_mode, patch(
"custom_components.versatile_thermostat.underlyings.UnderlyingClimate.hvac_mode",
HVACMode.COOL,
):
# Wait 11 sec so that the event will not be discarded
event_timestamp = now + timedelta(seconds=11)
await send_climate_change_event(
entity,
HVACMode.OFF,
HVACMode.HEAT,
HVACAction.OFF,
HVACAction.HEATING,
event_timestamp,
underlying_entity_id="switch.mock_climate3",
)
# Should be call for all Switch
assert mock_underlying_set_hvac_mode.call_count == 0
# mock_underlying_set_hvac_mode.assert_has_calls(
# [
# call.set_hvac_mode(HVACMode.OFF),
# ]
# )
# No change
assert entity.hvac_mode == HVACMode.HEAT
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize("expected_lingering_timers", [True])
async def test_multiple_switch_power_management(

View File

@@ -288,7 +288,7 @@ async def test_security_feature_back_on_percent(
assert entity.security_state is False
assert mock_send_event.call_count == 0
# 3. Set safety mode with a preset change
# 3. Set security mode with a preset change
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
) as mock_send_event, patch(
@@ -400,7 +400,7 @@ async def test_security_over_climate(
skip_turn_on_off_heater,
skip_send_event,
):
"""Test that when a underlying climate is not available the VTherm doesn't go into safety mode"""
"""Test that when a underlying climate is not available the VTherm doesn't go into security mode"""
tz = get_tz(hass) # pylint: disable=invalid-name
now: datetime = datetime.now(tz=tz)
@@ -471,7 +471,7 @@ async def test_security_over_climate(
assert mock_find_climate.mock_calls[0] == call()
mock_find_climate.assert_has_calls([call.find_underlying_entity()])
# Force safety mode
# Force security mode
assert entity._last_ext_temperature_measure is not None
assert entity._last_temperature_measure is not None
assert (
@@ -505,7 +505,7 @@ async def test_security_over_climate(
event_timestamp = now - timedelta(minutes=6)
await send_temperature_change_event(entity, 15, event_timestamp)
# Should stay False because a climate is never in safety mode
# Should stay False because a climate is never in security mode
assert entity.security_state is False
assert entity.preset_mode == "none"
assert entity._saved_preset_mode == "none"

View File

@@ -1,4 +1,4 @@
# pylint: disable=unused-argument, line-too-long, protected-access, too-many-lines
# pylint: disable=unused-argument, line-too-long, protected-access
""" Test the Window management """
import asyncio
import logging
@@ -295,7 +295,6 @@ async def test_window_auto_fast(hass: HomeAssistant, skip_hass_states_is_state):
assert entity.target_temperature == 21
assert entity.window_state is STATE_OFF
assert entity.is_window_auto_enabled is True
# Initialize the slope algo with 2 measurements
event_timestamp = now + timedelta(minutes=1)
@@ -432,125 +431,6 @@ async def test_window_auto_fast(hass: HomeAssistant, skip_hass_states_is_state):
entity.remove_thermostat()
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize("expected_lingering_timers", [True])
async def test_window_auto_fast_and_sensor(
hass: HomeAssistant, skip_hass_states_is_state
):
"""Test that the auto-window detection algorithm is deactivated if a window sensor is provided"""
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,
"eco_temp": 17,
"comfort_temp": 18,
"boost_temp": 21,
CONF_USE_WINDOW_FEATURE: True,
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_SECURITY_DELAY_MIN: 5,
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
CONF_WINDOW_SENSOR: "binary_sensor.fake_window_sensor",
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
},
)
entity: BaseThermostat = await create_thermostat(
hass, entry, "climate.theoverswitchmockname"
)
assert entity
tz = get_tz(hass) # pylint: disable=invalid-name
now = datetime.now(tz)
tpi_algo = entity._prop_algorithm
assert tpi_algo
await entity.async_set_hvac_mode(HVACMode.HEAT)
await entity.async_set_preset_mode(PRESET_BOOST)
assert entity.hvac_mode is HVACMode.HEAT
assert entity.preset_mode is PRESET_BOOST
assert entity.target_temperature == 21
assert entity.window_state is STATE_OFF
assert entity.is_window_auto_enabled is False
# Initialize the slope algo with 2 measurements
event_timestamp = now + timedelta(minutes=1)
await send_temperature_change_event(entity, 19, event_timestamp)
event_timestamp = event_timestamp + timedelta(minutes=1)
await send_temperature_change_event(entity, 19, event_timestamp)
event_timestamp = event_timestamp + timedelta(minutes=1)
await send_temperature_change_event(entity, 19, event_timestamp)
# Make the temperature down
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
) as mock_send_event, patch(
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
) as mock_heater_on, patch(
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
) as mock_heater_off, patch(
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
return_value=True,
):
event_timestamp = event_timestamp + timedelta(minutes=1)
await send_temperature_change_event(entity, 19, event_timestamp)
# The heater don't turns on
assert mock_send_event.call_count == 0
assert entity.is_device_active is True
assert entity.last_temperature_slope == 0.0
assert entity._window_auto_algo.is_window_open_detected() is False
assert entity._window_auto_algo.is_window_close_detected() is False
assert entity.hvac_mode is HVACMode.HEAT
# send one degre down in one minute
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
) as mock_send_event, patch(
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
) as mock_heater_on, patch(
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
) as mock_heater_off, patch(
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
return_value=True,
):
event_timestamp = event_timestamp + timedelta(minutes=1)
await send_temperature_change_event(entity, 18, event_timestamp)
assert mock_send_event.call_count == 0
assert mock_heater_on.call_count == 0 # no change in heater
assert mock_heater_off.call_count == 0 # no change in heater
assert entity.last_temperature_slope == -6.24
# The window open should be detected (but not used)
# because we need to calculate the slope anyway, we have the algorithm running
assert entity._window_auto_algo.is_window_open_detected() is True
assert entity._window_auto_algo.is_window_close_detected() is False
assert entity.window_auto_state == STATE_OFF
assert entity.hvac_mode is HVACMode.HEAT
# Clean the entity
entity.remove_thermostat()
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize("expected_lingering_timers", [True])
async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_state):
@@ -581,7 +461,7 @@ async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_st
CONF_SECURITY_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
CONF_WINDOW_AUTO_MAX_DURATION: 0, # Should be 0 for test
},
)
@@ -604,9 +484,8 @@ async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_st
assert entity.target_temperature == 21
assert entity.window_state is STATE_OFF
assert entity.is_window_auto_enabled is True
# 1. Initialize the slope algo with 2 measurements
# Initialize the slope algo with 2 measurements
event_timestamp = now + timedelta(minutes=1)
await send_temperature_change_event(entity, 19, event_timestamp)
event_timestamp = event_timestamp + timedelta(minutes=1)
@@ -614,7 +493,7 @@ async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_st
event_timestamp = event_timestamp + timedelta(minutes=1)
await send_temperature_change_event(entity, 19, event_timestamp)
# 2. Make the temperature down
# Make the temperature down
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
) as mock_send_event, patch(
@@ -634,7 +513,7 @@ async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_st
assert entity._window_auto_algo.is_window_close_detected() is False
assert entity.hvac_mode is HVACMode.HEAT
# 3. send one degre down in one minute
# send one degre down in one minute
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
) as mock_send_event, patch(
@@ -670,14 +549,12 @@ async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_st
assert entity.window_auto_state == STATE_ON
assert entity.hvac_mode is HVACMode.OFF
# 4. This is to avoid that the slope stay under 6, else we will reactivate the window immediatly
# This is to avoid that the slope stayx under 6, else we will reactivate the window immediatly
event_timestamp = event_timestamp + timedelta(minutes=1)
dearm_window_auto = await send_temperature_change_event(
entity, 19, event_timestamp, sleep=False
)
await send_temperature_change_event(entity, 19, event_timestamp, sleep=False)
assert entity.last_temperature_slope > -6.0
# 5. Waits for automatic disable
# Waits for automatic disable
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
) as mock_send_event, patch(
@@ -686,8 +563,7 @@ async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_st
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
return_value=False,
):
# simulate the expiration of the delay
await dearm_window_auto(None)
await asyncio.sleep(0.3)
assert entity.hvac_mode is HVACMode.HEAT
assert entity.preset_mode is PRESET_BOOST
@@ -875,7 +751,6 @@ async def test_window_bypass(hass: HomeAssistant, skip_hass_states_is_state):
assert entity.target_temperature == 19
assert entity.window_state is STATE_OFF
assert entity.is_window_auto_enabled is False
# change temperature to force turning on the heater
with patch(
@@ -992,7 +867,7 @@ async def test_window_auto_bypass(hass: HomeAssistant, skip_hass_states_is_state
CONF_SECURITY_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
CONF_WINDOW_AUTO_MAX_DURATION: 0, # Should be 0 for test
},
)
@@ -1015,7 +890,6 @@ async def test_window_auto_bypass(hass: HomeAssistant, skip_hass_states_is_state
assert entity.target_temperature == 21
assert entity.window_state is STATE_OFF
assert entity.is_window_auto_enabled
# Initialize the slope algo with 2 measurements
event_timestamp = now + timedelta(minutes=1)