Revue : EDF absent en session, voiture payee par la batterie, interventions, kWh sur la puissance ; piles : hysteresis et acquittement
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
import { pilesAAlerter } from '../../tools/piles.mjs';
|
||||
import { lireAcquittements, pilesAAlerter } from '../../tools/piles.mjs';
|
||||
const T = Date.parse('2026-10-10T00:30:00+02:00');
|
||||
const e = (entity_id, state, attrs = {}, last = '2026-10-09T22:00:00+02:00') => ({ entity_id, state, attributes: attrs, last_changed: last });
|
||||
// Extrait reel des etats HA du 10/10 00:30.
|
||||
@@ -25,4 +25,20 @@ ok('muet-plus-de-24h', r.alertes.find((a) => a.entite === 'sensor.tt_chambre_bat
|
||||
ok('muet-recent-pas-encore', !ids.includes('sensor.chambre_danielle_etat_batterie'));
|
||||
ok('ignorees', !pilesAAlerter(etats, T, ['sensor.kt_chambre_batterie']).alertes.some((a) => a.entite === 'sensor.kt_chambre_batterie'));
|
||||
ok('texte', /SYLVIE CHAMBRE Batterie : pile a 12 %/.test(r.texte) && /TT CHAMBRE Batterie ne publie plus depuis 5 j/.test(r.texte), r.texte);
|
||||
// 13/10 : hysteresis. GRENIER 13 -> 19 % -> 6 % : une seule alerte, qui tient tant que < 40 %.
|
||||
const grenier = (n) => [{ entity_id: 'sensor.salle_de_bain_bruz_batterie', state: String(n), last_changed: new Date(T).toISOString(),
|
||||
attributes: { device_class: 'battery', unit_of_measurement: '%', friendly_name: 'GRENIER Batterie' } }];
|
||||
ok('hysteresis-tient-a-25', pilesAAlerter(grenier(25), T, [], { precedentes: ['sensor.salle_de_bain_bruz_batterie'] }).alertes.length === 1);
|
||||
ok('hysteresis-pas-de-nouvelle-a-25', pilesAAlerter(grenier(25), T, [], { precedentes: [] }).alertes.length === 0);
|
||||
ok('hysteresis-retombe-a-40', pilesAAlerter(grenier(40), T, [], { precedentes: ['sensor.salle_de_bain_bruz_batterie'] }).alertes.length === 0);
|
||||
// Acquittement : « vu, je change dans 3 jours » -> plus de rappel jusqu'a la date.
|
||||
const acq = lireAcquittements('salle_de_bain_bruz_batterie:2026-10-16, mauvais format, x:2026-13-99');
|
||||
const ra = pilesAAlerter(grenier(6), Date.parse('2026-10-14T09:00:00+02:00'), [], { acquittements: acq });
|
||||
ok('acquittee-pas-de-rappel', ra.alertes.length === 1 && ra.a_rappeler.length === 0 && ra.acquittees[0].jusqu_au === '2026-10-16' && /jusqu'au 16\/10/.test(ra.texte), JSON.stringify(ra));
|
||||
const rb = pilesAAlerter(grenier(6), Date.parse('2026-10-17T08:00:00+02:00'), [], { acquittements: acq });
|
||||
ok('acquittement-expire-rappel', rb.a_rappeler.length === 1 && rb.a_rappeler[0].cle === 'salle_de_bain_bruz_batterie');
|
||||
ok('acquittement-format-tolerant', Object.keys(acq).length === 1);
|
||||
const gerard = (v) => [{ entity_id: 'sensor.chambre_gerard_etat_batterie', state: v, last_changed: new Date(T).toISOString(), attributes: { device_class: 'enum', friendly_name: 'Chambre Gerard Etat batterie' } }];
|
||||
ok('enum-low-middle-tient', pilesAAlerter(gerard('middle'), T, [], { precedentes: ['sensor.chambre_gerard_etat_batterie'] }).alertes.length === 1
|
||||
&& pilesAAlerter(gerard('middle'), T, []).alertes.length === 0 && pilesAAlerter(gerard('high'), T, [], { precedentes: ['sensor.chambre_gerard_etat_batterie'] }).alertes.length === 0);
|
||||
console.log(f ? `\n${f} ECHEC(S)` : '\nPILES OK'); process.exit(f ? 1 : 0);
|
||||
|
||||
@@ -20,7 +20,7 @@ const ok = (id, cond, info = '') => { if (cond) console.log(`✅ ${id}`); else {
|
||||
const codes = (r) => r.constats.map((c) => c.code).join(',');
|
||||
|
||||
{ const r = constatsRevue(base());
|
||||
ok('rien-a-signaler', r.constats.length === 0 && /Rien a signaler/.test(r.texte), r.texte); }
|
||||
ok('rien-a-signaler', r.constats.length === 0 && /Aucun des cas surveilles/.test(r.texte) && /seuls ces cas sont verifies/.test(r.texte), r.texte); }
|
||||
|
||||
{ // 07/10 18:06 -> 01:24, 8,3 kWh, ferme par l'automatisation SoC < 22 %
|
||||
const d = base();
|
||||
@@ -29,7 +29,8 @@ const codes = (r) => r.constats.map((c) => c.code).join(',');
|
||||
d.edfKwh.push({ ts: T('07T18:05:00'), v: 100 }, { ts: T('08T01:24:00'), v: 108.3 }, { ts: T('08T07:24:00'), v: 113 });
|
||||
d.soc.push({ ts: T('07T18:00:00'), v: 21 });
|
||||
const r = constatsRevue(d); const c = r.constats.find((x) => x.code === 'edf_heures_pleines');
|
||||
ok('hp-releve-0710', !!c && c.chiffres.minutes === 438 && c.chiffres.kwh === 8.3 && /18:06 a 01:24/.test(c.texte)
|
||||
// 13/10 : kWh = puissance reseau mesuree (1 800 W x 438 min = 13,14 kWh), plus le compteur du disjoncteur.
|
||||
ok('hp-releve-0710', !!c && c.chiffres.minutes === 438 && c.chiffres.kwh === 13.14 && /18:06 a 01:24/.test(c.texte)
|
||||
&& /Grid ON si SoC < 22%/.test(c.texte) && r.constats.filter((x) => x.code === 'edf_heures_pleines').length === 1, JSON.stringify(r.constats)); }
|
||||
|
||||
{ const d = base(); // reseau 4 min en heures pleines : ignore
|
||||
@@ -105,5 +106,35 @@ const sessionMidi = (d, requis) => {
|
||||
const c = constatsRevue(d).constats.find((x) => x.code === 'charge_max_bridee_en_cours');
|
||||
ok('charge-max-bridee-en-cours', c && /depuis 12:24/.test(c.texte) && c.gravite === 'a_examiner', JSON.stringify(constatsRevue(d).constats.map((x) => x.code))); }
|
||||
|
||||
// 13/10 : EDF demande mais absent. Releve du 12-13/10 : session engagee a 01:24,
|
||||
// reseau 0 W, batterie a -900 W, contacteur rearme au levier a 05:58.
|
||||
const nuitEdfAbsent = () => { const d = base();
|
||||
d.sessionNuit = [{ ts: T('07T07:25:00'), v: 'off' }, { ts: T('08T01:24:00'), v: 'on' }, { ts: T('08T07:24:00'), v: 'off' }];
|
||||
d.batterieW = [{ ts: T('07T07:25:00'), v: 0 }, { ts: T('08T01:25:00'), v: -900 }, { ts: T('08T05:58:00'), v: 1500 }];
|
||||
d.soc.push({ ts: T('08T01:25:00'), v: 36 }, { ts: T('08T05:58:00'), v: 26 });
|
||||
return d; };
|
||||
{ const r = constatsRevue(nuitEdfAbsent()); const c = r.constats.find((x) => x.code === 'edf_absent_session');
|
||||
ok('edf-absent-1213', c && c.gravite === 'a_examiner' && /ABSENT de 01:25 a 05:58/.test(c.texte) && /36 % -> 26 %/.test(c.texte) && c.chiffres.kwh === 4.1 && /session HC engagee oui/.test(c.etat) && !/Aucun des cas/.test(r.texte), JSON.stringify(r.constats)); }
|
||||
{ const d = nuitEdfAbsent(); d.reseauW.push({ ts: T('08T01:25:00'), v: 2300 }, { ts: T('08T07:24:00'), v: 0 });
|
||||
ok('edf-present-rien', !constatsRevue(d).constats.some((x) => x.code === 'edf_absent_session')); }
|
||||
{ const d = nuitEdfAbsent(); d.sessionNuit = [{ ts: T('07T07:25:00'), v: 'off' }];
|
||||
ok('pas-demande-rien', !constatsRevue(d).constats.some((x) => x.code === 'edf_absent_session')); }
|
||||
{ const d = nuitEdfAbsent(); d.sessionNuit = [{ ts: T('07T07:25:00'), v: 'off' }];
|
||||
d.verrouHysteresis = [{ ts: T('07T07:25:00'), v: 'off' }, { ts: T('08T01:24:00'), v: 'on' }];
|
||||
ok('verrou-hysteresis-absent', constatsRevue(d).constats.some((x) => x.code === 'edf_absent_session' && /hysteresis/.test(x.texte))); }
|
||||
// 12/10 : VW payee par la batterie (16:16-16:44, borne 3,4 kW, batterie -3,6 kW).
|
||||
const vwBatterie = (batt = -3600, source = 'Solaire') => { const d = base();
|
||||
d.decisions.push({ ts: T('07T16:16:00'), profil: 'outside_window', source_mode: source, etat: 'hold_min_run', session_engagee: false, cible_matin_pct: 30, raison: 'Maintien jusqu au temps mini ON' });
|
||||
d.borneW = [{ ts: T('07T07:25:00'), v: 0 }, { ts: T('07T16:16:00'), v: 3363 }, { ts: T('07T16:44:00'), v: 0 }];
|
||||
d.batterieW = [{ ts: T('07T07:25:00'), v: 0 }, { ts: T('07T16:16:00'), v: batt }, { ts: T('07T16:44:00'), v: 0 }];
|
||||
return d; };
|
||||
{ const c = constatsRevue(vwBatterie()).constats.find((x) => x.code === 'voiture_payee_par_batterie');
|
||||
ok('vw-payee-1210', c && /de 16:16 a 16:44/.test(c.texte) && c.chiffres.kwh === 1.57 && /hold_min_run/.test(c.texte), JSON.stringify(c)); }
|
||||
ok('vw-solaire-pur-rien', !constatsRevue(vwBatterie(600)).constats.some((x) => x.code === 'voiture_payee_par_batterie'));
|
||||
ok('vw-sur-reseau-rien', !constatsRevue(vwBatterie(-3600, 'Réseau HC autorisé')).constats.some((x) => x.code === 'voiture_payee_par_batterie'));
|
||||
{ const d = base(); d.interventions = [{ ts: T('08T05:58:00'), texte: 'contacteur EDF ferme hors du systeme (levier ou appli)' }];
|
||||
const r = constatsRevue(d);
|
||||
ok('intervention-info', r.constats.length === 1 && r.constats[0].gravite === 'info' && /Intervention a 05:58/.test(r.texte)); }
|
||||
|
||||
console.log(echecs ? `\n${echecs} ECHEC(S)` : '\nREVUE OK');
|
||||
process.exit(echecs ? 1 : 0);
|
||||
|
||||
Reference in New Issue
Block a user