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:
@@ -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,
|
||||
|
||||
@@ -92,6 +92,9 @@ const vm = balance.vehicleMidday || {};
|
||||
setBool('input_boolean.evcs_balance_vehicle_grid_needed', !!vm.gridNeeded);
|
||||
setNumber('input_number.evcs_balance_vehicle_need_kwh', vm.active ? vm.reachableKwh : 0);
|
||||
setNumber('input_number.evcs_balance_vehicle_solar_kwh', vm.active ? vm.solarKwh : 0);
|
||||
// Maison sur le reseau pendant la fenetre HC de nuit si la session s'engage (29/09).
|
||||
const nh = balance.nightHcImport || {};
|
||||
setNumber('input_number.evcs_balance_night_hc_house_kwh', nh.active && nh.houseKwh !== null ? nh.houseKwh : 0);
|
||||
setNumber('input_number.evcs_balance_energy_to_cover_kwh', c.energyToCoverKwh);
|
||||
setNumber('input_number.evcs_balance_grid_energy_needed_kwh', c.gridEnergyNeededKwh);
|
||||
setNumber('input_number.evcs_balance_vehicle_surplus_kwh', balance.vehicle.surplusAvailableKwh);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
instants : la fin de la fenetre HC en cours (vide hors fenetre) et le debut
|
||||
de la fenetre HC suivante. Strategie du proprietaire : la batterie doit
|
||||
tenir jusqu'a la prochaine fenetre HC. -#}
|
||||
{%- set ns = namespace(fin='', suivant='', nuit='', fen=[]) -%}
|
||||
{%- set ns = namespace(fin='', suivant='', nuit='', fen=[], nd='', nf='') -%}
|
||||
{%- for j in [0, 1, 2] -%}
|
||||
{%- for a, b, t in [('victron_evcs_hc_night_start', 'victron_evcs_hc_night_stop', 'nuit'), ('victron_evcs_hc_midday_start', 'victron_evcs_hc_midday_stop', 'midi')] -%}
|
||||
{%- set d = today_at(states('input_datetime.' ~ a)) + timedelta(days=j) -%}
|
||||
@@ -20,6 +20,11 @@
|
||||
{%- if w[0] >= repere and ns.suivant == '' -%}{%- set ns.suivant = w[0] -%}{%- endif -%}
|
||||
{%- if w[0] >= repere and w[2] == 'nuit' and ns.nuit == '' -%}{%- set ns.nuit = w[0] -%}{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{#- Fenetre HC de NUIT en cours, sinon la prochaine (29/09) : sert a prevoir
|
||||
ce que la maison achetera au reseau si la session de nuit s'engage. -#}
|
||||
{%- for w in ns.fen | sort(attribute='0') -%}
|
||||
{%- if w[2] == 'nuit' and w[1] > now() and ns.nd == '' -%}{%- set ns.nd = w[0] -%}{%- set ns.nf = w[1] -%}{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{#- Vehicule branche a midi (28/09/2026) — JEEP, VW ou ZERO, selon le
|
||||
selecteur. Pour chacun, HA porte le calendrier (jours et heure de depart
|
||||
apres le dejeuner), la capacite et la puissance de charge MESUREES ; le
|
||||
@@ -74,6 +79,8 @@
|
||||
"hc_window_end_ms": (as_timestamp(ns.fin) * 1000) if ns.fin != '' else none,
|
||||
"next_hc_start_ms": (as_timestamp(ns.suivant) * 1000) if ns.suivant != '' else none,
|
||||
"next_night_hc_start_ms": (as_timestamp(ns.nuit) * 1000) if ns.nuit != '' else none,
|
||||
"night_hc_start_ms": (as_timestamp(ns.nd) * 1000) if ns.nd != '' else none,
|
||||
"night_hc_end_ms": (as_timestamp(ns.nf) * 1000) if ns.nf != '' else none,
|
||||
"nowMs": as_timestamp(now()) * 1000,
|
||||
|
||||
"balance_enabled": states("input_boolean.evcs_balance_enabled"),
|
||||
|
||||
@@ -77,6 +77,10 @@ return [{
|
||||
hc_window_end_ms: snapshot.hc_window_end_ms,
|
||||
next_hc_start_ms: snapshot.next_hc_start_ms,
|
||||
next_night_hc_start_ms: snapshot.next_night_hc_start_ms,
|
||||
// Fenetre HC de nuit en cours ou prochaine (29/09) : import prevu si la
|
||||
// session de nuit s'engage.
|
||||
night_hc_start_ms: snapshot.night_hc_start_ms,
|
||||
night_hc_end_ms: snapshot.night_hc_end_ms,
|
||||
|
||||
// Repris pour l'écriture des helpers, sans influencer le calcul.
|
||||
resourceUsable: resource.usable,
|
||||
|
||||
Reference in New Issue
Block a user