workspace: niveau du vehicule par le concierge (option A), simulation par drapeau
- concierge-write.js : setVehicleLevel (entier 0-100, refus sans correction, relecture), ZERO dans SELECTOR_LABELS ; tests 13/13. - concierge-live.js answer : reconnait « NN % », ecrit le niveau, lignes « 🔋 Niveau noté » / « ⚠️ Niveau NON noté ». - Drapeau workspace/.simulation lu par concierge-live.js et airtria-ha-vehicule.js : aucune ecriture HA pendant un banc agent. - airtria-ha-vehicule.js : validation de tous les arguments avant ecriture. - AGENTS.md et reference-concierge.md : vehicule et niveau passent par le concierge. - Journaux de tri Orange et AIRTRIA, DREAMS.
This commit is contained in:
@@ -36,13 +36,21 @@ async function ha(method, url, body) {
|
||||
} finally { clearTimeout(t); }
|
||||
}
|
||||
const etat = async (e) => ha('GET', `/api/states/${e}`);
|
||||
// 03/10/2026 : fichier drapeau `.simulation` (pose avant un banc qui passe par
|
||||
// l'agent complet) -> AUCUNE ecriture, les lectures restent reelles. Incident
|
||||
// du 02/10 : niveau 100 % ecrit en reel pendant un banc.
|
||||
const SIMULATION = fs.existsSync(path.join(__dirname, '.simulation'));
|
||||
const ecrit = async (url, body) => {
|
||||
if (SIMULATION) { console.log(`[SIMULATION : rien écrit — ${url} ${JSON.stringify(body)}]`); return {}; }
|
||||
return ha('POST', url, body);
|
||||
};
|
||||
|
||||
(async () => {
|
||||
if (modeArg !== undefined) {
|
||||
const m = await etat(MODE); const opts = m.attributes.options || [];
|
||||
const o = opts.find((x) => x.toLowerCase() === String(modeArg).toLowerCase());
|
||||
if (!o) { console.log(`refus : mode « ${modeArg} » inconnu de HA, options : ${opts.join(', ')}`); process.exit(2); }
|
||||
await ha('POST', '/api/services/input_select/select_option', { entity_id: MODE, option: o });
|
||||
await ecrit('/api/services/input_select/select_option', { entity_id: MODE, option: o });
|
||||
await new Promise((r) => setTimeout(r, 800));
|
||||
const lu = (await etat(MODE)).state;
|
||||
if (lu !== o) { console.log(`erreur : écrit ${o} mais HA relit ${lu}`); process.exit(1); }
|
||||
@@ -61,15 +69,29 @@ const etat = async (e) => ha('GET', `/api/states/${e}`);
|
||||
console.log(`${prefix}${branche} ; véhicule sélectionné = ${s.state}, dernier niveau saisi = ${Math.round(Number(n.state))} %, ${departTxt(d)} (options : ${options.join(', ')})`);
|
||||
if (vehicule === undefined && niveauArg === undefined && departArg === undefined) { affiche(sel, niv, await etat(DEP), 'HA : '); return; }
|
||||
|
||||
// Tout est validé AVANT la première écriture : un refus n'écrit jamais rien (30/09).
|
||||
if (niveauArg !== undefined) {
|
||||
const n0 = Number(niveauArg);
|
||||
if (!Number.isInteger(n0) || n0 < 0 || n0 > 100) { console.log(`refus : niveau « ${niveauArg} » invalide, entier de 0 à 100 attendu`); process.exit(2); }
|
||||
}
|
||||
if (vehicule !== undefined && !options.some((x) => x.toLowerCase() === String(vehicule).toLowerCase())) {
|
||||
console.log(`refus : véhicule « ${vehicule} » inconnu de HA, options : ${options.join(', ')}`); process.exit(2);
|
||||
}
|
||||
if (departArg !== undefined && String(departArg).toLowerCase() !== 'aucun') {
|
||||
const m0 = /^([01]?\d|2[0-3]):([0-5]\d)$/.exec(String(departArg));
|
||||
const now0 = new Date(); const nowHM0 = `${String(now0.getHours()).padStart(2, '0')}:${String(now0.getMinutes()).padStart(2, '0')}`;
|
||||
if (!m0) { console.log(`refus : départ « ${departArg} » invalide, heure HH:MM d'aujourd'hui attendue (ou « aucun »)`); process.exit(2); }
|
||||
if (`${m0[1].padStart(2, '0')}:${m0[2]}` <= nowHM0) { console.log(`refus : départ ${m0[1]}:${m0[2]} déjà passé (il est ${nowHM0}), le départ ponctuel ne vaut que pour la suite de la journée`); process.exit(2); }
|
||||
}
|
||||
if (vehicule !== undefined) {
|
||||
const o = options.find((x) => x.toLowerCase() === String(vehicule).toLowerCase());
|
||||
if (!o) { console.log(`refus : véhicule « ${vehicule} » inconnu de HA, options : ${options.join(', ')}`); process.exit(2); }
|
||||
await ha('POST', '/api/services/input_select/select_option', { entity_id: SEL, option: o });
|
||||
await ecrit('/api/services/input_select/select_option', { entity_id: SEL, option: o });
|
||||
}
|
||||
if (niveauArg !== undefined) {
|
||||
const n = Number(niveauArg);
|
||||
if (!Number.isInteger(n) || n < 0 || n > 100) { console.log(`refus : niveau « ${niveauArg} » invalide, entier de 0 à 100 attendu`); process.exit(2); }
|
||||
await ha('POST', '/api/services/input_number/set_value', { entity_id: NIV, value: n });
|
||||
await ecrit('/api/services/input_number/set_value', { entity_id: NIV, value: n });
|
||||
}
|
||||
if (departArg !== undefined) {
|
||||
let heure = '00:00';
|
||||
@@ -80,7 +102,7 @@ const etat = async (e) => ha('GET', `/api/states/${e}`);
|
||||
const now = new Date(); const nowHM = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;
|
||||
if (heure <= nowHM) { console.log(`refus : départ ${heure} déjà passé (il est ${nowHM}), le départ ponctuel ne vaut que pour la suite de la journée`); process.exit(2); }
|
||||
}
|
||||
await ha('POST', '/api/services/input_datetime/set_datetime', { entity_id: DEP, datetime: `${aujourdhui} ${heure}:00` });
|
||||
await ecrit('/api/services/input_datetime/set_datetime', { entity_id: DEP, datetime: `${aujourdhui} ${heure}:00` });
|
||||
}
|
||||
await new Promise((r) => setTimeout(r, 800));
|
||||
affiche(await etat(SEL), await etat(NIV), await etat(DEP), 'écrit et relu — ');
|
||||
|
||||
Reference in New Issue
Block a user