Revue glissante toutes les 15 min (alertes), recharge maximale jugee contre le possible
This commit is contained in:
@@ -1280,6 +1280,55 @@ async function publierRevueHistorique(client) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// REVUE GLISSANTE (10/10/2026, proprietaire) : les memes constats que la revue
|
||||
// du matin, toutes les 15 min sur les 3 dernieres heures. Un constat « a
|
||||
// examiner » nouveau devient une ALERTE : sensor.evcs_alerte_revue (etat = id),
|
||||
// relayee par SPARK sur WhatsApp, historisee dans revue_alerte. La voiture
|
||||
// bloquee reste a l'arbitre (pas de doublon). Un episode qui dure (EDF en heures
|
||||
// pleines) ne donne qu'une alerte : on prolonge la ligne existante.
|
||||
const CODES_GLISSANTS = new Set(['edf_heures_pleines', 'charge_max_bridee_en_cours', 'charge_max_bridee',
|
||||
'batterie_sous_objectif_nuit', 'batterie_sous_objectif_midi']);
|
||||
let revueGlissanteSchema = false;
|
||||
async function revueGlissante(sql, client, st) {
|
||||
if (!client) return 0;
|
||||
if (!revueGlissanteSchema) {
|
||||
await client.query(`CREATE TABLE IF NOT EXISTS revue_alerte (
|
||||
id text PRIMARY KEY, code text, debut timestamptz, fin timestamptz, texte text, etat text, envoyee timestamptz DEFAULT now())`);
|
||||
revueGlissanteSchema = true;
|
||||
}
|
||||
const hc = (id) => (st.get(id)?.state || '').slice(0, 5);
|
||||
const fenetres = [
|
||||
{ nom: 'nuit', debut: hc('input_datetime.victron_evcs_hc_night_start'), fin: hc('input_datetime.victron_evcs_hc_night_stop') },
|
||||
{ nom: 'midi', debut: hc('input_datetime.victron_evcs_hc_midday_start'), fin: hc('input_datetime.victron_evcs_hc_midday_stop') },
|
||||
];
|
||||
const d = await donneesRevue(client, fenetres, Date.now(), 180);
|
||||
d.enCours = true;
|
||||
d.abonnementVa = Number(st.get('input_number.victron_grid_subscription_va')?.state) || 12000;
|
||||
const { constats } = constatsRevue(d);
|
||||
let n = 0;
|
||||
for (const c of constats) {
|
||||
if (c.gravite !== 'a_examiner' || !CODES_GLISSANTS.has(c.code)) continue;
|
||||
if (c.code === 'edf_heures_pleines' && (c.chiffres?.minutes ?? 0) < 15) continue;
|
||||
const { rows: [deja] } = await client.query(
|
||||
`SELECT id FROM revue_alerte WHERE code = $1 AND fin >= $2 ORDER BY fin DESC LIMIT 1`,
|
||||
[c.code, new Date(c.debut - 20 * 60000)]);
|
||||
if (deja) { await client.query(`UPDATE revue_alerte SET fin = $2, texte = $3 WHERE id = $1`, [deja.id, new Date(c.fin), c.texte]); continue; }
|
||||
const id = `${c.code}-${new Date(c.debut).toISOString().slice(0, 16)}`;
|
||||
await client.query(`INSERT INTO revue_alerte (id, code, debut, fin, texte, etat) VALUES ($1,$2,$3,$4,$5,$6) ON CONFLICT DO NOTHING`,
|
||||
[id, c.code, new Date(c.debut), new Date(c.fin), c.texte, c.etat || null]);
|
||||
const { rows: hist } = await client.query(`SELECT id, code, texte, to_char(envoyee AT TIME ZONE 'Europe/Paris','DD/MM HH24:MI') a
|
||||
FROM revue_alerte ORDER BY envoyee DESC LIMIT 10`);
|
||||
await publierCapteur('sensor.evcs_alerte_revue', id, {
|
||||
friendly_name: 'Alerte de la revue glissante', icon: 'mdi:alert-outline',
|
||||
id, code: c.code, texte: c.texte, etat_systeme: c.etat || '', a: new Date().toISOString(), dernieres: hist,
|
||||
});
|
||||
await journaliser(sql, 'revue', `Alerte revue glissante : ${c.code}`, { id, texte: c.texte });
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
function decalageParis(jour) {
|
||||
const d = new Date(`${jour}T12:00:00Z`);
|
||||
const h = Number(new Intl.DateTimeFormat('en-GB', { timeZone: 'Europe/Paris', hour: '2-digit', hour12: false }).format(d));
|
||||
@@ -2669,6 +2718,9 @@ async function cycle(client) {
|
||||
arbitrage: DRY ? 0 : await arbitrer(sql, client, st).catch((e) => {
|
||||
console.error('arbitrage :', e.message); return 0;
|
||||
}),
|
||||
revueGlissante: (DRY || new Date().getMinutes() % 15 !== 11) ? 0 : await revueGlissante(sql, client, st).catch((e) => {
|
||||
console.error('revue glissante :', e.message); return 0;
|
||||
}),
|
||||
revue: DRY ? 0 : await revueDeLaJournee(sql, client, st).catch((e) => {
|
||||
console.error('revue de la journee :', e.message); return 0;
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user