concierge : alertes piles, alertes de l'arbitre ; fiche : piles, surplus SDB

This commit is contained in:
2026-10-10 01:11:59 +02:00
parent 713626b432
commit 740c83e20e
6 changed files with 90 additions and 3 deletions

View File

@@ -269,6 +269,9 @@ async function detect() {
let alerteEcs = '';
try { alerteEcs = await checkAlerteECS(); } catch { /* idem : jamais bloquant */ }
if (alerteEcs) alert = [alert, alerteEcs].filter(Boolean).join('\n\n');
let piles = '';
try { piles = await checkPiles(); } catch { /* idem : jamais bloquant */ }
if (piles) alert = [alert, piles].filter(Boolean).join('\n\n');
let arbitrage = '';
try { arbitrage = checkArbitrage(); } catch { /* idem : jamais bloquant */ }
if (arbitrage) alert = [alert, arbitrage].filter(Boolean).join('\n\n');
@@ -533,6 +536,31 @@ async function checkAlerteECS() {
return String(a.message).slice(0, 300);
}
// 10/10/2026, demande du propriétaire (via EVCS) : piles faibles et capteurs muets. EVCS calcule
// sensor.evcs_piles (alertes [{entite, statut, texte}]) ; on relaie le `texte` de chaque alerte QUI APPARAÎT
// (clé entite|statut), une fois, regroupées en un seul message. Une alerte disparue puis revenue repart.
// Envoi de 08:00 à 20:59 (heure de Paris) seulement : la nuit, les nouvelles alertes attendent le matin.
// Capteur illisible ou absent → état local inchangé (pas de rafale au retour de HA).
const PILES = 'sensor.evcs_piles';
const PILES_STATE = path.join(__dirname, 'concierge-piles-state.json');
async function checkPiles() {
if (fs.existsSync(ALERT_KILL)) return '';
let s;
if (SIM) { if (!SIM.piles) return ''; s = { state: '1', attributes: { alertes: SIM.piles } }; }
else { try { s = await haState(PILES); } catch { return ''; } }
const alertes = s?.attributes?.alertes;
if (!Array.isArray(alertes) || s.state === 'unknown' || s.state === 'unavailable') return '';
const heure = SIM?.heure ?? Number(new Intl.DateTimeFormat('fr-FR', { hour: 'numeric', hour12: false, timeZone: 'Europe/Paris' }).format(new Date()));
if (heure < 8 || heure >= 21) return '';
const cle = (a) => `${a.entite}|${a.statut}`;
const deja = new Set((SIM ? SIM.pilesState : loadJSON(PILES_STATE, {}))?.envoyees || []);
const valides = alertes.filter((a) => a && a.entite && a.statut && a.texte);
const nouvelles = valides.filter((a) => !deja.has(cle(a)));
saveJSON(PILES_STATE, { envoyees: valides.map(cle) }); // les disparues sortent : elles repartiront si elles reviennent
if (!nouvelles.length) return '';
return '🔋 Capteurs à vérifier :\n' + nouvelles.map((a) => `- ${String(a.texte).trim()}`).join('\n');
}
// 08/10/2026, « GO arbitre » : question d'arbitrage d'EVCS (une fois par id) et verdict « repondu » pas encore
// relayé. Tout est dans arbitrage.js (seul à écrire la réponse). Tests : SIM.arbitrage → ARBITRAGE_SIMULATION,
// sans lui un banc CONCIERGE_SIMULATION ne lit pas l'arbitrage réel.