Détail cellule exposé en 3 helpers HA pour l'agent vocal OpenClaw
Les trames BMS cellule de HA sont mortes depuis le 15/09 ; le relevé série est la source vivante. Le service publie evcs_cell_spread_max_mv, evcs_cell_weakest_module et evcs_cell_releve_age_min à chaque cycle (publierCellulesHelpers). L'âge donne à l'agent la discipline anti-valeur-figée (comme le gel GX). Vérifié en réel : 21 mV, âge 1 min, K220803C30160323. Package evcs_cellules.yaml (hors dépôt, HA). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
This commit is contained in:
22
HANDOFF.md
22
HANDOFF.md
@@ -501,3 +501,25 @@ Regle-cle : bridage NORMAL ⇒ import nul ; substitution ANORMALE ⇒ import ~ c
|
||||
|
||||
---
|
||||
*Document mis a jour le : 24/09/2026 — banc PV 9/9 pour OpenClaw (source de verite + discrimination bridage/vraie baisse/substitution), la source vit dans MANUEL §0*
|
||||
|
||||
## 78. Session du 24-25/09/2026 — Détail cellule exposé en helpers HA pour l'agent vocal
|
||||
|
||||
Les trames BMS cellule de HA sont mortes depuis le 15/09 (§69) ; le relevé série
|
||||
(table `cellule`, sur le NAS depuis §75) est la seule source vivante. Pour que
|
||||
l'agent vocal OpenClaw lise le détail cellule en direct sans taper PostgreSQL, le
|
||||
service d'historisation publie désormais trois helpers HA à chaque cycle, depuis
|
||||
le dernier relevé série :
|
||||
- `input_number.evcs_cell_spread_max_mv` — écart max du pack (mV)
|
||||
- `input_text.evcs_cell_weakest_module` — code-barres du module le plus sensible
|
||||
- `input_number.evcs_cell_releve_age_min` — âge du dernier relevé (min)
|
||||
|
||||
L'âge permet à l'agent la même discipline que pour le gel GX : frais → il donne
|
||||
la valeur, vieux → il dit « muet ». `publierCellulesHelpers()` dans
|
||||
`tools/historise-evcs.mjs` (SQL sur les modules du dernier lot, à ±5 min du
|
||||
max(ts)), appelée après l'ingestion. Package `evcs_cellules.yaml` (sans
|
||||
`initial:` — réécrits chaque cycle), rechargé sans redémarrage. Vérifié en réel
|
||||
le 25/09 : écart 21 mV, âge 1 min, module K220803C30160323 (le plus ancien du
|
||||
pack 2). SPARK bascule l'agent dessus (fiche + gamme G13 live).
|
||||
|
||||
---
|
||||
*Document mis a jour le : 25/09/2026 — détail cellule publié en helpers HA (source série vivante), agent vocal câblé*
|
||||
|
||||
@@ -1792,6 +1792,43 @@ async function ecrireHelperTexte(entite, valeur) {
|
||||
} catch { /* le helper reste a sa valeur, on reessaiera au prochain cycle */ }
|
||||
}
|
||||
|
||||
async function ecrireHelperNombre(entite, valeur) {
|
||||
if (DRY || valeur === null || valeur === undefined || !Number.isFinite(valeur)) return;
|
||||
try {
|
||||
await fetch(`${HA_URL}/api/services/input_number/set_value`, {
|
||||
method: 'POST',
|
||||
headers: { Authorization: `Bearer ${HA_TOKEN}`, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ entity_id: entite, value: valeur }),
|
||||
signal: AbortSignal.timeout(8000),
|
||||
});
|
||||
} catch { /* on reessaiera au prochain cycle */ }
|
||||
}
|
||||
|
||||
// Publie le detail cellule (relevé serie, table `cellule`) dans des helpers HA,
|
||||
// pour que l'agent vocal OpenClaw le lise sans taper PostgreSQL. Les trames BMS
|
||||
// cellule de HA sont mortes depuis le 15/09 (§69) : ce relevé serie est la seule
|
||||
// source vivante. On expose l'ECART max du pack, le module extreme, et l'AGE du
|
||||
// dernier relevé — c'est l'age qui permet a l'agent d'appliquer la meme
|
||||
// discipline que pour le gel GX (frais -> il le donne, vieux -> il dit muet).
|
||||
async function publierCellulesHelpers(client) {
|
||||
if (DRY || !client) return 0;
|
||||
const { rows: [r] } = await client.query(
|
||||
`WITH mx AS (SELECT max(ts) AS t FROM cellule),
|
||||
recent AS (SELECT DISTINCT ON (module) module, ts FROM cellule
|
||||
WHERE ts > (SELECT t FROM mx) - interval '5 minutes' ORDER BY module, ts DESC),
|
||||
spreads AS (SELECT c.module, max(c.mv) - min(c.mv) AS ecart
|
||||
FROM cellule c JOIN recent rc ON rc.module = c.module AND rc.ts = c.ts
|
||||
GROUP BY c.module)
|
||||
SELECT (SELECT max(ecart) FROM spreads) AS spread_max,
|
||||
(SELECT module FROM spreads ORDER BY ecart DESC NULLS LAST LIMIT 1) AS weakest,
|
||||
(SELECT round(EXTRACT(EPOCH FROM (now() - t)) / 60)::int FROM mx) AS age_min`);
|
||||
if (!r || r.age_min === null) return 0; // table cellule vide : rien a publier
|
||||
await ecrireHelperNombre('input_number.evcs_cell_spread_max_mv', r.spread_max === null ? null : Number(r.spread_max));
|
||||
await ecrireHelperNombre('input_number.evcs_cell_releve_age_min', Number(r.age_min));
|
||||
await ecrireHelperTexte('input_text.evcs_cell_weakest_module', r.weakest || 'indisponible');
|
||||
return 1;
|
||||
}
|
||||
|
||||
async function cycle(client) {
|
||||
// En blanc, on compte ce qu'on ECRIRAIT. Un essai a blanc qui renvoie
|
||||
// toujours zero ne verifie rien — c'est le piege classique du test qui ne
|
||||
@@ -1840,6 +1877,12 @@ async function cycle(client) {
|
||||
console.error(`ingestion cellules en echec : ${e.message}`);
|
||||
return 0;
|
||||
}),
|
||||
// Publie le detail cellule dans des helpers HA (pour l'agent vocal), APRES
|
||||
// l'ingestion pour utiliser le relevé qui vient d'arriver.
|
||||
cellulesHelpers: DRY ? 0 : await publierCellulesHelpers(client).catch((e) => {
|
||||
console.error(`publication helpers cellule en echec : ${e.message}`);
|
||||
return 0;
|
||||
}),
|
||||
};
|
||||
const total = r.mesures + r.bilan + r.decision + r.prevision + r.evenement + r.session + r.cellules + r.observation + r.etiquette + (r.rapport || 0);
|
||||
if (total > 0 || ONCE) {
|
||||
|
||||
Reference in New Issue
Block a user