docs : heures creuses et batterie — décision D7, pleine puissance en heures creuses (lot e2)

§8 gagne D7 (2026-10-24) et §8.1 : la règle (minimum = plafond de cycle),
le choix des phases, la sécurité (LM-1500-h en heures creuses seulement, L4
garde le dernier mot), la fin de session au seuil mesuré, le motif
EV_OFF_PEAK_FULL_POWER. Deux points restent à trancher : le double
écrêtage hors heures creuses, et l'oscillation de la consigne près de la
limite de phase (le plafond ne rend pas à la borne ce qu'elle tire).
Lot futur, non implémenté : ne réserver que ce dont la maison a besoin
jusqu'au soleil, d'après la prévision. §2 renvoie à D7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Patrick Schurig 2026-10-24 22:22:15 +02:00
parent 1291f72d1f
commit 225fbc5a8d

View File

@ -27,15 +27,16 @@ horaires (`tou`) dont les prix **diffèrent** (`TariffConfig::zonesCreuses()`).
**Modes concernés** — `ChargingModeEcoWithMinCurrent`, `ChargingModeEcoMinWithTargetTime`, **Modes concernés** — `ChargingModeEcoWithMinCurrent`, `ChargingModeEcoMinWithTargetTime`,
`ChargingModeEcoWithTargetTime` : ceux dont le besoin réseau peut attendre. `EvAdapter` le `ChargingModeEcoWithTargetTime` : ceux dont le besoin réseau peut attendre. `EvAdapter` le
DÉCLARE (`LoadNeeds::offPeakShift`, `offPeakMinPowerW` = le plancher de la borne), le scheduler DÉCLARE (`LoadNeeds::offPeakShift`, `offPeakMinPowerW` = le plafond de cycle de la borne depuis
le DÉCIDE (règle 2). `ChargingModeEco` ne demande jamais le réseau, `ChargingModeNormal` est le lot e2, son plancher au lot e1 — §8, D7), le scheduler le DÉCIDE (règle 2). `ChargingModeEco` ne demande jamais le réseau, `ChargingModeNormal` est
piloté par l'utilisateur : tous deux sont inchangés. piloté par l'utilisateur : tous deux sont inchangés.
| | hors heures creuses | en heures creuses | | | hors heures creuses | en heures creuses |
|---|---|---| |---|---|---|
| minimum réseau (`minPowerWAlways`) | **retiré** — surplus seulement | le plancher de la borne, au moins | | minimum réseau (`minPowerWAlways`) | **retiré** — surplus seulement | le **plafond** de la borne (lot e2, §8 D7) |
| démarrage sous tolérance (`EV_GRID_START`) | **refusé** (le minimum par une autre porte) | inchangé | | démarrage sous tolérance (`EV_GRID_START`) | **refusé** (le minimum par une autre porte) | inchangé |
| motif d'une consigne nulle | **`EV_WAITING_OFF_PEAK`** `{at, startsAt, budgetW}` | motifs ordinaires | | motif d'une consigne nulle | **`EV_WAITING_OFF_PEAK`** `{at, startsAt, budgetW}` | motifs ordinaires |
| motif de la consigne servie | — | **`EV_OFF_PEAK_FULL_POWER`** (lot e2, §8 D7) |
| échéance (`EV_DEADLINE`, proxy) | inchangée | inchangée | | échéance (`EV_DEADLINE`, proxy) | inchangée | inchangée |
**Le changement de comportement** : une borne « Éco avec minimum » ne prend plus ses 6 A au **Le changement de comportement** : une borne « Éco avec minimum » ne prend plus ses 6 A au
@ -47,7 +48,8 @@ parce que la cause de la consigne nulle n'est plus le manque de surplus. Le plaf
verrous gardent la tête : ils diraient la même chose en heures creuses. verrous gardent la tête : ils diraient la même chose en heures creuses.
**En heures creuses**, le plancher est servi au réseau par la passe éco (`ECO_FLOOR_GRID`), **En heures creuses**, le plancher est servi au réseau par la passe éco (`ECO_FLOOR_GRID`),
bornée par l'autorisation de soutirage ; le confort ajoute le surplus s'il y en a. La borne bornée par l'autorisation de soutirage ; le confort ajoute le surplus s'il y en a. *Lot e2 :
c'est désormais le plafond, sous `EV_OFF_PEAK_FULL_POWER` — §8, D7.* La borne
déclare un plafond écrêté par `evPhaseAllowanceW()`, `verifyOverloadProtection()` garde le dernier déclare un plafond écrêté par `evPhaseAllowanceW()`, `verifyOverloadProtection()` garde le dernier
mot : l'invariant 2 tient sans rien ajouter. mot : l'invariant 2 tient sans rien ajouter.
@ -277,6 +279,82 @@ aucune ne change le code.
| D4 | Une borne en `ChargingModeNormal` qui charge en heures creuses déclenche-t-elle le blocage (§3.2) ? | **Oui, c'est le but** : la mesure porte sur toutes les bornes, mode compris. | | D4 | Une borne en `ChargingModeNormal` qui charge en heures creuses déclenche-t-elle le blocage (§3.2) ? | **Oui, c'est le but** : la mesure porte sur toutes les bornes, mode compris. |
| D5 | Seuil de « la voiture charge réellement » : 230 W sur la somme des bornes (§3.2) ? | **Accepté.** | | D5 | Seuil de « la voiture charge réellement » : 230 W sur la somme des bornes (§3.2) ? | **Accepté.** |
| D6 | Plugin SunSpec : une action « limite de décharge » en une séquence (`planBatteryMode(NO_DISCHARGE)`), et `enableDischarging` renommé ou redécrit (§3.1, §7) ? | **Oui aux deux**, dans le dépôt du plugin, à la charge de l'orchestrateur. Le garde ne change pas : il reste compatible avec les deux actions actuelles (`dischargingRate` puis `enableDischarging`). | | D6 | Plugin SunSpec : une action « limite de décharge » en une séquence (`planBatteryMode(NO_DISCHARGE)`), et `enableDischarging` renommé ou redécrit (§3.1, §7) ? | **Oui aux deux**, dans le dépôt du plugin, à la charge de l'orchestrateur. Le garde ne change pas : il reste compatible avec les deux actions actuelles (`dischargingRate` puis `enableDischarging`). |
| D7 | À quelle puissance la borne charge-t-elle en heures creuses (lot e2) ? | **À la pleine puissance permise**, et non plus au plancher. La session finit plus tôt, et la décharge de la batterie n'est bloquée que pendant ce temps-là : ensuite, elle couvre la maison pour le reste de la nuit. Détail en §8.1. |
La mesure du minuteur de retour sur un vrai GEN24 (hypothèse AC-10 du plugin, §3.4) reste La mesure du minuteur de retour sur un vrai GEN24 (hypothèse AC-10 du plugin, §3.4) reste
ouverte : elle relève du plugin et d'un essai sur matériel réel. ouverte : elle relève du plugin et d'un essai sur matériel réel.
### 8.1 D7 — pleine puissance en heures creuses (lot e2)
**Pourquoi.** Au plancher (6 A, 1,4 kW en monophasé), une nuit de 22:00 à 06:00 livre au plus
11 kWh : une session de 10 à 25 kWh n'est pas finie au départ. Et la décharge de la batterie
reste bloquée toute la nuit, puisque la voiture charge toute la nuit : la batterie est encore
pleine le matin, et le surplus solaire part au réseau.
**La règle.** Dans les trois modes qui reportent en heures creuses (§2), le minimum servi au
réseau en heures creuses est le **plafond de cycle** de la borne (`declared.maxPowerW`) :
- il porte le courant maximal de la borne, ses phases, et la limite de phase
(`evPhaseAllowanceW()`) — rien n'est retiré de ces écrêtages ;
- il ne descend jamais sous le plancher : la limite de phase **rabaisse** la borne, elle ne la
coupe pas ; couper reste le geste de `verifyOverloadProtection()` (L4), qui garde le dernier
mot ;
- hors heures creuses, et sans heure creuse dans le tarif, rien ne change.
Par exemple : 3 680 W en monophasé 16 A, 11 040 W en triphasé 16 A.
**Les phases.** En heures creuses, une borne qui peut charger en triphasé charge en triphasé.
La règle de bascule du manager est inchangée ; c'est le courant qu'on lui présente qui change.
Hors heures creuses, c'est « courant de la borne + surplus ». En heures creuses, c'est la pleine
puissance de la borne. Raison : la nuit, « courant + surplus » bride dans un cas précis — une
batterie (non pilotable, ou pas encore bloquée) couvre la maison et la voiture, le compteur lit
≈ 0, et la référence vaut le courant que la borne tire déjà. À 6 A en monophasé, la règle garde
le monophasé : 3,7 kW au lieu de 11. La limite de phase n'entre pas dans le choix, et c'est sans
perte : par phase, elle borne pareil une monophasée et une triphasée, donc trois phases donnent
toujours au moins autant.
**Sécurité.** Le plafond d'une borne porte déjà l'autorisation de soutirage, résolue sur les
phases qu'elle occupe et multipliée par leur nombre. La passe éco ne lui oppose donc pas en plus
la marge d'**une** phase de la maison (`LM-1500-h`, déjà appliquée en tête de passe et en passe
confort). Sans cela, une triphasée serait servie à 7 A au lieu de 16. Une autre charge allumée
la nuit réduit le plafond au cycle suivant ; sous le plancher, la borne est tenue au plancher, et
L4 coupe au dépassement. Cette exemption ne vaut **qu'en heures creuses** : sans heure creuse, le
plancher éco d'une borne reste écrêté par la marge de la maison, comme avant.
**Reste à trancher** (rien n'est changé par ce lot) :
- *Le double écrêtage hors heures creuses.* Le plancher éco d'une borne triphasée, sans heure
creuse, est encore comparé à la marge d'une phase. L'étendre à `LM-1500-h` changerait des
décisions sans tarif : c'est un choix à faire à part.
- *L'oscillation près de la limite de phase.* Le plafond d'une borne est la place libre **sans
lui rendre ce qu'elle tire** (`evPhaseAllowanceW()`, choix de sécurité documenté). À pleine
puissance, la borne voit donc sa propre consommation lui réduire le plafond au cycle suivant,
puis le lui rendre au cycle d'après. En simulation, avec un compteur qui voit la borne (maison
à 2 A par phase, borne triphasée 16 A), la consigne alterne à chaque cycle entre 16 et 7 A
sous une limite de 25 A, et entre 16 et 14 A sous 32 A. Au plancher (lot e1), le phénomène ne
se voyait pas. Une piste : rendre à la borne, en heures creuses, son propre courant moins une
marge (la règle de l'échéance chez l'amont, `adjustEvChargers()` : marge − 1 A + courant de la
borne).
**Fin de session.** Le blocage de la décharge se lève sur la puissance **mesurée** des bornes,
au seuil de 230 W (D5). Une borne commandée à 16 A dont la voiture ne prend plus rien (pleine,
ou session arrêtée par le véhicule) ne tient donc pas la batterie bloquée.
**Motif.** `EV_OFF_PEAK_FULL_POWER {gridW, maxW, phases, until, endsAt, o:boundBy}` remplace,
en heures creuses, `ECO_FLOOR_GRID` sur la borne. `gridW` est la puissance retenue, `maxW` la
pleine puissance du matériel aux phases visées. `boundBy` n'est présent que si la protection de
surcharge l'a rabaissée : `phaseLimit` (à ce que la limite laisse) ou `floor` (tenue au
plancher, L4 décide de la suite). Rendu : « Borne charge à pleine puissance en heures creuses :
11040 W achetés au réseau (3 phases, jusqu'à 06:00) ».
**Preuves.** `testOffPeakChargesAtFullPower`, `testOffPeakFullPowerSwitchesToThreePhases`,
`testOffPeakFullPowerYieldsToThePhaseLimit` ; les tests du lot e1 en heures creuses attendent
désormais le plafond. Sans heure creuse, la preuve `decisions` est identique.
**Lot futur, non implémenté** — *réserver seulement ce dont la maison a besoin jusqu'au soleil,
d'après la prévision.* Aujourd'hui la décharge est bloquée entière tant que la voiture charge
(D1). Une version plus fine laisserait la batterie se décharger dans la voiture au-delà de ce que
la maison consommera d'ici le retour du soleil — consommation de base prévue (`BaseloadLog`) et
heure de la première production utile (prévision PV). Elle demande une prévision fiable des deux,
et un pilotage de `OutWRte` plus fin qu'un tout-ou-rien : c'est un lot à part.