Quatrieme valeur : « Session », le compteur de la BORNE, celui qui vaut les
8 kWh de VRM et compte depuis le vrai debut de la charge.
Il vient de PostgreSQL et non d'InfluxDB : `sensor.evcs_hq2239dnt7p_*` n'est
pas dans les globs d'entites envoyees a InfluxDB. Plutot que de redemarrer Home
Assistant pour l'y ajouter — en pleine charge, a 4 h du matin — la valeur est
reprise de la table `session_charge`, ou elle est deja enregistree. Le panneau
passe donc en source « Mixed », chaque requete portant la sienne.
La session n'est affichee que si elle date de moins de deux heures : au-dela,
la case reste vide plutot que d'exhiber le reliquat d'une charge terminee la
veille — meme principe que la fenetre de lecture des autres panneaux.
La premiere rangee passe a sept unites de hauteur et la Batterie a neuf
colonnes : quatre et cinq valeurs cote a cote redevenaient illisibles a cinq
unites, c'est le defaut deja corrige une fois sur ce meme panneau.
54/54 requetes verifiees. Valeur attendue a l'ecran : 8,30 kWh.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Le tableau annoncait 750 Wh la ou VRM affichait 8 kWh. Ce n'etait pas une
erreur de mesure mais une erreur de SOURCE : j'integrais la puissance depuis le
moment ou mon detecteur avait commence a fonctionner — 03:16 — pour une session
ouverte a 01:25.
Or la borne tient son propre compteur de session,
`sensor.evcs_hq2239dnt7p_last_session_energy`, qui vaut exactement les 8,0 kWh
de VRM et compte depuis le vrai debut. Nouvelle colonne
`energie_station_kwh` : c'est elle qui alimente desormais les totaux et le
graphique.
Mon integration est conservee en colonne « kWh integres » : l'ecart entre les
deux signale un demarrage ou un redemarrage du service en cours de session, ce
qui est une information en soi. Et elle sert de secours si la borne ne publie
rien.
Cherche au passage, sans succes : VRM affiche « Vehicule : Guest EV » mais
AUCUNE entite ne porte ce champ cote Home Assistant. « Guest EV » signifie
d'ailleurs vehicule NON identifie — Victron ne sait pas non plus qui est
branche.
50/53 : les trois requetes en echec portent sur la nouvelle colonne, que la
migration creera au prochain demarrage du service.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
« No data » sur le panneau Chargeur PV a 03:20 : la production avait ete ecrite
pour la derniere fois au coucher du soleil, 370 minutes plus tot, et ma fenetre
etait de 6 h. La valeur zero etait pourtant exacte et connue.
C'est la seconde erreur sur ce meme reglage, en sens inverse de la premiere :
- trop LARGE partout (7 jours), le panneau Reseau affichait un courant vieux de
quatorze heures, parce que ces capteurs passent en `unavailable` quand AC-IN
s'ouvre au lieu de tomber a zero ;
- trop ETROITE partout (6 heures), les entites qui publient un vrai zero au
repos disparaissent de l'ecran alors que leur derniere valeur reste juste.
Il n'y a donc pas de bonne valeur unique. Regle inscrite dans le generateur :
fenetre LARGE (24 h) pour ce qui publie un vrai zero — production PV, borne a
l'arret, trackers ; fenetre COURTE (6 h) pour ce qui disparait, c'est-a-dire
les seules grandeurs du reseau.
Consigne au passage dans le manuel : le proprietaire possede une troisieme
monture, une moto electrique Zero Motorcycles SR/F, a ajouter au selecteur fin
septembre. Avec la remarque qui compte : sa batterie et son chargeur embarque
etant bien plus petits, elle sera peut-etre le premier vehicule du foyer
electriquement distinguable des deux autres.
53/53 requetes verifiees.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Demande du proprietaire : voir ce que la JEEP ou la VW encaisse dans une
session, et evaluer sur une periode (jour, semaine, mois), en assumant
l'imprecision liee a l'impossibilite d'identifier le vehicule au branchement.
Trois panneaux : les totaux par vehicule sur la periode, l'energie par periode
et par vehicule avec le meme pas adaptatif que les autres tableaux (heure /
jour / mois), et la liste des sessions.
L'incertitude est AFFICHEE plutot que masquee :
- un compteur « Etiquette douteuse » — sessions ou le selecteur a change en
cours de route, ou n'etait pas renseigne ;
- une colonne « Doute » dans le tableau ;
- une serie « Non etiquete » dans le graphique ;
- l'heure de debranchement, qui confirme apres coup puisque les deux vehicules
partent a des heures differentes.
Le commentaire du generateur consigne pourquoi aucune verification n'est
possible : electriquement les deux voitures sont indiscernables (3 680 contre
3 655 W a consigne identique de 20 A), et horairement la routine s'inverse le
week-end, donc une regle horaire serait fausse un week-end sur deux.
Ajout a la table : `energie_reseau_kwh`, la part venue du reseau, fondee sur le
`source_mode` du controleur — son intention — et non sur la puissance reseau
instantanee, laquelle peut alimenter la maison pendant que le soleil alimente
la voiture.
52/53 requetes verifiees. La seule en echec porte sur cette nouvelle colonne,
que la migration creera au prochain demarrage du service.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Effet de bord du correctif precedent : pour montrer les alarmes, qui sont du
texte, j'avais mis « fields: /.*/ » — ce qui fait aussi remonter la colonne
_time des requetes Flux, affichee en gros au-dessus de chaque valeur.
Un panneau stat n'a besoin d'aucun champ temporel. Les requetes ne renvoient
plus que la valeur. Applique a tous les panneaux stat, pas seulement au BMS :
_time n'y servait a rien et restait un piege latent, invisible tant que le
reglage « champs numeriques seulement » le masquait.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Le filtre de vue fonctionne sur le graphique en barres — la capture du
proprietaire montrait bien « Solaire, Voiture » seuls — et echouait sur « Les
flux » avec « Data is missing a time field ». La seule difference entre les
deux etait le format de sortie : `table` d'un cote, `time_series` de l'autre.
Un panneau time series accepte parfaitement une trame de type table des lors
qu'elle porte une colonne temporelle, et le rendu est identique. On aligne donc
« Les flux » sur le format dont on a la PREUVE qu'il se laisse filtrer, plutot
que de continuer a deviner comment `time_series` nomme son champ temporel.
Changement circonscrit a ce seul panneau : les trois autres tableaux utilisent
le meme generateur de requete, n'ont pas de filtre de vue, et restent en
time_series.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
1. « Data is missing a time field » sur Les flux. Mon filtre de vue laissait
passer « time » en minuscules, or la source PostgreSQL nomme le champ
temporel « Time » avec une majuscule dans le format time_series. Le filtre
supprimait donc l'axe des temps. Les deux graphies sont desormais acceptees.
2. Les deux alarmes du panneau BMS n'apparaissaient pas. Un panneau stat ne
reduit que les champs NUMERIQUES par defaut, et « no_alarm » est du texte :
il faut "/.*/" pour l'afficher. Applique a ce seul panneau — les autres
n'ont que des nombres et le reglage par defaut y est correct.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Trois demandes du proprietaire apres usage reel.
1. SELECTEUR DE VUE. Variable « vue » en haut du tableau, dans l'esprit de VRM :
Vue generale / Consommation / Reseau / Batterie / Chargeur VE. La valeur de
chaque option est directement une alternative d'expression reguliere,
consommee par la transformation filterFieldsByName des deux graphiques —
d'ou le separateur « | ». Un seul jeu de requetes, cinq lectures.
2. PAS ADAPTATIF. L'histogramme d'energie suit desormais la periode choisie :
l'heure jusqu'a 4 jours, le jour jusqu'a 70, le mois au-dela. Sans cela
« 30 derniers jours » rendait 720 barres illisibles. C'est ce que fait VRM
en passant de l'heure au jour puis au mois.
3. PANNEAU BATTERIE ILLISIBLE — un defaut que j'avais cree. Cinq valeurs dans
huit colonnes : Grafana reduisait le texte jusqu'a l'illisible. Porte a dix
colonnes avec une taille imposee, plutot que de laisser l'ajustement
automatique decider. Reseau et Charges CA resserres en consequence.
Ajout lie a la panne en cours : panneau « Ce que le BMS impose » — limite de
courant de charge, alarme de tension de cellule, desequilibre, etat de sante.
C'est ce qu'il faudra regarder cet apres-midi.
Sa fenetre de lecture est de 48 h, deliberement differente des 6 h du reste :
un etat d'alarme ne devient jamais indisponible, il se publie, donc sa derniere
valeur EST la valeur courante meme vieille de dix heures. A l'inverse du
courant reseau, dont le capteur disparait et laisse un chiffre qui ment.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Trois defauts signales par le proprietaire sur une capture prise a 00:04.
1. FENETRE GLISSANTE. La plage etait « aujourd'hui » : a 00:04 il n'y avait que
quatre minutes a montrer. Passee a 24 h glissantes. Les etiquettes d'heure
portent desormais le jour, sans quoi « 22 h » designerait deux heures
differentes dans la meme fenetre.
2. VALEUR PERIMEE PRESENTEE COMME ACTUELLE — le vrai defaut. Le panneau Reseau
affichait « Courant 2,2 A » : ecrit QUATORZE HEURES plus tot, du temps ou le
contacteur etait ferme, alors qu'il est ouvert depuis 10:08. Cause : ma
fenetre de lecture de 7 jours, posee pour eviter les cases vides.
Les capteurs du reseau passent en `unavailable` quand AC-IN disparait ; ils
ne tombent pas a zero. Leur derniere valeur numerique reste donc celle
d'avant. Fenetre ramenee a 6 h : assez large pour couvrir une nuit sans
soleil et une borne au repos — dont les zeros sont VRAIS — assez etroite
pour ecarter une lecture de quatorze heures.
3. Une absence de mesure s'affiche desormais comme un tiret, jamais comme zero.
Verifie apres coup sur les valeurs reelles : Reseau Courant = tiret (la valeur
fausse a disparu), Chargeur PV = 0 W et Chargeur VE = 0 A conserves puisque
justes, Batterie et Charges CA en direct.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
La console VRM est hebergee dans le cloud Victron et disparait quand une
coupure d'orage emporte Internet. Meme vision, lue sur le reseau local :
reseau, charges, batterie, borne, production, detail par tracker, les flux
dans le temps et l'energie heure par heure.
Tout dans Grafana, rien dans Home Assistant — et pour une raison trouvee en
verifiant si son tableau Energie pouvait servir : gx_device_pv_energy et les
compteurs d'energie batterie du GX se remettent a zero sans le signaler.
state_class total sans last_reset, donc HA n'auto-detecte pas la remise a zero
et a enregistre -373,35 kWh sur l'heure de 07:00. Les energies sont donc
obtenues en INTEGRANT LA PUISSANCE, methode qui ignore le probleme.
Trois versions du calcul avant la bonne : somme ponderee (laissait des trous,
une grandeur stable n'etant jamais reecrite), moyenne des minutes presentes
(sur-comptait : 5,13 kWh a 01 h pour 22 minutes observees), puis axe des
minutes complet + report + avg x count/60 = energie reellement accumulee,
correcte y compris pour l'heure en cours.
Recoupement avec la capture VRM du proprietaire : 8,07 kWh de reseau contre
"Depuis reseau 9,0 kWh", l'ecart valant exactement les treize minutes entre
l'ouverture des heures creuses et le demarrage du service d'historisation.
45/45 requetes verifiees contre les bases reelles.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
L'application Grafana de l'App Store ne parle qu'a Grafana Cloud ; une instance
auto-hebergee se consulte au navigateur, epingle sur l'ecran d'accueil. Reste
que les trois tableaux existants sont dessines pour un ecran large.
Contrainte de conception, verifiee et notee dans le README : sous ~770 px,
Grafana passe CHAQUE panneau en pleine largeur et les empile. Le nombre de
panneaux devient le nombre d'ecrans a faire defiler. D'ou six panneaux
seulement, et les chiffres regroupes dans deux panneaux "stat" — plusieurs
valeurs dans un meme panneau restent cote a cote, la ou six panneaux separes
auraient fait six ecrans.
La reponse d'abord : batterie, marge (ce qu'elle a moins ce qu'il lui faut),
excedent. Puis l'energie a couvrir et l'heure du relais solaire. Puis les deux
courbes qui expliquent ces chiffres, la frise du reseau, et les huit derniers
evenements.
26/26 requetes verifiees contre les bases reelles.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Trois defauts trouves en LISANT les tableaux, qu'aucune des 19 requetes ne
signalait puisqu'elles s'executaient toutes sans erreur.
1. `historise-evcs.mjs` horodate chaque mesure avec son propre last_updated —
le vrai instant de la mesure, et c'est le bon choix. Mais deux grandeurs ne
partagent alors presque jamais le meme ts : 2656 lignes pour 2656 instants
distincts. Mes GROUP BY ts rendaient une ligne par grandeur avec une seule
colonne remplie, donc la courbe "Excedent" — la grandeur meme du §36 —
etait VIDE sur les 2650 lignes.
2. Le service n'ecrit que les changements, donc un regroupement a la minute
laisse des trous : la difference n'existait que 73 minutes sur 434. Report
de la derniere valeur connue, ce que fait aussi le controleur en temps
reel. 430/435 apres.
3. L'energie horaire par sum(valeur)/60 suppose 60 echantillons par heure ; il
y en a eu 26 a 47. Integration ponderee par la duree, plafonnee a 300 s
pour qu'un arret du service n'extrapole pas une valeur perimee. ~9 %
d'ecart. Le "25 a 58 %" que j'avais d'abord annonce etait faux : il
comparait la somme a la moyenne, qui ignore la duree.
Plus deux corrections d'affichage : la colonne `jour` s'affichait
"2026-09-04 02:00:00" (date nue rendue comme instant UTC), et le decompte des
chargeurs MPPT est de six entites publiees, pas sept.
Lecon : verifier-dashboards.mjs prouve qu'une requete s'EXECUTE, pas qu'elle
rend la grandeur voulue — une colonne integralement nulle passe sans un mot.
Ce sont les courbes regardees a l'ecran qui ont attrape les trois.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Grafana journalise au niveau ERREUR l'absence des dossiers de provisionnement
`plugins/` et `alerting/`, que ce deploiement n'utilise pas. Le service
demarre et fonctionne parfaitement, mais un journal qui crie au loup apprend a
etre ignore — et celui-la sera lu pour comprendre un incident.
Deux dossiers vides, avec un .gitkeep qui explique pourquoi ils existent
(git ne versionne pas les dossiers vides). Effet au prochain demarrage du
conteneur, rien d'urgent.
Deploiement verifie en reel : Grafana repond 200 sur http://10.10.10.22:3001,
database ok, provisionnement des tableaux termine sans erreur.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Trois tableaux de bord provisionnes depuis git, sur le modele de la regle R2
(le depot est la source de verite, l'interface ne peut pas les ecraser) :
La nuit SOC reel contre SOC exige par le bilan, et la marge entre les
deux. C'est la question qui avait demande une nuit d'archeologie
le 03/09.
Le solaire l'excedent (§36), la censure, et le mode declare par chacun des
sept chargeurs (§37) — le signal le plus direct dont on dispose.
Prevision l'ecart heure par heure, avec la bande de censure dessous : une
production sous la prevision peut vouloir dire mauvaise
prevision OU absence de preneur.
Les evenements de la table `evenement` deviennent des marqueurs verticaux sur
tous les graphiques — une courbe sans ses evenements ne s'interprete pas.
tools/verifier-dashboards.mjs rejoue CHAQUE requete pour de vrai (SQL contre
PostgreSQL, Flux contre InfluxDB, macros Grafana substituees), annotations
comprises puisqu'elles s'executent sur tous les panneaux. Sans lui une requete
cassee ne se voit qu'a l'ecran, panneau par panneau. 19/19 au deploiement.
Port 3001 et non 3000 : sonde avant d'ecrire la ligne, quelque chose ecoute
deja sur 3000 — la lecon du 5432 deja pris par le PostgreSQL de DSM.
Connexion PostgreSQL par le role evcs_lecture : un tableau de bord ne doit pas
pouvoir ecrire dans la memoire. Aucun secret duplique, aucun secret commite :
le provisionnement les reference par $VARIABLE depuis les deux .env.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ