Nuit : la voiture profite d'EDF ferme pour la batterie, la nuit prepare le soir ; conseiller IA relecteur de la journee (revue calculee + pistes)
This commit is contained in:
@@ -1,67 +1,41 @@
|
||||
// =====================================================
|
||||
// EVCS ADVISOR SHADOW V1 — BUILD_HA_CALLS
|
||||
// Écrit les helpers advisor_* + divergence + compteurs + logbook.
|
||||
// GARANTIE MODE OMBRE : ce node ne produit QUE des écritures vers
|
||||
// des entités advisor_* et le logbook. AUCUN switch, AUCUNE stratégie
|
||||
// réelle, AUCUNE commande borne. Ne pas ajouter d'autres entités ici.
|
||||
// EVCS ADVISOR — BUILD_HA_CALLS (relecteur, 08/10/2026)
|
||||
// GARANTIE : ce node n'ecrit QUE des entites advisor (input_text.evcs_advisor_*,
|
||||
// sensor.evcs_advisor_revue) et le logbook. AUCUN switch, AUCUNE strategie,
|
||||
// AUCUNE commande. Ne pas ajouter d'autres entites ici.
|
||||
// Les items `state_entity` sont envoyes a /api/states (capteur avec attributs),
|
||||
// les autres a /api/services/<domain>/<service>.
|
||||
// =====================================================
|
||||
|
||||
const { status, detail, advice, modelUsed, context } = $input.first().json;
|
||||
const { status, detail, pistes, rejetees, modelUsed, context } = $input.first().json;
|
||||
|
||||
function stampParis() {
|
||||
const p = new Intl.DateTimeFormat('fr-FR', {
|
||||
timeZone: 'Europe/Paris', day: '2-digit', month: '2-digit',
|
||||
hour: '2-digit', minute: '2-digit', hour12: false,
|
||||
}).formatToParts(new Date());
|
||||
const g = t => p.find(x => x.type === t)?.value || '';
|
||||
const p = new Intl.DateTimeFormat('fr-FR', { timeZone: 'Europe/Paris', day: '2-digit', month: '2-digit',
|
||||
hour: '2-digit', minute: '2-digit', hour12: false }).formatToParts(new Date());
|
||||
const g = (t) => p.find((x) => x.type === t)?.value || '';
|
||||
return `${g('day')}/${g('month')} ${g('hour')}:${g('minute')}`;
|
||||
}
|
||||
|
||||
const calls = [];
|
||||
function push(domain, service, data) {
|
||||
calls.push({ json: { domain, service, data } });
|
||||
}
|
||||
function setText(entity, value) {
|
||||
push('input_text', 'set_value', { entity_id: entity, value: (value ?? '').toString().slice(0, 250) });
|
||||
}
|
||||
function setNumber(entity, value) {
|
||||
push('input_number', 'set_value', { entity_id: entity, value });
|
||||
}
|
||||
const push = (domain, service, data) => calls.push({ json: { domain, service, data } });
|
||||
const setText = (entity, value) => push('input_text', 'set_value', { entity_id: entity, value: (value ?? '').toString().slice(0, 250) });
|
||||
|
||||
// Statut + horodatage + modèle : écrits à CHAQUE run
|
||||
setText('input_text.evcs_advisor_status', status + (detail ? `: ${detail}` : ''));
|
||||
setText('input_text.evcs_advisor_last_run', stampParis());
|
||||
setText('input_text.evcs_advisor_model', modelUsed);
|
||||
|
||||
if (status === 'ok' && advice) {
|
||||
// Observation — la seule sortie desormais. Le conseiller ne planifie plus :
|
||||
// la planification est faite par le bilan, qui est calcule et mesure, et la
|
||||
// campagne du 12/09 a montre que lui demander les deux degradait les deux
|
||||
// (ecart de cible passe de 0 a 35 points sur certains cas des l ajout de la
|
||||
// mission d observation).
|
||||
setText('input_text.evcs_advisor_constat', advice.constat);
|
||||
setText('input_text.evcs_advisor_gravite', advice.gravite);
|
||||
setText('input_text.evcs_advisor_ce_qui_cloche', advice.ceQuiCloche || 'rien de signale');
|
||||
// Quand il n'y a rien a signaler il n'y a pas de piste, et recopier le
|
||||
// constat faisait afficher la meme phrase deux fois sur la carte — et
|
||||
// partir en double dans la colonne `piste` de la table d'observation.
|
||||
if (status === 'ok' && Array.isArray(pistes)) {
|
||||
calls.push({ json: { state_entity: 'sensor.evcs_advisor_revue', data: {
|
||||
state: context.jour,
|
||||
attributes: { friendly_name: 'Revue du conseiller IA', pistes, rejetees, modele: modelUsed,
|
||||
avertissement: 'Avis a verifier, pas des faits. Les constats chiffres sont dans sensor.evcs_revue_jour.' },
|
||||
} } });
|
||||
setText('input_text.evcs_advisor_reason',
|
||||
`[${Math.round(advice.confidence * 100)}%] ${advice.piste || 'rien a creuser'}`);
|
||||
|
||||
// Un observateur qui signale en permanence ne sert a rien : on compte le
|
||||
// VOLUME de signalements pour pouvoir le constater.
|
||||
if (advice.gravite === 'aucune') {
|
||||
setNumber('input_number.evcs_advisor_agree_count', context.agreeCount + 1);
|
||||
} else {
|
||||
setNumber('input_number.evcs_advisor_diverge_count', context.divergeCount + 1);
|
||||
}
|
||||
|
||||
`Revue du ${context.jour} : ${pistes.length} piste(s)${rejetees ? `, ${rejetees} ecartee(s)` : ''}`);
|
||||
push('logbook', 'log', {
|
||||
name: 'EVCS Advisor (observateur)',
|
||||
message: `[${advice.gravite}] ${advice.constat}`
|
||||
+ (advice.ceQuiCloche ? ` || ${advice.ceQuiCloche}` : '')
|
||||
+ (advice.piste ? ` || piste : ${advice.piste}` : ''),
|
||||
entity_id: 'input_text.evcs_advisor_constat',
|
||||
name: 'EVCS Advisor (relecteur)',
|
||||
message: pistes.map((p) => `[${p.code}] ${p.piste}`).join(' || ') || 'aucune piste retenue',
|
||||
entity_id: 'input_text.evcs_advisor_reason',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user