docs(brief): la question au moteur — le stockage est-il une charge arbitrable ?

Formulée depuis une demande simple de Patrick : que le surplus aille d'abord à l'eau chaude,
et à la batterie seulement ensuite. Elle n'est pas exprimable aujourd'hui, et le brief dit
pourquoi avec ce qui a été vérifié plutôt qu'avec ce qui est supposé.

Quatre constats : batteryLevelConsideration donne la priorité à la BATTERIE (le budget est
annulé sous le seuil, pas au-dessus) ; la batterie n'est dans aucun GetLoadConfig ;
enableCharging et ses quatre voisins ont zéro occurrence dans energyplugin/ ; et pourtant la
classe SunSpec Storage de .75 les déclare comme actions exécutables. Plus un indice :
domain: "battery" est déjà accepté par SetLoadConfig sans que rien n'en fasse quoi que ce
soit.

Quatre sous-questions, dont la première est la leçon de 3g-2 retournée vers eux : l'onduleur
Fronius a sa propre logique de charge, donc avant d'ajouter un commandeur il faut savoir qui
commande déjà. C'est littéralement le défaut d'adjustEvChargers(), et il serait absurde de le
réintroduire sur la batterie le jour où ils viennent de le supprimer sur les bornes.

Et ce que nous nous interdisons en attendant, dit explicitement : une règle Rules.* qui
couperait enableCharging fonctionnerait, et nous l'écartons — ce serait un second commandeur
sans arbitre. Mieux vaut dire « pas réglable aujourd'hui » qu'offrir un réglage dont personne
ne garantit l'effet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016vrTVifar2GN5rtUh89Wkq
This commit is contained in:
Patrick Schurig 2026-08-27 19:58:54 +02:00
parent b60c74d2e4
commit a1d0659db7

View File

@ -2,6 +2,98 @@
---
## 2026-08-27 — QUESTION : le stockage est-il une charge arbitrable ?
**Origine** : une demande de Patrick, formulée simplement — *« si je veux que l'énergie aille
d'abord dans l'eau chaude, et seulement si l'eau est chaude je commence à charger la
batterie, je fais comment ? »*
**Réponse honnête que nous lui avons faite : aujourd'hui, il ne peut pas.** Et le réglage
qu'il a sous les yeux fait l'inverse de ce qu'il demande. Voilà ce que nous avons vérifié
avant de vous écrire.
### 1. `batteryLevelConsideration` donne la priorité à la BATTERIE, pas aux charges
Sous le seuil, le budget de surplus est **annulé** (`rulebasedscheduler.cpp:125`) : l'ECS ne
reçoit rien tant que la batterie n'a pas dépassé 40 %. C'est exactement la priorité inverse
de celle qu'il demande, et c'est le seul levier « batterie » du contrat.
Le mettre à 0 ne donne pas non plus « ECS d'abord » : ça retire le blocage, après quoi
l'ECS et la batterie se servent **en même temps** et c'est l'onduleur qui tranche
physiquement. « Les deux se disputent » n'est pas « l'un puis l'autre ».
### 2. La batterie n'est dans aucun waterfall, et le moteur ne la commande nulle part
- Aucune entrée `GetLoadConfig` pour le stockage — quatre entrées sur `.75` : `chauffe-eau`,
`pac-terrain`, et les deux bornes depuis `+etm23`.
- `enableCharging`, `enableDischarging`, `chargingRate`, `dischargingRate`, `gridCharging` :
**zéro occurrence** dans `energyplugin/` (grep sur `.cpp` et `.h`).
### 3. Le levier matériel existe pourtant, et il est déclaré
La classe **SunSpec Storage** de `.75` (le Fronius du banc) publie ces cinq **actions
exécutables** :
```
enableCharging · enableDischarging · chargingRate · dischargingRate · gridCharging
```
La box sait donc dire « ne charge pas maintenant ». Personne ne le lui demande.
### 4. Et `battery` est déjà dans l'énumération fermée des domaines assignables
`SetLoadConfig` accepte `domain: "battery"` — au même titre que `ecs`, `ev`, `heating`,
`hvac`. Rien n'en fait quoi que ce soit. Cela ressemble à une question qui a été effleurée
puis laissée ; d'où notre question.
---
### La question, et ses quatre sous-questions
> **Le stockage doit-il devenir une charge du waterfall, avec un `priority` ordinaire —
> comme les bornes viennent de le devenir en 3g-2 ? Ou reste-t-il définitivement hors du
> budget ?**
Si la réponse est **oui**, la demande de Patrick s'exprime sans aucun écran nouveau : il
glisse « eau chaude » au-dessus de « batterie », et c'est fini. Quatre points à trancher
avec vous :
**a) Le double commandeur — et c'est la leçon de 3g-2, pas une objection de forme.**
L'onduleur Fronius a sa propre logique de charge. Si l'arbitre commande `enableCharging =
false`, est-ce que l'onduleur obéit, ou re-décide derrière lui ? C'est **littéralement** le
défaut que `adjustEvChargers()` produisait sur les bornes : la décision publiée n'atteignait
pas le matériel, et l'écran avait l'air faux. Avant d'ajouter un commandeur, il faut savoir
qui commande déjà.
**b) Que devient `batteryLevelConsideration` ?** Un rang de batterie et un seuil qui annule
tout le budget expriment deux stratégies concurrentes. Si les deux survivent, il faut dire
laquelle gagne — sinon nous aurons deux réglages dont l'un défait l'autre en silence, ce que
l'écran ne saura pas présenter.
**c) La sûreté.** `batteryCritical` existe sur le Thing. Un rang de priorité doit-il pouvoir
faire descendre le stockage sous un plancher de sécurité, ou y a-t-il un seuil que
l'arbitrage ne franchit jamais ? Nous ne voulons pas offrir un glissement qui vide une
batterie.
**d) Le sens du signe.** Pour l'ECS, « allouer 2 000 W » veut dire *consommer*. Pour le
stockage, cela veut dire *stocker* — même unité, sens opposé au bilan. Si le stockage entre
dans `loads[]`, comment son `allocatedW` se réconcilie-t-il avec `budget.allocatedW` ?
C'est la question qui nous a déjà mordus avec `EV_GRID_START`.
### Ce que nous ne ferons PAS en attendant
Une règle `Rules.*` du type *« si l'ECS n'est pas chaud → `enableCharging = false` »*
**fonctionnerait**, et nous l'écartons volontairement : ce serait un second commandeur sur
la batterie, sans arbitre entre lui et l'onduleur. C'est le défaut que vous venez de
supprimer sur les bornes, réintroduit ailleurs par la porte de l'app.
Nous préférons dire à l'utilisateur « ce n'est pas réglable aujourd'hui » plutôt que lui
donner un réglage dont personne ne garantit l'effet.
---
---
## 2026-08-27 (soir) — retour sur le brief 3g-2
Les quatre points sont traités. Deux vérifications que vous nous demandiez, et trois