Prevision de nuit : annoncer l'achat EDF reel (maison en HC + manque batterie)

Nuit du 28-29/09 : « environ 0,14 kWh a prendre sur EDF » annonces, 4,6 importes.
0,14 etait le manque de la batterie ; une session engagee fait passer toute la
maison sur le reseau jusqu'a 07:24. Le bilan publie la maison non couverte sur
la fenetre HC de nuit (input_number.evcs_balance_night_hc_house_kwh) et
sensor.evcs_prevision_nuit annonce import_prevu_kwh = maison + manque ;
reseau_necessaire_kwh supprime. Bilan 72/72, diagnostics 85/85.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011uJ47NxgfpGnuuMr3f2n7Z
This commit is contained in:
Tallagrand Thierry
2026-09-29 10:46:13 +02:00
parent ebcba4637b
commit 24ccecbc02
11 changed files with 198 additions and 14 deletions

View File

@@ -394,6 +394,33 @@ const hcFloorPrudentPct = Math.max(hcReachFloorPct(slotsP80, nextHcStartMs), hcF
const typical = coverage(slotsP50, hcFloorTypicalPct);
const prudent = coverage(slotsP80, hcFloorPrudentPct);
// ---------------------------------------------------------------------
// CE QUE LA SESSION DE NUIT ACHETERA AU RESEAU (29/09/2026)
//
// Incident du 28/09 : la prevision annoncait « 0,14 kWh a prendre sur EDF » et
// le reseau en a fourni 4,6. Les deux etaient justes, mais le premier est le
// MANQUE de la batterie : une fois engagee, la session tient la batterie et la
// maison passe TOUTE la fenetre HC de nuit sur le reseau (§40). Le chiffre qui
// repond a « combien vais-je acheter » est donc la maison non couverte par le
// solaire sur la fenetre (profil habituel, recale sur la soiree), depuis
// maintenant si la fenetre est ouverte. Le manque batterie s'y ajoute, a part.
// ---------------------------------------------------------------------
const nightHcStartMs = num(input.night_hc_start_ms, NaN);
const nightHcEndMs = num(input.night_hc_end_ms, NaN);
const nightHcActive = Number.isFinite(nightHcStartMs) && Number.isFinite(nightHcEndMs)
&& nightHcEndMs > nightHcStartMs;
let nightHcHouseKwh = null;
if (nightHcActive) {
const depuis = Math.max(nightHcStartMs, num(input.nowMs, Date.now()));
nightHcHouseKwh = 0;
for (const sl of slotsP50) {
const debut = num(sl.startMs, NaN);
if (!Number.isFinite(debut)) continue;
const a = Math.max(debut, depuis), b = Math.min(debut + 3600000, nightHcEndMs);
if (b > a) nightHcHouseKwh += Math.max(0, -sl.netKwh) * (b - a) / 3600000;
}
}
// ---------------------------------------------------------------------
// VEHICULE BRANCHE EN HC AVEC UN DEPART AVANT LA PROCHAINE HC (28/09/2026)
//
@@ -667,6 +694,14 @@ return [{
forecastKwh: num(input.night_house_forecast_kwh, NaN) || null,
},
// Maison sur le reseau pendant la fenetre HC de nuit, si la session s'engage (29/09).
nightHcImport: {
active: nightHcActive,
startMs: nightHcActive ? nightHcStartMs : null,
endMs: nightHcActive ? nightHcEndMs : null,
houseKwh: nightHcHouseKwh === null ? null : round2(nightHcHouseKwh),
},
// Voiture branchee en HC, depart avant la prochaine HC (28/09).
vehicleMidday: {
active: vehicleRuleActive,