From 05310cf561b280240c4bb8a8226ba8aeaf22e0f8 Mon Sep 17 00:00:00 2001 From: Patrick Schurig Date: Fri, 28 Aug 2026 11:55:32 +0200 Subject: [PATCH] =?UTF-8?q?docs(spec):=20LM-1208=20=E2=80=94=20sortir=20de?= =?UTF-8?q?=20la=20d=C3=A9cision=20n'est=20pas=20sortir=20de=20la=20compta?= =?UTF-8?q?bilit=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quatre constats de l'agent app, vérifiés un par un sur le banc. A — la CONCLUSION est retenue, le MÉCANISME ne l'est pas. « Pas de voiture assignée » cesse d'être un critère d'exclusion (LM-1208-b). Les trois arguments tiennent, et le troisième est décisif : le critère contredit LM-1206, qui donne le rang et le plancher à la borne et non au véhicule. S'y ajoutent le cas de l'invité — la borne cesserait d'être arbitrée au moment précis où elle consomme — et l'invérifiabilité d'une assignation déclarée à la main. Mais le budget n'était pas faussé, et c'est le journal du banc qui le montre : pendant que la V2C tirait, le compteur est passé de −2 915 W (export) à +3 531 W (import) et l'arbitre a publié « Surplus insuffisant (−3 531 W) — chauffe-eau à 0 W ». L'ECS n'a pas été servi par-dessus. Le budget part de la mesure BRUTE (invariant 8) : la consommation d'une charge exclue y est déjà déduite. L'exclusion est conservatrice. La règle générale est néanmoins écrite, parce qu'elle a un porteur étroit et réel : une charge exclue du contexte mais commandée par le PROXY ne reçoit aucun evReservedW. Transitoire, sans effet aujourd'hui — mais elle mordra au §10, où la passe éco décide d'acheter. Et un écart de MESURE, distinct et non tranché, est signalé : le compteur racine lit ~1,5 kW de moins que la somme des charges mesurées. Même famille que son aveuglement documenté aux résistances ECS. Ce n'est pas un problème d'arbitrage, mais un budget juste suppose un compteur qui voit tout. B — même cause, mais le mode manuel n'est pas en cause : il reste une exclusion délibérée. Le vrai point est que le mode par défaut d'une borne détectée EST ChargingModeNormal — une borne neuve n'est donc jamais arbitrée tant que personne n'a choisi un mode éco. Correct, mais invisible à la mise en service. C — l'entrée résiduelle se supprime déjà depuis l'app : SetLoadConfig remplace l'ensemble, et l'auto-provisionnement ne recrée que les bornes dont le Thing existe. Le geste demandé existe ; la limite à connaître est qu'une entrée dont le Thing vit encore sera recréée — pour celle-là, c'est enabled: false. D — instruction reçue, aucun cas particulier V2C dans le moteur, C1 maintenue. Leur distinction est plus fine que ce que le brief anticipait : un champ absent se voit, un champ qui s'efface se lit comme un zéro. Troisième régime, et c'est pourquoi C2 exige que le régime soit publié plutôt que déduit d'une valeur. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_017TVywtayEeoRJ2yWUW4iZj --- AGENTS.md | 14 ++++++- docs/BRIEF_depuis_plugin.md | 78 ++++++++++++++++++++++++++++++++++++- specs/spec_loadmodel.md | 54 +++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 59187a7..19d43b8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -190,7 +190,19 @@ vers un gestionnaire d'énergie complet (EV, ECS, PAC SG-Ready, batterie). - **arm64** cross-compile validé en pré-déploiement (infra CI `etm-powersync-deploy`). - **`Doxyfile` + job CI `doxygen -W`** (automatiser l'audit doc). -**PROCHAINE ACTION** : **le rang par défaut des bornes auto-provisionnées**, qui retombe à +**PROCHAINE ACTION** : **retirer `assignedCarId` du filtre d'entrée du waterfall** +(`evParticipatesInWaterfall`) — décidé le 2026-08-28, `specs/spec_loadmodel.md` **LM-1208-b** : +le critère contredit LM-1206 (le rang appartient à la borne, pas au véhicule), il est +invérifiable, et il exclut la borne d'un invité au moment précis où elle consomme. Ce qu'on perd +sans voiture assignée est une fonction — échéance, cible d'énergie — pas l'arbitrage. Restent +exclusions : mode manuel (intention explicite) et `pluggedIn` (rien à consommer). + +À vérifier au passage, distinct et non tranché : **le compteur racine du banc lit ~1,5 kW de +moins que la somme des charges mesurées** (3 250 W contre 3 980 W pour la seule V2C, plus 800 W +de PAC). Même famille que l'aveuglement documenté aux résistances ECS. Un budget juste suppose un +compteur qui voit tout. + +Ensuite : **le rang par défaut des bornes auto-provisionnées**, qui retombe à égalité avec le rang 1 déjà occupé au lieu de mettre la borne « en tête » (`docs/RELEVE_3g2.md` §3.2). Trois issues possibles, aucune tranchée — autoriser le rang 0, renuméroter les autres, ou assumer l'égalité et laisser l'app poser les vrais rangs à la mise diff --git a/docs/BRIEF_depuis_plugin.md b/docs/BRIEF_depuis_plugin.md index 5dbf4f2..781d8b5 100644 --- a/docs/BRIEF_depuis_plugin.md +++ b/docs/BRIEF_depuis_plugin.md @@ -5,7 +5,8 @@ **Contexte** : `docs/RELEVE_3g2.md` (ce dépôt) porte les traces machine, cycle par cycle. **Contrat** : `INTERFACE.md` fait autorité — ce brief ne fait qu'en signaler les mouvements. -> Cinq points. Le deuxième **retire une mise en garde** que vous portiez — du code conditionnel +> Six points. Le sixième répond à vos quatre constats du 28 août. +> Le deuxième **retire une mise en garde** que vous portiez — du code conditionnel > peut disparaître. Le cinquième répond à **votre** question sur `targetPercentage`, et c'est > celui qui change un écran : l'avancement s'affichera en énergie livrée, pas en pourcentage. @@ -178,6 +179,81 @@ déjà côté moteur : `estimatedPowerW` porte son préfixe exprès. --- +--- + +## 6. Réponses à vos quatre constats du 2026-08-28 + +### A — la conclusion est retenue, le mécanisme ne l'est pas + +**Votre conclusion est juste et elle est adoptée** (`spec_loadmodel.md` **LM-1208-b**) : « pas de +voiture assignée » cesse d'être un critère d'exclusion. Vos trois arguments tiennent, et le +troisième est décisif — **le critère contredit LM-1206**, qui donne le rang et le plancher à la +borne et non au véhicule. + +**Mais le budget n'était pas faussé, et c'est votre propre banc qui le montre.** Le budget part +de la mesure **brute** du compteur (invariant 8) : la consommation d'une borne exclue y est déjà +déduite. Journal du 28 à 10:49, pendant que la V2C tirait : + +``` +Current load on root meter: 3531.4W (avant : −2915 W, en export) +[Arbitre] "chauffe-eau" → "Surplus insuffisant (−3531 W) — chauffe-eau à 0 W" +``` + +**L'ECS n'a pas été servi par-dessus** — l'arbitre a vu l'import et a refusé. L'exclusion est +*conservatrice* : la charge exclue retire du budget aux autres, et personne ne le lui rend. + +> **Votre règle générale est néanmoins retenue**, parce qu'elle a un porteur étroit et réel : une +> borne exclue du contexte mais **commandée par le proxy** ne reçoit aucun `evReservedW`. Sa +> puissance commandée et pas encore mesurée n'est réservée par personne. Transitoire — un cycle — +> et sans effet aujourd'hui, mais **elle mordra au §10**, où la passe éco décide d'acheter. + +**⚠️ Un écart de MESURE mérite votre attention, et il est distinct** : le compteur racine lit +**3 250 W** quand la V2C annonce **3 980 W** à elle seule (plus la PAC à 800 W). Environ 1,5 kW +que le compteur racine ne voit pas. Ce n'est pas un problème d'arbitrage — c'est une question de +câblage ou de vue SunSpec, de la même famille que l'aveuglement du compteur aux résistances ECS +documenté dans `AGENTS.md`. **À investiguer pour lui-même** : un budget juste suppose un compteur +qui voit tout. + +### B — même cause, mais le mode manuel n'est pas en cause + +Corriger A ne suffira pas : la V2C est en **`ChargingModeNormal`**, et le mode manuel reste un +critère d'exclusion **délibéré** — l'utilisateur pilote, l'arbitre s'abstient. + +**Le vrai point est ailleurs, et il vous concerne** : le mode par défaut d'une borne fraîchement +détectée **est** `ChargingModeNormal`. Une borne neuve n'est donc jamais arbitrée tant que +personne n'a choisi un mode éco. C'est correct par construction, mais **invisible** — et « la +borne ne charge pas toute seule » se lira comme un défaut. C'est un geste de mise en service à +montrer, pas un correctif moteur. + +### C — vous pouvez déjà la retirer, aujourd'hui, sans rien ajouter + +L'entrée résiduelle de la Terra AC **se supprime depuis l'app** : `SetLoadConfig` **remplace +l'ensemble**, donc renvoyer la liste sans cette entrée la retire. Et elle ne sera **pas +recréée** : l'auto-provisionnement ne tourne que pour les bornes présentes dans nymea, et le +Thing a été supprimé. + +C'est exactement le « geste, pas une suppression d'office » que vous demandez, et il existe déjà. + +> **La limite à connaître** : si vous supprimez l'entrée d'une borne dont le **Thing existe +> encore**, elle sera recréée au cycle suivant — c'est l'auto-provisionnement, et c'est voulu. +> Retirer une borne de l'arbitrage sans supprimer son Thing se fait par `enabled: false`, pas par +> suppression. + +### D — instruction reçue, rien ne bouge côté moteur + +Aucun cas particulier V2C dans le moteur : le contrat reste celui des autres bornes, et **C1 de +LM-1009 est maintenue** — d'autres bornes n'auront ni `sessionEnergy` ni valeur accumulable. + +Votre distinction est plus fine que ce que le brief avait anticipé et elle est notée : +**un champ absent se voit ; un champ qui s'efface se lit comme un zéro.** C'est un troisième +régime, entre « mesuré » et « pas mesurable » — et c'est précisément pourquoi C2 exige que le +régime soit *publié* et non déduit d'une valeur. + +Et `targetPercentage = 80` observé sur la V2C **confirme sur machine** le défaut corrigé en +`+etm23` : le champ omis retombait à son défaut. Ce n'est plus une déduction. + +--- + ## Ce qui n'a PAS changé, et qu'il ne faut pas déduire - **L'échéance de départ et le tarif dynamique restent au proxy**, financés au réseau diff --git a/specs/spec_loadmodel.md b/specs/spec_loadmodel.md index 1c6dc16..952ef0f 100644 --- a/specs/spec_loadmodel.md +++ b/specs/spec_loadmodel.md @@ -1031,6 +1031,60 @@ appartient à un chauffe-eau. `assignedCarId` existe déjà dans `ChargingInfo` : le jour où la communication véhicule arrive, la migration du rang de la borne vers le véhicule reste possible **sans casser l'acquis**. +**LM-1208 — Une charge sortie de la DÉCISION n'est jamais sortie de la COMPTABILITÉ.** +*(Règle posée par l'agent app, 2026-08-28, sur un constat de banc. La règle est retenue ; le +mécanisme qui l'accompagnait était inexact — voir l'encadré.)* + +Quel que soit le motif d'exclusion — mode manuel, véhicule inconnu, borne débranchée — **la +consommation réelle de la charge reste dans le bilan du budget**. Une charge qu'on cesse de +piloter ne cesse pas de consommer. + +> **Cette règle est DÉJÀ tenue, et par construction** : le budget part de la mesure **brute** du +> compteur (invariant 8 d'`AGENTS.md`), donc la consommation d'une charge exclue y est déjà +> déduite — sans que personne ait à la réserver. Vérifié au banc le 2026-08-28 : la V2C tirant +> 3,9 kW hors arbitrage, le compteur est passé de −2 915 W (export) à +3 531 W (import) et +> l'arbitre a publié « Surplus insuffisant (−3 531 W) — chauffe-eau à 0 W ». **L'ECS n'a pas été +> servi par-dessus.** L'exclusion est conservatrice : la charge exclue retire du budget aux +> autres, et personne ne le lui rend. +> +> **La règle garde pourtant un porteur, étroit et réel** : une charge exclue du contexte mais +> commandée par le **proxy** ne reçoit aucun `evReservedW` — sa puissance commandée et pas +> encore mesurée n'est réservée par personne (correction A ne couvre que les actions du +> scheduler). Le trou est transitoire — un cycle, jusqu'à ce que le compteur rattrape — et il ne +> mord pas aujourd'hui, le mode manuel faisant sauter la borne aussi côté proxy. **Il mordra au +> §10**, où la passe éco décide d'acheter : acheter en croyant disposer d'une puissance déjà +> engagée est exactement le défaut que la règle nomme. + +**LM-1208-b — « Pas de voiture assignée » cesse d'être un critère d'exclusion.** *(Décision +demandée, argument de l'agent app retenu.)* + +Trois raisons, et la troisième est décisive : + +1. **Le cas de l'invité le rend intenable.** Une voiture qui n'est pas celle du propriétaire ne + sera jamais déclarée, et la borne cesserait d'être arbitrée **précisément quand elle + consomme**. +2. **Le critère n'est pas vérifiable.** L'assignation est déclarée à la main ; rien ne dit ce qui + est réellement branché. Un critère d'arbitrage qui repose sur une déclaration invérifiable + n'arbitre pas, il devine. +3. **Il CONTREDIT LM-1206.** Le rang et le plancher appartiennent à la **borne**, pas au + véhicule. Exiger un véhicule connu pour arbitrer la borne réintroduit exactement la + dépendance que LM-1206 a écartée. + +**Ce qu'on perd sans voiture assignée est une FONCTION, pas l'arbitrage** : l'échéance et la +cible d'énergie deviennent indisponibles — dégradation, pas exclusion. C'est la même distinction +que C1 de LM-1009 : une capacité manquante se dit, elle ne fait pas disparaître la charge. + +> **Ce qui RESTE un critère d'exclusion, et pourquoi** : +> — **mode manuel** (`ChargingModeNormal`) : c'est une intention explicite de l'utilisateur — +> il pilote, l'arbitre s'abstient. Vérifiable, et voulu. +> — **aucun véhicule branché** (`pluggedIn`) : la borne ne peut rien consommer de ce qu'on lui +> allouerait (mesuré, `docs/RELEVE_3g2.md` §3.1). +> +> ⚠️ **Conséquence d'exploitation à connaître** : le mode par défaut d'une borne fraîchement +> détectée est `ChargingModeNormal`. **Une borne neuve n'est donc jamais arbitrée tant que +> personne n'a choisi un mode éco** — ce qui est correct par construction, mais doit être visible +> à la mise en service, sans quoi « la borne ne charge pas toute seule » se lira comme un défaut. + **LM-1207 — Ne PAS ajouter de `priority` à `ChargingInfo`.** Ce serait un **second système de priorité**, et il serait immédiatement insuffisant : il ne saurait pas exprimer **« VE1 > ECS > VE2 »**, puisqu'il ne classerait que les bornes entre elles. Deux classements