`1.15.2+etm23` construit arm64, posé sur `.75` par deploy.sh, exercé.
FRANCHI, journal et RPC à l'appui :
- Une charge, un commandeur. 9 lignes « Executing action Simulated wallbox »
sur la fenêtre, 9 AVANT « Adjusting chargers » (dispatch de l'arbitre), 0
après (proxy). 6 cycles sur 6 portent « is commanded by the ETM waterfall
this cycle. Not re-deciding here. » Le doublet du relevé 3g-1 §3.3 a
disparu, et quelqu'un commande — l'arbitre a bien allumé la borne à 10 A
sur sa propre décision.
- Le plancher publié est l'exigence réelle : 2 070 W sous +etm22, 4 140 W
sous +etm23, MÊME borne, MÊME journée. Et il suit le nombre de phases visé
d'un cycle à l'autre (4 140 en triphasé, 1 380 en monophasé).
- L'entrée evcharger est créée d'office, journalisée une fois par borne,
sans charge utile ; l'aller-retour GetLoadConfig → SetLoadConfig verbatim
est neutre et ne reconstruit aucun adaptateur ; loads[] ⊆ GetLoadConfig
est rétabli.
TROUVÉ, et c'est le point du passage machine :
- GRAVE — une borne SANS VÉHICULE BRANCHÉ absorbe le budget de la cascade.
4 853 W alloués à une wallbox `pluggedIn: false` qui tire 0 W, la PAC
derrière ne survivant que sur son propre recrédit. Trois cycles
consécutifs, 2 350 / 4 853 / 5 464 W donnés à personne. C'est le défaut du
relevé 3g-1 §3.4 par une autre porte : là le plancher mentait, ici c'est le
filtre d'entrée. evParticipatesInWaterfall() reprend le filtre du proxy —
voiture assignée, mode non manuel — mais pas pluggedIn. Le proxy n'en avait
pas besoin : son allocation n'était pas une cascade. Défaut de 3g-1,
correction PROPOSÉE ET NON APPLIQUÉE, à traiter dans son propre commit.
- Mineur — le rang par défaut des bornes auto-provisionnées retombe à
ÉGALITÉ avec le rang 1 déjà occupé, au lieu de « en tête ». Le tri reste
total et reproductible, mais ce n'est pas ce qui était demandé.
NON OBSERVÉ, et pas fabriqué : EV_GRID_START (le budget est passé de 385 W à
2 350 W sans s'arrêter dans la fenêtre de tolérance), BATTERY_RESERVE avec un
surplus réel, LM-1204-b matériel (la Terra AC ne répond pas à l'ARP depuis le
banc lui-même), et le cas de transition — aucune borne n'était sous commande au
moment de la bascule.
Banc rendu à son état d'origine : ChargingInfos identiques champ par champ,
voiture de test retirée, wallbox éteinte. Les entrées evcharger restent — elles
seraient recréées au prochain démarrage.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017TVywtayEeoRJ2yWUW4iZj
10 KiB
Relevé machine — 3g-2 sur le banc .75, 2026-08-27
Paquet : 1.15.2+etm23, construit arm64 dans build-cross-arm64, posé par
etm-powersync-deploy/deploy.sh (rollback : /var/lib/etm-deploy/archive/).
Compteur : Fronius SunSpec. Bornes : Terra AC réelle (absente du réseau) + wallbox simulée.
Méthode. Ce qui suit distingue ce qui a été observé sur machine, ce qui vient d'un test unitaire, et ce qui n'est qu'une lecture de code (
docs/RELEVE_LOTD.md). Tout ce qui est numéroté ci-dessous est machine, journal ou RPC à l'appui.
1. La Terra AC — toujours absente, et c'est physique
| Vérification | Résultat |
|---|---|
ping depuis le banc .75, même segment L2 |
Destination Host Unreachable |
Table ARP du banc pour .132 |
INCOMPLETE — aucune réponse ARP |
| TCP 502 depuis le banc | No route to host |
Balayage complet de 192.168.1.0/24 depuis le banc |
rien en .132 ; aucun autre Modbus TCP inconnu |
Integrations.GetThings |
Terra AC Charger (TCP) en ThingSetupStatusInProgress, en boucle |
Une machine qui ne répond pas à l'ARP est hors du réseau. LM-1204-b garde sa moitié matérielle non franchie — il faut deux bornes RÉELLES, et il n'y en a qu'une.
2. Ce qui est FRANCHI
2.1 Une charge, un commandeur — le critère central du lot
Avant (+etm22, même banc, wallbox en Eco avec voiture assignée) : la borne était arbitrée,
et adjustEvChargers() reprenait la main derrière.
Après (+etm23), chaque cycle porte, dans cet ordre :
[Arbitre] "{09e520fd…}" → "Surplus PV 2350 W — Simulated wallbox consigne 2350 W" | activé: true | phases: 1
Executing action Simulated wallbox to power: ON, Carging current: 10A, Switch phases to: 1, Issuer: Surplus
---------------- Adjusting chargers ---------------
"Simulated wallbox" is commanded by the ETM waterfall this cycle. Not re-deciding here.
Et dans planSurplusCharging, un cycle plus haut :
"Simulated wallbox" surplus is planned by the ETM waterfall. Skipping proxy planning.
Comptage sur la fenêtre d'observation : 9 lignes Executing action Simulated wallbox, 9
avant Adjusting chargers (donc émises par le dispatch de l'arbitre), 0 après (donc aucune
dérivée par le proxy). 6 cycles sur 6 portent la ligne de saut.
Le doublet a disparu, et quelqu'un commande. C'est le critère du lot, et il est franchi.
2.2 Le plancher publié est l'exigence réelle
Sur la MÊME borne, dans la même journée :
| motif publié | |
|---|---|
+etm22 |
BELOW_MIN_POWER {budgetW: 84, minPowerW: **2070**} |
+etm23 |
BELOW_MIN_POWER {budgetW: 395, minPowerW: **4140**} |
2 070 W était 6 A × 0,5 × 230 × 3 — le plancher multiplié par la tolérance d'acquisition.
4 140 W est 6 A × 230 × 3, ce que la borne exige réellement. Le défaut du relevé 3g-1 §3.4 est
fermé, et le chiffre le montre.
Et le plancher suit le nombre de phases VISÉ, cycle à cycle : au cycle suivant, la référence
de bascule ayant changé, le journal publie
BELOW_MIN_POWER {budgetW: 385, minPowerW: **1380**} — soit 6 A × 230 × 1. C'est le piège le
plus silencieux de DESIGN_3g §3.3, observé en train de fonctionner.
2.3 L'entrée evcharger auto-provisionnée
Au premier cycle après la bascule, une ligne par borne, à la création seulement :
[EnergyArbitrator] Borne "Simulated wallbox" ajoutée à la configuration des charges
(rang 1 , domaine ev) — entrée créée automatiquement, modifiable par SetLoadConfig.
[EnergyArbitrator] Borne "Terra AC Charger (TCP)" ajoutée à la configuration des charges (…)
GetLoadConfig passe de 2 à 4 entrées. Les deux entrées de borne portent
adapter: evcharger, mode: dynamic, domain: ev, et aucune charge utile — vérifié champ
par champ (relays, sgReady, powerLevels, maxPowerW, minPowerW, minOnS, minOffS
tous vides ou nuls).
Aller-retour NEUTRE, par la frontière RPC : GetLoadConfig → SetLoadConfig verbatim →
GetLoadConfig rend un objet identique, et le journal du cycle suivant dit
0 créée(s), 0 mise(s) à jour en place, 2 inchangée(s), 0 retirée(s) — aucun adaptateur
reconstruit, aucun verrou réarmé.
loads[] ⊆ GetLoadConfig est rétabli : les trois charges publiées ont leur entrée. La
Terra AC est dans GetLoadConfig sans être dans loads[] — c'est le sens autorisé de
l'inclusion : sans voiture assignée, elle est hors arbitrage, et le journal le dit
([Arbitre] Borne "Terra AC Charger (TCP)" hors waterfall).
2.4 La bascule elle-même
nymead arrêté 10:03:24, démarré 10:03:35, premier cycle d'arbitrage 10:04:00 — 36 s sans
arbitrage. L'ECS a repris son palier par relecture des contacts
(reprise au démarrage : palier 0 W [correspondance exacte], ECS-411).
⚠️ Le cas de transition que je voulais éprouver ne l'a PAS été : au moment de la bascule,
aucune borne n'était sous commande (surplus négatif, wallbox à l'arrêt). « Une borne
commandée par un chemin qui n'existe plus » reste donc non observé. Ce qui EST observé et qui
en couvre la moitié : l'arbitre émet activement des power: OFF (4 fois sur la fenêtre), donc
le mécanisme qui rattraperait une borne laissée allumée est en place et tourne.
3. CE QUE LA MACHINE A TROUVÉ, ET QUI N'EST PAS DANS LE LOT
3.1 GRAVE — une borne SANS VÉHICULE BRANCHÉ absorbe le budget de la cascade
Trois cycles consécutifs, wallbox en Eco avec voiture assignée mais pluggedIn: false :
[Arbitre] "chauffe-eau" → "Surplus PV 8353 W — chauffe-eau consigne 3500 W (palier)"
[Arbitre] "{09e520fd…}" → "Surplus PV 4853 W — Simulated wallbox consigne 4853 W" ← 4 853 W
[Arbitre] "pac-terrain" → "Surplus PV 1500 W — PAC banc recommandée (état 3, ~1500 W)"
Et dans la même charge utile de télémétrie, pour cette borne :
allocatedW: 4853 mécanisme: { chargingEnabled: false, pluggedIn: false, currentA: 7, phaseCount: 1 }
La borne est commandée power: ON, elle ne tire rien (currentPower: 0), et 4 853 W ont
été retirés du budget et donnés à personne. La PAC derrière elle n'a survécu que sur son
propre recrédit. Les deux cycles voisins donnent 2 350 W puis 5 464 W au même vide.
C'est le défaut du relevé 3g-1 §3.4 qui revient par une autre porte : là c'était le plancher qui mentait, ici c'est le filtre d'entrée.
Cause : EnergyArbitrator::evParticipatesInWaterfall() reprend le filtre d'entrée du proxy —
voiture assignée, mode non manuel — mais pas pluggedIn. Le proxy n'en avait pas besoin :
son allocation n'était pas une cascade, gaspiller ne privait personne. En cascade, si.
L'asymétrie est visible dans le code même : la boucle EV du scheduler, elle, teste bien
if (!ev->available() || !ev->pluggedIn()) continue; — seul le chemin waterfall ne le fait pas.
Défaut de 3g-1, révélé par 3g-2 parce que la décision atteint enfin le matériel.
Correction proposée, non appliquée : pluggedIn rejoint le filtre d'entrée. Une borne sans
véhicule est hors arbitrage, comme une borne sans voiture assignée ou en mode manuel
(DESIGN_3g §4) — absente du contexte, pas servie à 0 : sa consommation est nulle et déjà au
compteur. À traiter dans son propre commit, avec le même journal de saut que les deux autres cas.
3.2 Mineur — le rang par défaut retombe à ÉGALITÉ, pas « en tête »
Les deux bornes ont reçu rang 1, à égalité avec chauffe-eau qui l'occupait déjà.
La règle implémentée est « le plus petit rang existant moins un, borné à 1 ». Quand une charge occupe déjà le rang 1, « moins un » vaut 0, le plancher le ramène à 1, et l'intention — mettre la borne en tête sans bousculer les charges déjà classées — dégénère en égalité.
Sans conséquence sur la reproductibilité : le tri est total, l'identifiant départage, et l'ordre est stable d'un cycle à l'autre. Mais ce n'est pas ce qui était demandé. Trois issues possibles, aucune tranchée : autoriser le rang 0, renuméroter les autres (exclu par « sans bousculer »), ou assumer l'égalité et laisser l'app poser les vrais rangs à la mise en service.
3.3 Pour mémoire — deux écritures de configuration dans le même cycle
Deux bornes détectées ⇒ deux setConfigs() ⇒ deux changed() ⇒ deux rebuildLoadAdapters()
dans le cycle de démarrage. Les deux sont incrémentaux (2 inchangée(s)), donc aucun
adaptateur n'est détruit et ECS-412 tient. Sans conséquence, mais à savoir si le nombre de
bornes grandit.
4. CE QUI N'EST PAS PROUVÉ
EV_GRID_START: NON observé. Guetté six cycles durant, comme demandé — jamais fabriqué. Le budget de la borne est passé de 385 W à 2 350 W sans s'arrêter dans la fenêtre[plancher × 0,5 ; plancher[(690–1 380 W en monophasé). Le motif reste donc éprouvé par le seul test de simulation. À guetter, commeBELOW_MIN_POWERl'a été.BATTERY_RESERVEavec un surplus réel sous le seuil : toujours pas. Le SoC est à 50 %, le seuil à 0,4 — la réserve n'est pas active.- LM-1204-b, moitié matérielle : deux bornes réelles (§1).
- Le cas de transition « borne commandée par un chemin qui n'existe plus » (§2.4).
- La charge réelle d'un véhicule : aucune voiture n'a été branchée — la wallbox simulée
n'expose aucune action
pluggedIn, seulementconnect/disconnect(interfaceconnectable, étatconnected). C'est d'ailleurs ce qui a rendu §3.1 visible.
5. État où le banc a été rendu
| valeur | pourquoi | |
|---|---|---|
| Paquet | 1.15.2+etm23 |
posé par deploy.sh, +etm22 archivé |
ChargingInfos |
identiques à l'origine — les deux bornes en ChargingModeNormal, sans voiture, targetPercentage: 0 |
comparées champ par champ au relevé d'avant |
| Voiture de test | retirée (3G2-CAR-A-SUPPRIMER) |
|
| Wallbox simulée | éteinte (power: false) |
l'arbitre ne la commande plus, elle est hors arbitrage |
LoadConfig |
4 entrées : chauffe-eau, PAC banc, + les 2 bornes auto-provisionnées | les entrées de borne RESTENT — elles seraient recréées au prochain démarrage |
batteryLevelConsideration |
0,4 · acquisitionTolerance 0,5 · phasePowerLimit 0 |
inchangés |
Dernier cycle rendu : surplus 5 634 W, chauffe-eau 3 500 W, pac-terrain 3 000 W, aucune
borne dans loads[].