Le fait le plus utile n'est pas le décompte, c'est son contexte : 10 437 W et σ = 3065 W sur cinq heures, sans une seule divergence après 12:53. Deux épisodes dans le vide ne diraient rien ; deux épisodes sur cinq heures d'activité réelle avec une borne qui suit ses consignes à pleine puissance sont un signal. Un compte faible sur une charge inerte et un compte faible sur une charge sollicitée sont le même nombre et deux résultats opposés — donc les deux se lisent ensemble, et le contexte passe DANS le décompte, pas après. Et la réserve sur la résolution reformule la question de l'étape 4. Si des commandes se perdaient brièvement, elles seraient TOUTES invisibles : un épisode plus court qu'un cycle ne laisse aucune trace. La question n'est donc pas « combien d'épisodes longs » mais « existe-t-il des épisodes courts qu'on ne voit pas ». Ce n'est pas la même mesure : elle demande une cadence fine sur une fenêtre courte, pas une fenêtre longue à 60 s. Allonger l'observation actuelle n'y répondra jamais, quel que soit le nombre d'heures ajoutées — l'instrument dont le silence ressemble à un résultat, appliqué à un protocole. Et la fenêtre fine se paie en cadence de boucle de commande, ce qui n'est pas un réglage d'observation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015F7G5VeaPVSMeVNjiGj36p
519 lines
29 KiB
Markdown
519 lines
29 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.
|
||
|
||
---
|
||
|
||
## 9. OBSERVATION du 2026-09-08, 12:10 → 18:00 — rangée, pas conclue
|
||
|
||
Fenêtre de 5,8 h en **Min+PV**, `1.15.2+etm61`. Dépouillement par
|
||
`scratchpad/fenetre/analyse.py`, sur le journal de la box et sur `thingPower` (347 points par
|
||
charge, cadence 1 min).
|
||
|
||
> **Ce document ne décide pas de l'étape 4.** Il range ce qui a été observé. La raison est au
|
||
> §9.3, et elle tient en une ligne : *un tri qui garde un instrument sur quatre a trié, il n'a
|
||
> pas mesuré.*
|
||
|
||
### 9.1 Le décompte, ET CE QUI LUI DONNE SA FORCE
|
||
|
||
**10 épisodes bruts = 2 retenus + 8 écartés — sur une fenêtre où la borne a réellement
|
||
travaillé.**
|
||
|
||
Les deux chiffres se lisent ENSEMBLE, et l'ordre n'est pas décoratif :
|
||
|
||
| | |
|
||
|---|---|
|
||
| **activité de la V2C** | montée à **10 437 W**, σ = **3 065 W** sur 347 points |
|
||
| **divergences après 12:53** | **aucune**, pendant **cinq heures** |
|
||
| **épisodes retenus** | **2**, tous deux dans les 3 min suivant la bascule |
|
||
|
||
> **Deux épisodes dans le vide ne diraient rien.** Deux épisodes sur cinq heures d'activité
|
||
> réelle, avec une borne qui suit ses consignes **jusqu'à pleine puissance**, est un signal — et
|
||
> c'est lui, pas le décompte, qui porte la lecture. Un compte faible sur une charge inerte et un
|
||
> compte faible sur une charge sollicitée sont le même nombre et deux résultats opposés.
|
||
|
||
Le détail :
|
||
|
||
| | début | charge | durée | attendu → mesuré |
|
||
|---|---|---|---|---|
|
||
| **retenu** | 12:51:02 | V2C | 119 s | 4 140 W → 0 W |
|
||
| **retenu** | 12:53:00 | V2C | 479 s | 8 970 W → 3 934 W |
|
||
|
||
Durées : min 119 s · médiane 299 s · max 479 s — **quantifiées à 60 s**, cadence du cycle.
|
||
|
||
| écartés | motif |
|
||
|---|---|
|
||
| 1 (V2C, 11:57:01, 959 s) | **transition de dérogation** — bord de fermeture du boost |
|
||
| 6 (chauffe-eau) | **compteur constant** sur la fenêtre (0 W) — critère 2 |
|
||
| 1 (pac-terrain, non refermé) | **compteur constant** sur la fenêtre (0 W) — critère 2 |
|
||
|
||
**Les deux retenus sont des latences de démarrage**, à 12:51 et 12:53, dans les trois minutes
|
||
suivant la bascule en Min+PV.
|
||
|
||
### 9.2 Réserve 1 — la résolution est de 60 s, pas de 15
|
||
|
||
Le cycle d'arbitrage est déclenché par les entrées `SampleRate1Min` du journal de puissance de
|
||
nymea : **une par minute**. Les durées ci-dessus sont donc des multiples approximatifs de 60 s,
|
||
et **tout épisode plus court qu'un cycle est invisible**. La distribution est tronquée par le
|
||
bas — non par un seuil, qui n'existe pas, mais par l'échantillonnage.
|
||
|
||
#### La question que cette réserve REFORMULE, et c'est la prochaine
|
||
|
||
Si des commandes se perdaient **brièvement**, elles seraient **toutes invisibles** — un épisode
|
||
plus court qu'un cycle ne laisse aucune trace. La question de l'étape 4 n'est donc pas
|
||
« combien d'épisodes longs ? » mais :
|
||
|
||
> **Existe-t-il des épisodes COURTS qu'on ne voit pas ?**
|
||
|
||
Ce n'est pas la même mesure, et elle ne se prend pas de la même façon : il faut une **cadence
|
||
fine sur une fenêtre courte**, pas une fenêtre longue à 60 s. Allonger l'observation actuelle
|
||
n'y répondra jamais, quel que soit le nombre d'heures ajoutées — c'est le mode d'érosion de
|
||
l'instrument dont le silence ressemble à un résultat, appliqué à un protocole.
|
||
|
||
**À poser quand les SDM120 seront là**, et à décider alors : la fenêtre fine se paie en cadence
|
||
de boucle de commande, ce qui n'est pas un réglage d'observation.
|
||
|
||
### 9.3 Réserve 2 — un seul instrument valide, et c'est elle qui tranche
|
||
|
||
| charge | σ sur la fenêtre | min → max |
|
||
|---|---|---|
|
||
| **V2C Trydan** | **3 065 W** | 0 → 10 437 |
|
||
| chauffe-eau | 0,0 W | 0 → 0 |
|
||
| pac-terrain | 0,0 W | 0 → 0 |
|
||
| Simulated wallbox | 0,0 W | 0 → 0 |
|
||
|
||
Les huit épisodes écartés le sont **tous** pour la même raison de fond : le banc n'a **qu'un
|
||
compteur qui suit la commande de la charge qu'il mesure**. Le critère du §6 a fonctionné — il a
|
||
écarté sans nommer personne, sur la seule propriété observable de la donnée. Mais :
|
||
|
||
> **Une conclusion sur « le moteur perd-il des commandes » tirée d'un seul instrument est une
|
||
> conclusion sur CETTE BORNE, pas sur le moteur.**
|
||
|
||
### 9.4 Ce que les trois points disent, et ce qu'ils ne disent pas
|
||
|
||
Trois épisodes exploitables existent à ce jour — le 09:13 du 2026-09-05 (300 s) et les deux
|
||
d'aujourd'hui (119 s, 479 s). **Les trois pointent dans le même sens** : une consigne qui monte,
|
||
une mesure qui la rejoint en quelques centaines de secondes, un écart qui se referme seul.
|
||
**Latence de négociation, pas commande perdue.**
|
||
|
||
**Trois points sur une seule charge ne font pas une série.** La décision de l'étape 4 —
|
||
faut-il rejouer une commande ? — **reste ouverte**, et elle le restera tant que la question ne
|
||
sera pas posable.
|
||
|
||
### 9.5 Ce qui la rendra posable, et c'est daté
|
||
|
||
De **vrais SDM120** sur la PAC et l'ECS, prévus en fin de semaine. Deux instruments de plus, et
|
||
le critère aurait enfin quelque chose à trier. C'est la **condition d'existence** de l'étape 4,
|
||
pas un confort : décider de rejouer une commande demande de savoir si des commandes se perdent.
|
||
|
||
*(Cf. `INVENTAIRE_MOCK.md` §8 — le sixième manque sous sa forme chiffrée.)*
|