From 0c5f0ee30d72c07b9547138dfd49a93a2afd755c Mon Sep 17 00:00:00 2001 From: Patrick Schurig Date: Mon, 7 Sep 2026 16:49:34 +0200 Subject: [PATCH] =?UTF-8?q?docs(ev):=20Min+PV=20sert=20bien=20le=20planche?= =?UTF-8?q?r=20=E2=80=94=20prouv=C3=A9=20par=20deux=20comptages,=20et=20`b?= =?UTF-8?q?oundBy`=20ne=20prouve=20rien?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +etm58 posé (au-delà de +etm57 annoncé). Trois vérifications. 1. ANCRAGE DES INSTANTS : livré et observable. Les trois champs ISO de la trame portent le marqueur Z, `command.since` compris — `{divergent, expectedW, observedW, since: "2026-09-07T14:37:00Z"}`. 2. MIN+PV : livré. La voiture a chargé toute la journée sans jamais quitter ChargingModeEcoWithMinCurrent, et deux comptages sans source commune concordent à 4 % : surplus MAX du jour 536 W — 0 quart d'heure sur 71 au-dessus de 4140 fenêtre 08:45 -> 15:15 16,2 kWh dont 14,2 au-dessus de la base (539 W) sessionEnergy de la V2C 1,06 -> 14,72 kWh, soit +13,7 kWh Le surplus n'ayant jamais dépassé 536 W, tout a été acheté au réseau : c'est le plancher demandé. 3. `boundBy` : ABSENT, et cette absence ne prouve rien — le seul ECO_FLOOR_GRID de la trame est celui du chauffe-eau, dont le plancher vient d'une obligation quotidienne et non d'un minimum matériel ; et la borne est sortie de loads[] (pluggedIn: false). Un `grep -c boundBy` valant 0 aurait fait conclure « non livré » à l'instant où la mesure prouve le contraire. À revoir voiture branchée. Et une affirmation de CLAUDE.md devenue FAUSSE, corrigée : le plafond de soutirage du §10 existe désormais — "draw": { "authorisedW": 6000.4, "committedW": 103.2, "remainingW": 5897.2, "binding": "connection", "bindingPhase": "A", "perPhaseBound": true } `binding` nomme ce qui contraint et `bindingPhase` la phase qui mord : le plafond se dit donc avec sa source, la condition qu'on avait posée pour l'afficher. Aucun écran ne le lit encore, et rien n'est câblé — l'écran du §10 n'est pas validé. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01GKM8FDNHZWogAsjjfB8pSw --- CLAUDE.md | 41 +++++++++++++++++++++++++++++----- lib/models/load_telemetry.dart | 8 ++++++- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 0ac1324..9bc7588 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -101,7 +101,28 @@ Min+PV + échéance → ChargingModeEcoMinWithTargetTime + targetPercentage + > minimum** — la règle tient, mais pour une meilleure raison qu'avant : une limite matérielle > se lit sur le matériel, elle ne se demande pas à l'utilisateur. > -> 🔴 **Et le mode ne fait rien pour l'instant.** Sémantique voulue (Patrick, 2026-09-07) : +> ✅ **LIVRÉ ET MESURÉ le 2026-09-07 (`+etm58`).** Le mode fait ce qu'il annonce. Preuve par +> deux comptages indépendants, la voiture ayant chargé toute la journée en Min+PV sans jamais +> passer en Boost (`chargingMode` resté `ChargingModeEcoWithMinCurrent`) : +> +> | | | +> |---|---| +> | surplus **maximum** du jour | **536 W** — 0 quart d'heure sur 71 au-dessus de 4 140 W | +> | fenêtre de forte consommation | 08:45 → 15:15, 16,2 kWh dont **14,2 kWh** au-dessus de la base (539 W) | +> | `sessionEnergy` de la V2C | 1,06 kWh à 08:30 → **14,72 kWh** à 16:40, soit **+13,7 kWh** | +> +> 14,2 kWh vus au compteur contre 13,7 kWh vus par la borne : deux mesures qui ne partagent +> aucune source, à 4 % près. Et comme le surplus n'a jamais dépassé 536 W, **tout cela a été +> acheté au réseau** — c'est exactement le plancher demandé. +> +> ⚠️ **`boundBy` reste invérifié**, et son absence ne prouve rien : le seul `ECO_FLOOR_GRID` +> de la trame est celui du chauffe-eau, dont le plancher vient d'une **obligation +> quotidienne**, pas d'un minimum matériel. La borne, elle, est sortie de `loads[]` +> (`pluggedIn: false` — voiture débranchée), donc son niveau `eco` n'est pas observable. À +> revoir voiture branchée : c'est le seul endroit où le marqueur est attendu. +> +> 🔴 **Ce que le mode faisait AVANT `+etm57`** — gardé parce que le symptôme reviendra sur +> toute box non mise à jour. Sémantique voulue (Patrick, 2026-09-07) : > Min+PV charge **toujours** au minimum de la borne, acheté au réseau s'il le faut, **et > ajoute le surplus par-dessus** — 400 W d'injection sur un plancher de 4 140 W donnent > 4 540 W. Mesuré sur `.75` : la borne ne reçoit **qu'un niveau `comfort`**, aucun niveau @@ -341,15 +362,23 @@ installations déjà déployées. > (`evReservedW: 0` pendant qu'un `EV_GRID_START` partage entre les deux vrais compteurs). > **Ne réconcilier aucun total dessus, jamais** — la nature du champ l'interdit. -**`draw.committedW`** (`+etm31`) est publié dans la **même trame que `budget`**, et **seul** : -`authorisedW`, `remainingW`, `binding`, `perPhaseBound` sont **absents, pas à zéro** — le -plafond de soutirage du §10 n'existe pas encore, et un `authorisedW: 0` afficherait un plafond -fictif avec sa source. +**`draw` porte désormais le PLAFOND du §10** — corrigé le 2026-09-07 contre `.75` en +`+etm58`. La phrase précédente (« `authorisedW`, `remainingW`, `binding`, `perPhaseBound` sont +absents, le plafond du §10 n'existe pas encore ») **est périmée** et enverrait un agent +chercher un champ qui est là : ```jsonc -"budget": { … }, "draw": { "committedW": 0 } +"draw": { "authorisedW": 6000.4, "committedW": 103.2, "remainingW": 5897.2, + "binding": "connection", "bindingPhase": "A", "perPhaseBound": true } ``` +`binding` nomme **ce qui contraint** (`"connection"` = le raccordement) et `bindingPhase` la +phase qui mord — donc le plafond se dit avec sa source, ce qui était la condition posée pour +l'afficher. **Aucun écran ne le lit encore** : `LoadTelemetry` ne modélise que +[drawCommittedW]. À câbler quand l'écran du §10 sera validé, pas avant. + +`draw.committedW` seul (`+etm31`) reste la forme des box entre `+etm31` et `+etm57`. + > **Publié même quand rien n'est acheté**, et **`counts` publié même à zéro avec sa > destination** (`{"budget.allocatedW": 0}` sur une charge non servie — le cas le plus > fréquent). Donc l'**absence** vaut « box antérieure », jamais « rien ce cycle » : **zéro est diff --git a/lib/models/load_telemetry.dart b/lib/models/load_telemetry.dart index 9529356..9d7c20c 100644 --- a/lib/models/load_telemetry.dart +++ b/lib/models/load_telemetry.dart @@ -873,7 +873,13 @@ class LoadTelemetry { /// `draw.committedW` — **les watts achetés du cycle**, né en `+etm31`. /// - /// Publié dans la même trame que [budget], et **seul** : `authorisedW`, `remainingW`, + /// ⚠️ **Le reste de `draw` existe depuis `+etm57`** — `authorisedW`, `remainingW`, + /// `binding` (`"connection"`), `bindingPhase`, `perPhaseBound` — et n'est **pas** modélisé + /// ici : aucun écran du §10 n'est validé. Vu sur `.75` en `+etm58` le 2026-09-07. La note + /// ci-dessous décrit les box **antérieures**, où ces clés sont absentes et non à zéro. + /// + /// Publié dans la même trame que [budget], et sur une box d'avant `+etm57` **seul** : + /// `authorisedW`, `remainingW`, /// `binding` et `perPhaseBound` (le plafond de soutirage du §10) sont **absents, pas à /// zéro** — un `authorisedW: 0` afficherait un plafond qui n'existe pas, avec sa source. ///