Bilan : reprise du chauffe-eau du soir comptee les jours faibles, prevision de l'apres-midi recalee sur la matinee
This commit is contained in:
20
HANDOFF.md
20
HANDOFF.md
@@ -2080,5 +2080,23 @@ SOC atteint a 07:24 contre la cible. La fenetre de midi du 07/10 s'est fermee 2
|
||||
- Tests ECS 23/23 (horloge simulee dans le harnais pour la reprise du soir ; coupure de la veille ignoree),
|
||||
mutation qui mord.
|
||||
|
||||
### 07/10 soir — Reprise de 16 h verifiee, EDF ferme en HP a 18:03, et le bilan apprend de la journee
|
||||
- **16:00** ballon rallume (`jour_faible_securite_soir`), BOOST 1,2 kW stable 16:15-18:05 (mesure sur 10 min :
|
||||
plus de clignotement), arret thermostat a 18:05 (eau a 65 °C pour 20 h, a priori), coupe a 20:00. 2,1 kWh.
|
||||
- **Cout** : batterie 35 % (14:25) -> 21 % (18:00), EDF ferme par l'hysteresis a **18:03 en HEURES PLEINES**
|
||||
(2,8 kWh HP a 20:31, ~8 kWh HP attendus jusqu'a 01:24 : ouverture seulement a 30 %).
|
||||
- **Estimation (memes conditions, nouveaux reglages de 14:17-14:22)** : HC de midi +3,9 kWh au lieu de +1,4 ->
|
||||
~44 % a 14:24, ~30 % a 18:00, EDF ferme vers 20:30 -> ~5 kWh HP au lieu de ~8. Pour zero HP il aurait fallu
|
||||
~60 % a 14:24 (+9 kWh en 2 h, ~4,5 kW, faisable sous 12 kVA si la maison reste < 6 kW).
|
||||
- **Correctifs du bilan (accord du proprietaire, deploye 22:40, tests 87/87, +4, mutations qui mordent)** :
|
||||
1. jour faible (decision du jour `on`) : `input_number.evcs_chauffe_eau_reprise_soir_kwh` (2,1 kWh MESURES le
|
||||
07/10, a recaler) ajoute a la consommation de 16 h a 20 h du jour -> plancher HC de midi 38,1 -> 45,1 %
|
||||
sur le cas sombre (+7 points = 2,1 / 0,30, verifie a la main) ;
|
||||
2. prevision des heures RESTANTES du jour x (reel du jour / prevu des heures ecoulees), borne [0,4 ; 1], seulement
|
||||
si >= 2 kWh prevus ecoules et production `complet`, jamais a la hausse -> cas sombre a 60 % : plancher
|
||||
49,4 %. Champs ajoutes au gabarit/PREPARE (garde-fou de transmission OK) ; sorties `ecsReprise`, `prodRecal`.
|
||||
- ⚠️ A verifier au prochain jour faible : plancher de midi publie, recharge HC (courant ACM, consigne), heure
|
||||
de fermeture EDF le soir (objectif : apres 01:24, pas en HP).
|
||||
|
||||
---
|
||||
*Document mis a jour le : 07/10/2026 (~14:40) — bilan HC de midi, reprise du soir apres coupure en pleine chauffe, mesure ECS sur 10 min ; recharge reseau HC : courant calcule (12 kVA) et consigne non tenue ; HC de midi : AUTO ne chauffe pas (BOOST), alerte v2, Jeep (contact, relecture, zone), recharge batterie bridee a 30 A par l'ACM ; jour faible = EDF les deux fenetres HC pour le chauffe-eau, alerte BOOST, Victron Mobile refait ; 1re decision jour faible en reel, mesure ECS reparee, douches 06:00/20:00, Grafana chauffe-eau, tableaux ECS ; chauffe-eau en HC de nuit les jours faibles (decision du bilan, workflow ECS sous controle du depot, VRM, V2.3 desactive) ; garde batterie reseau : voiture bridee a 6 A au lieu d'un arret ; garde-fou concierge 2 h ; allers-retours brefs de la borne retrouves dans l'historique HA (echange VW -> JEEP de 20 s), production 14,5 kWh contre 22 prevus, defaut garde batterie en mode reseau a trancher ; voiture a midi : la batterie n'est plus comptee comme du solaire (EDF automatique les jours de depart si le surplus ne couvre pas) ; nuit 05->06 : JEEP chargee sur EDF en complete (6,32 kWh), budget 0 du a la prevision, Windy/ECMWF contre VRM, a comparer ce soir ; concierge aligne sur la preuve fin de trajet ; a verifier : nuit 05->06 et mardi faible, comparaison VRM/Forecast.Solar ; JEEP identifiee aussi par sa fin de trajet, prevision de la nuit 05->06 ; identification JEEP reussie en reel, correction humaine qui prime (refus supprime), session du 04/10 coupee ; EVCS Master en quatre onglets ; Jeep lue par Uconnect et identifiee seule, capacite JEEP 10 kWh, concierge variante (a) ; releve par photo (SPARK), hass-uconnect en attente ; ecart semaine/week-end mesure (pas de profil week-end la nuit) ; nuit du budget : budget borne au plancher prudent, sans EDF = voiture bloquee meme EDF ferme (batterie seule) ; Energie : sauts corriges ; tableau Energie complete (Sud/Ouest, batterie par integration, borne ; aucun redemarrage HA) ; kilometrage des vehicules (km/kWh, capacite, releves de reference, agent cable 15/15) ; a verifier le 04/10 au matin : nuit du budget JEEP ; concierge : vehicule non confirme demande, heure de saisie ; Grafana vehicules en tableau ; Grafana vehicules : ZERO et Invite ajoutes, session 16:46 reetiquetee ZERO ; prevision SOC 10 h ~35 % ; concierge fiable : niveau note par le script, une ligne, dedoublonnage, simulation par drapeau ; agent : message incompris = question, bourse sur demande explicite (banc final 6/6) ; a verifier : nuit du samedi 03 au dimanche 04/10 (budget < besoin JEEP), cron orange-cloture lundi 05/10 apres 17:40, comparaison VRM / Forecast.Solar lundi 05/10*
|
||||
*Document mis a jour le : 07/10/2026 (~22:45) — reprise de 16 h verifiee, EDF en HP a 18:03, bilan : reprise du soir et prevision recalee sur la matinee ; bilan HC de midi, reprise du soir apres coupure en pleine chauffe, mesure ECS sur 10 min ; recharge reseau HC : courant calcule (12 kVA) et consigne non tenue ; HC de midi : AUTO ne chauffe pas (BOOST), alerte v2, Jeep (contact, relecture, zone), recharge batterie bridee a 30 A par l'ACM ; jour faible = EDF les deux fenetres HC pour le chauffe-eau, alerte BOOST, Victron Mobile refait ; 1re decision jour faible en reel, mesure ECS reparee, douches 06:00/20:00, Grafana chauffe-eau, tableaux ECS ; chauffe-eau en HC de nuit les jours faibles (decision du bilan, workflow ECS sous controle du depot, VRM, V2.3 desactive) ; garde batterie reseau : voiture bridee a 6 A au lieu d'un arret ; garde-fou concierge 2 h ; allers-retours brefs de la borne retrouves dans l'historique HA (echange VW -> JEEP de 20 s), production 14,5 kWh contre 22 prevus, defaut garde batterie en mode reseau a trancher ; voiture a midi : la batterie n'est plus comptee comme du solaire (EDF automatique les jours de depart si le surplus ne couvre pas) ; nuit 05->06 : JEEP chargee sur EDF en complete (6,32 kWh), budget 0 du a la prevision, Windy/ECMWF contre VRM, a comparer ce soir ; concierge aligne sur la preuve fin de trajet ; a verifier : nuit 05->06 et mardi faible, comparaison VRM/Forecast.Solar ; JEEP identifiee aussi par sa fin de trajet, prevision de la nuit 05->06 ; identification JEEP reussie en reel, correction humaine qui prime (refus supprime), session du 04/10 coupee ; EVCS Master en quatre onglets ; Jeep lue par Uconnect et identifiee seule, capacite JEEP 10 kWh, concierge variante (a) ; releve par photo (SPARK), hass-uconnect en attente ; ecart semaine/week-end mesure (pas de profil week-end la nuit) ; nuit du budget : budget borne au plancher prudent, sans EDF = voiture bloquee meme EDF ferme (batterie seule) ; Energie : sauts corriges ; tableau Energie complete (Sud/Ouest, batterie par integration, borne ; aucun redemarrage HA) ; kilometrage des vehicules (km/kWh, capacite, releves de reference, agent cable 15/15) ; a verifier le 04/10 au matin : nuit du budget JEEP ; concierge : vehicule non confirme demande, heure de saisie ; Grafana vehicules en tableau ; Grafana vehicules : ZERO et Invite ajoutes, session 16:46 reetiquetee ZERO ; prevision SOC 10 h ~35 % ; concierge fiable : niveau note par le script, une ligne, dedoublonnage, simulation par drapeau ; agent : message incompris = question, bourse sur demande explicite (banc final 6/6) ; a verifier : nuit du samedi 03 au dimanche 04/10 (budget < besoin JEEP), cron orange-cloture lundi 05/10 apres 17:40, comparaison VRM / Forecast.Solar lundi 05/10*
|
||||
|
||||
@@ -57,3 +57,16 @@ template:
|
||||
{% set b = states('sensor.victron_evcs_ac_power') | float(0) %}
|
||||
{{ [m - e - b, 0] | max | round(0) if m is not none else none }}
|
||||
availability: "{{ states('sensor.victron_consumption_power_l1') | is_number }}"
|
||||
|
||||
# Reprise du chauffe-eau le soir (16 h-20 h, douche de 20 h) a compter dans le
|
||||
# besoin de la HC de midi les jours faibles (07/10/2026) : 2,1 kWh MESURES le
|
||||
# 07/10 (BOOST, 16:06-18:05). A recaler sur les prochains jours faibles.
|
||||
input_number:
|
||||
evcs_chauffe_eau_reprise_soir_kwh:
|
||||
name: "Chauffe-eau : reprise du soir a prevoir (jour faible)"
|
||||
min: 0
|
||||
max: 10
|
||||
step: 0.1
|
||||
unit_of_measurement: kWh
|
||||
mode: box
|
||||
icon: mdi:water-boiler
|
||||
|
||||
@@ -184,13 +184,61 @@ function nightScaled(profile, slot) {
|
||||
return (profile[h] ?? 0) * (1 + (nightFactor - 1) * nightShare(slot.startMs));
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// JOUR FAIBLE : CE QUE LA JOURNEE DIT DEJA (07/10/2026, proprietaire)
|
||||
// =====================================================================
|
||||
// Le 07/10 la HC de midi visait 44 % (« arriver a 01:24 au-dessus de 22 % »),
|
||||
// et EDF a quand meme ete ferme en HEURES PLEINES a 18:03 (~8 kWh HP). Deux
|
||||
// erreurs du calcul, corrigees ici :
|
||||
// 1. La reprise du chauffe-eau de 16 h a 20 h (douche de 20 h, 2,1 kWh mesures
|
||||
// le 07/10) n'etait pas comptee : les jours faibles (decision du bilan),
|
||||
// `ecs_reprise_soir_kwh` est ajoute a la consommation de 16 h a 20 h du jour.
|
||||
// 2. La prevision de l'apres-midi n'etait pas recalee sur la matinee : VRM
|
||||
// annoncait ~9 kWh de 14 h a 19 h, il en est venu ~5, et la matinee le
|
||||
// disait deja (3,1 kWh produits a 12:36 pour ~5 prevus). Quand le reel du
|
||||
// jour est EN RETARD sur la prevision des heures ecoulees (au moins 2 kWh
|
||||
// prevus, production complete), les heures restantes du jour sont
|
||||
// multipliees par le meme rapport, borne a [0,4 ; 1]. Jamais a la hausse :
|
||||
// une matinee meilleure que prevu ne promet rien pour l'apres-midi.
|
||||
const ECS_SOIR_H0 = 16;
|
||||
const ECS_SOIR_H1 = 20;
|
||||
const nowMsSlots = num(input.nowMs, Date.now());
|
||||
const jourParis = (ms) => new Date(ms).toLocaleDateString('sv-SE', { timeZone: 'Europe/Paris' });
|
||||
const aujourdhuiParis = jourParis(nowMsSlots);
|
||||
function slotIsToday(slot) {
|
||||
return Number.isFinite(num(slot.startMs, NaN)) && jourParis(num(slot.startMs, 0)) === aujourdhuiParis;
|
||||
}
|
||||
const ecsNuitAujourdhui = typeof input.ecs_nuit_jour === 'string'
|
||||
&& input.ecs_nuit_jour.startsWith(aujourdhuiParis + '|on');
|
||||
const ecsRepriseSoirKwh = ecsNuitAujourdhui ? Math.max(0, num(input.ecs_reprise_soir_kwh, 0)) : 0;
|
||||
let prodRecal = { factor: 1, active: false };
|
||||
{
|
||||
const prevu = typeof input.forecast_today_csv === 'string' ? input.forecast_today_csv.split(',').map(Number) : [];
|
||||
const reel = num(input.production_jour_kwh, NaN);
|
||||
if (prevu.length === 24 && prevu.every(Number.isFinite) && Number.isFinite(reel)
|
||||
&& input.production_jour_statut === 'complet') {
|
||||
const p = new Intl.DateTimeFormat('fr-FR', { timeZone: 'Europe/Paris', hour: '2-digit', minute: '2-digit', hour12: false })
|
||||
.format(new Date(nowMsSlots)).split(':').map(Number);
|
||||
let ecoule = 0;
|
||||
for (let h = 0; h < 24; h++) ecoule += h < p[0] ? prevu[h] : (h === p[0] ? prevu[h] * p[1] / 60 : 0);
|
||||
if (ecoule >= 2) {
|
||||
const r = reel / ecoule;
|
||||
prodRecal = { factor: round2(Math.max(0.4, Math.min(1, r))), active: r < 1, ratio: round2(r),
|
||||
realKwh: round2(reel), expectedSoFarKwh: round2(ecoule) };
|
||||
}
|
||||
}
|
||||
}
|
||||
const prodRecalFactor = prodRecal.factor;
|
||||
|
||||
function buildSlots(consumption, prudent = false) {
|
||||
return horizon.slice(0, CFG.SEARCH_HOURS).map(slot => {
|
||||
const hour = num(slot.hour, 0);
|
||||
const productionKwh = Math.max(0, num(slot.expectedKwh, 0));
|
||||
const consumptionKwh = prudent
|
||||
const aujourdhui = slotIsToday(slot);
|
||||
const productionKwh = Math.max(0, num(slot.expectedKwh, 0)) * (aujourdhui ? prodRecalFactor : 1);
|
||||
const consumptionKwh = (prudent
|
||||
? Math.max(consumption[hour] ?? 0, nightScaled(consumptionP50, slot))
|
||||
: nightScaled(consumption, slot);
|
||||
: nightScaled(consumption, slot))
|
||||
+ (aujourdhui && hour >= ECS_SOIR_H0 && hour < ECS_SOIR_H1 ? ecsRepriseSoirKwh / (ECS_SOIR_H1 - ECS_SOIR_H0) : 0);
|
||||
return {
|
||||
startMs: slot.startMs,
|
||||
hour,
|
||||
@@ -800,6 +848,9 @@ return [{
|
||||
|
||||
// Chauffe-eau en HC de nuit les jours faibles (07/10).
|
||||
ecsNight,
|
||||
// Reprise du soir et prevision du jour recalee sur la matinee (07/10).
|
||||
ecsReprise: { active: ecsRepriseSoirKwh > 0, kwh: round2(ecsRepriseSoirKwh) },
|
||||
prodRecal,
|
||||
|
||||
// Nuit prevue par la soiree (28/09) : facteur applique au profil.
|
||||
nightModel: {
|
||||
|
||||
@@ -82,6 +82,9 @@
|
||||
"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,
|
||||
"ecs_nuit_jour": states("input_text.evcs_balance_ecs_nuit_jour"),
|
||||
"ecs_reprise_soir_kwh": states("input_number.evcs_chauffe_eau_reprise_soir_kwh"),
|
||||
"production_jour_kwh": states("sensor.evcs_production_jour_kwh"),
|
||||
"production_jour_statut": state_attr("sensor.evcs_production_jour_kwh", "statut"),
|
||||
"nowMs": as_timestamp(now()) * 1000,
|
||||
|
||||
"balance_enabled": states("input_boolean.evcs_balance_enabled"),
|
||||
|
||||
@@ -83,6 +83,12 @@ return [{
|
||||
night_hc_end_ms: snapshot.night_hc_end_ms,
|
||||
// Decision du jour pour le chauffe-eau (07/10) : « AAAA-MM-JJ|on|raison ».
|
||||
ecs_nuit_jour: snapshot.ecs_nuit_jour,
|
||||
// 07/10 : reprise du chauffe-eau le soir (jour faible) et production reelle
|
||||
// du jour pour recaler la prevision de l'apres-midi.
|
||||
ecs_reprise_soir_kwh: snapshot.ecs_reprise_soir_kwh,
|
||||
production_jour_kwh: snapshot.production_jour_kwh,
|
||||
production_jour_statut: snapshot.production_jour_statut,
|
||||
forecast_today_csv: snapshot.forecast_today_csv,
|
||||
|
||||
// Repris pour l'écriture des helpers, sans influencer le calcul.
|
||||
resourceUsable: resource.usable,
|
||||
|
||||
@@ -128,6 +128,8 @@ const SUMMARIZE = {
|
||||
ecsOn: o.ecsNight ? (o.ecsNight.on ?? null) : null,
|
||||
ecsProjectedSocPct: o.ecsNight ? (o.ecsNight.projectedSocPct ?? null) : null,
|
||||
ecsRequiredSocPct: o.ecsNight ? (o.ecsNight.requiredSocPct ?? null) : null,
|
||||
ecsRepriseKwh: o.ecsReprise ? o.ecsReprise.kwh : null,
|
||||
prodRecalFactor: o.prodRecal ? o.prodRecal.factor : null,
|
||||
}) : ({ usable: false, missing: o.missing.join(',') }),
|
||||
};
|
||||
|
||||
|
||||
@@ -555,6 +555,42 @@ export const balanceScenarios = [
|
||||
{ night_hc_end_ms: Date.parse('2026-09-27T07:24:00+02:00'), ecs_nuit_jour: '2026-09-26|on|x' }),
|
||||
expect: { usable: true, ecsDue: false, ecsDecided: false },
|
||||
},
|
||||
// ======== JOUR FAIBLE : REPRISE DU SOIR ET PREVISION RECALEE (07/10/2026) ========
|
||||
{
|
||||
node: 'BALANCE',
|
||||
id: 'bilan-hc-midi-reference-sans-correction',
|
||||
label: 'Reference : HC de midi 12:30, SOC 31, journee sombre — plancher « tenir jusqu a 01:24 »',
|
||||
snapshot: snap2709('2026-09-27T12:30:00+02:00', 31, MIDI_2709, SOMBRE),
|
||||
expect: { usable: true, hcReachActive: true, hcFloorPct: 38.1 },
|
||||
},
|
||||
{
|
||||
node: 'BALANCE',
|
||||
id: 'bilan-hc-midi-jour-faible-reprise-du-soir',
|
||||
label: 'Meme midi, jour faible : 2,1 kWh de chauffe-eau de 16 h a 20 h comptes -> plancher plus haut',
|
||||
snapshot: Object.assign(snap2709('2026-09-27T12:30:00+02:00', 31, MIDI_2709, SOMBRE),
|
||||
{ ecs_nuit_jour: '2026-09-27|on|x', ecs_reprise_soir_kwh: '2.1' }),
|
||||
// Verifie a la main : 2,1 kWh / 0,30 kWh par point = +7,0 points (38,1 -> 45,1).
|
||||
expect: { usable: true, hcReachActive: true, ecsRepriseKwh: 2.1, hcFloorPct: 45.1 },
|
||||
},
|
||||
{
|
||||
node: 'BALANCE',
|
||||
id: 'bilan-hc-midi-prevision-recalee-sur-la-matinee',
|
||||
label: 'Meme midi, matinee a 60 % de la prevision : les heures restantes du jour x 0,6 -> plancher plus haut',
|
||||
snapshot: Object.assign(snap2709('2026-09-27T12:30:00+02:00', 31, MIDI_2709, SOMBRE), {
|
||||
forecast_today_csv: FS_2709.map((v) => (v * SOMBRE).toFixed(3)).join(','),
|
||||
production_jour_kwh: String(Math.round(FS_2709.slice(0, 12).reduce((a, b) => a + b, 0) * SOMBRE * 0.6 * 100 + FS_2709[12] * SOMBRE * 0.5 * 0.6 * 100) / 100),
|
||||
production_jour_statut: 'complet' }),
|
||||
expect: { usable: true, hcReachActive: true, prodRecalFactor: 0.6, hcFloorPct: 49.4 },
|
||||
},
|
||||
{
|
||||
node: 'BALANCE',
|
||||
id: 'bilan-prevision-jamais-recalee-a-la-hausse',
|
||||
label: 'Matinee meilleure que prevu : facteur 1, on ne promet rien de plus pour l apres-midi',
|
||||
snapshot: Object.assign(snap2709('2026-09-27T12:30:00+02:00', 31, MIDI_2709, SOMBRE), {
|
||||
forecast_today_csv: FS_2709.map((v) => (v * SOMBRE).toFixed(3)).join(','),
|
||||
production_jour_kwh: '40', production_jour_statut: 'complet' }),
|
||||
expect: { usable: true, prodRecalFactor: 1 },
|
||||
},
|
||||
// ======== LES TROIS VEHICULES (28/09/2026) ========
|
||||
{
|
||||
node: 'BALANCE',
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user