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