Nuit du 16 au 17/09 : neuf arrets de la charge nuit de la VW, de 30 s a 3 min,
sans que le controleur EVCS ait bouge — sa table de decision ne porte que deux
lignes sur toute la periode. Le journal de bord de Home Assistant montre le
switch de charge passant a off SANS contexte de service, donc commande depuis
le GX, puis le controleur qui reessaie au cycle suivant.
Correlation un pour un avec les actions du chien de garde, trois secondes
avant chacune, et aucune coupure sans action. Son message porte la signature :
« CONTROLEUR MUET — derniere execution il y a NaNs ».
Cause : n8n inscrit une execution AVANT de la demarrer, avec status "new" et
startedAt null. Date.parse(null) vaut NaN, et le test !(ageSec <= 600) — forme
choisie pour echouer du cote sur — declare alors mort le controleur qui vient
precisement de demarrer un cycle. Le signal de vie retourne contre lui-meme.
La fenetre dure moins d une seconde : 3 sondages sur 968 y tombent, 0,3 %. Ce
qui a change le 16/09 n est pas le code mais la PHASE du chien de garde, qui
derive d environ vingt secondes par jour et est venue se poser exactement sur
les instants de declenchement du controleur (:00 et :30) — 34 evenements ce
jour-la contre 1 a 2 les jours precedents. Le defaut dormait depuis le 01/09.
Correction a la session precedente : la nuit du 15 au 16, presentee comme
irreprochable, portait deja trois coupures dont une de trois minutes. Ce que
j avais verifie — consigne a 6 A inchangee pendant 153 min — restait exact et
ne prouvait rien : la consigne ne bouge pas quand la borne s arrete, seule la
puissance tombe.
Second defaut, latent et plus grave : CFG.idleSetpointW valait 50 W quand le
controleur est passe a 700 W le 06/09, donc dangerousSetpoint etait vrai en
permanence et chaque fausse alerte ecrasait aussi la consigne reseau a 50 W.
Sans consequence cette nuit — EDF etait ouvert — mais pendant une nuit ou le
reseau porte la maison, c est le defaut du 04/09 reintroduit.
Trois correctifs : un horodatage manquant n est plus une panne (on prend le
plus recent startedAt exploitable, repli cote sur si aucun) ; valeur de repos
portee a 700 W avec le commentaire qui dit ou vit l autre exemplaire ; et une
panne doit DURER — deux lectures consecutives avant d agir, meme doctrine que
la tolerance batterie et le relachement du contacteur.
Verification par REJEU et non par absence de symptome : le redemarrage a remis
la phase a :07, donc une nuit calme ne prouverait rien. Un serveur local
rejouant la charge JSON exacte capturee a 02:07:01 donne, code d avant,
« MUET — il y a NaNs » et les deux ecritures ; code corrige, « controleur
vivant (execution il y a 36s) » et aucune ecriture. Le filet mord toujours sur
une panne soutenue : 1/2 puis alerte et StartStop = 0 au second cycle.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Le graphe « production prevue et realisee heure par heure » du troisieme
onglet du bilan energetique ne montrait que du passe : sa courbe « prevue »
etait la prevision publiee le matin de chaque jour ECOULE, et la fenetre
s arretait a l heure en cours. C est un instrument de mesure du biais, pas
une prevision.
Deux courbes desormais, et elles n ont ni la meme provenance ni le meme
usage. Pour un jour ecoule, ce qui avait ete annonce LE MATIN MEME reste la
seule reference honnete : une prevision revisee a 18 h connait deja la
journee, la comparer au reel ne mesure plus rien. Pour les heures a venir,
c est la DERNIERE publication qui fait foi — aujourd hui jusqu au soir,
demain en entier. Les deux se touchent sur l heure en cours au lieu de
laisser un trou, et la seconde est tracee en pointilles.
Au-dela de l heure en cours, « reel » et « bridage » valent NULL et non
zero : un zero dessinerait une chute de production qui n a pas eu lieu.
Defaut trouve en chemin : l ecart moyen comptait l heure EN COURS, mesuree
sur ses seules minutes ecoulees. A 14h05 son reel vaut cinq minutes de
production contre une prevision d heure pleine, soit -92 % qui n existent
pas. La colonne `clos` l exclut. Et la serie mesuree s arrete desormais a
la minute courante et non au debut de l heure, si bien que l heure en cours
est reellement tracee au lieu de valoir zero.
Le partage aujourd hui / demain se fait en SQL, dans le fuseau deja utilise
par le reste de la requete : le conteneur repond en UTC a `date`, il ne
doit pas servir d arbitre.
Fenetre de la carte portee a hier / aujourd hui / demain (graph_span 3d,
span end day offset +1d) : sans cela la prevision, qui est justement ce
qu on veut voir, tombe hors du cadre. Verifie dans le paquet installe :
`span.offset` exige bien un signe, et l offset decale les deux bornes.
Verification en production : 47 points de prevision publies, du 17/09 01 h
au 18/09 23 h, 33,3 kWh encore attendus aujourd hui et 34,5 annonces pour
demain.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
La colonne courant_mA etait vide depuis la mise en service : le mode --modules
interroge chaque adresse avec soh <n>, qui donne les quinze tensions mais AUCUN
courant. La source juste est pwr, qui rend courant, tension et SOC pour TOUS les
modules en un seul appel — une commande serie par cycle au lieu d'une par
module.
⚠️ LE TABLEAU pwr N'A PAS LES MEMES COLONNES SELON LA FAMILLE DE MODULES.
Mesure du 16/09 : les US5000 (firmware B69.26) intercalent Tlow.Id, Thigh.Id,
Vlow.Id et Vhigh.Id que les US2000C (B69.13) n'ont pas. Un parseur a index figes
lit donc n'importe quoi des qu'on change de pack — c'est la meme famille de
piege que le trou de 44 h. Les colonnes sont resolues PAR LEUR NOM dans
l'en-tete. Les trois utiles (Volt, Curr, Coulomb) precedent Time, dont la valeur
contient une espace, donc le decoupage positionnel reste valable.
Echec de pwr non bloquant : on ecrit la ligne sans courant plutot que de perdre
les tensions, qui sont l'essentiel du releve.
Verifie sur cinq modules, trois cycles : courant et SOC par module dans le
journal et dans le CSV. Pack 2 a 13:18 — 9,5 + 9,4 + 9,0 + 9,2 + 9,1 = 46,2 A,
SOC 82/79/83/81/87 %.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
MODULES=1,2,3,4,5. Le cinquieme etait vivant et ignore depuis la mise en service
du releve : constate le 16/09, la chaine enumerait un module 5 a 50,7 V / 14,6 A
/ 80 % que personne ne lisait. Son code-barres est K220803C30160323 — le seul
module sain de l'ANCIEN parc (zero cellule marquee, zero compteur, cf. §51), que
le proprietaire a garde. Ecart de cellules 6 mV contre 2 a 4 pour les quatre
Y230202C de 2023 : acceptable.
⚠️ Il faut relancer le SUPERVISEUR et pas seulement son fils : lancer.sh lit
MODULES a son demarrage, donc tuer le processus node laisse le superviseur
relancer avec l'ancienne liste.
⚠️ TROU DE 44 H dans la table cellule, du 14/09 17:01 au 16/09 13:02, explique :
le cable console etait sur le PACK 1 pendant cette periode, et les US5000
n'emettent pas le meme tableau console que les US2000C — colonnes Tlow.Id,
Thigh.Id, Vlow.Id, Vhigh.Id presentes chez les uns, absentes chez les autres.
Le parseur du releve ne sait lire que le format US2000C : sur le pack 1 il
journalise « module N : illisible » et n'ecrit rien. Rien d'autre ne le signale.
A traiter si le releve doit un jour couvrir le pack 1.
⚠️ Et mes propres commandes console s'entrelacent avec le releveur sur le meme
port serie : la garde anti-doublon de lancer.sh ne filtre que son propre motif.
Les « illisible » de 12:42 et 12:52 sont de mon fait. Arreter le releveur avant
toute lecture manuelle.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Nuit : zero bascule du contacteur, 0,00 kWh de reseau contre 14,04 la nuit
precedente, charge terminee d'elle-meme a 6,90 kWh, reserve 7,7 kWh. Le plancher
P12 n'a jamais ete touche — il est DYNAMIQUE et descend plus vite que le SOC, ce
que j'avais mal anticipe en l'annoncant fixe a 47,1 %.
Trouvaille principale : 26 entites BMS sur 32 figees depuis 31 h, alarmes
comprises, sans que rien ne le signale. Le rechargement de l'integration
rafraichit les horodatages mais pas les valeurs. Preuve par la console serie :
41 mV de divergence a 12:30. Le battement de coeur ne couvre PAS ce cas — une
entite qui republie la meme valeur reste indetectable.
Correction d'une affirmation de la journee : mon « arithmetiquement impossible »
comparait une tension de bus a des tensions de cellule sans verifier le point de
mesure. Raisonnement faux, conclusion juste, demontree autrement.
Les deux packs debitent (99,3 A et 80,7 A pour 180 A au Cerbo) ; pack 1
irreprochable a 3 mV d'ecart entre cellules. A instruire : le pack 2, plus petit
et plus vieux, prend 2,5 fois plus de courant par ampere-heure.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Valide separement par le proprietaire le 16/09, comme la session OpenClaw et moi
l'avions demande : c'est la premiere fois qu'une reponse WhatsApp touche au
PILOTAGE et non a une etiquette consultative.
⚠️ LA LISTE BLANCHE EST DANS LE SERVICE, JAMAIS CHEZ L'AGENT — moindre
privilege : il demande, il ne decide pas de ce qui est demandable. Six ordres
admis : p12, p9, hc_nuit, strategie, vehicule, plafond_edf (borne 6-28).
Les options d'un input_select sont lues EN DIRECT sur l'entite, jamais codees en
dur : ZERO sera consomme sans modification quand la moto reviendra.
⚠️ HORS LISTE DEFINITIVEMENT : le contacteur EDF, les limites DVCC, la consigne
de puissance reseau, les planchers SOC de securite — exactement ceux qui peuvent
vider la batterie sous son plancher, la gaver sur le reseau, ou evincer le
solaire une journee entiere.
Garde supplementaire : un ordre de pilotage exige un canal HUMAIN. Une regle qui
deduit « il faudrait activer P12 » n'a rien a faire ici — c'est une decision,
pas une observation.
Interrupteur DISTINCT de celui du concierge (input_boolean.airtria_ordres_enabled,
a OFF), pour que couper le pilotage ne coupe pas l'etiquetage des vehicules.
Il gate l'ECRITURE, pas la lecture : a OFF le service journalise ce qu'il aurait
fait, ce qui permet d'eprouver la chaine avant qu'elle ne compte.
NEUF ESSAIS, tous verifies. Refuses : ordre edf, dvcc, consigne_reseau,
soc_stop_min (hors liste) · source regle-puissance (canal non humain) ·
plafond 45 A (hors bornes) · strategie « turbo » et vehicule « MEGANE » (absents
des options, listees en direct). Applique : plafond_edf 28 -> 20, journalise avec
l'etat anterieur ; rejeu du MEME confirmed_at -> ordre=0, rien ; nouveau
confirmed_at -> restauration a 28. P12 intact tout du long.
⚠️ DEFAUT TROUVE EN EPROUVANT CECI : le mode --once n'appelait pas
assurerConnexion(). Une base absente au demarrage lui donnait client = null,
donc un TypeError au lieu d'un message clair. Trouve sur un simple mauvais
numero de port. Corrige.
Carte « Agents & surveillance » completee : le guichet et son dernier ordre, a
cote du concierge et de l'etat du service.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Question du proprietaire : « il est ou cet interrupteur, dans quel dashboard ».
Reponse : celui du guichet d ordres n existe pas encore (annonce comme une
intention, pas construit). Mais la question en revele un vrai trou —
input_boolean.airtria_concierge_enabled existe depuis le 13/09 et n etait
affiche sur AUCUN tableau de bord. Il fallait passer par les outils de
developpement pour l atteindre. Un interrupteur d urgence hors de portee n en
est pas un.
La carte groupe desormais ce qui tourne tout seul et de quoi le couper :
le kill-switch du concierge, la derniere reponse WhatsApp recue, le selecteur
de vehicule qu elle pilote, et l etat du service d historisation (battement de
coeur, age, cause du dernier echec).
Le toggle du guichet d ordres viendra s y ajouter quand il sera construit.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
binary_sensor.historisation_evcs_muette + sensor de l age du battement.
Bascule a 'on' dans les deux cas : statut degrade (le service vit mais ses
cycles echouent, la base typiquement) et battement plus vieux que 5 minutes
(le service ne publie plus du tout). Cinq minutes = cinq cycles manques.
Verifie en simulant les deux pannes sur le capteur source : degrade+frais -> on,
ok+vieux de 10 min -> on avec age=10, puis retour a off en 18 s des que le
service de production a repris la main. Un detecteur qu on n a pas vu detecter
n est pas un detecteur.
⚠️ Toute automatisation qui alerte sur ce drapeau doit porter for: 00:05:00 :
le capteur source est cree par l API, il n existe donc pas pendant une minute au
plus apres un redemarrage de Home Assistant, et le drapeau passerait a on
brievement a chaque fois.
Le paquet porte aussi la raison pour laquelle un capteur DEDIE est necessaire
la ou la fraicheur d une entite metier ne dit rien : last_reported == last_changed.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Valide par le proprietaire le 16/09. Le service publie desormais
sensor.evcs_historisation_heartbeat a chaque cycle : etat = horodatage ISO 8601
UTC, attributs statut (ok|degrade), base_joignable, cycles_en_echec,
dernier_echec. Forme figee avec la session OpenClaw pour que les deux battements
du systeme soient identiques.
POURQUOI UN CAPTEUR DEDIE. 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. Sur une installation saine, trois entites sur cinq paraissaient
figees. La vivacite se lit donc sur ce capteur seul, dont l'etat est un
horodatage : il change forcement a chaque ecriture.
L'appel est HORS du try/catch du cycle, dans les deux branches. C'est tout le
correctif : base morte, le battement part quand meme en portant degrade et la
cause. Avant, un cycle en echec n'ecrivait que sur console.error, et l'incident
n'etait journalise qu'au RETOUR a la normale — dans PostgreSQL, donc jamais
quand c'est PostgreSQL qui est tombe.
⚠️ CE QUE LE TEST A TROUVE, ET QUI RENDAIT LE BATTEMENT INUTILE. Eprouve sur une
base JETABLE derriere un relais TCP coupable a volonte (pas sur la production :
deux instances sur la meme base double-compteraient l'energie des sessions, le
UPDATE energie_kwh = energie_kwh + ... n'est pas idempotent). Premier essai : le
service a CRASHE a la coupure. Le client pg emet un evenement 'error' sur le
socket ; sans ecouteur, c'est une exception non capturee qui ne passe PAS par le
try/catch du cycle — il n'attend qu'une promesse — et qui tue le processus. Le
service mourait donc exactement dans la panne que le battement existe pour
signaler.
Trois correctifs qui en decoulent : un ecouteur 'error' qui marque la connexion
morte au lieu de faire tomber le processus ; une reconnexion, un client pg
n'etant pas reutilisable apres erreur (sans elle le service resterait vivant mais
definitivement muet) ; et une connexion initiale non fatale, pour qu'une base
absente au demarrage ne tue pas le service — un service mort ne signale rien.
Sequence complete verifiee : base vivante -> ok ; coupure -> service VIVANT,
degrade, base_joignable false, cycles_en_echec 2, cause « connect ECONNREFUSED » ;
retour -> reconnexion automatique, ok, et l'episode journalise avec sa duree.
Le message de reprise disait « Home Assistant injoignable » quelle que soit la
cause ; il nomme desormais ce qui a reellement echoue.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
En outillant la session OpenClaw, recherche du champ qui distinguerait « pas
ecrit » de « ecrit a l identique ». Home Assistant expose last_reported depuis
2024, cense marquer chaque remontee d etat meme sans changement de valeur. Il ne
sert a rien ici : mesure sur cinq entites, il est rigoureusement EGAL a
last_changed, alors que le controleur reecrit source_mode et night_target_soc a
chaque cycle de 30 s.
Consequence generale : aucun champ de l API ne distingue un ecrivain mort d un
ecrivain qui republie la meme valeur. L anciennete d une entite metier n est
donc jamais une preuve de panne. Releve sur une installation saine :
vehicle_connected inchange depuis 752 min, night_target_soc 194, source_mode
139 — trois faux positifs sur cinq entites.
Regle adoptee avec OpenClaw : la vivacite se lit sur un battement de coeur dedie
dont l etat est un horodatage, seule entite dont l immobilite soit
interpretable. Les entites metier se lisent pour leur VALEUR, jamais pour leur
fraicheur. « inchange depuis X » est un fait, « fige » est un verdict.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
L'enquete sur une reponse fausse du concierge (« 12,1 kWh absorbes cette nuit »,
alors que la voiture en avait pris 3,18) l'a etabli par recoupement :
gx_device_pv_energy valait 29,136 quand la production mesuree de la veille etait
29,13 kWh. Ce sont des compteurs JOURNALIERS ; les sauts negatifs de plusieurs
centaines de kWh sont leur remise a zero vue comme un delta. Ma note du 04/09
les disait « corrompus », c'etait faux — la conclusion pratique, elle, tient.
Le piege qui a produit l'erreur est ailleurs : ils se FIGENT. A 01:32,
dc_battery_charge_energy portait encore la valeur de la veille 17:31:50.
Regle generale ajoutee : verifier last_changed avant de citer une valeur comme
actuelle.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Le proprietaire a demande la creation du role. Il existait deja, avec exactement
les deux SELECT du contrat (session_charge, evenement) et aucun droit
d'ecriture. Mon affirmation « toujours pas cree », repetee deux fois dans la
nuit dont une dans un message a la session OpenClaw, etait fausse.
Ce qui manquait n'etait pas le role mais son MOT DE PASSE : absent du .env du
projet, de celui de la pile d'historisation, et des variables du conteneur
openclaw-gateway. Un identifiant que personne ne connaissait.
Renouvele, range dans AIRTRIA_RO_PASSWORD (.env du projet, ignore par git), avec
CONNECTION LIMIT 5 pour qu'un agent emballe ne puisse pas epuiser le pool.
Verifie par 14 essais depuis le poste : SELECT autorise sur session_charge et
evenement, refuse sur les sept autres tables, et refuse pour INSERT, UPDATE,
DELETE, CREATE TABLE et la lecture de pg_authid. Acces reseau confirme :
pg_hba porte host all all all scram-sha-256, et 5433 est joignable depuis
10.10.10.17.
⚠️ ET LE RENOUVELLEMENT A CASSE LE CONCIERGE. La session OpenClaw a repondu
quelques minutes apres qu'elle EST codee pour se connecter en airtria_ro et
qu'elle avait lu evenement le soir meme. Ma verification ne regardait que
Config.Env du conteneur, pas son code : j'ai conclu « rien ne l'utilise » d'une
absence de preuve.
LECON : avant de renouveler un identifiant, l'absence de trace la ou JE range
mes secrets ne prouve pas qu'il est inutilise. Le seul test concluant etait de
demander a l'utilisateur presume — ici une session pair joignable en une minute.
Le nouveau mot de passe ne transite pas par un message d'agent a agent : c'est
au proprietaire de le remettre a OpenClaw.
MANUEL : capacite des vehicules, reference mesuree au compteur de la borne.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Corriger le selecteur a la main ne corrige rien : « demain si je dis JEEP il va
rester sur VW, donc la solution c'est de le piloter quand je reponds ».
Le selecteur n'est pas qu'une etiquette. Le CONTROLEUR n8n le lit pour en
deduire l'heure de depart (VW 08:50, JEEP 06:30), donc minutesUntilDeparture,
donc batteryRecoveryUrgent — qui coupe P12 et ferme EDF trente minutes avant le
depart suppose. Mesure de cette nuit : selecteur reste sur JEEP alors que la VW
etait branchee et confirmee par WhatsApp a 19:56 => EDF se serait ferme a 06:00
pour rien, la voiture etant pleine depuis 05:30 et la batterie a 51 %.
Deux correctifs, indissociables.
1. piloterSelecteurVehicule() : une reponse du proprietaire ecrit
input_select.victron_evcs_vehicle. UNE SEULE FOIS par reponse — la fonction
appelante est idempotente par confirmed_at — donc le dernier mot reste a
l'humain quel que soit le canal. Seulement pour les labels qui SONT des
options du selecteur : MEGANE, INVITE et ZERO n'y figurent pas, et l'heure de
depart n'a aucun sens pour un vehicule de passage.
2. ecrireSession() n'ecrase plus une session confirmee. Cette ligne reecrivait
le vehicule depuis le selecteur a CHAQUE CYCLE d'une session ouverte, pendant
que appliquerEtiquettesEnAttente remettait l'etiquette juste apres : deux
ecrivains sur la meme colonne toutes les 60 s, et une ligne de journal a
chaque passe — une soixantaine le 15/09. Le drapeau vehicule_sur dit « un
humain a confirme » : quand il est vrai, le selecteur n'a plus voix au
chapitre.
Preuve du diagnostic, par l'experience : le dernier « Etiquette VW posee » est a
01:40:58, le selecteur passe a VW a 01:41:59, et plus une seule ligne ensuite.
La bagarre s'arrete a la seconde ou les deux ecrivains s'accordent.
Preuve du correctif 2, en lecture seule sur les lignes reelles : sur les deux
sessions VW, l'expression d'avant ecrirait JEEP, la nouvelle garde VW ; sur les
sessions JEEP les deux concordent. Et sur un cas synthetique non confirme, la
nouvelle expression suit bien le selecteur — la garde est ciblee.
DEFAUT TROUVE EN RELISANT LA SORTIE DU PREMIER ESSAI A BLANC : sans garde, un
--dry-run aurait pilote le selecteur pour de vrai. Seule l'egalite fortuite
actuel === label avait evite l'ecriture. Garde posee, puis eprouvee en mettant
le selecteur sur JEEP : la sortie annonce « [blanc] piloterait JEEP -> VW » et
le selecteur est reste JEEP.
MANUEL : capacite des vehicules. La VW annonce 10 kWh de plaque pour 42 km ;
la reference MESUREE au compteur de la borne est 7,70 kWh pour une charge menee
a son terme (15/09 01:25-03:41). C'est ce chiffre qui dimensionne une nuit, pas
la plaque. La JEEP n'est pas mesuree de la meme facon : ne pas lui appliquer
les 7,70 kWh.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Le proprietaire veut comparer prevision et production heure par heure sur une
semaine, dans son tableau de bilan. Les courbes de prevision vivent dans des
input_text ECRASES a chaque publication : HA n en garde aucun historique. La
base, elle, a treize jours de previsions horaires et la production mesuree.
Le service pousse donc la serie dans un capteur cree par l API HA, dont les
attributs portent les tableaux — un input_text plafonne a 255 caracteres ne
tiendrait pas 168 points.
⚠️ Premiere ecriture de ce service vers Home Assistant, qui a toujours ete
lecteur. Perimetre minuscule et delibere : un capteur, son propre espace de
noms, aucun actionneur.
⚠️ Et la troisieme serie n est pas decorative. Une heure BRIDEE n est pas
comparable : production sous la prevision peut vouloir dire mauvaise prevision
OU batterie pleine. Les mesures le montrent — le 13/09 a 15 h, prevu 5,32 et
realise 1,82 avec 100 % de bridage, l ecart n est pas meteorologique ; le 15/09
a 13 h, prevu 3,92 et realise 7,12 sans aucun bridage, la prevision SOUS-estime
de 82 %. Sans la bande, la courbe ferait accuser la meteo a tort.
L etat du capteur porte l ecart moyen sur les seules heures comparables — non
bridees — qui est le seul chiffre qui juge vraiment la prevision.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Consigne l idee du proprietaire et le calcul qui la fonde, le verrou
anti-oscillateur trouve en construisant, et surtout la contrainte decouverte a
05:30 en conditions reelles : P12 doit gagner le premier cycle de la nuit. Si la
reprise reseau s engage avant lui, le verrou anti-creneaux de juillet tient le
reseau pour toute la session — et il a raison, c est exactement le creneau qu il
existe pour empecher. Aucun des cinq scenarios initiaux ne le montrait, ils
partent tous d une nuit vierge.
Note aussi qu une mutation qui ne mute rien ne prouve rien : ma premiere
tentative cherchait un motif absent du fichier, zero occurrence, zero echec, et
j allais conclure que le test tenait.
Et corrige deux affirmations que j avais faites avec trop d aplomb : le garde dur
a -30 A (je lisais la table de base, pas les valeurs appliquees) et le bilan qui
sous-estimerait la batterie de 30 % (j avais divise une courbe par morceaux par
un seul ratio).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Idee du proprietaire, apres la nuit du 14 au 15/09 : 8 kWh achetes au reseau, la
batterie encore a 69 % a 5 h du matin, et une prevision de 38,7 kWh le lendemain
dont 10,5 auraient ete ecretes faute de place. Payer du reseau la nuit pour
ecreter le solaire le lendemain, c est perdre deux fois.
Le mode `battery_assist_night` existait pour exactement ca, et etait MORT depuis
toujours : il exige `batteryCurrentA >= plancher de decharge` (0 A), impossible
la nuit puisque la maison tire sur la batterie. On ne cree donc pas un chemin,
on rend viable celui qui existe — en remplacant un test de COURANT impossible
par un test d ENERGIE.
Le plancher n est PAS une constante nouvelle : c est `required_soc_prudent`, que
le bilan publie deja en profil p80. La voiture descend la batterie jusqu au
niveau qui lui permet encore de tenir jusqu au croisement PV, et pas plus bas.
La bascule vers le reseau est automatique quand le surplus est epuise — la
soupape decrite par le proprietaire, sans aucune regle horaire.
⚠️ Verrou anti-oscillateur, et il n est pas decoratif. Le plancher descend
pendant la nuit et le SOC aussi : voiture en charge le SOC perd 7,1 pt/h contre
3,7 pour le plancher, mais voiture ARRETEE il n en perd que 2,6. Le surplus
reapparaitrait tout seul et la charge repartirait. Une seule passe par session
de nuit, comme la recovery batterie depuis le 27/08.
Les gardes de courant restent : commonSafety, l arret dur, et la garde souple
avec sa tolerance temporelle — c est elle qui arretera la charge quand la bande
de SOC deviendra trop basse pour le courant tire. Ce qu on retire est uniquement
le plancher de PROFIL, qui interdisait de demarrer des que la batterie n etait
pas a l equilibre.
Cinq scenarios, six mutations qui mordent chacune sur un jeu different. Deux
d entre elles ont trouve de vraies faiblesses : les attendus ne verifiaient que
le choix du mode et pas que la voiture charge, et la garde de fraicheur du bilan
n etait couverte par aucun scenario.
Rien n est deploye et le toggle est a off.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Le proprietaire demande d assouplir la garde de decharge souple en bande 40-60,
de -12 a -15 A de base — 39 a 49 A appliques sur treize modules, soit 3,5 A par
equivalent US2000 et 19 % de ce que le BMS autorise. Son argument : en ete, avec
52 panneaux et une production bridee des midi, garder le parc plein n a aucun
sens, et cette nuit a coute 8 kWh de reseau en touchant a peine la batterie.
Le reglage aurait ete perdu. Les cinquante helpers de la table de politique
batterie portaient un `initial:`, qui DESACTIVE la restauration d etat : chaque
redemarrage de Home Assistant les remet a leur valeur d origine, en silence. Et
un redemarrage etait prevu le soir meme pour le tableau du moniteur LLM.
Meme defaut que les cinq helpers corriges le 06/09 — selecteur de vehicule,
toggles de cablage — mais ici sur une table entiere de REGLAGE, donc sur tout
ajustement futur et pas seulement celui-ci.
Les valeurs par defaut restent dans INPUT_PARSE, qui les applique quand le
helper est absent. Rien n est perdu.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Le paquet propose par la session Airtria portait trois entites — interrupteur
d alertes, RAM disponible, libelle d etat. Il lui manquait celle sans laquelle
les trois autres mentent : un horodatage ecrit a chaque passage.
Sans lui, un moniteur mort est indiscernable d un systeme sain. Les trois
entites gardent leur derniere valeur, qui dit « tout va bien », indefiniment.
C est exactement l incident du 08/09 sur la prevision solaire, ou 4 h 45 de
panne n ont laisse aucune trace. Et on ne peut PAS deduire la fraicheur du
last_updated des autres entites : Home Assistant ne rafraichit pas l horodatage
d un helper reecrit a l identique — une RAM stable une heure produirait la meme
illusion.
Ajoutes : l horodatage, le modele charge, un capteur d age, et deux alarmes —
moniteur muet, RAM sous le seuil ou earlyoom tue le plus gourmand.
Defaut trouve et corrige apres creation : l alarme RAM se declenchait avant que
le moniteur ait tourne une seule fois, une valeur jamais ecrite valant zero.
Une mesure qu on n a pas recue n est pas une mesure basse. Elle est desormais
conditionnee a la fraicheur.
Tableau separe des tableaux energie : ce qu il montre n a aucun rapport avec le
photovoltaique.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Il vient de me dire directement quel vehicule est branche. C est une
confirmation humaine au meme titre qu une reponse WhatsApp, mais le code ne
reconnaissait que ce canal-la et aurait marque sa parole « non confirmee ».
Les canaux humains sont desormais enumeres explicitement — whatsapp et
proprietaire — plutot que teste contre une seule valeur. Enumeres, et non
inverses : un canal inconnu ne doit pas valoir confirmation par defaut.
`regle-puissance` n y est pas et n y sera jamais, c est une deduction.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Plusieurs scans successifs, aucun changement — l inventaire reste a 4 modules et
400 Ah. La capture au bandeau bleu a ete prise PENDANT un scan : il s est donc
bien declenche et n a rien trouve de plus.
Ce que ca elimine : l inventaire simplement perime. Le Cerbo redemande et le BMS
agrege lui repond quatre. Le probleme n est pas cote Cerbo mais dans ce que le
hub lui presente — ce qui promeut l etape 3, la seule qui demande si le pack 2
est joignable du tout par ce chemin.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Le bloc qui inverse la semantique de vehicule_sur n etait pas garde : a chaque
redemarrage il remettait les lignes anterieures a faux puis les six arbitrees a
vrai. Le resultat restait juste — l operation est idempotente en sortie — mais
elle ecrivait une ligne de journal trompeuse a chaque fois. Quatre en une
journee, qui seraient apparues en annotation sur tous les tableaux Grafana comme
autant de faux evenements.
Garde sur la trace elle-meme : si la ligne de journal existe, c est fait.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Il demandait « quel vehicule ? » a l ouverture d une session de charge. Trop
tard, et ca s est vu ce soir : a 19:55 la voiture est branchee, le selecteur
perime depuis six jours, et aucune question ne peut partir parce qu aucune
session n existe — la borne ne tire rien, il fait nuit. La premiere session de
la nuit serait nee etiquetee VW sans que personne ne soit consulte.
On etiquette desormais le BRANCHEMENT. C est d ailleurs l invariant du projet —
un cable, un vehicule — et ca rend la question possible des l instant ou on sait
qu il y a une voiture.
Deux temps. Le lecteur accepte une clef `branchement` en plus des `sessions`, et
memorise l etiquette dans une table dediee ; une passe differee, a chaque cycle,
la pose sur les sessions du branchement AU FUR ET A MESURE qu elles s ouvrent,
sans nouvelle question. Bornee par le debranchement suivant, avec les deux
secondes de tolerance du 09/09 — une session s ouvre jusqu a 62 ms avant que sa
transition de branchement soit journalisee.
L ancien contrat reste accepte : une etiquette portant des sessions fonctionne
comme avant.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Le hub reconnait les deux groupes — LED verte et trois bips, son accuse de
reception — mais le Cerbo n en enumere qu un : 4 modules et 400 Ah la ou le parc
en compte 9 et 650.
Le releve de reference apporte le fait qui manquait : a 20:14 les quatre US5000
debitent 24 A au total pendant que le Cerbo annonce 41 A au parc. Les 17 A
d ecart sont le pack 2, qui porte donc bien du courant sans etre enumere. Le
courant mesure au shunt n est pas un indicateur d enumeration — seuls
nombre_de_modules_en_ligne et capacite_installee le sont.
Quatre etapes par risque croissant, la premiere ne touchant a aucun cable : un
redemarrage du Cerbo, l inventaire ayant deja change une fois le 13/09 a 21:35,
evenement isole verifie comme n etant pas un redemarrage de Home Assistant.
Regle de securite tiree de l incident d aujourd hui : fermer EDF AVANT toute
manoeuvre. Couper la communication du BMS arrete la gestion batterie, donc l
onduleur, donc la maison — 72 secondes dans le noir a 16:24. EDF deja ferme, la
maison passe en direct et ne voit rien.
L etape 4 renvoie a la documentation constructeur et n avance aucune theorie de
cablage : sur du materiel batterie je ne raisonne pas de memoire.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
L oscillation rapide se calibre sans ambiguite : sur le contacteur reseau, le
plus grand ecart pathologique vaut 193 s et le plus petit ecart normal 857 s,
facteur 4,4 sans aucune valeur entre les deux. Quatre bascules en dix minutes
isole exactement la salve du 12/09 et reste muet sur dix entites pendant dix
jours.
Piege trouve en calibrant : les plus petits ecarts normaux de plusieurs entites
valent 242 a 320 s, c est-a-dire la cadence des workflows. Ce ne sont pas des
oscillations mais deux executions consecutives qui changent d avis — toute
regle a deux bascules en cinq minutes se declenche sur le fonctionnement normal.
En revanche la regle des sessions reseau repetees NE SE CALIBRE PAS : les ecarts
entre fermetures forment un continuum de 4 minutes a 24 heures, sans
discontinuite. Or c est la pathologie la plus couteuse des deux. Je ne pose pas
de seuil dessus : elle demande une formulation metier et plus d historique, et
la bacler serait refaire l erreur que ce projet a payee six fois.
La regle de la mesure figee, elle, se valide sur un incident reel : le 05/09 la
tension et le courant batterie se sont tus 27 minutes pendant que le SOC, issu
du meme flux, publiait toutes les deux minutes. Le discriminant est relatif, pas
absolu — un silence long est normal pour une grandeur intermittente.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Consigne le defaut (un nom de champ inexistant qui vidait 416 lignes), les trois
signatures relevees, la regle du balayage vers l avant, et le benefice non
cherche : le declencheur porte la raison que chaque workflow publie lui-meme —
ce que « expliquer les decisions » reclamait etait deja enregistre.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
auteurDeLaTransition filtrait sur x.context_name. Ce champ n existe pas dans le
journal de bord de Home Assistant : la fonction rendait null a tous les coups et
les 416 transitions journalisees portaient un auteur vide. Personne ne s en
etait apercu parce qu un auteur absent ressemble a un auteur inconnaissable.
Le contexte etait la, sous d autres noms, avec trois signatures distinctes
relevees sur des transitions dont je connaissais l auteur : une ligne voisine
script/automation qui se nomme ; un service exterieur dont la rafale se CLOT par
une ligne de narration portant le nom du workflow ET sa raison ; ou une simple
derivation depuis un autre capteur — qui n est pas un auteur et ne doit pas etre
annoncee comme tel.
On balaie vers l AVANT pour trouver la narration : un workflow ecrit ses helpers
puis se journalise, donc vers l arriere on ramasserait celle du precedent.
Verifie sur la seconde ou l Auto Charge Manager et le Water Heater Advisor
ecrivent ensemble — chaque helper revient a son propre workflow, 3 sur 3.
Benefice non cherche : le declencheur porte desormais la raison que le workflow
a lui-meme publiee. C est ce que « expliquer les decisions » reclamait, et
c etait deja dans le journal.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Deploye le 14/09 a 02:23. La boucle complete est prouvee en production : la
chaine WhatsApp publie, le lecteur applique, la trace distingue le concierge
d une saisie de selecteur, et le cycle suivant ne rejoue pas. Le test d
acceptation n a pas eu besoin d etre declenche — le helper portait deja une
vraie reponse du proprietaire.
Le GO m etait arrive relaye par la session Airtria. Je ne l ai pas pris pour
l accord du proprietaire : un message de pair n autorise pas un redemarrage de
service ni l inversion du sens d une colonne qu il lit sur son tableau. Demande
directe, reponse, puis deploiement.
Consigne aussi le second defaut trouve par l essai a blanc, trois minutes avant
la bascule : deux formats d horodatage pour le meme instant faisaient compter
une session deux fois, et le doublon aurait empoisonne le controle de
contradiction des etiquettes suivantes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Airtria envoie la clef telle que PostgreSQL l affiche — 2026-09-12
11:55:54.493+02 — et la base me la rend en ISO. Meme instant, caracteres
differents : mon Set les comptait deux fois, et le journal annoncait « 2
sessions, dont 1 ajoutee par le branchement » la ou le branchement n en
contient qu une.
L UPDATE resistait, les deux formes se transtypant en timestamptz. Ce qui ne
resistait pas, c est le tableau sessions du detail, qui portait le doublon —
et c est precisement lui que le controle de contradiction interroge sur les
etiquettes suivantes.
Trouve par le journal du service en essai a blanc, trois minutes avant la
bascule du kill-switch. Mon harnais de verification ne pouvait pas le voir :
il comptait les lignes SQL, pas les elements du Set.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Les trois pieces soudees, parce qu aucune ne tient seule. Le defaut de la
colonne passe a faux ; plus rien dans le chemin d ecriture ordinaire ne peut le
mettre a vrai ; le libelle Grafana « selecteur change » devient « a confirmer »,
et le compteur « Etiquette douteuse » devient « A confirmer ».
L ancienne semantique — « le selecteur n a pas bouge pendant la session » — ne
prouvait rien : le selecteur est reste sur VW du 07/09 au 13/09 et les onze
sessions fausses portaient toutes true. La mesure d hier a acheve de la
disqualifier : sur douze branchements, le selecteur n a ete regle au bon moment
qu une seule fois.
Rattrapage des lignes anterieures a faux, sauf les six que le proprietaire a
arbitrees lui-meme le 13/09 — une vraie confirmation humaine, seulement donnee
de vive voix, qu il serait absurde de jeter. Une ligne de journal l explique.
Rien n est deploye : le service tourne encore l ancien code.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Treize paquets et dix-sept cartes n existaient qu en un seul exemplaire vivant
sur le partage de 10.10.10.17. La sauvegarde quotidienne les couvre contre la
perte, mais elle ne donne ni diff ni historique : le retrait des initial: du
06/09, les helpers de la reserve d orage, la politique batterie dynamique, la
carte du conseiller reecrite hier n avaient aucune trace de leur evolution.
⚠️ Ce sont des COPIES. La source de verite reste le partage — c est l inverse
de src/nodes/, et le LISEZMOI le dit en tete pour qu une prochaine session
n edite pas la copie en croyant changer l installation.
Verifie avant de verser : aucun identifiant en clair. Le paquet du bilan ne
porte que la DECLARATION de la cle Forecast.Solar, en mode password ; sa valeur
vit dans .storage, qui n entre pas ici.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Mesure, pas supposition : dix changements de selecteur journalises depuis le
04/09, croises avec les douze branchements. Une seule fois le reglage tombe
dans la fenetre du branchement.
Et la decouverte qui compte : un changement de selecteur EN COURS de
branchement est un drapeau rouge et non un signe de fraicheur — le cable n a
pas bouge, donc changer le label ecrit forcement un faux. Les deux seuls
branchements ou il a ete touche en cours de route sont les deux seuls mal
etiquetes. La regle de fraicheur qu Airtria construisait se serait tue sur
exactement ces deux cas.
Consigne aussi pourquoi last_changed ne vaut rien comme signal : un passage par
unavailable le remet a zero sans qu aucun etat n ait bouge.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Le kill-switch gate l ecriture, pas la lecture : tant qu il est a OFF, le
lecteur resout le branchement, applique ses refus et journalise ce qu il aurait
ecrit. L essai grandeur nature d Airtria eprouve donc aussi ma moitie, pas
seulement la leur.
Et il a servi immediatement. La resolution du branchement rendait deux sessions
sur trois : une session s ouvre AVANT que sa transition de branchement soit
journalisee, les deux etant ecrites dans le meme cycle — 62 ms d ecart le
09/09 — donc la session qui OUVRE un branchement etait exclue de son propre
groupe. Tolerance de deux secondes sur la borne basse ; les trois remontent.
Le meme controle, passe sur tout l historique, signale deux branchements
anterieurs a etiquettes contradictoires. Rien n est repare : un groupe mixte
peut aussi etre un echange de vehicule que le capteur a manque, et c est au
proprietaire de trancher.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Quatre echanges avec la session Airtria pour arreter l interface. Le point
qui a failli passer : leur etiquette porte une provenance, whatsapp ou
regle-puissance, et les deux ne peuvent pas valoir la meme certitude. Une
deduction n est pas une confirmation — marquer « sur » un invite detecte a la
puissance aurait recree, sous une autre forme, le defaut que la bascule de
vehicule_sur corrige.
Consigne aussi le vocabulaire (MAJUSCULES sans accent, releve sur l etat reel
de la colonne) et le sens unique de la regle de puissance, qui impose au
lecteur de refuser un VW ou un JEEP venu de ce chemin.
Ma part — lecteur du helper et bascule du defaut — reste a ecrire, et les deux
sont indissociables.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Le proprietaire demande comment suivre l'effet du relevement du plafond.
Verification faite : la DVCC n'apparait que dans deux tableaux de debug, et
l'ecart entre cellules comme le mode des chargeurs solaires n'apparaissent
NULLE PART — alors que ce sont exactement les trois grandeurs a regarder.
Deux capteurs modeles crees (`batterie_qui_limite.yaml`), parce que le
systeme publiait les ingredients sans jamais la grandeur :
- **Ecart entre cellules** : le BMS donne la plus haute et la plus basse,
mais c'est leur difference qui dit si le parc est sain. 2 mV aujourd'hui,
contre 168 mV sur l'ancien module 3 juste avant qu'il fasse effondrer le
courant de tout le monde. C'est le garde-fou d'un relevement de plafond.
- **Chargeurs qui se retiennent** : six entites publient leur regime et
aucune n'etait affichee, alors que c'est le seul signal DIRECT de
ressource refusee — la puissance mesuree etant censuree par construction
sur une installation sans injection. `off` ne compte pas : la nuit tout
est `off` sans que rien ne soit refuse.
Carte « Charge de la batterie — qui limite ? » sur le tableau Bilan : le
courant pris face au plafond que NOUS imposons et a celui que le BMS
autorise, idem pour la tension, puis l'ecart entre cellules et les
chargeurs brides. Avec le mode d'emploi de lecture, parce qu'une carte qui
ne dit pas comment l'interpreter se lit de travers.
Nombre de modules et capacite installee du BMS volontairement absents : ils
ne comptent que le groupe maitre (4 modules, 400 Ah pour un parc de neuf).
Le paquet du concierge vehicule entre aussi dans le depot.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
`energie_compteur_kwh` vaut la difference de deux releves du compteur
cumulatif de la borne, proches de 3 800 kWh : en double precision la
soustraction rend « 0.8000000000001819 » pour une mesure dont la resolution
est de 0,1 kWh. Arrondi a l ecriture, au millieme, plutot que de laisser
chaque lecteur s en charger.
Signale par la session OpenClaw en calibrant son module de detection sur la
table. Cosmetique pour la logique, mais ce projet a deja paye le prix de la
fausse precision affichee comme une mesure.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Consigne au dossier ce que la journee a produit autour du concierge
vehicule : le drapeau `vehicule_sur` qui ne detecte pas le cas qui compte,
la puissance qui distingue un vehicule invite la ou elle ne distingue pas
les deux du foyer, et surtout la frontiere d'un branchement — un fait lu
dans le journal, jamais un ecart de temps, les creux soir/heures creuses
faisant 5 h 20.
Plus le contrat arrete avec la session OpenClaw (helper unique en liste,
clef verbatim avec millisecondes, max:255 explicite, fenetre commencant sur
un branchement) et la correction sur `evcs_lecture`, qui porte un INSERT
sur `evenement` et ne doit donc pas etre confie a un tiers.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Correction de ma propre correction. J'avais mis 09/09 15:55 en JEEP et
laisse les deux sessions suivantes en VW — physiquement impossible, il n'y
a qu'un point de charge et le journal `evenement` montre aucun
debranchement entre mercredi 15:55 et jeudi 09:05.
L'explication du proprietaire est exactement ce qu'aucune regle ne
produira : sa femme a branche la JEEP l'apres-midi, et le soir son fils
n'a PAS debranche pour mettre la VW a la place — il a roule a l'essence le
jeudi. Trois sessions, un seul cable, un seul vehicule, et une decision
humaine que ni l'heure, ni la puissance, ni l'historique ne laissent
deviner.
La reparation passe de quatre a six lignes. Etiquettes finales sur la
semaine : 5 VW, 6 JEEP, 1 MEGANE.
Lecon inscrite dans le commentaire : la frontiere d'un branchement est un
FAIT lu dans `evenement`, jamais un ecart de temps — les creux entre la
session du soir et celle des heures creuses font 5 h 20 et ne se
distinguent pas d'une nuit entiere.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Verification des droits reels : SELECT sur toutes les tables, plus INSERT
sur `evenement` — un octroi deliberé et documente plus haut dans ce meme
README (les annotations qu aucun service ne peut deviner s ecrivent a la
main), mais que deux autres passages decrivaient comme « lecture seule ».
Je l ai moi-meme affirme a un pair qui prepare un acces pour un agent
externe. La consequence est concrete : confier ce role a un tiers lui
donnerait l ecriture sur le journal qui alimente les annotations Grafana,
le rapport de nuit et l attribution des transitions — et ses lignes y
seraient indiscernables des notres.
Pour un tiers : un role dedie, SELECT sur les seules tables necessaires.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Le selecteur de vehicule est reste sur VW du 07/09 20:49 au 13/09 : onze
sessions consecutives ont herite de cette etiquette, toutes marquees
« sur » — le drapeau `vehicule_sur` ne passe a faux que si le selecteur
bouge PENDANT une session, donc un selecteur perime reste fiable a ses
propres yeux.
Quatre lignes corrigees, apres arbitrage du proprietaire :
mer 09/09 15:55 6,61 kWh -> JEEP
ven 11/09 16:54 7,45 kWh -> MEGANE
sam 12/09 11:42 0,09 kWh -> JEEP
sam 12/09 11:55 5,94 kWh -> JEEP
La session du 11/09 n'est ni la VW ni la JEEP : 6 360 W a 28 A quand les
deux vehicules du foyer plafonnent vers 3 680 W. C'est une Megane de
service. Ce cas n'etait documente nulle part, et il corrige la doctrine
« vehicules indiscernables » : elle ne vaut que pour la VW et la JEEP l'une
par rapport a l'autre, un vehicule invite se lit dans `p_max_w`.
Les sept autres lignes etaient justes — par chance, la VW etant celle qui
charge le plus souvent.
L'arbitrage a repose sur un contexte qu'aucun capteur ne produit : sa femme
(JEEP) en conges, son fils (VW) en stage sans retour le midi. C'est
l'argument central pour l'agent conversationnel — il dit lui-meme qu'il lui
est plus facile de donner cela par WhatsApp que de venir sur un PC.
Reparation idempotente, fenetre d'une minute, verifiee en lecture avant
ecriture : chaque predicat vise exactement une ligne, energies concordantes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Le patch precedent n'avait releve que pv_boost : au-dessus de 80 % de SOC
c'est pv_mid qui commande, donc son plafond de 110 A restait le plus bas et
rien n'etait observable cet apres-midi. Table finale : 150 / 130 / 80 / 30,
toujours decroissante.
Applique a 13:31. Le courant est passe de 90 a 116 A dans la minute — mais
la charge de la maison a chute de 2,6 kW au meme moment, et le courant n'a
repris que 1,3 kW des 2,6 liberes tandis qu'un chargeur de plus se bridait.
Ce n'est donc PAS une preuve propre, et je ne la presente pas comme telle.
Ce que le releve montre vraiment : dans la tranche 80-90, le courant a
plafonne vers 116 A sans jamais approcher les 130, pendant que la tension
montait de 50,82 a 51,07 V vers la consigne. A ce niveau de SOC c'est la
TENSION qui contraint, pas le courant.
La ou le plafond mordait : a 12:36-12:42, SOC 78-80, le courant etait a
129 A pour une DVCC de 130 — colle dessus. C'est la tranche pv_boost, donc
c'est la charge du matin qui dira ce que le 150 A libere.
Cellules a 2 mV et aucune alarme sur toute la sequence. Golden ACM 20/20,
attendu de acm-jour-mid mis a jour dans le meme commit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Mesure du 13/09, 10:39 a 12:50 : la DVCC etait a 130 A et la batterie
prenait 114 a 127 A, soit 88 a 98 % du plafond, avec une tension plate a
50,6 V — a 0,5 V sous notre propre consigne. C'est le point decisif : il n'y
avait aucune phase d'absorption, le courant ne retombait pas de lui-meme,
il butait. Pendant ce temps six chargeurs sur sept se declaraient
`voltage_current_limited`, et sans injection cette ressource est perdue.
Le BMS, lui, declare autoriser 250 A et 53,2 V, ses 135 cellules tiennent
dans 2 mV et aucun module ne bloque la charge. Le 130 A venait de l'ANCIEN
parc, dont une cellule montait a 3 649 mV et faisait effondrer le courant de
tous. Ces modules sont sortis le 12/09.
- `pv_boost` 130 -> 150 A : un palier, pas une cible. 150 A reste a 60 % de
ce que le BMS declare ; on regarde ce que ca libere et l'ecart entre
cellules avant d'aller plus loin.
- `pv_mid` 51,2 -> 51,5 V : la colonne des tensions REDESCENDAIT entre 80 et
90 % avant de remonter, reste du 06/09 ou seul pv_topoff avait ete releve.
pv_topoff et pv_hold ne sont pas touches. L'effet du 150 A ne se verra que
sous 80 % de SOC, donc a la charge du matin.
Golden ACM : les trois scenarios qui epinglaient ces valeurs sont tombes,
attendus mis a jour dans le meme commit, 20/20. Verifie en reel : consigne
appliquee, aucune alarme, cellules toujours a 2 mV.
Corrige au passage : l'ACM tourne toutes les 5 MINUTES, pas 30 s comme
l'annoncaient le manuel et MEMORY.md.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Quand il n y a rien a signaler il n y a pas de piste, et le repli sur le
constat faisait afficher la meme phrase deux fois de suite sur la carte —
et serait parti en double dans la colonne `piste` de la table
d observation, ou elle ne serait plus interrogeable pour rien.
« [95%] rien a creuser » garde la confiance visible et dit la verite.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Six helpers que plus personne n ecrivait depuis la specialisation du 12/09
restaient affiches sur la carte du tableau EVCS Master comme des
recommandations courantes : strategie, charge du soir, divergence, cible SOC
matin figee a 55 %, plafond courant, et le toggle qui appliquait la cible.
C est exactement ce fantome qui a rendu le cablage dangereux — la garde de
fraicheur datait le run, pas la valeur.
Retires du paquet et de la carte, sauvegardes dans SAVE/. La carte est
reecrite pour ce que le conseiller fait desormais : gravite, ce qu il voit,
ce qui cloche, la piste et sa confiance.
Le conseiller relisait aussi SA PROPRE strategie precedente — figee depuis
le 12/09, et parsee sans jamais servir dans le prompt. Retiree de son
snapshot et de BUILD_PROMPT.
Apres rechargement des trois domaines : dix helpers restants, exactement
ceux que l observateur ecrit. Les compteurs ont survecu (8 cycles calmes,
0 signalement), ce qui valide la suppression des `initial:` du matin meme.
Gabarit du conseiller re-rendu contre Home Assistant : 48 champs, JSON
valide, aucun null. Pousse.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Le premier cablage reel (§20, 09/08) faisait suivre a la cible SOC du matin
`input_number.evcs_advisor_night_target_soc`, derriere quatre gardes :
toggle, statut ok, fraicheur de 120 minutes, bornage [22, 90].
Depuis que le conseiller est devenu observateur le 12/09, il n emet plus de
cible et ce helper est fige a 55 %. Les quatre gardes continuaient pourtant
de passer toutes les quatre, parce que la garde de fraicheur date le RUN et
non la VALEUR : le conseiller tourne toujours, donc son horodatage est
frais. Activer le toggle aurait applique un chiffre perime sans qu aucune
garde ne s y oppose.
Retire : les quatre parametres d INPUT_PARSE, le bloc de WINDOWS_SOURCEV2,
le passe-plat de BATTERY_CLOUD_LOCKS, la trace (ADVISOR) de DECISION et les
quatre champs du gabarit de snapshot. Le cablage du BILAN (§39) est intact.
`parseAdvisorRunToMs` devient `parseRunStampToMs` : le bilan publie le meme
format et reste son seul appelant.
Golden 98 → 96. Les trois scenarios du cablage sont remplaces par un seul,
`advisor-cible-ignoree`, qui pinne l ABSENCE de cablage : toutes les
conditions de l ancienne regle reunies, et la cible doit rester celle des
regles de prevision. Mutation : cablage restaure → il tombe, avec
« target=22% (ADVISOR) » dans la raison ; retire → 96/96.
Gabarit re-rendu contre Home Assistant : 196 champs, JSON valide, aucun
null. Pousse en production, cycle suivant en succes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Reprise de la campagne apres la specialisation en observateur. Le harnais
affichait encore `strategy` et `night_target_soc`, deux champs que
l observateur n emet plus : il mesurait des undefined. Reecrit pour noter
ce qui compte chez un observateur — la gravite tombe-t-elle dans la
fourchette attendue, et a-t-il NOMME la chose, par des mots-cles choisis
hors du vocabulaire du prompt.
Quatre defauts trouves, aucun n etant un defaut de raisonnement du modele :
- « Contacteur FERME » : pour un relais, ferme veut dire qui laisse passer.
Le modele l a lu comme coupe et a demande, reseau present, « pourquoi le
contacteur reste FERME alors que le bilan juge le reseau necessaire ».
- Le signe de l excedent : le prompt affichait « 14 W », il a ecrit
« negatif (-14 W) » — et sur un autre cas « negatif » puis « positif » au
passage suivant, sur le MEME prompt.
- « day_vehicle_full_idle » ne veut rien dire pour lui : il signalait une
ressource refusee sans voir que le vehicule est PLEIN.
- Un excedent calcule sous censure ne veut rien dire : sur le BOOST du
11/09 il concluait « pas de soleil, donc le reseau est normal » alors que
les 121 W de PV sont bas PARCE QUE la consigne de 8260 W les evince.
Plus une grandeur derivee de plus, `consigne - maison`, parce qu il voyait
la version flagrante du defaut (SOC 20, 0 A) et manquait la version
discrete (SOC 45, +2 A). Elle a d abord fait TOMBER le cas du BOOST, en
annoncant « il reste 7005 W pour recharger » comme une bonne nouvelle sur
une batterie a 96 % : corrigee en lui faisant dire l inverse quand il n y a
rien a recharger, la question ayant deja une reponse dans le bilan.
Trois defauts etaient les miens : deux fixtures decrivaient un etat que
l installation ne peut pas prendre — c est le conseiller qui l a signale —
et un attendu exigeait « haute » la ou l echelle de gravite du prompt ancre
elle-meme cet incident sur « moyenne ».
Incidents 39/40 au final, contre 23/35 au depart. Les deux cas de vrai
silence restent silencieux 5/5.
⚠️ Trouve en marge : cinq helpers du conseiller sont geles depuis la
specialisation, et le cablage de la cible SOC matin les lit encore — ses
quatre gardes passent toutes, la fraicheur datant le RUN et non la VALEUR.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Les treize captures de la soiree du 12/09 : les tentatives sur le LVHUB,
les lectures des deux chaines pendant qu elles etaient separees, puis la
chaine complete une fois les neuf modules reunis. Elles sont la matiere
brute derriere la procedure de mise en service a deux groupes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Ses helpers sont ecrases toutes les quinze minutes : un signalement grave
emis a 3 h du matin avait disparu au reveil, et rien dans la memoire du
projet n en gardait trace. C est precisement ce que le proprietaire
demandait quand il a dit vouloir un outil pour garder une trace des
evolutions — voir un comportement idiot du systeme ne sert a rien si
personne ne peut le relire le lendemain.
Une table `observation`, alimentee par le service d historisation, clef sur
l horodatage du marqueur du conseiller : rejouer un cycle n invente rien et
un conseiller a l arret n ecrit pas la meme ligne toutes les minutes. La
confiance est extraite de `_reason` (« [NN%] la piste ») pour rester
interrogeable sans decouper une chaine en SQL.
`node tools/enquete.mjs observations [heures] [gravite]` ne montre par
defaut que ce qui a ete signale, et compte a part les cycles calmes : un
observateur qui fonctionne est silencieux la plupart du temps, et noyer les
signalements sous des centaines de « rien a dire » les rendrait invisibles.
Essai a blanc : observation=1, le service ecrirait bien sa ligne.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Releve par le proprietaire : l extremite etiquetee « BATTERY » va sur le
maitre, celle etiquetee « Inverter » va sur le LV-HUB. Tous les autres
cables de communication Pylontech sont 8 broches droit, donc reversibles ;
celui-ci ne l est pas, et rien sur le connecteur ne le signale.
La raison est dans l annotation du schema constructeur, que j avais
extraite sans en tirer la consequence : « The first 3 pins ON THE PORT OF
BATTERY SIDE should be NULL. » Les broches ne sont coupees qu a UNE
extremite. Inverse, le cable presente un 8-broches complet au maitre et
un cable ampute au hub — les deux erreurs a la fois.
Piege supplementaire : l etiquette dit « Inverter » parce que le cable a
ete fabrique pour relier une batterie a un onduleur ; c est pourtant bien
cette extremite qui va au hub.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Trouvee par le proprietaire apres une soiree de fausses pistes. Le detail
qui debloque tout n est ecrit nulle part dans la documentation Pylontech :
⚠️ LE CABLE MAITRE 1 -> LV-HUB DOIT ETRE DEBRANCHE PENDANT TOUTE
L INITIALISATION. La doc dit « puis connectez le cable » sans preciser
qu il doit etre ABSENT auparavant. Avec le cable en place,
l initialisation ne va jamais a son terme, les trois bips ne se
produisent pas, et le hub reste rouge quoi qu on fasse.
Consigne aussi : les deux cables ne sont pas interchangeables (hub vers
maitre = 3 premieres broches NON connectees, reference 5WRPY01-00132 ;
partout ailleurs 8 broches droit), la semantique des LED du hub (le ROUGE
signale un groupe RETIRE, ce n est pas une panne), et les quatre fausses
pistes suivies ce soir pour ne pas les refaire.
Resultat : 9 modules, SOC 81 %, 130 A charge / 250 A decharge, aucune
alarme, parc declare a 13 equivalents. La reserve utile est passee de
6,8 a environ 22 kWh dans la journee.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
Les trois modules en panne ont GONFLE. Cela annule le plan d essai a
l alimentation stabilisee propose le 05/09 : un module gonfle a produit
du gaz, il ne se charge pas, ne s ouvre pas, ne se met pas sous tension.
Cible : 5 US2000C (les 4 recents plus K220803C30160323, le module ancien
sain) et 4 US5000, accouples par le LV Hub — soit 13 equivalents.
⚠️ Point le plus important de la procedure : sans batterie, le MultiPlus
s arrete et il n y a plus rien sur AC-out, meme contacteur ferme. La
maison sera hors tension pendant l intervention s il n existe pas de
bypass manuel — et Home Assistant comme n8n tournent sur le .17, alimente
par la maison.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj