From f2a96a019321cfe07c9ca53ccc6fdeac8fd73cc6 Mon Sep 17 00:00:00 2001 From: Patrick Schurig Date: Sun, 30 Aug 2026 22:37:27 +0200 Subject: [PATCH] =?UTF-8?q?docs(relev=C3=A9=20app):=20trois=20constats=20?= =?UTF-8?q?=C3=A0=20traiter=20apr=C3=A8s=20le=20=C2=A710,=20et=20sessionEn?= =?UTF-8?q?ergy=20tranch=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rangés pour ne pas se perdre — aucun ne passe devant le §10, et aucun ne se déduit du code : les trois viennent de la machine. 1. Une commande perdue pendant une indisponibilité n%s est jamais réappliquée. Coupure Modbus, la box restaure « false 6 A », la borne reste à 7 A : 4,4 kW tirés, draw.committedW à 0, budget de 2 349 W qui les ignore. Une seconde de coupure suffit. Sur 18 kVA invisible, sur 6 kVA c%s est le disjoncteur. Même famille qu%sECS-111 et ECS-415, sous une troisième forme : après la télémétrie et après la valeur de retour, voici l%sexécution. 2. chargingState figé à Idle pendant une charge réelle — pas de la péremption, personne ne maintient le champ. Un champ sans mainteneur doit être ABSENT, pas figé, sinon un écran dit « à l%sarrêt » pendant une charge. 3. ChargingModeNormal n%est pas un boost : il restaure des valeurs mémorisées qui peuvent être false/6 A. Le nom et l%seffet ne coïncident pas. Et un point ouvert qui se clôt : la V2C publie sessionEnergy. PIÈGE consigné dans le design §10 étape C — l%saccumulateur porte un OFFSET constant (7,2044 au dix-millième sur deux échantillons), donc deliveredWh doit être une différence depuis une base capturée. Une lecture directe ferait croire toute obligation éco tenue de 7,2 kWh au premier cycle. --- docs/DESIGN_10.md | 11 +++++ docs/RELEVE_APP_20260831.md | 80 +++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 docs/RELEVE_APP_20260831.md diff --git a/docs/DESIGN_10.md b/docs/DESIGN_10.md index b9efb5d..c740e2f 100644 --- a/docs/DESIGN_10.md +++ b/docs/DESIGN_10.md @@ -444,6 +444,17 @@ Cette étape les branche **en lecture seule** : `sessionWh` alimenté, `progress quand le régime est `unmeasurable` — jamais à zéro, sans quoi une dégradation se lirait comme un avancement nul, ce que `LM-1009 C1` interdit nommément. +> **⚠️ `sessionEnergy` porte un OFFSET — mesuré le 2026-08-31.** Sur la V2C, l'écart entre +> `sessionEnergy` et `chargeEnergy` est constant au dix-millième (7,2044), parce que +> l'accumulateur du plugin porte les incréments d'avant la dernière remise à zéro. **La valeur +> absolue n'est donc pas l'énergie de la session courante.** `deliveredWh` doit être une +> **différence depuis une base capturée**, jamais une lecture directe — sans quoi toute +> obligation éco se croirait tenue de 7,2 kWh dès le premier cycle. Un nombre crédible et faux, +> que rien ne signalerait. Détail et mesures : `RELEVE_APP_20260831.md`. +> +> Corollaire : **la V2C n'est plus un cas `unmeasurable`.** `LM-1009 C1` reste vraie pour les +> bornes sans l'état, mais le porteur d'exemple change — R6 devra citer une autre classe. + > **C'est ici que R5 devient vraie, et R6 devient TESTABLE avant d'être nécessaire.** Le régime > se publie sans qu'aucune décision ne s'y appuie : l'app peut afficher « non mesurable » sur la > V2C dès cette étape, et la garde de R6 — `ECO_FLOOR_MET` interdit sous `unmeasurable` — aura diff --git a/docs/RELEVE_APP_20260831.md b/docs/RELEVE_APP_20260831.md new file mode 100644 index 0000000..eeff77a --- /dev/null +++ b/docs/RELEVE_APP_20260831.md @@ -0,0 +1,80 @@ +# RELEVÉ — trois constats de l'agent app, à traiter APRÈS le §10 + +*(Remontés le 2026-08-31, mesurés sur `.75`. Rangés ici pour ne pas se perdre : ils ne passent +pas devant le §10, et aucun ne se déduit du code — les trois viennent de la machine.)* + +--- + +## 1. Une commande perdue pendant une indisponibilité n'est JAMAIS réappliquée + +**Mesuré.** La box journalise `Restoring manual values of false 6 A` trois secondes après une +coupure Modbus. La borne, elle, reste à `power: true`, **7 A** — ce que l'arbitre lui avait +commandé au cycle précédent. Le lien revient : **rien ne réapplique**. En mode manuel personne ne +commande, donc l'écart est **permanent**. + +**Ce que ça coûte, chiffré :** 4,4 kW réellement tirés, `draw.committedW` à **0**, et un budget de +surplus de **2 349 W** qui ignore ces watts. + +Une coupure d'**une seconde** suffit donc à laisser une borne à un courant que plus personne n'a +choisi, et le budget est faux tant que ça dure. Sur 18 kVA c'est invisible ; **sur 6 kVA c'est le +disjoncteur**. + +**La question posée par l'app** était étroite — « une entrée en mode manuel devrait-elle +réappliquer ses valeurs à la reconnexion du Thing ? ». Elle est **élargie** : toute commande +perdue pendant une indisponibilité devrait être **réappliquée au retour, ou la divergence +signalée**. + +**Et c'est calculable dès aujourd'hui.** On sait ce qu'on a commandé, la borne dit ce qu'elle +fait, et `measurement.source` (`LM-1105` / `LM-1106`) dit désormais **ce que vaut la +comparaison** — une divergence entre commandé et `device` n'a pas le même statut qu'une +divergence contre `none`. + +> **Même famille que toute la semaine** : le lien revient, l'état a l'air sain, `available` est +> vrai, et personne ne sait que la commande n'a jamais atterri. C'est `ECS-111` et `ECS-415` sous +> une troisième forme — après la télémétrie et après la valeur de retour, voici **l'exécution**. + +--- + +## 2. `chargingState` reste `ChargingStateIdle` pendant une charge RÉELLE + +**Mesuré.** Lien vivant, borne publiant 4 372 → 4 397 W, courants qui bougent — et le champ reste +à `Idle`. + +**Ce n'est donc PAS de la péremption**, et c'est ce qui rend le constat utile : personne ne +maintient le champ quand l'arbitre ne commande plus la borne. + +**Un champ que plus personne ne maintient devrait être ABSENT, pas figé.** Figé, un écran affiche +« à l'arrêt » pendant une charge. C'est l'invariant 12 d'`AGENTS.md` — un champ absent vaut mieux +qu'un champ nul ou forgé — appliqué à un champ dont le *mainteneur* a disparu, et non la valeur. + +--- + +## 3. `ChargingModeNormal` n'est pas un boost, et son nom le laisse croire + +Il **restaure des « valeurs manuelles mémorisées »**, qui peuvent être `power: false`, `6 A`. Y +passer peut donc **arrêter une charge** alors que l'utilisateur croit demander la pleine +puissance. Le nom du mode et son effet ne coïncident pas. + +**À documenter au minimum.** À corriger si l'on juge que le nom peut bouger — c'est une frontière +amont, et un renommage se paie côté clients. + +--- + +## Et un point OUVERT qui se CLÔT : la V2C publie `sessionEnergy` + +**Mesuré**, deux échantillons à deux heures d'écart sur charge réelle : l'écart entre +`sessionEnergy` et `chargeEnergy` est **constant au dix-millième** — 7,2044 dans les deux cas. +C'est l'accumulateur du plugin V2C qui porte les incréments d'**avant la dernière remise à +zéro**, et **ça ne se déduisait pas du code**. + +**Conséquences, et elles touchent l'étape C du §10 :** + +1. **`LM-1009 C1` reste vraie** pour les bornes qui n'ont pas l'état — mais **la V2C n'en fait + plus partie**. Le cas « réel dès aujourd'hui » qui motivait R6 change de porteur. +2. **`sessionEnergy` est l'accumulateur à lire** pour alimenter `LoadContextTelemetry::sessionWh`. +3. **⚠️ Il porte un OFFSET.** Sa valeur absolue n'est pas l'énergie de la session courante. + `deliveredWh` doit donc être une **différence depuis une base capturée**, jamais une lecture + directe — sinon toute obligation éco se croirait déjà tenue de 7,2 kWh au premier cycle. C'est + le genre d'erreur qui produit un nombre crédible et faux, et que rien ne signalerait. + +L'app a corrigé sa maquette et son modèle en conséquence.