« 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
L'etiquette du vehicule n'existe QUE pendant la session.
`input_select.victron_evcs_vehicle` est un reglage manuel, il change, et rien
ne conservait sa valeur au moment ou la charge avait lieu — une session d'il y
a trois semaines etait anonyme pour toujours, et toute analyse d'usage
impossible.
Nouvelle table `session_charge` : debut, fin, vehicule tel que le selecteur
l'indiquait PENDANT la session, un drapeau disant s'il a change en cours de
route, energie accumulee, puissance et courant maximum, mode source, et
l'heure de debranchement — qui confirme apres coup, les deux vehicules partant
a des heures differentes.
Le service applique lui-meme la migration au demarrage : `schema.sql` n'est
joue qu'a la creation de la base, une table ajoutee plus tard n'y arriverait
jamais. `CREATE TABLE IF NOT EXISTS` rend l'operation rejouable.
On ne DEVINE rien, et le commentaire du schema dit pourquoi :
- electriquement, la VW accepte 3 680 W et la JEEP 3 655 W a consigne
identique de 20 A — 0,1 A d'ecart, indiscernables ;
- horairement, la routine s'inverse le week-end (la femme du proprietaire
travaille samedi et dimanche matin), donc « midi = JEEP, nuit = VW » serait
faux un week-end sur deux.
Essai a blanc : la session en cours serait correctement inscrite (JEEP,
3396 W, Reseau force, profil night_hc).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Recherche d'un signal permettant d'identifier automatiquement le vehicule
branche, a la demande du proprietaire. Resultat NEGATIF, et il merite d'etre
consigne pour qu'on ne le recherche pas deux fois.
Mesure sur deux sessions a consigne identique de 20 A, etiquetees par le
proprietaire : la VW accepte 3 680 W, la JEEP 3 655 W. Vingt-cinq watts
d'ecart, 0,1 A. Les deux embarquent un chargeur de 3,7 kW et saturent au meme
endroit. Ni la puissance de plateau ni le taux d'acceptation de la consigne ne
les separent.
La piste de la latence de demarrage est inexploitable : la table `decision` ne
commence qu'a 01:37 le 04/09, donc l'ordre de demarrage de la session VW de
cette nuit-la n'a pas ete enregistre et les 761 s calcules sont un artefact.
Ce qui EST un signal, et c'est le proprietaire qui l'apporte : la routine du
foyer. La JEEP charge le midi en semaine (sa femme rentre dejeuner), la VW le
soir et la nuit (son fils part a 9 h). Forte presomption, pas certitude — cette
nuit meme, un samedi, c'est la JEEP qui charge.
Consigne dans MANUEL_COMPLET §0, avec le rappel que le selecteur manuel reste
le seul etiquetage fiable et qu'un redemarrage de Home Assistant peut l'annuler.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Generateur rejouable (tools/gen-page-batteries.py) plutot qu'un HTML ecrit a la
main : les chiffres viennent des mesures et se recalculent.
Base : 37 nuits completes issues des statistiques long terme de Home Assistant
(fin juillet au 4 septembre, maison seule, voiture deduite) et la courbe
energie/SOC etablie sur 576 paliers.
Le chiffre qui cadre la decision : les 7 modules actifs delivrent 10,7 kWh a la
maison, la nuit mediane en demande 13,2 — la batterie passe la nuit seule
1 fois sur 37. Reparer le module en panne porte cela a 5/37 seulement ; deux
modules de plus le portent a 32/37. Reparer seul ne resout rien.
Second point, moins attendu : au-dela de la consommation nocturne le stockage
ne cycle plus. Le surplus de milieu de journee est un probleme de preneur, pas
de stockage — la voiture absorbe deja 9,8 kWh/jour en mediane.
Reserve inscrite en clair : toutes les mesures sont d'ete, les compteurs
exploitables ne remontant qu'a fin juillet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Informations donnees par le proprietaire, a ne pas lui faire repeter.
La consommation est pilotee par les repas et non par une courbe lisse : quatre
personnes, bouilloire a 05:45, grille-pain a 08:00, cuisson du soir dont
l heure varie entre 20 h et 23 h selon les jours, et des repas differents d un
jour a l autre. Un profil horaire moyen ne represente donc rien, et moyenner
deux jours dont le pic est a 20 h et a 23 h produit un profil que ni l un ni
l autre ne ressemble. C est la cause la plus probable de la sous-estimation du
profil p50 mesuree la nuit du 02-03/09. Le proprietaire souligne aussi qu une
decharge courte mais forte n a pas le meme effet sur le stockage et l autonomie
qu une decharge lente de meme energie, et que ce n est pas lineaire — la courbe
energie/SOC du 03/09 ne dit rien du rendement sous fort courant.
Strategie hivernale : deux charges reseau par jour, batterie a 85 % en heures
creuses de nuit pour faire la jonction avec le PV du matin, puis une recharge de
midi pour tenir jusqu a la fenetre suivante. C est un contournement manuel de la
meme famille que les charges programmees ESS et la consigne a 4200 W ; le besoin
reste entier et ne doit pas etre retire avant que le bilan sache le produire
seul. Le cablage du 03/09 ne couvre que la session de nuit.
Un pack bloque la charge a 94 %, ce qui explique que la courbe mesuree s arrete
a 93. En rebranchant le pack isole, le blocage pourrait descendre a 85 %, valeur
possiblement fausse et donc a mesurer. Si le blocage reel est a 85, le plafond
de 90 % de la cible du matin devient inatteignable.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
576 paliers de SOC mesures sur 8 jours (tools/mesure-courbe-batterie.mjs,
ajoute) : pour chaque palier ou le SOC reste a une valeur puis descend d un
point, on integre la puissance batterie, en ecartant les paliers ou la batterie
a charge et ceux ou le reseau a apporte quoi que ce soit.
Resultat : plate a 0,169 kWh/point de 33 a 93 — six tranches independantes entre
0,163 et 0,171 — genou net a 32-33, puis 0,097 en dessous. Sous le genou un
point de SOC vaut 57 % de ce qu il vaut au-dessus, ce qui est coherent avec le
parc reel (un module en panne sur huit, un autre qui faiblit).
Energie utile totale de 100 a 22 % : 12,39 kWh mesures, contre 11,70 vus par le
bilan (15 kWh a plat) et 13,65 par INPUT_PARSE (17,5). Les deux constantes
etaient fausses, dans des sens opposes.
Comme 15 kWh se situe ENTRE les deux pentes, l erreur changeait de signe : SOC
requis trop bas de 3 a 4 points pour un petit deficit, trop haut de 4 a 6 pour
un gros. Cela corrige au passage une affirmation inexacte de la section 40, ou
j avais ecrit que required_soc etait systematiquement trop bas d un facteur
1,75 : ce facteur comparait la vitesse de descente du SOC a celle de la ligne,
deux grandeurs differentes, et l ecart venait surtout de la sous-estimation de
la consommation par le profil p50. La correction est posee en tete de la
section 40.
Trois fonctions remplacent les cinq conversions lineaires de BALANCE.js ;
requiredSocAtStartPct reste non ecrete au-dela de 100, l extrapolation utilisant
la pente haute. INPUT_PARSE passe de 17,5 a 16,9 avec la consigne explicite
qu un calcul traversant le genou doit lire la courbe et non cette constante.
Tests du bilan 42/42 apres mise a jour deliberee de six attendus, chacun verifie
a la main contre la courbe. Un libelle corrige : le seuil fixe de 30 % tombait
juste ce matin-la par coincidence, pas par construction. Deux mutations — pente
basse ramenee a la pente haute, puis genou ramene au plancher — font tomber les
six memes scenarios. Golden 78, hysteresis 7 et advisor inchanges.
Les trois nombres sont des resultats de mesure, pas des reglages, et vivent dans
le code avec l outil qui les produit ; a rejouer apres l extension du parc.
Principale erreur restante du bilan, desormais devant la conversion : le profil
de consommation p50 sous-estimait de 33 % les heures 03-06 de la nuit du
02-03/09. A instruire separement.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
§26 avait pose l objectif et designe le critere. Avant d ecrire quoi que ce
soit, j ai mesure les kWh reellement sortis de la batterie par point de SOC sur
cinq fenetres et trois nuits : 0,164 a 0,171 kWh/point au-dessus de 42 %, soit
environ 17 kWh, mais 0,121 entre 45 et 22 % et 0,082 entre 33 et 20 %. En bas
d echelle un point de SOC vaut moitie moins, alors que BALANCE.js convertit avec
une constante unique de 15 kWh. required_soc y est donc systematiquement trop
bas — c est le facteur 1,75 mesure la nuit du 02-03/09, ou le SOC descendait
bien plus vite que la ligne.
Cette mesure a dicte la conception : le relachement de la session ne peut pas
etre un seuil de SOC, puisqu il porterait sur une grandeur fausse et que tout
seuil que le SOC repasse ensuite rouvre l oscillateur du 27/08. Les deux
variantes evidentes — relacher sur required_soc, ou sur required_soc_prudent
avec la bande p50/p80 — ont ete ecartees pour cette raison.
Retenu : engagement sur le bilan (batterie sous la cible), relachement a la fin
de la fenetre. L oscillation devient structurellement impossible, la condition
de sortie etant monotone : une fenetre ne se ferme qu une fois. Un nouveau
helper input_boolean.victron_evcs_night_grid_session_committed porte
l engagement, cree par input_boolean.reload sans redemarrage HA et ecrit
seulement sur changement reel ; sans cette persistance la garde redeviendrait
une bande, donc un oscillateur.
Effet : l ACM recharge jusqu a la cible puis tient la batterie a 2 A, la maison
finit la nuit sur le reseau en heures creuses au lieu de vider la reserve, et la
batterie arrive a l aube pres de sa cible avec de la place pour le solaire. La
coupure immediate E2 de l hysteresis exige l absence d override et le helper
takeover reste ON : aucune modification du workflow d hysteresis.
Golden 75 -> 78. Le scenario epingle quelques heures plus tot comme limite
connue devient celui du correctif, attendu mis a jour dans le meme commit.
Quatre mutations ; la plus parlante retire la garde bilan et fait tomber les
trois scenarios anti-oscillateur du 27/08 — les tests de l ancien correctif
protegent le nouveau code.
Prerequis identifie et non traite : la conversion kWh vers points de SOC est une
constante la ou la realite est une courbe. Consequence, un sous-declenchement
possible en bas d echelle, jamais une oscillation. Prochain chantier du bilan.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
La regle classait le lendemain en trois paliers a partir de son TOTAL (>= 18 kWh
-> 35 %, >= 10 -> 55 %, sinon 85 %) et ignorait donc l heure d arrivee de
l energie. Le 03/09 demain annoncait 33,9 kWh — donc "fort", donc 35 % — avec un
matin creux (0,03 kWh a 7 h, 0,77 a 8 h) et un croisement a 9 h. Meme defaut que
le plancher du soir, a l autre bout de la nuit.
Releve de la nuit 02-03/09, requis contre reel : 00:30 62,4 / 53 ; 03:00
50,4 / 45 ; 04:30 41,7 / 37 ; 06:00 37,1 / 22 — cible fixe a 35 tout du long.
Le required_soc decroit proprement avec la nuit qui se consomme (6,1 -> 0 kWh a
couvrir), la batterie est restee sous la ligne toute la nuit, et le bilan le
savait des 00:30. A 03:00 EDF a ete relache cinq points sous la ligne ; le
reseau est revenu de 07:24 a 10:33 au plein tarif, 1,49 kWh.
La cible vaut desormais min(90, max(palier ou advisor, required_soc)). Sens
unique delibere : la direction corrigee est celle de l echec observe, et le
principe unificateur des deux cablages est que le bilan ne pousse jamais dans le
sens "couvre moins bien la nuit". Plafond 90 parce qu au-dela la batterie cesse
d etre un puits et evince la production du matin, et parce que le bilan publie
sans ecretage des valeurs superieures a 100 — sans ce plafond la cible serait
inatteignable et EDF resterait allume toute la nuit. C est deja la borne du
chemin advisor, aucune constante nouvelle.
Pas d oscillateur : required_soc decroit de facon monotone pendant la nuit et la
passe unique de recovery reste en place. Gardes et repli identiques au plancher
du soir, kill-switch existant.
Golden 70 -> 75. Quatre mutations font tomber chacune exactement un scenario
different. Un cinquieme scenario fige une LIMITE CONNUE, mesuree par sonde : la
passe unique de recovery latche le relachement pour toute la session, donc la
cible dynamique n ameliore que la premiere passe. §26 avait deja designe le bon
critere de re-engagement — un budget d energie restant a couvrir, qui appartient
au bilan ; la suite touche la machine a etats de la nuit et fera l objet d un
chantier propre.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
grep evcs_balance sur les deux workflows de decision renvoyait 0 depuis la mise
en service du bilan le 26/08 : il calculait l heure de croisement, l energie a
couvrir et le SOC requis, et personne ne l ecoutait. Le 03/09 a 19:44 les deux
nombres coexistaient dans le meme systeme — evening_soc_start_min a 85 %, un
niveau qui ne sait rien de la nuit, contre evcs_balance_required_soc a 99,7 %,
l energie a couvrir jusqu au croisement de 9 h. A SOC 94 le premier autorisait
la charge, le second disait que la batterie ne passerait pas la nuit seule.
Le plancher de demarrage du soir vaut desormais max(regle, bilan). Sens unique
delibere : le bilan peut durcir, jamais relacher. L assouplir — il dira souvent
moins de 85 % par forte prevision d ete — autoriserait des charges qui n ont pas
lieu aujourd hui, decision distincte a valider pour elle-meme. Le max rend au
passage la garde robuste sans borne ni ecretage : une valeur nulle, negative ou
aberrante ne peut pas relacher le plancher.
Portee demarrage : le plancher de maintien reste min(...), donc a 80 %, et
aucune charge en cours n est coupee. L abondance P6 continue de primer, etant
une preuve mesuree que la ressource depasse ce que le systeme absorbe.
Gardes : fraicheur inferieure a 30 min (six cycles du bilan), horodatage futur
rejete, statut ok, valeur finie. Sinon regle historique. Aucun nouveau toggle :
evcs_balance_enabled a OFF arrete les ecritures du bilan, balance_last_run se
fige, la fraicheur expire et le plancher retombe seul sur 85 % en une
demi-heure — un helper de plus aurait fait doublon.
Gabarit complet re-rendu contre HA : 195 champs, JSON valide, aucun null.
parseAdvisorRunToMs reutilise, l advisor et le bilan publiant le meme format.
Golden 66 -> 70. Quatre mutations — bilan ignore, Math.max remplace par une
affectation directe, garde de fraicheur supprimee, garde de statut supprimee —
font tomber chacune exactement un scenario, et un different a chaque fois.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Le correctif precedent bloque l incident de 19:44, mais un excedent proche de
zero est ambigu : c est la signature de la censure ET celle de l equilibre de
fin de journee. Le releve du 03/09 contient les deux avec le meme excedent —
18:50 : +14 W, ressource refusee ; 19:41 : +1 W, plus rien a donner. Rejeu du
19:41 : batteryAssistSolarStartOk etait encore vrai. Trois minutes avant
l incident, le systeme aurait commis la meme faute.
Le plan annoncait de lire evcs_balance_pv_censored. Lecture de CENSORSHIP.js :
ce drapeau est un OU de motifs dont l un est exactement le proxy qu on voulait
remplacer (socPct >= 90 et batterie sans puits). Et il est reste ON jusqu au
calcul de 19:50, soit cinq minutes APRES le demarrage de la charge — ce qui l a
fait basculer n est pas la censure mais sun_elevation passant sous 10 degres.
Il n aurait pas bloque l incident.
Le signal juste, ce sont les chargeurs eux-memes : sept entites
sensor.*_mppt_operation_mode, jamais lues par aucun workflow. mppt_active = je
suis a mon point de puissance maximale, je donne tout ; voltage_current_limited
ou off = je me retiens faute de preneur. Le 03/09 elles ont bascule a 19:20,
soit 24 minutes avant pv_censored, sans aucun proxy et a la cadence de la
boucle. Contre-verification le 01/09 a 14:22 : les trackers restaient limites
PENDANT une charge de 3,4 kW sous 6,9 kW de PV, donc le signal ne s auto-annule
pas a midi.
Collecte sans aucun entity_id code en dur (selectattr sur mppt et
operation_mode), expression testee sur /api/template puis gabarit complet
re-rendu : 191 champs, JSON valide, aucun null. Lectures inexploitables
ecartees, et repli sur le comportement anterieur quand il n en reste aucune.
Garde de DEMARRAGE uniquement, structurellement : la lier au sourceMode ou au
maintien ferait que la charge, en donnant un preneur au MPPT, detruirait sa
propre condition d autorisation — le bistable de l abondance P6 corrige le
24/08.
Golden 64 -> 66. Mutation dans trois directions : garde neutralisee -> 1 echec
cible, provocation toujours refusee -> 3 echecs, lecture illisible traitee
comme "a fond" -> 1 echec sur le scenario de repli.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Le 03/09 a 19:44, voiture branchee : PV 758 W, maison 1202 W, batterie deja
a -12 A, nuit qui tombe. Le controleur a lance 1,6 kW de charge parce que
pv_start_min_w (700 W) est une puissance PV absolue : "758 >= 700, donc il y
a du soleil". L excedent valait -444 W. En 33 minutes la voiture a pris
0,897 kWh et la batterie en a rendu 1,479 kWh (SOC 94 -> 85), la veille d une
nuit que le bilan energetique annoncait deja deficitaire.
Rejeu du releve dans la vraie chaine : rawSolarStartOk ET
batteryAssistSolarStartOk etaient tous deux vrais. Corriger le seul seuil PV
n aurait donc rien change ; les deux chemins sont traites ensemble.
La grandeur juste est ce qui reste une fois la maison servie. Sans injection
et reseau absent, PV - maison(hors EVCS) vaut la puissance batterie au signe
pres, et separe les deux situations que la mesure PV seule confond : sous
censure la production se cale sur la maison, l excedent vaut ~0 et il y a de
la ressource refusee ; en deficit reel l excedent est negatif et la batterie
porte deja la maison. Zero est la frontiere physique entre les deux, verifiee
sur le releve du 03/09 (excedent positif sur toute la plage ou pv_censored
etait ON, negatif ensuite).
Aucune constante nouvelle, aucun champ de snapshot, aucun helper :
derived.houseNonEvcsW existait deja. Le chemin "soleil reel" reutilise
pv_start_min_w tel quel, applique a la bonne grandeur ; le chemin
"provocation" exige seulement excedent >= 0. Demarrage uniquement : les
conditions de maintien gardent leur plancher et leur tolerance temporelle.
Golden 61 -> 64, autour d une paire de releves reels pris a 54 minutes d ecart
dont les lectures PV ne different que de 11 W (769 puis 758) : le premier
demarre, le second non. apresmidi-provocation-p3 est corrige : il portait
PV 300 W, maison 600 W, batterie +2 A reseau ouvert, un trou de 300 W que rien
n alimente, et passait quand meme parce que le demarrage ne regardait jamais
le bilan. Mutation dans les deux sens : 2 echecs cibles a chaque fois,
excedent-censure-demarre restant vert (il tient par le chemin assistance).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
La table des bandes SOC declarait depuis toujours un courant souple tolere
pendant des minutes et un courant dur tolere quelques secondes. Les deux
tolerances etaient calculees, exportees dans le debug, et lues par aucune
decision : le controleur comparait un echantillon instantane a un plancher,
toutes les 30 s.
A SOC 94 la batterie est en float et son courant oscille entre +1,8 et -2,6 A
d'un echantillon a l'autre. Le test devenait un tirage a pile ou face et la
charge du vehicule s'arretait sur du bruit : deux fois le 01/09, quatre a six
fois par jour la semaine precedente. Chaque arret coutait environ 0,45 kWh,
la batterie etant pleine et le vehicule le seul preneur.
Le correctif est purement temporel : aucun seuil n'est deplace, aucune
constante ajoutee. La tolerance de la bande est branchee sur les trois
conditions de MAINTIEN, via un helper de persistance qui porte le debut du
depassement en cours. Le plancher de demarrage et le garde dur restent
instantanes : la tolerance est du confort, jamais du risque.
Golden 56 -> 61. Preuve par mutation dans les deux sens : tolerance supprimee
-> 2 echecs cibles, tolerance infinie -> 3 echecs cibles, l'arret dur restant
vert dans les deux cas.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Integration de l historique HA sur 8 jours : 64% de l energie livree au
vehicule vient d un excedent reel, 16% sort de la reserve batterie. La
frontiere se ferme entre 18h30 et 19h50 fin aout, franchement.
Cote reserve nocturne, le bilan repond deja et il repond mal a notre
avantage : sept jours sur huit, meme pleine, la batterie ne passe pas la
nuit. Le deficit est structurel, ce qui est evitable c est de l aggraver.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Campagne decisive a SOC 90-92 %, batterie n absorbant plus que 22 A. La
fermeture du contacteur fait bien chuter la production de 79 % en un pas de
mesure (2663 -> 559 W), simultanement a l apparition de l import -- l
observation du proprietaire est exacte. Mais la recuperation est totale en
~2 min 30 : import 112 W et production 3158 W, au-dessus du niveau d avant.
Etat etabli hors transitoire : -7,0 % et +2,0 % contre les phases ouvertes
voisines. Aucune substitution permanente.
Meme mecanisme qu a batterie preneuse ; sans tampon, la seule variable d
ajustement est le bridage des MPPT, d ou l effet spectaculaire. Avec l ancienne
consigne a 4200 W le transitoire ne pouvait pas se terminer. Cout par
fermeture : ~150 Wh batterie pleine, ~50 Wh sinon.
Ni VEConfigure ni firmware justifies par ces mesures.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Nuit complete + deux campagnes alternees apres la correction de la consigne
reseau (4200 -> 50 W) : l'import colle a la consommation, la production monte
librement contacteur ferme, et les transitions locales donnent +0,5 % et
+13,1 % la ou le 27/08 mesurait -73 %.
Le transitoire de fermeture est caracterise : le reseau reprend toute la maison
et le solaire bascule vers la batterie, puis l'import retombe a la consigne en
~2 min 15 (25 W, 52 W). Cout ~50-60 Wh par fermeture.
Outillage : tools/test-edf-alterne.mjs (protocole alterne, restauration
garantie) et tools/analyse-test-alterne.mjs. Deux pieges d'instrumentation
corriges -- garde meteo quand les phases ouvertes divergent entre elles, et
biais du parseur qui laissait tomber les lignes ou le premier tracker etait
bride.
Reste ouvert : le cas batterie pleine, celui que le proprietaire designe comme
decisif, ou le solaire n'a plus de destination quand le reseau reprend la maison.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Le mode ESS passe en « Optimise sans BatteryLife » depuis l'ecran GX — le mode
n'est pas expose a Home Assistant, contrairement a tous les autres reglages ESS.
La limite de SOC active tombe immediatement de 40 a 20 %, au lieu de descendre
par paliers de 5 % sur quatre jours, et l'etat BatteryLife devient
self_consumption_soc_above_min.
Le GX cesse ainsi d'entretenir une limite dynamique que rien dans les workflows
ne lisait et qui montait de 5 % chaque nuit. C'est le troisieme acteur non lu de
la decision reseau neutralise en quatre jours, apres les charges programmees de
l'ESS et la consigne de puissance a 4200 W.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Trois reglages GX modifies ce soir, journal rempli dans la procedure.
Le point de consigne reseau passe de 4200 a 50 W a 21:46 : c'est la correction
visee, et desormais la seule variable qui separe l'installation des mesures du
27/08. Le test alterne pourra donc etre interprete.
Deux parametres avaient ete pris pour des limites de SOC alors qu'ils sont des
pourcentages des courants declares par la batterie. A 20 % de DCL la decharge
aurait ete plafonnee a 30 A, soit 1,5 kW, quand la maison avait tire 73,7 A le
soir meme. Remis a 100 % / 100 %, leur valeur par defaut : Victron les range
lui-meme sous « parametres obsoletes », DVCC en est le proprietaire reel.
Le plancher ESS descend de 40 a 20 % pour cesser de concurrencer la cible du
matin du controleur. Mais la limite qui agit reellement reste a 40 % :
BatteryLife maintient sa propre limite dynamique, qui monte de 5 % chaque nuit
et ne redescend que de 5 % par journee de charge complete — l'historique de
sept jours ne la montre jamais sous 40. Soit on attend quatre jours, soit on
bascule le mode ESS sur « sans BatteryLife ». Les deux options sont
documentees, le choix revient au proprietaire.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Le symptome prouve le 27/08 (73 % de la production solaire remplacee par du
reseau des que le contacteur se ferme) trouve une explication complete cote
GX, sans toucher aux onduleurs.
number.gx_device_ac_power_setpoint vaut 4200 W la ou le defaut Victron est
50 W. C'est le Grid setpoint de l'ESS : la puissance que le systeme s'efforce
en permanence de prelever sur le reseau. L'ESS regulant la puissance au point
de raccordement, son seul levier pour faire place a cet import quand la maison
et la batterie sont deja servies est de brider les MPPT via DVCC.
Les deux campagnes du 27/08 se reconcilient arithmetiquement : a 10:47 l'import
monte a 4113 W, soit la consigne ; a 11:38 la batterie en absorption n'accepte
que ~1070 W et conso 2258 + batterie 1070 - PV 1043 = 2285 W contre 2287
mesures. Le residu constant de ~1040 W etait la signature d'un plancher, pas
d'une reduction proportionnelle.
Seconde trouvaille : le SOC minimal de l'ESS est a 40 %, au-dessus de la cible
de 35 % du controleur. Le GX recharge donc sur le reseau de sa propre
initiative des que le controleur relache — etat `recharge` observe les 29 et
30/08. Troisieme automate contradictoire sur la meme batterie apres les charges
programmees. Arbitrage laisse au proprietaire.
L'assistant ESS tourne et aucune alarme VE.Bus n'est levee : l'hypothese d'un
assistant perdu au passage en parallele est affaiblie, pas eliminee. La partie
VEConfigure reste donc en seconde intention dans la procedure, avec sauvegarde
obligatoire et interdiction de relancer le System Configurator.
Aucun reglage n'est modifie ici : ce commit ne contient que le diagnostic et la
procedure.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Protocole alterne OFF/ON/OFF/ON, 15 s d echantillon, avec la tension batterie
et l etat des chargeurs MPPT — des capteurs qu aucun workflow ne lisait.
PV 3858 W hors reseau, 1112 W reseau present, 4025 W hors reseau, 1043 W
reseau present, 4358 W a la fin. Consommation inchangee, DVCC constant,
batterie loin de la saturation. Bascule en 75-90 s, retour en 32 s, quatre
fois. La production moyenne est plus haute a la fin qu au debut : l hypothese
nuages du test precedent est morte.
Ce n est pas la censure normale par manque de preneur : le solaire alimentait
integralement les memes charges 90 s plus tot. Anomalie apparue depuis le
passage des deux MultiPlus II en maitre/esclave. Piste configuration ESS en
parallele avant tout firmware.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Le test infirme deux hypotheses et en decouvre une troisieme. La limite DVCC
reste a 130 A pendant toute la fenetre : l Auto Charge Manager n est pas en
cause. Aucun bridage du MPPT visible, mais la batterie avait 25 points de
marge — la condition du proprietaire (batterie pleine) n est pas reproduite,
donc son observation n est pas contredite, seulement pas testee.
En revanche, fermer EDF fait importer du reseau en rampe jusqu a 4113 W pour
charger la batterie, conso maison a 880 W. A la coupure le courant batterie
tombe de 104,6 a 25,7 A en 15 s. Les programmations ESS etaient deja
desactivees : le proprietaire de cet ordre reste a identifier.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Trois fenetres actives tous les jours (01:35 et 07:30 vers 45 %, 12:24 vers
55 %) chargeaient la batterie sur le reseau des qu EDF etait present, en
concurrence avec la cible du matin de l EVCS. C etait un contournement manuel
du proprietaire, utile l hiver, inutile l ete. Les cinq sont desactivees : le
controleur EVCS est seul proprietaire de la decision reseau.
Consigne le besoin hivernal correspondant : en heure solaire l hiver ajoute
~2 h de nuit a couvrir, donc la cible du matin doit monter vers 80 % et se
deduire du croisement production/consommation, pas d un palier fixe.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
La bande de 2 points du Fix A engageait le takeover a SOC 33 et le relachait
a 35 : 0,34 kWh, soit une demi-heure de conso nocturne plate. Trois cycles EDF
la nuit du 26-27/08, six la nuit du 20-21/08, 2,5 kWh importes pour rien.
Une seule passe de recovery par session de nuit. Le plancher dur reste un
terme independant, l hysteresis garde sa bande 20/30, et le vrai critere de
re-engagement (un budget d energie) appartient au bilan, pas a une constante
de plus ici.
Golden 40 -> 42, preuve par mutation. Documente aussi deux acteurs non lus :
les charges programmees de l ESS (45 % la nuit, contre notre cible 35 %) et
le regime majoritairement hors reseau.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Le drapeau « degrade » introduit la veille s'allumait de 20 h a 07 h toutes les
nuits. La qualite de forme d'une heure vient du taux de censure ; les heures
sans soleil portent un taux de 1 faute d'avoir quoi que ce soit a observer, pas
parce que la mesure serait douteuse. Comme les heures de deficit sont justement
les heures sans soleil, le drapeau se declenchait exactement quand le bilan
sert.
Une heure dont l'enveloppe demontree est nulle recoit desormais la qualite
'nuit'. Scenario epingle sur l'enveloppe et le taux de censure releves en
production, pas sur le fixture — dont la nuit valait 0 et qui ne reproduisait
donc pas le defaut. Preuve par mutation : avant 'minoree', apres 'nuit'.
Suite 37 -> 38. Documente la nuit du 25-26/08 : profil corrige verifie a
0,2 kWh/h pres, bilan qui predit le point bas a un point pres, et non-linearite
du SOC mesuree (huit points en dix-sept minutes pour 0,16 kWh).
Journal de la premiere nuit observee avec le bilan en service : 12,30 kWh
importes, dont 1,19 kWh entre 06 h et 07 h sans aucun vehicule en charge, en
deux cycles EDF de ~25 min. Cause : la cible SOC du matin (35 %, valeur de
table) avec liberation a `SOC > cible` et rearmement a `SOC <= cible - 2` —
meme pathologie que les trois oscillateurs du 24/08, sur un autre seuil.
Corrige aussi le chiffre de la part matinale de production, une troisieme fois :
l'enveloppe subissait le meme decalage d'une heure. Le « 39,3 % du matin » est
abandonne dans le manuel comme dans le journal de chantier.
Ajoute la note sur `initial: off` du toggle advisor : tout redemarrage de Home
Assistant le repositionne a OFF.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
RESOURCE_ESTIMATE consomme desormais la courbe horaire publiee par le workflow
de prevision : forme et magnitude d'un seul tenant, sur 6 jours, avec les trois
plans reels et sans censure. Plus de repartition au prorata, plus de
renormalisation — le noeud se simplifie.
L'enveloppe est retrogradee en repli, utilisee seulement si la courbe est
absente ou vieille de plus d'une heure, le champ `mode` disant laquelle a
servi. Elle garde un role de repere de vraisemblance mais n'ecrete PLUS la
prevision : etant minoree l'apres-midi, elle tronquerait a tort une prevision
correcte.
Piege corrige au passage : le nouveau champ `source` entrait en collision avec
l'objet `source` deja present dans la sortie et etait silencieusement ecrase.
Renomme en `mode`.
Suite portee a 35 scenarios (courbe fraiche lue telle quelle, courbe perimee
basculant en repli).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Configuration appliquee (3 plans, inverter_size 11000, cle Professional) : la
prevision du jour passe de 30,2 a 43,5 kWh, aucune erreur au journal. Pieges
d'API notes : convention d'azimut inverse (0 = sud), et plans multiples en
triplets successifs dans le chemin, pas en listes separees par virgules (422).
Test : forme ciel clair contre enveloppe mesuree — matin 21,4 % contre 39,3 %
(c'etait 15,1 % avant), ecart absolu moyen de 4,5 a 2,53 points. Amelioration
nette mais ecart residuel.
Confrontation plan par plan contre le MPPT correspondant, sur les 4 heures a
censure <= 4 % : le modele ciel clair de Forecast.Solar presente exactement le
meme biais que mon modele geometrique local. Deux modeles independants
s'accordent et divergent de l'enveloppe — c'est donc l'enveloppe qui a tort.
Mecanisme : un maximum horaire pris sur des jours differents surpondere le
matin, dont la variabilite jour a jour est plus forte qu'a midi.
Correction assumee : le "39,3 % du matin mesures" cite toute la journee comme
preuve du defaut de configuration etait lui-meme gonfle. Le defaut etait reel,
son ampleur surestimee.
Consequence : l'enveloppe doit ceder la place a la courbe horaire de l'API dans
RESOURCE_ESTIMATE, qui apporte forme et magnitude sur 6 jours.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Tentative de produire la forme horaire depuis la geometrie et les quatre
orientations reelles, pour eviter l'abonnement. Abandonnee pour trois raisons
cumulees.
Seules 4 heures de la journee sont exploitables (censure 0-4 % de 08 a 11 h,
puis 59 % a 12 h, 77 % a 13 h, 81 % a 14 h) : ajuster une forme journaliere sur
quatre heures propres n'est pas serieux. L'enveloppe n'est de plus pas une
courbe de journee valide — c'est le maximum horaire pris independamment sur des
jours differents, donc plus plate que n'importe quelle journee reelle. Enfin le
modele direct seul predit zero production matinale sur le plan ouest la ou la
mesure donne 14 % a 9 h : il manquait le rayonnement diffus, dont la fraction
ajustee part en butee sans converger, le modele restant trop pique sur midi
pour les quatre plans a la fois.
Decouverte utile : correspondance etablie entre entrees MPPT et orientations —
airtria_mppt1 = 10 PV sud-est (pic 11 h), v1 = 3 PV suiveur (pic 9 h),
RS450 tracker_solar_1/2/3 = 3 strings sud (pics 13-14 h), tracker_solar_4 =
string ouest (trainee jusqu'a 19 h). Chaque plan est donc confrontable a sa
propre mesure.
Consequence : l'abonnement Professional est le bon choix, pour une raison que
je n'avais pas identifiee en le deconseillant. Avec la cle, n8n interrogera
api.forecast.solar directement et obtiendra la courbe horaire complete, que
l'integration HA n'expose pas meme abonnee. Cette courbe remplacera a la fois
la forme et la magnitude dans RESOURCE_ESTIMATE.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
52 panneaux RECOM/SILLIA 310 Wc, 16 120 Wc au total, quatre orientations :
10 en sud-est a 40 degres (2 strings de 5), 30 plein sud a 35 degres (3 strings
de 10), 9 plein ouest a 45 degres (1 string de 9), et 3 sur un tracker qui
demarre plein est puis suit la course du soleil, dont la moitie passe a l'ombre
du support des 30 panneaux sud en fin d'apres-midi.
Configuration Forecast.Solar reelle lue dans .storage : un seul plan, plein sud
a 25 degres, 15 000 Wc, avec un inverter_size de 8 000 W alors que
l'installation a deja produit 10 770 W mesures — le plafond tronque donc toute
prevision. Les quatre plans a declarer et la valeur d'inverter_size corrigee
sont inscrits dans la doc.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Dashboard YAML dedie "bilan-energetique", declare dans configuration.yaml et
copie versionnee dans dashboards/ du depot.
Vue Bilan : la comparaison qui decidera du cablage — seuil calcule, seuil fixe
encore en vigueur, SOC reel — avec un commentaire automatique disant lequel des
deux est trop haut ou trop bas ; la decision immediate ; la prochaine traversee
deficitaire ; une alerte conditionnelle chiffrant la capacite manquante quand
meme une batterie pleine ne passe pas ; l'etat de bridage de la production avec
son motif ; deux graphiques d'historique sur 48 h.
Vue Profils et reglages : tableau horaire des quatre profils avec le taux de
censure par heure, capacite batterie modifiable, kill-switch, statut.
configuration.yaml sauvegarde dans SAVE_CONFIG/ avant modification,
check_config valide, redemarrage HA effectue, journal sans erreur nouvelle.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
5c — BALANCE ne repondait qu'a "combien jusqu'a ce que le solaire prenne le
relais". A 15 h la reponse est zero : exacte mais inutile, le deficit qui
approche etant celui de la nuit. Ajout de la prochaine traversee deficitaire
(heure de debut, energie, SOC a atteindre avant). Ce SOC n'est PAS ecrete a
100 % : au-dela, meme une batterie pleine ne passe pas, et le manque est
publie comme storage_shortfall_kwh — c'est le chiffre du dimensionnement.
5b — Workflow "EVCS Energy Profiles Daily V1" (N6UaB4ZozsbRPrFb), actif,
03:30 : lit /api/history/period sur 30 jours glissants et republie les quatre
CSV (conso p50 et p80, enveloppe de production, taux de censure).
CONSUMPTION_PROFILE devient DAILY_PROFILES et sait desormais decoder la
reponse brute de l'API en plus des series deja pretes.
Piege trouve : sans end_time, /api/history/period ne renvoie qu'UNE journee,
silencieusement. Mes premieres mesures "sur 3 jours" n'en couvraient qu'une.
Validation croisee : profils calcules depuis l'API REST (etats bruts, 11 j)
contre profils calcules depuis les statistiques long terme (28 j) — 0,20 kWh/h
d'ecart absolu moyen, par deux chemins de donnees independants.
BUILD_HA_CALLS_PROFILES refuse d'ecraser les profils en place si l'historique
ne couvre pas les 24 heures. Meme garantie de perimetre que le bilan.
Suite a 27 scenarios.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
BALANCE.js ne pilote rien : il publie les faits qui remplacent les seuils fixes
— heure de croisement, energie a couvrir, SOC requis (remplacant de
grid_soc_off), energie reseau strictement necessaire, surplus disponible pour
le vehicule, indice de confiance. Sans une de ses entrees il se declare
inutilisable et les controleurs gardent leurs regles.
Deux niveaux de prudence. Le premier jet n'utilisait que le profil p80 et
exigeait 48 % de SOC pour franchir la matinee du 24/08, soit plus cher que le
seuil fixe de 30 % qu'il remplace. Corrige : la decision reseau, reevaluee a
chaque cycle et reversible, utilise le profil typique p50 ; le prudent p80 sert
a la planification. La marge de securite de 10 % ajoutee au depart etait une
constante arbitraire et un double comptage : mesure faite, p80(somme) egale
somme(p80) sur toutes les fenetres, les heures de consommation etant fortement
correlees. Marge supprimee.
Rejeu fige de la matinee du 24/08 (SOC 21 %, capacite 15 kWh, production
reellement mesuree) : croisement a 08 h, 0,82 kWh a couvrir contre 0,80 calcule
a la main, SOC requis 27,5 %, une session reseau de 0,97 kWh. Suite a 21
scenarios.
MANUEL_COMPLET section 0 : description materielle complete relevee dans VRM et
completee par le proprietaire — 2 MultiPlus-II 48/5000 en parallele, 53
panneaux sur trois orientations (10 est/sud-est, 30 sud, 10 ouest, 3 sur un
petit MPPT), parc Pylontech, borne 32 A. Explique pourquoi aucun modele
solaire mono-plan ne peut representer la production, et pourquoi Forecast.Solar
mal configure se trompe de repartition.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
RESOURCE_ESTIMATE.js. Recalage de la prevision : ecarte, la censure est
correlee au beau temps (facteur 4,29 a 9 h sur 27 echantillons contre 0,48 a
15 h sur 3), les donnees manquantes ne le sont pas au hasard. Forme
geometrique : ecartee, un plan unique ajuste sur les heures propres converge
sur plein est 20 degres et predit 2,0 % de la journee a 18 h contre 5,8 %
mesures — le champ a plusieurs orientations que ce modele ne represente pas.
Retenu : forme = enveloppe horaire demontree (comportement reel du champ, sans
modele), magnitude = prevision Forecast.Solar (meteo, insensible a notre
batterie). L'enveloppe de l'apres-midi etant elle-meme censuree, le noeud
publie un indice de confiance et signale les heures minorees au lieu de les
presenter comme fiables. Sans enveloppe, il se declare inutilisable plutot que
d'inventer une forme.
Defaut trouve au passage : l'orientation declaree a Forecast.Solar ne
correspond pas au champ. Matin 07-11 h, 15,1 % de la journee prevus contre
39,3 % reels ; apres-midi 14-18 h, 52,1 % contre 35,2 %. Les totaux
journaliers tiennent, la repartition intra-journaliere est inutilisable.
Suite portee a 17 scenarios.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Parc reel : 8 US2000C en 2 packs de 4 avec hub, packs d'ages differents, un
module en panne et isole (7 actifs), un autre qui faiblit. Consequence :
batteryUsableCapacityKwh = 17,5 code en dur dans INPUT_PARSE surestime la
reserve reelle de 15 a 20 %. Aucun capteur de capacite ou de sante batterie
n'existe cote HA.
Energie perdue faute de puits : la premiere estimation (23,9 kWh/jour, 38 %)
etait fausse. Le facteur de recalage global de 1,22 est domine par les heures
de 8-9 h ou il vaut 4 a 7. Probleme structurel : la censure est correlee au
beau temps, donc les donnees manquantes ne le sont pas au hasard et aucun
facteur appris sur cet echantillon n'est transportable. Cela invalide le plan
initial de l'etape 3.
Estimation retenue, borne basse sans recalage, plafonnee par l'enveloppe
horaire reellement demontree : 11,8 kWh/jour en moyenne, 23 % de la ressource.
On jette donc plus qu'on n'importe (7,83 kWh/jour) : l'energie existe, il
manque le reservoir. +8 kWh utiles sont a la fois necessaires et remplissables.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Le proprietaire vise l'autonomie et doit decider combien de batteries ajouter.
La ressource gaspillee par la censure est exactement l'energie qu'un stockage
supplementaire capterait : le bilan doit donc aussi estimer l'energie perdue
faute de puits et le gain par kWh ajoute.
Constat mesure sur 27 jours : import reseau 7,83 kWh/jour en moyenne, un seul
jour sur 27 a zero ; decharge batterie 11,5 kWh/jour en moyenne, p90 14,3, max
16,1 sur 17,5 utiles. La batterie se vide presque integralement chaque jour :
c'est elle le facteur limitant, pas la puissance des onduleurs.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
CONSUMPTION_PROFILE.js : compteurs d'energie cumules -> deltas horaires ->
distribution par heure de la journee -> percentiles. La consommation du
vehicule est retiree : c'est une charge pilotable, elle ne doit pas polluer le
profil de la charge subie. Les remises a zero de compteur et les deltas
implausibles sont jetes, jamais rattrapes par une valeur inventee, et une heure
sans assez de jours observes est marquee non fiable au lieu d'etre publiee en
silence.
Valide sur 28 jours reels (639 heures, 0 reset) : 31,9 kWh/jour typique hors
vehicule, 42,8 kWh au p80. Le profil tient dans un helper input_text
(119 caracteres sur 255).
Verification prealable de la methode : seulement 7,8 % des heures de deficit
sont censurees. Censure et deficit sont physiquement presque exclusifs, donc la
grandeur qui pilote la decision EDF est mesuree sur des donnees propres.
Suite tests/energy-balance/ etendue aux deux noeuds : 14 scenarios.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Sans injection reseau, PV_mesuree = min(ressource, conso + absorption batterie).
La mesure est donc censuree a droite des que la batterie est pleine ou que le
reseau alimente AC-IN. Mesure sur l'historique du 28/07 au 24/08 : 48 % des
heures de jour sont censurees, 77 a 96 % a partir de 13 h. Un profil de
production bati sur la mesure brute mesure en realite sa propre consommation.
src/energy-balance/HA_SNAPSHOT_TEMPLATE.json.tpl : 26 champs, dont tous les
signaux qu'aucun workflow ne lisait jusqu'ici — etats des trois MPPT, etat
VE.Bus, alarme de surcharge onduleur, ESS BatteryLife, etat du bus DC, statut
natif de la borne, prevision horaire, elevation du soleil.
src/energy-balance/CENSORSHIP.js : qualifie chaque echantillon (censure et ses
motifs, exploitabilite) et verifie en continu l'identite du bus DC
PV + VE.Bus = batterie, qui boucle a 95 W pres — un capteur qui derive devient
detectable. Ne decide rien.
tests/energy-balance/ : 10 scenarios, dont un snapshot reel du 24/08 14:29
(soleil 52 degres, prevision 3462 W, production bridee a 1159 W, SOC 94 %)
correctement classe censure.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Journal leger pour ne rien perdre en route (documentation definitive a la fin,
comme convenu) : decisions actees, sorties attendues du bilan, et backlog des
defauts releves en chemin — doublon unique_id victron_vebus_dc_power,
evcsDedicatedMaxW code en dur, alarmes et etats MPPT jamais lus, controle de
vraisemblance PV + VE.Bus = batterie, etats zombies source_lost.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Incident du 24/08 12:24-12:28 : bascule de profil vers midday_hc_or_solar
avec SOC 58 %. Plancher de demarrage = min(midday_soc_min 75, abondance P6
40) = 40 ; plancher de maintien = max(soc_stop_min 29, 75-15) = 60. Le
systeme avait donc le droit de DEMARRER ce qu'il n'avait pas le droit de
MAINTENIR : cycle limite a la periode de min_run (3 min) sur toute la bande
[40 %, 60 %], et ~2,6 kW de PV ecretes a chaque creux (PV 10,24 kW -> 7,64 kW
quand la borne s'arrete, ESS sans injection).
Deux volets indissociables dans BATTERY_CLOUD_LOCKS.js :
- effectiveSocHoldFloor = min(regle du profil, plancher de demarrage
effectif). Sans abondance, comportement inchange.
- l'abondance P6 se prouve au demarrage (batterie >= +20 A) mais se maintient
en charge (batterie >= 0) : sinon la charge du vehicule, qui detourne
precisement le surplus, detruit sa propre condition d'autorisation.
Golden 39 -> 40. Preuve par mutation sur midday-inversion-start-hold : code
d'avant -> stop / "Conditions de maintien perdues", apres -> step_up 19 A.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Fix G provoquait un yoyo EDF de 2-4 min (coupure a SOC 21 en bypass min_on
contre rallumage a SOC 20 en bypass cooldown) : son garde `soc > gridSocOn`
ne protegeait que l'instant de l'engagement sur SOC bas, pas la phase de
remontee 20 -> 30. jsCode restaure byte-identique a la version pre-Fix-G.
Le fixture de test portait les fallbacks du code (22/35) au lieu des valeurs
de production lues via MCP (20/30), et le scenario de non-regression testait
SOC 18 %, le seul point que Fix G epargnait. Suite reecrite avec les
garde-fous manquants h-recovery-band-no-cut-21/-25. Mutation : Fix G
reapplique -> 4/7 echecs, retire -> 7/7.
Documentation du diagnostic des deux oscillateurs (yoyo EDF et oscillation
de la charge EVCS en plein soleil) dans MANUEL_COMPLET 11.8 et HANDOFF 25.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
Incident nuit 21-22/08 : la fenêtre HC nuit se ferme pendant que le véhicule
est encore en session active (pas encore flag "charge terminée"). L'EVCS
relâche correctement son override, mais émet un état transitoire générique
(stop_source_lost/idle_wait_source) qu'aucune règle de coupure immédiate du
workflow Grid Hysteresis (Fix C/E2) ne reconnaît. EDF restait alors maintenu
des heures par la boucle générique jusqu'au seuil statique gridSocOff,
plafonnant le MPPT Victron à ~100W et privant la maison de solaire.
Nouvelle règle générique (Compute Grid Hysteresis) basée sur evcsGridOverride
plutôt que sur une liste blanche de noms de surplus_state — couvre donc aussi
tout futur état non énuméré. Garde anti-glitch sur lecture HA invalide.
Nouvelle suite tests/golden-hysteresis/ (7 scénarios, première pour ce
workflow), câblée bloquante dans tools/n8n-push.mjs. Déployé et validé
(golden-hysteresis 7/7, golden EVCS 39/39 inchangé).
Écarte le diagnostic incomplet laissé par un autre agent dans HANDOFF.md
(edf_general_ok_off côté EVCS aurait créé un deuxième écrivain non coordonné
sur le même switch).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- WINDOWS: dayVehicleFullIdle (statut 3 ou VDF, héritages jour<->nuit),
sourceMode blocked même face au solaire
- DECISION: branche collante day_vehicle_full_idle au-dessus des gardes
- échappatoires force_charge_now/force_grid_now (golden)
- golden 33->36, validé live 10:04:30 (latch en 16 s sur la VW pleine)
- HANDOFF §22 + MANUEL états collants