From cfb63f072b6dea51cab5e0be155a864d51afa073 Mon Sep 17 00:00:00 2001 From: Tallagrand Thierry Date: Tue, 15 Sep 2026 06:25:51 +0200 Subject: [PATCH] Section 68 : P12, et la contrainte que seul l essai reel pouvait montrer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj --- HANDOFF.md | 117 ++++++++++++++++++++++++++++++++++++ dashboards/evcs_master.yaml | 4 ++ tests/golden/scenarios.mjs | 37 ++++++++++++ 3 files changed, 158 insertions(+) diff --git a/HANDOFF.md b/HANDOFF.md index adaed7c..410862f 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -6494,3 +6494,120 @@ normales du cycle jour/nuit ne doivent pas. --- *Document mis a jour le : 14/09/2026 (~03:20) — auteur des transitions repare et deploye, 7 cas valides en rejeu* + + +## 68. Nuit du 14 au 15/09/2026 — P12 : la voiture se charge sur le solaire d'hier + +### L'idee, et le calcul qui la fonde +Le proprietaire, le 14 au soir : plutot qu'acheter du reseau la nuit pour +charger la voiture, lui donner le solaire DEJA STOCKE — doucement, a courant +minimal — et laisser ainsi de la place dans la batterie pour la production du +lendemain. « Payer du reseau la nuit pour ecreter le solaire le lendemain, c'est +perdre deux fois. » + +Projection sur la prevision du 15/09 (38,7 kWh, pic a 16 h) : + +| scenario | SOC a 9 h | ecrete | +|---|---:|---:| +| VW sur EDF (ce qui s'est passe) | 55 % | **10,5 kWh** | +| VW sur batterie, 4 kWh | 38 % | 5,3 kWh | +| + JEEP qui charge le matin | 38 % | **0,0 kWh** | + +Releve de la nuit reelle : **8 kWh achetes au reseau**, batterie encore a **69 % +a 5 h du matin**. Confirmation par l'exemple. + +### Ce qui existait deja, et etait mort +Le mode `battery_assist_night` existe depuis l'origine pour exactement cela, et +**n'a jamais demarre une seule fois** : il exige +`batteryCurrentA >= plancher de decharge du profil` (0 A), condition impossible +la nuit puisque la maison tire sur la batterie (§11, ~ -14 A). On n'a donc pas +cree un chemin, on a rendu 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`, +publie par le bilan 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 quand le surplus est epuise est automatique — la +soupape decrite par le proprietaire, sans aucune regle horaire. + +### ⚠️ Le verrou anti-oscillateur, trouve en construisant +Le plancher DESCEND pendant la nuit (il reste moins de nuit a couvrir) et le SOC +aussi. Mesure : + +| | SOC | plancher | surplus | +|---|---:|---:|---| +| voiture EN CHARGE | −7,1 pt/h | −3,7 pt/h | s'epuise | +| voiture ARRETEE | −2,6 pt/h | −3,7 pt/h | **REAPPARAIT** | + +Sans verrou, la charge repartirait des qu'elle s'arrete : cinquieme oscillateur +du projet, par construction. **Une seule passe de surplus par session de nuit**, +comme la recovery batterie depuis le 27/08. Helper +`input_boolean.victron_evcs_night_battery_done`. + +### ⚠️ ET LA CONTRAINTE TROUVEE EN ESSAI REEL : P12 DOIT GAGNER LE PREMIER CYCLE +Essai du 15/09 a 05:30. P7 s'etait engage a **05:13**, avant que le toggle P12 ne +soit active a 05:20. Resultat mesure dans l'execution : + + nightBatterySurplusAvailable = true <- P12 fonctionne + nightGridHcPreferred = false <- il a bien desengage P7 + nightTakeoverLatched = true <- MAIS le verrou de juillet tient + nightGridTakeoverNeeded = true + sourceMode = grid_hc_allowed + +Le verrou anti-creneaux P2 (09/07) maintient `nightGridTakeoverNeeded` +independamment de `nightGridHcPreferred`. **Et c'est le comportement SUR** : +basculer reseau → batterie en pleine session est exactement le creneau que ce +verrou existe pour empecher. + +Consequence : **si la reprise reseau s'engage avant P12, le reseau est verrouille +pour la session.** Aucun des cinq scenarios initiaux ne le montrait — ils partent +tous d'une nuit vierge. Le test propre se fait avec P12 deja actif a l'ouverture +de la fenetre HC. + +### Tests : 96 → 102 +`p12-charge-nuit-sur-batterie` (SOC 69 au-dessus du plancher 38,7 → la voiture +demarre a 6 A sur la batterie) · `p12-surplus-epuise-le-reseau-prend-le-relais` +(SOC 37 sous le plancher → P7 reprend) · `p12-verrou-pas-de-reprise-du-surplus` +(SOC repasse au-dessus mais verrou pose) · `p12-toggle-off-comportement-historique` +· `p12-bilan-perime-pas-de-charge-batterie` · et +`p12-verrou-p2-tient-si-le-reseau-est-deja-engage`, ajoute apres l'essai reel. + +**Deux faiblesses trouvees par la mutation, et elles valent d'etre notees :** +1. Les attendus ne verifiaient que le choix du MODE, pas que la voiture charge. + Neutraliser la condition de demarrage dans BCL ne cassait aucun scenario. + Corrige : `state`, `decision`, `desiredCharging`, `currentA` sont verifies. +2. La garde de fraicheur du bilan n'etait couverte par aucun scenario — un bilan + perime aurait laisse vider la batterie sur un plancher obsolete. + +⚠️ Et une mutation qui ne mute RIEN ne prouve rien : ma premiere tentative sur le +verrou P2 cherchait `nightTakeoverLatched ||`, motif absent du fichier. Zero +occurrence, zero echec, et j'allais conclure que le test tenait. **Toujours +verifier que le motif existe avant de lire le resultat d'une mutation.** + +### La table de politique batterie assouplie, et un piege de 50 helpers +Pour que P12 puisse descendre sous SOC 60, `batt_discharge_soft_40_60_a` passe de +−12 a −15 A de base, soit **39 → 49 A appliques** (parkScale 13/4) : 3,5 A par +equivalent US2000, 19 % de ce que le BMS autorise. Le garde DUR ne bouge pas +(−98 A appliques). + +⚠️ **Les 50 helpers de la table portaient un `initial:`**, qui DESACTIVE la +restauration d'etat : chaque redemarrage de Home Assistant les remet a leur +valeur d'origine, en silence. Le reglage aurait ete annule par le redemarrage +prevu le soir meme. Meme defaut que les cinq helpers corriges le 06/09, mais ici +sur une table entiere de REGLAGE — donc sur tout ajustement futur. +Retire, et **verifie par le redemarrage du 15/09 05:11** : `initial: aucun`, la +valeur −15 a survecu. + +### Corrections a mes propres affirmations +Deux fois de suite j'ai annonce un blocage inexistant, et le proprietaire a eu +raison de pousser : +1. « Le garde dur bloquerait P12 a −30 A » — **faux**, je lisais les valeurs de + BASE de la table en croyant lire les valeurs APPLIQUEES. `parkScale` existe + et vaut 13/4 ; le garde dur applique vaut −98 A. +2. « Le bilan sous-estime la batterie de 30 % » — **faux**, j'avais divise une + courbe par morceaux par un seul ratio. Le bilan met sa courbe a l'echelle par + `modules_en_service / 7` et donne 0,314 kWh/point, contre **0,308 mesure**. + Quant a `usable_capacity_kwh` = 15, il est INERTE depuis le 03/09. + +--- +*Document mis a jour le : 15/09/2026 (~05:45) — P12 construit, teste (102/102) et deploye ; contrainte du premier cycle trouvee en essai reel* diff --git a/dashboards/evcs_master.yaml b/dashboards/evcs_master.yaml index de55251..42a2ae0 100755 --- a/dashboards/evcs_master.yaml +++ b/dashboards/evcs_master.yaml @@ -198,6 +198,10 @@ views: name: Stratégie EVCS - entity: input_boolean.victron_evcs_allow_grid_hc_night name: Réseau HC nuit + - entity: input_boolean.victron_evcs_night_battery_charge + name: 🔋 Charge nuit sur batterie (P12) + - entity: input_boolean.victron_evcs_night_battery_done + name: └ surplus de la nuit épuisé - entity: input_boolean.victron_evcs_allow_grid_hc_midday name: Réseau HC midi - entity: input_boolean.victron_evcs_surplus_auto_enabled diff --git a/tests/golden/scenarios.mjs b/tests/golden/scenarios.mjs index f302a15..870ebfa 100644 --- a/tests/golden/scenarios.mjs +++ b/tests/golden/scenarios.mjs @@ -2612,4 +2612,41 @@ export const scenarios = [ edfOnAction: true, }, }, + + // ⚠️ P12 DOIT GAGNER LE PREMIER CYCLE DE LA NUIT, OU IL NE GAGNE PAS. + // + // Decouvert en essai reel le 15/09 a 05:30. P7 s'etait engage a 05:13, avant + // que le proprietaire n'active P12 : le helper `night_grid_takeover_needed` + // etait donc deja ON, et le verrou anti-creneaux de juillet (P2) tenait le + // reseau — `nightGridHcPreferred` passe bien a false grace a P12, mais + // `nightTakeoverLatched` maintient `nightGridTakeoverNeeded` de son cote. + // + // Et c'est le comportement SUR : basculer reseau -> batterie en pleine + // session, c'est exactement le creneau que ce verrou existe pour empecher. + // Aucun des cinq scenarios P12 ne le montrait — ils partent tous d'une nuit + // vierge. Celui-ci epingle la contrainte pour qu'un changement futur soit + // delibere. + { + id: 'p12-verrou-p2-tient-si-le-reseau-est-deja-engage', + label: 'Nuit HC, P7 deja engage (takeover ON) puis P12 active -> le verrou anti-creneaux tient, pas de bascule', + time: '2026-09-15T05:30:00+02:00', + overrides: { + ...VEHICLE_NIGHT, soc_percent: '69', + allow_grid_hc_night: 'on', + night_battery_charge_enabled: 'on', night_battery_done_prev: 'off', + // LE point du scenario : la reprise reseau est deja engagee. + night_takeover_prev: 'on', + grid_state: 'on', victron_acin1_available: '1', + battery_current_a: '1', + evcs_charging_switch: 'on', + balance_status: 'ok', balance_last_run: '15/09 05:25', + balance_required_soc: '36.8', balance_required_soc_prudent: '36.2', + balance_energy_to_cover_kwh: '3.18', + }, + expect: { + profile: 'night_hc', + sourceMode: 'grid_hc_allowed', + takeoverNeeded: true, + }, + }, ];