Piles : acquittements a cle courte groupes par date (255 caracteres)

This commit is contained in:
Tallagrand Thierry
2026-10-14 00:28:15 +02:00
parent 84185188cc
commit 5d638f3831
3 changed files with 26 additions and 16 deletions

View File

@@ -23,17 +23,24 @@ const EXCLUS = /^(sensor|number|binary_sensor)\.(victron_|gx_device_|airtria_8_|
*/
// ACQUITTEMENT (13/10, demande du proprietaire) : « j'ai compris, je change les
// piles dans N jours » -> plus de rappel pour cet appareil jusqu'a la date dite.
// input_text.evcs_piles_acquittees = « cle:AAAA-MM-JJ,cle:AAAA-MM-JJ », cle =
// entite sans « sensor. » ; valable jusqu'a la fin de ce jour (heure de Paris).
// Ecrit par le concierge (SPARK) ; une cle d'un appareil qui n'est plus en
// alerte (piles changees) est simplement sans effet.
// input_text.evcs_piles_acquittees, ecrit par le concierge (SPARK), 255 car. max.
// 14/10 : les identifiants complets ne tenaient pas (9 alertes ~ 370 car.) ->
// CLE COURTE (6 caracteres, sha1 de l'entite, attribut `cle`) et format GROUPE
// PAR DATE : « AAAA-MM-JJ:cle|cle,AAAA-MM-JJ:cle » (~75 car. pour 9 alertes).
// Valable jusqu'a la fin de ce jour (heure de Paris). Une cle d'un appareil qui
// n'est plus en alerte (piles changees) est sans effet.
import { createHash } from 'node:crypto';
export const cleCourte = (entite) => createHash('sha1').update(String(entite)).digest('hex').slice(0, 6);
export function lireAcquittements(texte) {
const out = {};
for (const part of String(texte || '').split(',')) {
const m = /^\s*([a-z0-9_]+)\s*:\s*(\d{4}-\d{2}-\d{2})\s*$/.exec(part);
const out = {}; // cle courte -> { jusquAu, finMs }
for (const groupe of String(texte || '').split(',')) {
const m = /^\s*(\d{4}-\d{2}-\d{2})\s*:\s*([0-9a-f|\s]+)$/.exec(groupe);
if (!m) continue;
const fin = Date.parse(`${m[2]}T23:59:59+02:00`);
if (Number.isFinite(fin)) out[`sensor.${m[1]}`] = { jusquAu: m[2], finMs: fin };
const fin = Date.parse(`${m[1]}T23:59:59+02:00`);
if (!Number.isFinite(fin)) continue;
for (const k of m[2].split('|').map((x) => x.trim()).filter((x) => /^[0-9a-f]{6}$/.test(x))) {
if (!out[k] || out[k].finMs < fin) out[k] = { jusquAu: m[1], finMs: fin };
}
}
return out;
}
@@ -75,10 +82,10 @@ export function pilesAAlerter(etats, maintenantMs, ignorees = [], opts = {}) {
}
alertes.sort((x, y) => (x.statut === y.statut ? x.nom.localeCompare(y.nom) : x.statut === 'faible' ? -1 : 1));
for (const a of alertes) {
const k = acq[a.entite];
a.cle = cleCourte(a.entite);
const k = acq[a.cle];
a.acquittee = !!(k && k.finMs >= maintenantMs);
if (a.acquittee) a.jusqu_au = k.jusquAu;
a.cle = a.entite.replace(/^sensor\./, '');
}
const aRappeler = alertes.filter((a) => !a.acquittee);
const acquittees = alertes.filter((a) => a.acquittee);