DÉCISION PRODUIT (Patrick, 2026-09-08, après validation du lot sur le banc) : trois modes — Normal (manuel), PV, Min+PV — et le boost n'en est PAS un quatrième. C'est la dérogation : un bouton d'action à côté du sélecteur, posé par SetLoadDerogation et non par SetChargingInfo, avec sa durée obligatoire et bornée [60 s, 6 h] que l'écran doit faire saisir. Gravé dans les RÉPONSES FIGÉES : un mode se choisit et dure, une dérogation répond à un besoin ponctuel et s'efface — les deux ne se rangent pas au même endroit. CRITÈRE DE TRI DE L'ÉTAPE 4 — une clause de plus, écrite sur la mesure. Une dérogation fait bouger la consigne de plusieurs kilowatts d'un coup, et CHAQUE BORD ouvre une divergence : à l'ouverture la voiture négocie sa montée (13800 attendus, 3930 mesurés, convergence en 300 s), à la fermeture la borne n'a pas encore décru (0 attendu, 8367 mesurés). La fermeture est la plus trompeuse : immédiate, énorme, et trait pour trait semblable à une commande ignorée. Le discriminant est temporel et déjà publié — une divergence née dans le même cycle qu'un DEROGATION_ENDED, ou qu'un DEROGATION_ACTIVE neuf, est une transition. Sans cette clause, chaque boost compterait pour DEUX incidents, et l'étape 4 se justifierait d'elle-même en comptant ses propres transitoires : le mécanisme du §6.2 — un instrument qui fabrique la preuve dont il a besoin — déplacé du banc vers la mesure. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015F7G5VeaPVSMeVNjiGj36p
413 lines
24 KiB
Markdown
413 lines
24 KiB
Markdown
# DESIGN — la commande perdue, et l'écart que personne ne mesure
|
||
|
||
*(Ouvert le 2026-09-01, sur le premier constat de `RELEVE_APP_20260831.md`. Le design avant le
|
||
code, comme pour le délestage et le §10.)*
|
||
|
||
## 1. Le fait, tel qu'il a été mesuré
|
||
|
||
Coupure Modbus. La box journalise `Restoring manual values of false 6 A` trois secondes après.
|
||
La borne, elle, reste à `power: true`, **7 A** — la consigne que l'arbitre lui avait donnée au
|
||
cycle d'avant. Le lien revient : **rien ne réapplique**. En mode manuel personne ne commande,
|
||
donc l'écart est **permanent**.
|
||
|
||
**4,4 kW réellement tirés, `draw.committedW` à 0, un budget de surplus de 2 349 W qui ignore ces
|
||
watts.**
|
||
|
||
## 2. Ce que le fait dit vraiment — et il est plus large que son titre
|
||
|
||
« Réappliquer la commande de l'arbitre » ne décrit pas le cas : **en mode manuel, l'arbitre ne
|
||
commande pas**. Ce qui s'est passé est autre chose, et c'est pire :
|
||
|
||
1. Le proxy amont a voulu restaurer des valeurs manuelles (`false 6 A`) ;
|
||
2. l'écriture a échoué pendant l'indisponibilité ;
|
||
3. **personne ne l'a rejouée** ;
|
||
4. l'organe est resté sur une consigne **dont plus aucun commandeur ne se réclame** — ni
|
||
l'arbitre, qui ne commande plus, ni le mode manuel, dont la consigne n'a pas atterri.
|
||
|
||
> **La troisième forme de la même famille.** Après la télémétrie qui ne distinguait pas une
|
||
> issue de son contraire (`ECS-111`) et la valeur de retour qui faisait passer un refus pour un
|
||
> succès (`ECS-415`), voici **l'exécution** : une écriture perdue, un état sain en apparence,
|
||
> `available` à vrai, et personne pour savoir que la commande n'a jamais atterri.
|
||
|
||
## 3. Ce que le moteur a déjà — et ce qui manque
|
||
|
||
| Pièce | État |
|
||
|---|---|
|
||
| Dernière consigne écrite, charges en watts | **existe** — `m_currentSetpointW`, `m_currentStage` |
|
||
| Dernière consigne écrite, **bornes VE** | **MANQUE** — `EvAdapter` ne garde que `m_lastActionAt` |
|
||
| Ce que l'organe FAIT | **existe** — `EvCharger::maxChargingCurrent()`, états du Thing |
|
||
| Ce que l'organe MESURE, et ce que ça vaut | **existe** — `deviceMeasurement()`, `measurement.source` (`LM-1105`/`LM-1106`) |
|
||
| Détection de la FIN d'une indisponibilité | **MANQUE** — le seul chemin est `clearFault()`, actionné par l'opérateur |
|
||
| Comparaison commandé / constaté | **MANQUE** — nulle part |
|
||
|
||
**Le constat porte sur les bornes, et c'est précisément là que la mémoire de la commande manque.**
|
||
Ce n'est pas un hasard : les adaptateurs de charges en watts gardent leur consigne parce qu'ils
|
||
en ont besoin pour l'écrêtage de verrou ; la borne, elle, était pilotée par le proxy amont, qui
|
||
n'a jamais eu à se relire.
|
||
|
||
## 4. LES DÉCISIONS
|
||
|
||
**4.1 — Réappliquer, ou signaler ?**
|
||
Réappliquer automatiquement une consigne vieille de plusieurs minutes est un geste **dangereux** :
|
||
le monde a changé pendant l'indisponibilité — le surplus, l'heure, l'échéance. Rejouer une
|
||
décision périmée, c'est décider avec des données mortes, exactement ce que le mode dégradé L2
|
||
refuse de faire.
|
||
|
||
**Recommandation : SIGNALER toujours, RÉAPPLIQUER jamais telle quelle.** Au retour de
|
||
disponibilité, le cycle normal reprend la main et décide sur des données fraîches — c'est déjà
|
||
le bon comportement. Ce qui manque n'est pas le rejeu, c'est que **l'écart soit dit tant qu'il
|
||
dure**. Et il dure indéfiniment quand personne ne reprend la main, ce qui est le cas du relevé.
|
||
|
||
**4.2 — Que publie-t-on, et sous quelle forme ?**
|
||
Un écart n'a de sens que rapporté à ce qu'on sait de l'organe. Proposition : un objet `command`
|
||
au niveau de la charge, publié **seulement quand la comparaison est possible** —
|
||
|
||
```jsonc
|
||
"command": { "expectedW": 1380, "observedW": 4400, "divergent": true, "since": "…" }
|
||
```
|
||
|
||
**`measurement.source` conditionne ce que vaut cette comparaison**, et doit donc la gouverner :
|
||
contre `none`, il n'y a rien à comparer et l'objet est **absent** — pas `divergent: false`, qui
|
||
affirmerait la concordance qu'on ne peut pas constater. Même règle que partout ailleurs ici.
|
||
|
||
**4.3 — La COMPTABILITÉ : le diagnostic était à corriger, et le vrai défaut est plus grave.**
|
||
|
||
> **MESURÉ le 2026-09-01, avant d'implanter.** Le constat disait « un budget de surplus qui
|
||
> ignore ces watts ». **Ce n'est pas ce qui se passe.** Quand une charge consomme et **obéit**,
|
||
> la comptabilité est juste : sa conso est recréditée puis réallouée à elle-même, et les
|
||
> suivantes ne reçoivent que le surplus réel (mesuré : export 500 W, A à 4 400 W obéissante → B
|
||
> reçoit 500 W). **Corriger cela aurait été corriger un non-défaut.**
|
||
|
||
**Le vrai défaut : le recrédit est un PRÊT consenti contre l'obéissance.** Son hypothèse est
|
||
écrite dans le code — *« le budget est une mesure dont la conso de la charge a déjà été
|
||
retranchée »* — c'est-à-dire **« je peux rendre ces watts parce que je peux les reprendre »**.
|
||
Rien ne vérifie que l'emprunteur rembourse.
|
||
|
||
Mesuré, le cas où la promesse est engagée : export 500 W, A consomme 4 400 W, plancher de A à
|
||
5 000 W. A est commandée à **0**, et ses 4 400 W sont **redistribués à B**.
|
||
|
||
| | si A obéit | si A n'obéit pas |
|
||
|---|---|---|
|
||
| A | tombe à 0 | reste à 4 400 W |
|
||
| B | 4 000 W réels | 4 000 W **fictifs** |
|
||
| maison | 4 000 W pour 4 900 de production | **8 400 W pour 4 900** → 3 500 W importés |
|
||
|
||
**Et l'identité de réconciliation TIENT dans les deux cas** — `surplus + recrédit − alloué ==
|
||
restant`. C'est ce qui distingue un prêt d'une erreur : la comptabilité est juste, c'est
|
||
l'**hypothèse sur laquelle elle repose** qui n'est pas vérifiée. Aucun contrôle de cohérence ne
|
||
pouvait donc l'attraper.
|
||
|
||
**Ce qui change maintenant : l'obéissance est CONSTATABLE.** `command.divergent` (étape 2) dit
|
||
si la charge a suivi au cycle précédent. Le recrédit peut donc être **conditionné** — c'est la
|
||
proposition, et elle demande une décision parce qu'elle a son propre risque : l'anti-clignotement
|
||
existe pour une raison, et le suspendre trop vite ferait osciller une charge saine sur un écart
|
||
transitoire. `since` est précisément ce qui permet de distinguer les deux.
|
||
|
||
**Ce que le §4.3 d'origine proposait — retrancher la conso subie du budget — est SANS OBJET** :
|
||
elle en est déjà retranchée, par le compteur. La note est conservée ici pour que personne ne la
|
||
réimplante en la croyant oubliée.
|
||
|
||
**4.3-bis — l'ancienne formulation, conservée pour mémoire.**
|
||
`draw.committedW` à 0 pendant que 4,4 kW sont tirés n'est pas un défaut d'affichage : le budget
|
||
de surplus est calculé sans ces watts, donc **le moteur alloue de l'énergie qui n'existe pas**.
|
||
Une charge que l'arbitre ne commande plus mais qui consomme est de la **consommation fixe**, au
|
||
même titre que la base de la maison — c'est exactement le raisonnement d'`ECS-410` pour une
|
||
charge gelée, appliqué à une cause nouvelle.
|
||
|
||
**Recommandation : la retrancher du budget, sans l'allouer.** Elle n'est pas servie, elle est
|
||
subie. La compter comme allouée serait prétendre l'avoir décidée.
|
||
|
||
> **Sur 18 kVA c'est invisible ; sur 6 kVA c'est le disjoncteur.** Et le délestage ne rattrape
|
||
> pas ce cas : il agit sur la marge MESURÉE, qui inclut bien ces 4,4 kW — donc il protège. Ce
|
||
> qui reste faux est le **budget**, qui promet un surplus déjà consommé.
|
||
|
||
**4.4 — Faut-il un état « commande en vol perdue » distinct d'un défaut ?**
|
||
`ECS-410`/`ECS-414` couvrent l'écriture qui échoue trois fois → défaut. Ici l'écriture a échoué
|
||
**pendant une indisponibilité**, et la charge est ensuite redevenue disponible : le défaut se
|
||
lève, la divergence reste. À trancher : est-ce un `faultCode` de plus, ou un état orthogonal ?
|
||
|
||
## 5. ORDRE DE TRAVAIL — deux étapes à comportement constant d'abord
|
||
|
||
**Étape 1 — la MÉMOIRE de la commande, sans rien en faire.** `EvAdapter` retient sa dernière
|
||
consigne appliquée, comme les autres adaptateurs le font déjà. Publication seule, comportement
|
||
constant. Sans cette pièce, aucune des suivantes n'est calculable.
|
||
|
||
**Étape 2 — l'ÉCART publié, sans décider dessus.** L'objet `command`, gouverné par
|
||
`measurement.source`. C'est la moitié qui rend le défaut **visible**, et elle ne change aucune
|
||
décision — même stratégie qu'à l'étape C du §10, où publier le régime a précédé de décider avec.
|
||
|
||
**Étape 3 — la COMPTABILITÉ corrigée.** La conso subie sort du budget. C'est ici que le
|
||
comportement change, et c'est la seule étape qui le fasse.
|
||
|
||
**Étape 4 — la reprise en main**, si elle est jugée nécessaire après avoir vu les traces des
|
||
étapes 2 et 3. **Délibérément en dernier** : c'est la seule qui commande du matériel, et on
|
||
saura alors combien de fois le cas se produit réellement.
|
||
|
||
---
|
||
|
||
## 6. CRITÈRE DE TRI DES TRACES — écrit le 2026-09-05, AVANT d'avoir les données
|
||
|
||
> **Écrit avant exprès.** Un critère rédigé après coup se plie aux résultats : on écarte ce qui
|
||
> gêne et on garde ce qui confirme, sans jamais mentir, et sans jamais pouvoir le prouver. Celui-ci
|
||
> est daté et poussé avant l'ouverture de la fenêtre d'observation. S'il doit changer ensuite, ce
|
||
> sera un commit visible, avec sa raison.
|
||
|
||
### Pourquoi il faut un tri
|
||
|
||
Le journal de divergence (`+etm56`) a produit **14 épisodes en 24 h** sur le banc, avant même le
|
||
retour de la V2C. Aucun n'est exploitable :
|
||
|
||
```
|
||
08:05 DÉBUT "chauffe-eau" — attendu 3500 W, mesuré 1500 W
|
||
08:13 DÉBUT "chauffe-eau" — attendu 500 W, mesuré 1500 W
|
||
10:01 DÉBUT "chauffe-eau" — attendu 3000 W, mesuré 1500 W
|
||
```
|
||
|
||
`ECS-Meter` publie **1500 W en permanence**, `PAC-Meter` **800 W** — vérifié sur trois lectures
|
||
espacées. Ce sont des simulateurs à valeur fixe. L'écart mesuré n'est donc pas une désobéissance :
|
||
c'est la distance entre une consigne qui varie et un compteur qui ne varie pas. La divergence
|
||
« finit » quand la consigne passe par 1500 W — une coïncidence arithmétique, pas une obéissance.
|
||
|
||
**Dimensionner l'étape 4 là-dessus aurait été la dimensionner sur des divergences qui n'existent
|
||
pas.**
|
||
|
||
### Le critère, en deux conditions
|
||
|
||
Une divergence n'est exploitable que sur une charge dont le compteur **suit réellement la
|
||
consigne**. Deux conditions, et les deux sont nécessaires :
|
||
|
||
1. **`measurement.source` ≠ `none`.** Sans mesure propre, l'écart est calculé contre une
|
||
estimation, et il ne dit rien de la charge.
|
||
2. **Le compteur doit avoir VARIÉ sur la fenêtre**, indépendamment de la consigne. Un compteur
|
||
dont l'écart-type est nul sur la période n'est pas un compteur : c'est une constante déguisée,
|
||
et tout écart contre lui est un artefact.
|
||
|
||
**Ne PAS trier par nom de charge.** Écarter `chauffe-eau` et `pac-terrain` nommément serait
|
||
fragile de deux façons : ça se périme au premier renommage, et ça n'attrape pas la troisième
|
||
charge à compteur fixe qu'on ajoutera sans y penser. Le critère porte sur une **propriété
|
||
observable de la donnée**, pas sur une liste.
|
||
|
||
### Les faux positifs de la V2C, et ils sont d'une autre nature
|
||
|
||
La V2C a un vrai compteur, donc elle passe le critère ci-dessus. Mais **chaque perte de lien
|
||
produira une divergence qui n'est pas une commande perdue** : c'est une **mesure absente**.
|
||
|
||
Il faut donc distinguer deux affirmations que l'écart seul confond :
|
||
|
||
| | ce que ça veut dire | geste |
|
||
|---|---|---|
|
||
| **elle n'obéit pas** | la commande est partie, la mesure la contredit | c'est le cas de l'étape 4 |
|
||
| **on ne sait pas si elle obéit** | la mesure manque ou est périmée | rien à reprendre en main |
|
||
|
||
**C'est exactement la distinction `none` contre l'absence d'un champ, appliquée à un écart.** Une
|
||
mesure absente qui se lit comme une mesure à zéro produit une divergence maximale, et c'est le pire
|
||
faux positif possible : il ressemble trait pour trait au cas qu'on cherche.
|
||
|
||
Concrètement, une divergence dont la mesure vaut 0 pendant que le lien est tombé doit être
|
||
**comptée à part**, jamais avec les autres. Le relevé du 2026-08-30 le documente : à la perte du
|
||
lien, la V2C publie `currentPower` **0** et ses booléens à `false`, tandis que `sessionEnergy`
|
||
reste à sa dernière valeur (`LM-1012-d`). Le zéro est donc **publié**, pas absent — et rien dans
|
||
l'objet `command` ne le distingue d'un zéro réel.
|
||
|
||
> **Conséquence à porter au lot**, et à trancher avant de compter : `command` devrait pouvoir dire
|
||
> que son `observedW` n'est pas fiable, plutôt que de laisser déduire. C'est la même parade que
|
||
> `progress.regime` pour l'avancement. Tant qu'elle n'existe pas, le tri se fait à la main sur les
|
||
> traces, en croisant avec les pertes de lien du journal.
|
||
|
||
### Ce qui sera compté, et ce qui ne le sera pas
|
||
|
||
- **Compté** : les épisodes sur une charge à compteur variable, hors fenêtres de perte de lien.
|
||
- **Compté à part** : les épisodes concomitants d'une perte de lien — ils mesurent la
|
||
disponibilité, pas l'obéissance.
|
||
- **Écarté** : les épisodes sur une charge dont le compteur est constant sur la fenêtre.
|
||
- **Le compte des écartés est publié aussi.** Un tri dont on ne dit pas ce qu'il a jeté n'est pas
|
||
un tri, c'est une sélection.
|
||
- **Écarté aussi : les épisodes de TRANSITION DE DÉROGATION** — ajouté le 2026-09-08, mesuré.
|
||
Une dérogation fait bouger la consigne de plusieurs kilowatts d'un coup, dans les deux sens, et
|
||
chaque bord ouvre une divergence :
|
||
|
||
| bord | trace du banc | nature |
|
||
|---|---|---|
|
||
| ouverture | `11:53:00 DÉBUT — attendu 13800 W, mesuré 3930 W` → `11:57:00 FIN après 300 s — attendu 8970 W, mesuré 8396 W` | la voiture **négocie sa montée** |
|
||
| fermeture | `11:58:00 DÉBUT — attendu 0 W, mesuré 8367 W` | la borne **n'a pas encore décru** |
|
||
|
||
**La fermeture est la plus trompeuse** : l'écart est immédiat, énorme, et il ressemble trait
|
||
pour trait à une commande ignorée. Le discriminant est temporel et il est publié — **une
|
||
divergence qui naît dans le même cycle qu'un `DEROGATION_ENDED`, ou dans celui d'un
|
||
`DEROGATION_ACTIVE` neuf, est une transition en cours.**
|
||
|
||
Sans cette clause, **chaque boost compterait pour deux incidents**, et l'étape 4 se justifierait
|
||
d'elle-même en comptant ses propres transitoires. C'est le mécanisme du §6.2 — un instrument
|
||
qui fabrique la preuve dont il a besoin — appliqué à la mesure au lieu du banc.
|
||
|
||
---
|
||
|
||
## 7. CONDITIONS DE LA FENÊTRE D'OBSERVATION — week-end du 2026-09-06
|
||
|
||
Noté pour que les traces de lundi soient lisibles. **Rien n'a été restauré** : la configuration
|
||
ci-dessous reste en place tout le week-end.
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Posé le** | dimanche 2026-09-06 à **08:19** (Europe/Paris ; box et atelier à la même heure depuis la correction du 2026-09-05) |
|
||
| **Charge** | `chauffe-eau` |
|
||
| **Changement** | `minEnergyWhPerDay` **3000 → 2000**, `dailyDeadline` inchangé à `"12:00"` |
|
||
| **Vérification** | 76 clés comparées entre capture et relecture : 1 divergence attendue, 0 imprévue |
|
||
| **Capture d'avant** | conservée hors dépôt, `scratchpad/loadconfig_AVANT_weekend.json` |
|
||
| **Moteur** | `1.15.2+etm56` · plugin générique `1.14.2+etm3` |
|
||
| **Symboles de débogage** | `libnymea1-dbgsym` / `libnymea-core-dbgsym` arm64 **laissés en place** jusqu'à lundi — donc **aucune couture supplémentaire** pendant la fenêtre |
|
||
|
||
### Ce que l'écran montre à la pose, et pourquoi ce n'est pas un défaut
|
||
|
||
À 08:19, le palier éco est `ECO_FLOOR_MET` avec `deliveredWh` = **30 475 Wh** pour une cible de
|
||
2 000, `measuredSince` = `2026-09-05T10:00:00Z`. L'obligation est tenue vingt fois.
|
||
|
||
**C'est arithmétiquement correct et sans intérêt** : le compteur de l'ECS publie 1 500 W en
|
||
permanence (cf. §6), donc `deliveredWh` monte de 1,5 kWh par heure que la charge soit commandée ou
|
||
non. La période courante a basculé hier à 12:00 ; vingt heures plus tard, elle a « livré » 30 kWh.
|
||
|
||
### La fenêtre utile est à 12:00, et elle dure ~80 minutes
|
||
|
||
À chaque bascule de période, la base d'avancement est reprise (`LM-1013-c`). `deliveredWh` repart
|
||
de 0 face à une cible de 2 000 Wh sur 24 h — soit une cadence de **83 W**, financée par le réseau
|
||
si le surplus manque. Le compteur fixe la comble en **2000 / 1500 = 80 minutes**, après quoi
|
||
l'écran repasse à `ECO_FLOOR_MET` pour les 22,7 h restantes.
|
||
|
||
**Donc deux fenêtres exploitables sur le week-end** : dimanche 12:00 et lundi 12:00, ~80 min
|
||
chacune, où l'on voit un vrai plancher éco, son financement et sa cadence. Le reste du temps,
|
||
l'écran montre l'état « tenue » — qui est aussi une forme à valider.
|
||
|
||
> **Et c'est la cinquième forme d'homogénéité qui fixe ce plafond** (`INVENTAIRE_MOCK.md` §7).
|
||
> Sur un banc dont le compteur ne suit pas la commande, on ne peut pas avoir à la fois une cible
|
||
> **modeste** et un chemin d'achat **longuement exercé** : ce qui décide n'est pas la cible, c'est
|
||
> la constance du compteur. Choisir une cible qui tienne l'achat en éveil tout le week-end
|
||
> reviendrait à dépasser 36 kWh/jour — c'est-à-dire acheter au plafond, précisément ce qu'on
|
||
> voulait éviter. La contrainte est du banc, pas du moteur.
|
||
|
||
### Coutures ajoutées le 2026-09-06 — à connaître pour lire les traces
|
||
|
||
| heure | événement | effet sur les traces |
|
||
|---|---|---|
|
||
| **11:47:23** | crête PV du simulateur portée de **9 000 à 6 000 W** (`banc/cmd/peak`, retenu, courtier `192.168.1.131`) | moins de surplus, donc plus d'achat réseau pour tenir le plancher éco |
|
||
| **~12:00** | **voiture branchée** à la V2C (`pluggedIn: true`, lien `connected`, `sessionEnergy` 0,44 kWh) | la borne entre dans l'arbitrage |
|
||
|
||
**Aucun redémarrage de `nymead`** dans les deux cas : ce ne sont pas des coutures de baseline, seulement des changements de régime du banc.
|
||
|
||
> **Ce que le passage à 6 kWc ne casse PAS, contrairement à ce que j'avais craint.** Le seuil de
|
||
> démarrage de la borne est `minPowerW = 4140 W` (3 × 6 A × 230 V) et le surplus ne dépasse pas
|
||
> ~2 700 W à 6 kWc. J'en avais conclu que la borne ne démarrerait jamais. **Faux** : mesuré à midi
|
||
> simulé, elle passe en `EV_GRID_START` dès 2 140 W de budget, puis en `SURPLUS_SETPOINT`. Le
|
||
> chemin d'appoint réseau (§3g-2, `acquisitionTolerance`) existe précisément pour ce cas, et
|
||
> `BELOW_MIN_POWER` seul ne dit pas que la borne est bloquée — il dit que **ce budget-là** ne
|
||
> suffit pas.
|
||
|
||
### Convention de signe du réseau — mesurée, pour lever une ambiguïté d'écran
|
||
|
||
`Energy.GetPowerBalance.currentPowerAcquisition` est **négatif en injection, positif en
|
||
soutirage** — même convention que `banc/etat/grid` du simulateur. Vérifié le 2026-09-06 sur dix
|
||
échantillons appariés dont un **passage par zéro** (−638 → +1939 W) : 10/10 de même signe, écart
|
||
moyen ~90 W dû au décalage d'échantillonnage entre les deux sources.
|
||
|
||
De même, `currentPowerProduction` est **négatif** — c'est la convention nymea, énoncée dans
|
||
l'interface `smartmeterproducer` : « currentPower is always from a consumer perspective. Thus it
|
||
will be a negative value for producing devices. »
|
||
|
||
> Un client qui afficherait « consommation réseau » sur un `currentPowerAcquisition` négatif
|
||
> inverse le sens : la valeur négative dit que l'installation **injecte**. Le signe porte la
|
||
> direction ; la valeur absolue seule ne la porte pas.
|
||
|
||
### VERDICT de la fenêtre du week-end — 2026-09-06 : elle n'a rien produit d'exploitable
|
||
|
||
Établi au journal, pas déduit.
|
||
|
||
**La V2C est restée HORS WATERFALL du samedi 18:00 au dimanche 11:46 — 1 066 cycles**, tous
|
||
portant la même ligne :
|
||
|
||
```
|
||
[Arbitre] Borne "V2C Trydan" hors waterfall (mode manuel ou aucun véhicule branché).
|
||
"V2C Trydan" has no car assigned. Ignoring...
|
||
```
|
||
|
||
Elle n'a donc **pas produit une seule trace** sur toute la période visée. Ce n'était pas un
|
||
battement de lien : le moteur ne la voyait ni en mode automatique, ni avec un véhicule branché.
|
||
La voiture est devenue visible à **11:46 le dimanche** — `Executing action V2C Trydan to power:
|
||
ON, Charging current: 7A` — et non le samedi soir.
|
||
|
||
**Puis huit cycles utiles, entre 11:47 et 12:08**, sur le PV simulé à 9 kWc :
|
||
|
||
```
|
||
11:47 Démarrage : plancher 4140 W, dont 896 W SOUTIRÉS (3245 W de surplus, tolérance d'acquisition)
|
||
12:03 Démarrage : plancher 4140 W, dont 2000 W SOUTIRÉS (2140 W de surplus)
|
||
12:05 Surplus PV 6663 W — consigne 6663 W
|
||
12:08 Surplus PV 5598 W — consigne 5598 W
|
||
```
|
||
|
||
**Puis plus rien**, depuis le passage au PV réel : le banc est passé d'un **simulateur à 9 kWc** à
|
||
une **installation réelle de 2 kWc**. Un champ de 2 kWc ne peut pas alimenter le plancher de
|
||
4 140 W qu'exige une borne triphasée à 6 A. La tolérance d'acquisition comblait l'écart tant que
|
||
le budget valait 2 000 à 3 200 W ; à 670 W elle n'a plus rien à combler.
|
||
|
||
**Bilan pour l'étape 4** : rien d'exploitable ce week-end.
|
||
|
||
| charge | traces | statut |
|
||
|---|---|---|
|
||
| V2C | **aucune** — hors waterfall 1 066 cycles | rien à trier |
|
||
| `chauffe-eau` | nombreuses | **écartées** — compteur constant (1 500 W puis 0) |
|
||
| `pac-terrain` | quelques-unes | **écartées** — compteur constant (800 W puis 0) |
|
||
|
||
Le critère de tri du §6 écarte tout ce qui reste. **C'est un résultat, pas un échec** : il dit que
|
||
la fenêtre a été ouverte sur un banc qui ne pouvait pas la remplir, et il nomme les deux raisons —
|
||
une borne hors arbitrage, et des compteurs qui ne mesurent pas.
|
||
|
||
**Précondition pour la prochaine fenêtre** : un compteur RÉEL sur une charge pilotée
|
||
(`TEST_TERRAIN.md` §12), et une borne effectivement dans le waterfall — à vérifier au journal
|
||
avant d'ouvrir, pas après.
|
||
|
||
---
|
||
|
||
## 8. PROTOCOLE DU RELEVÉ DU 2026-09-08 — écrit avant, comme le critère
|
||
|
||
> La voiture revient vers 9 h. Ce qui suit est écrit **avant** de mesurer, pour la même raison que
|
||
> le critère de tri du §6 : un protocole rédigé après coup se plie à ce qu'on a vu.
|
||
|
||
### Ce qu'on observe, et ce qui serait un résultat
|
||
|
||
**1. `progress.regime` de la V2C — première bascule observable sur du réel.**
|
||
|
||
`sessionEnergy` est construit par le plugin, donc le régime devrait sortir `measured`. Mais sur un
|
||
lien qui perd 40 % de ses trames, il **basculera**. C'est l'observation qui compte le plus, parce
|
||
que **la dérogation en dépend entièrement** : sa fin par `measurementLost` se déclenche sur ce
|
||
signal, et on ne l'a jamais vu changer ailleurs qu'en test.
|
||
|
||
| ce qu'on voit | ce que ça dit |
|
||
|---|---|
|
||
| `measured` en continu | le lien tient assez pour que la cible soit vérifiable — la dérogation par cible est utilisable |
|
||
| bascules `measured` ↔ `unmeasurable` | **le cas nominal** de cette borne : la fin par perte de mesure va se déclencher souvent, et il faudra savoir à quelle fréquence avant de promettre une dérogation par cible |
|
||
| `unmeasurable` en continu | la cible en énergie n'est pas servable ici, et seule la durée reste |
|
||
|
||
**Aucune de ces trois n'est un échec** — chacune décide de ce qu'on peut promettre.
|
||
|
||
**2. `command.divergent` — les premières traces qui passent le critère du §6.**
|
||
|
||
Jusqu'ici, aucune trace n'était exploitable : compteurs constants des deux côtés (§7). Avec une
|
||
borne qui charge vraiment et un compteur qui suit, le critère est enfin satisfait —
|
||
`measurement.source ≠ none` et un compteur qui **a varié**.
|
||
|
||
**Regarder d'abord les épisodes COURTS.** Ce sont eux qui décident si l'étape 4 vaut le risque de
|
||
rejouer une commande : un écart de trois minutes qui se referme seul ne justifie pas de commander
|
||
du matériel sur une consigne ancienne ; un écart qui dure et ne se referme jamais, si.
|
||
|
||
> Et se souvenir du biais du journal : `grep -c` compte des **lignes**, pas des transitions
|
||
> (`PORTING_STATUS.md`). Ici la ligne `[Divergence] DÉBUT` / `FIN` est émise **aux transitions
|
||
> seulement** — c'est le comptage juste, contrairement à `error limit reached`.
|
||
|
||
**3. Min+PV lui-même** : palier éco au minimum avec `boundBy: minimum`, palier confort alimenté
|
||
par le surplus, et le recrédit visible dans `recreditedW`. Vérifié sur le chauffe-eau le
|
||
2026-09-07 ; reste à le voir sur la borne, où le tirage est dix fois plus grand.
|
||
|
||
### Ce qui invaliderait le relevé
|
||
|
||
- Un redémarrage de `nymead` pendant la fenêtre : la base d'avancement se repose et
|
||
`measuredSince` repart. **Ne rien déployer pendant l'observation.**
|
||
- Une bascule de fuseau : aucune n'est prévue, et il n'y en aura pas.
|