From 225fbc5a8d1c118a38167bbbc33e431613094a41 Mon Sep 17 00:00:00 2001 From: Patrick Schurig Date: Sat, 24 Oct 2026 22:22:15 +0200 Subject: [PATCH] =?UTF-8?q?docs=20:=20heures=20creuses=20et=20batterie=20?= =?UTF-8?q?=E2=80=94=20d=C3=A9cision=20D7,=20pleine=20puissance=20en=20heu?= =?UTF-8?q?res=20creuses=20(lot=20e2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §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 --- docs/DESIGN_HC_BATTERIE.md | 86 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/docs/DESIGN_HC_BATTERIE.md b/docs/DESIGN_HC_BATTERIE.md index de9aaf9..ae064f4 100644 --- a/docs/DESIGN_HC_BATTERIE.md +++ b/docs/DESIGN_HC_BATTERIE.md @@ -27,15 +27,16 @@ horaires (`tou`) dont les prix **diffèrent** (`TariffConfig::zonesCreuses()`). **Modes concernés** — `ChargingModeEcoWithMinCurrent`, `ChargingModeEcoMinWithTargetTime`, `ChargingModeEcoWithTargetTime` : ceux dont le besoin réseau peut attendre. `EvAdapter` le -DÉCLARE (`LoadNeeds::offPeakShift`, `offPeakMinPowerW` = le plancher de la borne), le scheduler -le DÉCIDE (règle 2). `ChargingModeEco` ne demande jamais le réseau, `ChargingModeNormal` est +DÉCLARE (`LoadNeeds::offPeakShift`, `offPeakMinPowerW` = le plafond de cycle de la borne depuis +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. | | 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é | | 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 | **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. **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 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. | | 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`). | +| 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 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. +