136 lines
7.8 KiB
Markdown
136 lines
7.8 KiB
Markdown
# Chauffage radiateurs — AppDaemon et C6
|
||
|
||
L'app `radiator_heating` expose `climate.radiator_heating` par MQTT Discovery.
|
||
La version MQTT directe utilise le plugin MQTT d'AppDaemon pour les publications
|
||
et les abonnements. Le plugin Home Assistant sert à lire les thermomètres.
|
||
Les commandes du climate et les retours C6 restent sur les mêmes topics.
|
||
|
||
## Configuration MQTT
|
||
|
||
Le plugin `MQTT` est configuré dans `appdaemon.yaml`, namespace `mqtt`.
|
||
Les identifiants du broker sont dans `secrets.yaml` (exclu de Git) et référencés
|
||
par `!secret`. Ils doivent être sauvegardés séparément pour une réinstallation.
|
||
Un redémarrage complet du conteneur/service AppDaemon est nécessaire pour charger
|
||
un nouveau plugin ; le rechargement des apps ne suffit pas.
|
||
|
||
Le climate et son watchdog exigent ce plugin. Les deux anciennes automatisations
|
||
Home Assistant ont été supprimées après vérification des commandes et de la
|
||
télémétrie en MQTT direct. Aucun relais MQTT dans Home Assistant n'est nécessaire.
|
||
|
||
## Fichiers
|
||
|
||
- `apps/boilerclimate.py` : MQTT Discovery, consigne, mode, mesures et commandes.
|
||
- `apps/boilerwatchdog.py` : surveillance indépendante du heartbeat.
|
||
- `apps/boilerregulator.py` : calcul indépendant de la température d'eau.
|
||
- `apps/global/heating.yaml`, blocs `radiator_heating` et
|
||
`radiator_heating_watchdog` : paramètres actifs des deux apps.
|
||
- `appdaemon.yaml`, plugin `MQTT` : connexion broker, abonnements et Last Will.
|
||
|
||
## Régulation
|
||
|
||
Avec S la consigne ambiante, Ti la température du couloir et Te la plus basse
|
||
des températures extérieures (`sensor.ext_front_temperature` et
|
||
`sensor.ext_back_temperature`, configurées dans `outdoor_sensors`) :
|
||
|
||
courbe = S + pente × (S − Te) + décalage
|
||
correction P = kp × (S − Ti)
|
||
correction I += ki × (S − Ti) × durée_en_heures
|
||
demande = courbe + correction bornée(P + I)
|
||
|
||
La sortie est arrondie au demi-degré et limitée entre 30 et 50 °C initialement.
|
||
`ki` est exprimé en degrés d'eau par degré d'écart intérieur et par heure.
|
||
Les bornes de sortie et de correction disposent d'une protection anti-windup.
|
||
L'intégrale est remise à zéro à l'arrêt, en cas de mesure invalide, au changement
|
||
manuel de consigne et au redémarrage. Consigne et mode sont persistés dans
|
||
`apps/data/appdaemon_radiator_heating.json`, exclu de Git.
|
||
Une sauvegarde absente au premier lancement utilise la configuration initiale.
|
||
Une sauvegarde illisible ou invalide impose le mode `off` avec un avertissement.
|
||
Une erreur d'écriture est journalisée sans bloquer la commande chaudière,
|
||
notamment l'arrêt demandé par l'utilisateur ou l'arrêt ordonné de l'app.
|
||
|
||
À l'équilibre, la chauffe peut rester demandée même lorsque Ti = S.
|
||
L'app inhibe le chauffage si Ti >= S + 0,5 °C, ou si la demande calculée descend
|
||
sous la température minimale utile (avec une hystérésis de 1 °C d'eau).
|
||
Après arrêt, le redémarrage exige Ti <= S + 0,1 °C et une demande suffisante.
|
||
Les gains sont des valeurs initiales à ajuster après les essais de circulation,
|
||
pas des coefficients identifiés pour cette maison.
|
||
|
||
Le capteur intérieur et les deux capteurs extérieurs doivent fournir des valeurs
|
||
finies en °C, entre −40 et 60 °C. Le minimum extérieur est recalculé à chaque
|
||
mise à jour de l'un des capteurs et à chaque cycle. L'attribut `outdoor_sensors`
|
||
liste les sondes utilisées et `outdoor_sensor` identifie celle sélectionnée.
|
||
Si l'une des sondes est invalide, le chauffage reste inhibé comme auparavant.
|
||
La configuration historique `outdoor_sensor` reste acceptée pour une seule sonde.
|
||
Une température inchangée, même ancienne, reste valide : ces sondes peuvent
|
||
ne publier qu'en cas de changement. Aucun délai sur l'âge de la mesure n'est
|
||
appliqué. Les états indisponibles/inconnus, les valeurs invalides et les unités
|
||
incorrectes provoquent toujours l'inhibition. Une sonde déconnectée conservant
|
||
une valeur plausible n'est donc pas détectée par ce contrôle.
|
||
|
||
Un défaut publie un log ERROR avec l'identifiant, le nom du capteur et sa cause
|
||
(état invalide, unité ou valeur incohérente). Le log est émis
|
||
à l'apparition du défaut ou au changement des capteurs concernés, sans répétition
|
||
chaque minute. Le détail actualisé reste disponible dans l'attribut `sensor_error`
|
||
du capteur « État de la régulation », même quand le climate est indisponible.
|
||
Un log INFO signale le rétablissement. L'app utilise le pipeline standard
|
||
`LoggerInterface` (`log_info`, `log_warning`, `log_error`) ; les erreurs sont
|
||
également envoyées dans `error_log`. L'option `ascii_encode=False`, propre à
|
||
cette app, conserve les accents et le symbole °C.
|
||
|
||
## MQTT et disponibilité
|
||
|
||
- Configuration : `homeassistant/climate/appdaemon_radiator_heating/config`.
|
||
- Commandes utilisateur : `appdaemon/radiator_heating/command/mode` (`heat`/`off`)
|
||
et `/command/temperature` (consigne ambiante entre 10 et 23 °C).
|
||
- État et diagnostics : `appdaemon/radiator_heating/state` et `/attributes`.
|
||
- Chaudière : `themaplus-condens/bai/SetMode/set`.
|
||
|
||
Le plugin transmet les commandes MQTT et les retours chaudière à l'événement
|
||
`MQTT_MESSAGE` du namespace `mqtt`, écouté directement par l'app. Le watchdog
|
||
AppDaemon marque le climate indisponible après trois minutes sans heartbeat
|
||
(vérification toutes les dix secondes). Il ne commande PAS la chaudière.
|
||
Il utilise un worker distinct du climate. Il publie `offline` au démarrage et
|
||
après reconnexion tant qu'aucun heartbeat récent n'est arrivé. Seul le climate
|
||
publie `online`, selon la validité de ses mesures.
|
||
|
||
La disponibilité MQTT Discovery exige simultanément la disponibilité de l'app
|
||
(`/availability`) et celle de la connexion MQTT (`/connection`). Le plugin
|
||
publie `online` sur `/connection` à la connexion, et le broker publie `offline`
|
||
via le Last Will si cette connexion est perdue. Ce mécanisme ne garantit pas
|
||
une détection immédiate et ne coupe pas le chauffage. Configuration et états
|
||
sont retenus ; les commandes utilisateur et chaudière ne doivent jamais l'être.
|
||
Une reconnexion MQTT republie la découverte et renouvelle la commande.
|
||
|
||
`SetMode` est renouvelé chaque minute et lors d'un changement de demande.
|
||
Les retours de télémétrie ne renouvellent pas la commande. Un arrêt ordonné
|
||
publie une inhibition du chauffage ; un crash repose sur l'expiration observée
|
||
de la commande chaudière. Les champs de consigne ECS sont `null` et les bits
|
||
d'inhibition sanitaire restent à zéro.
|
||
|
||
`heating_requested` désigne la demande de l'app. L'action `heating` du climate
|
||
n'est annoncée qu'avec un état chaudière S.04 récent et est actualisée dès
|
||
réception du statut, sans recalcul ni renouvellement de commande ; une chauffe sanitaire
|
||
n'est pas comptée comme chauffage des radiateurs. Sans télémétrie récente,
|
||
`idle` ne constitue pas une preuve d'absence de flamme : consulter aussi la
|
||
chaudière. L'écho SetMode confirme une transmission C6, pas la consigne effective.
|
||
|
||
## Essais actuels
|
||
|
||
Les écritures sont autorisées (`send_commands: true`), pont thermostat fermé.
|
||
Le climate démarre en mode `heat`, consigne 18 °C, sauf état utilisateur persisté.
|
||
Un couloir plus chaud que la consigne entraîne normalement une inhibition.
|
||
Le retour au réglage local de 10 °C après environ 15 minutes sans renouvellement
|
||
a été observé pont ouvert. L'arrêt réel après perte de communication reste à
|
||
vérifier avec circulation autorisée ; ce délai n'est pas une coupure immédiate.
|
||
|
||
Un premier essai pont fermé avec une consigne ambiante de 23 °C a produit une
|
||
demande d'eau à 46 °C et un démarrage de la chauffe. Les réglages restent à
|
||
ajuster selon l'évolution réelle des températures. Ne pas modifier les mesures
|
||
réelles pour simuler la chauffe.
|
||
`send_commands: false` permet de conserver l'interface et les calculs sans écrire
|
||
SetMode. Les lectures de télémétrie continuent.
|
||
|
||
## Vérification
|
||
|
||
python -m unittest discover -s tests -p test_boilerclimate.py -v
|