fix: publish fresh live energy at poll publication #68
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fresh-energy-publish"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Corrige la cause dominante des warnings recorder
state is not strictly increasing— celle que la PR #66 ne couvrait pas.Problème (constaté en production)
Les entités
*_total_energy(state_class: TOTAL_INCREASING) reculent ~8 fois par heure, déclenchant à chaque fois le WARNING recorder. La PR #66 a bien corrigé la réconciliation (saut des corrections backward ≤ 5 Wh) mais les reculs persistent : la réconciliation ne tourne qu'~1×/h (gateENERGY_MIN_FETCH_INTERVAL_S= 55 min) et ne peut donc pas produire 8 reculs/h.Analyse de l'historique du solaire sur 13 h (3397 points) : 108 petits reculs (81 entre 0.01–0.1 Wh, 18 entre 0.1–1, 9 entre 1–5), répartis 6 à 11 par heure, toutes les heures.
Trace live prouvant la cause (soutirage, sans aucun redémarrage) :
Mécanisme
_fetch_device_metricscaptureenergy = state.live_total_whau moment où il traite CE device._fetch_allboucle séquentiellement sur les ~21 devices, chacun faisant son I/O réseau (~0.5–1 s), et ne renvoiedevices_dataqu'à la fin (~10–20 s plus tard).DataUpdateCoordinatorremplaceself.datad'un seul coup → l'energydu 1er device est périmé de ~20 s à la publication.state.live_total_whet écritdev["energy"]viaintegrate_live_energy. La publication du poll écrase cette valeur plus récente → recul → warning.La magnitude corrèle avec la lenteur du poll : les polls rapides publient +0.0001 (inoffensif), les polls lents (dont celui de la réconciliation horaire, qui fait un appel API en plus) produisent les reculs de 1–5 Wh.
Correctif
Passe finale dans
_fetch_all, juste avant lereturn, qui relit l'énergie depuis l'état live courant :La fenêtre de péremption passe de ~10–20 s à quelques microsecondes. La garde
live_total_wh is not Nonepréserve intégralement le chemin legacy (device dont le stream n'a pas encore pris le relais)._fetch_device_metricsn'est pas modifié — son instantané sert toujours au chemin legacy et à la réconciliation ; la correction est purement au niveau de la publication.Tests
2 nouveaux (TDD RED→GREEN) : le premier simule l'avancée du stream pendant la boucle de fetch (via un
side_effectsur l'appel client du device 2 qui fait avancer l'état du device 1) et asserte que la valeur publiée est la valeur fraîche et non l'instantané périmé — il échoue avant le correctif. Le second vérifie que le chemin sans stream n'est pas écrasé. 91 tests au total, ruff + mypy clean.Périmètre
custom_components/comwatt/coordinator.py+tests/test_coordinator.pyuniquement. Basemain. Indépendante de la PR sœursave-on-stop(qui touche__init__.py).WIP: fix: publish fresh live energy at poll publicationto fix: publish fresh live energy at poll publication