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

@@ -593,6 +593,16 @@ export function previsionNuit(st, maintenant = new Date()) {
const session = txt('input_boolean.victron_evcs_night_grid_session_committed') === 'on';
const branche = txt('binary_sensor.victron_evcs_vehicle_connected');
const hcDebut = (txt('input_datetime.victron_evcs_hc_night_start') || '').slice(0, 5) || null;
const hcFin = (txt('input_datetime.victron_evcs_hc_night_stop') || '').slice(0, 5) || null;
// CE QUI SERA ACHETE, pas le manque de la batterie (incident 28/09 21:32 :
// « 0,14 kWh a prendre sur EDF » annonces, 4,6 importes). Une session engagee
// tient la batterie et fait passer TOUTE la maison sur le reseau jusqu'a la
// fin des heures creuses : achat = maison sur la fenetre (calculee par le
// bilan) + manque de la batterie. 0 publie = fenetre inconnue -> null.
const maisonHc = nombre(st, 'input_number.evcs_balance_night_hc_house_kwh');
const maisonHcKwh = maisonHc !== null && maisonHc > 0 ? maisonHc : null;
const manqueKwh = reseauNecessaire && reseauKwh !== null ? reseauKwh : 0;
const importPrevu = maisonHcKwh !== null ? Math.round((maisonHcKwh + manqueKwh) * 10) / 10 : null;
const marge = soc !== null && socRequis !== null ? Math.round((soc - socRequis) * 10) / 10 : null;
// TROIS verdicts, pas deux (incident 28/09 21:16 : « la batterie suffit, sans
@@ -607,10 +617,13 @@ export function previsionNuit(st, maintenant = new Date()) {
const attributs = {
maison_kwh_a_couvrir: aCouvrir, heure_retour_solaire: retour,
reseau_necessaire: reseauNecessaire, reseau_necessaire_kwh: reseauNecessaire ? reseauKwh : 0,
reseau_necessaire: reseauNecessaire,
// ⚠️ Plus de `reseau_necessaire_kwh` (29/09) : c'etait le manque de la
// batterie, lu comme ce qui serait achete. Deux grandeurs, deux noms.
import_prevu_kwh: importPrevu, maison_en_heures_creuses_kwh: maisonHcKwh, manque_batterie_kwh: manqueKwh,
verdict,
soc_actuel_pct: soc, soc_requis_maintenant_pct: socRequis, soc_requis_prudent_maintenant_pct: socPrudent,
marge_points: marge, debut_heures_creuses: hcDebut,
marge_points: marge, debut_heures_creuses: hcDebut, fin_heures_creuses: hcFin,
contacteur_edf: reseau, session_reseau_nuit_engagee: session,
voiture: branche === 'on' ? 'branchee' : branche === 'off' ? 'aucune' : 'inconnue',
bilan_calcule_il_y_a_min: age,
@@ -629,16 +642,26 @@ export function previsionNuit(st, maintenant = new Date()) {
? 'Un vehicule est branche : sa charge s ajoute et sera decidee par le controleur.'
: 'Etat du vehicule inconnu.';
const hc = hcDebut ? `a ${hcDebut}` : 'a l ouverture des heures creuses';
const kwh = (x) => String(x).replace('.', ',');
const jusqua = hcFin ? `jusqu a ${hcFin}` : 'jusqu a la fin des heures creuses';
const plage = hcDebut && hcFin ? `de ${hcDebut} a ${hcFin}` : 'en heures creuses';
const detail = maisonHcKwh === null ? ''
: manqueKwh > 0 ? ` (maison ${kwh(maisonHcKwh)}, batterie ${kwh(manqueKwh)})` : '';
const achat = importPrevu !== null
? `environ ${kwh(importPrevu)} kWh achetes en heures creuses${detail}, car la maison passe la nuit sur le reseau`
: manqueKwh > 0 ? `au moins ${kwh(manqueKwh)} kWh achetes en heures creuses, plus la consommation de la maison` : null;
const edf = {
edf_engage: `EDF est branche pour la nuit, en heures creuses${reseauNecessaire ? ` : environ ${reseauKwh} kWh a prendre sur EDF avant le retour du solaire` : ''} ; la batterie est tenue jusqu au matin.`,
reseau_necessaire: `Environ ${reseauKwh} kWh a prendre sur EDF en heures creuses avant le retour du solaire.`,
edf_engage: `EDF est branche pour la nuit, ${jusqua}${achat ? ` : ${achat}` : ''} ; la batterie est tenue jusqu au matin.`,
reseau_necessaire: `EDF sera branche ${plage}${achat ? ` : ${achat}` : ''}.`,
batterie_suffit: 'La batterie suffit jusqu au retour du solaire, meme si la maison consomme plus que d habitude : EDF ne devrait pas etre necessaire.',
juste: `C est juste : la batterie suffit seulement si la maison consomme comme d habitude${marge !== null ? ` (marge ${String(marge).replace('.', ',')} point${Math.abs(marge) >= 2 ? 's' : ''})` : ''}. ` +
`Le systeme refait le calcul ${hc} : si la soiree a consomme davantage, il prendra EDF en heures creuses.`,
juste: `C est juste : la batterie suffit seulement si la maison consomme comme d habitude${marge !== null ? ` (marge ${kwh(marge)} point${Math.abs(marge) >= 2 ? 's' : ''})` : ''}. ` +
`Le systeme refait le calcul ${hc} : si la soiree a consomme davantage, il prendra EDF en heures creuses` +
`${maisonHcKwh !== null ? `, et la maison y achetera alors environ ${kwh(Math.round(maisonHcKwh * 10) / 10)} kWh` : ''}.`,
}[verdict];
const texte = `La maison doit couvrir environ ${aCouvrir} kWh jusqu au retour du solaire vers ${retour}. ` +
`${edf} Batterie a ${soc !== null ? Math.round(soc) : '?'} %. ${voiture}`;
return { etat: reseauNecessaire ? reseauKwh : 0, attributs: { ...attributs, statut: 'frais', explication: texte, texte_rapport: texte } };
const etat = verdict === 'edf_engage' || verdict === 'reseau_necessaire' ? (importPrevu ?? manqueKwh) : 0;
return { etat, attributs: { ...attributs, statut: 'frais', explication: texte, texte_rapport: texte } };
}
// ---------------------------------------------------------------------