diff --git a/packages/evcs_historisation.yaml b/packages/evcs_historisation.yaml new file mode 100755 index 0000000..c559e5a --- /dev/null +++ b/packages/evcs_historisation.yaml @@ -0,0 +1,80 @@ +# Detection du silence du service d'historisation (10.10.10.22) +# --------------------------------------------------------------------------- +# Pose le 16/09/2026, sur validation du proprietaire. +# +# POURQUOI CE PAQUET EXISTE. Jusqu'ici, un cycle du service en echec n'ecrivait +# que sur console.error — le journal du conteneur, que personne ne lit — et +# l'incident n'etait journalise qu'au RETOUR a la normale, dans PostgreSQL, +# c'est-a-dire jamais quand c'est PostgreSQL qui est tombe. Base injoignable : +# plus de mesures, plus d'etiquetage, et le rapport de nuit de 06:47 ne partait +# pas, sans qu'un mot ne le dise. +# +# ⚠️ POURQUOI UN CAPTEUR DEDIE ET PAS LA FRAICHEUR D'UNE ENTITE METIER. +# Mesure du 16/09 : Home Assistant ne materialise PAS une ecriture identique, et +# `last_reported` — le champ introduit en 2024 pour marquer chaque remontee +# d'etat — est rigoureusement EGAL a `last_changed`. Aucun champ de l'API ne +# distingue donc un ecrivain mort d'un ecrivain qui republie la meme valeur. +# Releve le meme jour sur une installation parfaitement saine : +# vehicle_connected inchange depuis 752 min, night_target_soc depuis 194, +# source_mode depuis 139 — trois faux positifs sur cinq entites. +# La vivacite se lit donc sur le battement SEUL, dont l'etat est un horodatage : +# il change forcement a chaque ecriture. Les entites metier se lisent pour leur +# VALEUR, jamais pour leur fraicheur. +# +# La source `sensor.evcs_historisation_heartbeat` est creee par l'API a chaque +# cycle : elle disparait au redemarrage de Home Assistant et se recree dans la +# minute. D'ou le `for:` obligatoire sur toute automatisation (voir plus bas). + +template: + - sensor: + - name: "Historisation EVCS — âge du battement" + unique_id: evcs_historisation_age_min + unit_of_measurement: "min" + state: > + {% set t = states('sensor.evcs_historisation_heartbeat') %} + {% if t not in ['unknown','unavailable',''] %} + {{ ((as_timestamp(now()) - as_timestamp(t, 0)) / 60) | round(0) }} + {% else %}unknown{% endif %} + + - binary_sensor: + # Le service tourne toutes les 60 s. Cinq minutes, c'est cinq cycles + # manques : assez long pour ignorer un hoquet, assez court pour qu'une + # panne de nuit ne coute pas une journee de mesures. + # + # Deux pannes distinctes, un seul drapeau : + # - MUET : le service ne publie plus du tout (processus mort, + # conteneur arrete, NAS eteint, reseau coupe) ; + # - DEGRADE : le service vit mais ses cycles echouent — typiquement la + # base injoignable. Le battement porte alors la cause. + - name: "Historisation EVCS — muette" + unique_id: evcs_historisation_muette + device_class: problem + state: > + {% set t = states('sensor.evcs_historisation_heartbeat') %} + {% if t in ['unknown','unavailable',''] %}on + {% elif state_attr('sensor.evcs_historisation_heartbeat','statut') == 'degrade' %}on + {% else %} + {{ (as_timestamp(now()) - as_timestamp(t, 0)) > 300 }} + {% endif %} + attributes: + statut: > + {% set t = states('sensor.evcs_historisation_heartbeat') %} + {% if t in ['unknown','unavailable',''] %}muet + {% else %}{{ state_attr('sensor.evcs_historisation_heartbeat','statut') or 'inconnu' }}{% endif %} + cause: > + {{ state_attr('sensor.evcs_historisation_heartbeat','dernier_echec') or '' }} + cycles_en_echec: > + {{ state_attr('sensor.evcs_historisation_heartbeat','cycles_en_echec') or 0 }} + +# ⚠️ TOUTE AUTOMATISATION QUI ALERTE SUR CE DRAPEAU DOIT PORTER +# for: "00:05:00" +# Le capteur source est cree par l'API : au redemarrage de Home Assistant il +# n'existe pas pendant une minute au plus, et le drapeau passe donc a `on` +# brievement a chaque redemarrage. Sans le `for:`, chaque redemarrage produirait +# une fausse alerte. +# +# ⚠️ CE QUE CE DETECTEUR NE COUVRE PAS : si 10.10.10.17 tombe, Home Assistant +# meurt avec, et ce paquet avec lui. Cette direction-la est couverte dans +# l'autre sens par le chien de garde qui tourne sur 10.10.10.22 et surveille +# n8n. Chaque machine surveille l'autre, aucune ne se surveille elle-meme ; +# aucune des deux briques n'est complete seule.