From f18ce33d320f83943261b2309eac01e7acdcf381 Mon Sep 17 00:00:00 2001 From: Thierry Tallagrand Date: Wed, 30 Sep 2026 23:50:32 +0200 Subject: [PATCH] workspace: mode de charge de nuit, concierge sans relais parasite, journaux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - airtria-ha-vehicule.js : option --mode-nuit complete|sans_edf (seul input_select.victron_evcs_night_charge_mode, relecture, refus des options inconnues) ; libelle « aucune voiture branchee » distinct du selecteur. - concierge-live.js : message sans vehicule marque « (aucune action concierge », a ne pas relayer. - AGENTS.md : routage charge voiture de la nuit et budget, regle §5.0. - Journaux de tri Orange et AIRTRIA. --- workspace/AGENTS.md | 9 ++++++++- workspace/airtria-ha-vehicule.js | 21 +++++++++++++++++++-- workspace/airtria-housekeeping.md | 11 +++++++++++ workspace/concierge-live.js | 2 +- workspace/orange-housekeeping.md | 12 ++++++++++++ 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/workspace/AGENTS.md b/workspace/AGENTS.md index de8b387..f91a4ac 100644 --- a/workspace/AGENTS.md +++ b/workspace/AGENTS.md @@ -218,6 +218,12 @@ inventer. d'AUJOURD'HUI, à venir) ; « non » → rien. « il ne repart plus » → `--depart aucun`. « refus » ou « erreur » → rapporter, ne pas insister. Jamais d'écriture sans annonce de Thierry, jamais d'autre entité. +- **Charge voiture de la nuit** : « charge complète / à fond cette nuit » → + `node …/airtria-ha-vehicule.js --mode-nuit complete` ; « sans EDF cette nuit / seulement la + batterie » → `--mode-nuit sans_edf`, À CHAQUE demande, même si tu crois le mode déjà + réglé. Relaie sa ligne MOT POUR MOT : sans la ligne « C'est noté : charge … » de CE script, + le mode N'A PAS changé, ne dis jamais « noté ». Pas de concierge ici. « Combien la voiture + peut prendre cette nuit ? » → `prevision-nuit.js`, relayé tel quel. JAMAIS écrire le budget. - **SOC batterie maison, AVEC SON SENS** : `sensor.victron_battery_soc` (valeur) ET `sensor.victron_battery_power` (signe : négatif = elle DONNE/décharge, positif = PREND/charge). Ne jamais publier l'un sans l'autre — l'oubli a produit le faux « et ça @@ -357,7 +363,8 @@ ton TOUT PREMIER geste, avant de saluer ou de répondre quoi que ce soit, via `e `node /home/node/.openclaw/workspace/concierge-live.js answer ""` Il imprime TOUJOURS une ligne (« ✅ Noté : … » ou « Rien n'est noté : … ») : relaie-la MOT POUR MOT, intégrale, sans la raccourcir ni la reformuler. N'annonce JAMAIS qu'un -véhicule est noté ou branché sans cette ligne. Il gère seul la question en attente : ne +véhicule est noté ou branché sans cette ligne. Une sortie qui commence par « (aucune action +concierge » ne se relaie PAS : réponds simplement au message. Il gère seul la question en attente : ne teste pas `concierge-pending.json`. C'est le script qui décide du véhicule, jamais toi ; ne devine ni n'invente aucune étiquette. Détail : reference-concierge.md. diff --git a/workspace/airtria-ha-vehicule.js b/workspace/airtria-ha-vehicule.js index b871806..a23fd41 100644 --- a/workspace/airtria-ha-vehicule.js +++ b/workspace/airtria-ha-vehicule.js @@ -5,8 +5,11 @@ // node airtria-ha-vehicule.js --vehicule JEEP --niveau 12 // node airtria-ha-vehicule.js --niveau 40 → niveau seul (véhicule inchangé) // node airtria-ha-vehicule.js --depart 16:00 → départ ponctuel AUJOURD'HUI (VW, ZERO) ; --depart aucun l'efface +// node airtria-ha-vehicule.js --mode-nuit complete|sans_edf → charge voiture de la nuit (remis à sans_edf chaque jour à 12:00 par HA) // Écrit UNIQUEMENT : input_select (véhicule, option lue dans HA), input_number (niveau, entier 0-100) -// et input_datetime (départ ponctuel, toujours daté du JOUR, jamais une autre date). +// et input_datetime (départ ponctuel, toujours daté du JOUR, jamais une autre date), +// et input_select.victron_evcs_night_charge_mode (option lue dans HA). JAMAIS le budget +// (input_text.victron_evcs_night_budget, input_number.evcs_balance_night_vehicle_budget_kwh). // Ne touche JAMAIS victron_evcs_vehicle_level_ref_kwh ni victron_evcs_vehicle_level_at : une automatisation HA // les mémorise seule à chaque appel (une saisie identique compte aussi). 'use strict'; @@ -16,10 +19,11 @@ const token = () => fs.readFileSync(process.env.HA_TOKEN_FILE || path.join(__dir const SEL = 'input_select.victron_evcs_vehicle'; // « Véhicule branché » (désigné par EVCS) const NIV = 'input_number.victron_evcs_vehicle_level_pct'; // niveau saisi, % const DEP = 'input_datetime.victron_evcs_departure_ponctuel'; // départ ponctuel du jour (00:00 = aucun) +const MODE = 'input_select.victron_evcs_night_charge_mode'; // sans_edf | complete const args = process.argv.slice(2); const opt = (n) => { const i = args.indexOf(n); return i >= 0 ? args[i + 1] : undefined; }; -const vehicule = opt('--vehicule'); const niveauArg = opt('--niveau'); const departArg = opt('--depart'); +const vehicule = opt('--vehicule'); const niveauArg = opt('--niveau'); const departArg = opt('--depart'); const modeArg = opt('--mode-nuit'); async function ha(method, url, body) { const ac = new AbortController(); const t = setTimeout(() => ac.abort(), 10000); @@ -34,6 +38,19 @@ async function ha(method, url, body) { const etat = async (e) => ha('GET', `/api/states/${e}`); (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 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); } + console.log(lu === 'complete' + ? "C'est noté : charge complète cette nuit (batterie d'abord, puis EDF en heures creuses pour le reste). Retour à « sans EDF » demain à midi." + : "C'est noté : charge sans EDF cette nuit (la voiture s'arrête au budget batterie et attend le soleil)."); + return; + } const sel = await etat(SEL); const niv = await etat(NIV); const options = sel.attributes.options || []; const aujourdhui = new Date(Date.now() - new Date().getTimezoneOffset() * 60000).toISOString().slice(0, 10); diff --git a/workspace/airtria-housekeeping.md b/workspace/airtria-housekeeping.md index 83c5fc0..4eec282 100644 --- a/workspace/airtria-housekeeping.md +++ b/workspace/airtria-housekeeping.md @@ -75,3 +75,14 @@ Total déplacés : 3 | A3.01 | NVIDIA / Victron → Veille | 2 | Veille | 0 | Total déplacés : 4 + +## 2026-09-30 19:50:00 — airtria-menage --quotidien + +| Règle | Description | Déplacés | Destination | Écartés (whitelist) | +|---|---|---:|---|---:| +| A1.12 | Audible promos | 1 | Trash | 0 | +| A1.17 | Vertical-Mail | 2 | Trash | 0 | +| A1.28 | Amazon Business (désabo) | 1 | Trash | 0 | +| A3.01 | NVIDIA / Victron → Veille | 1 | Veille | 0 | + +Total déplacés : 5 diff --git a/workspace/concierge-live.js b/workspace/concierge-live.js index e4b92c9..553d277 100644 --- a/workspace/concierge-live.js +++ b/workspace/concierge-live.js @@ -173,7 +173,7 @@ async function answer(text) { if (Array.isArray(sel.attributes?.options)) options = sel.attributes.options; } catch { /* défaut VW/JEEP */ } const label = parseLabel(text, options); - if (!label) return "Rien n'est noté : ce message ne nomme pas de véhicule."; // non reconnu : on ne publie rien + if (!label) return "(aucune action concierge : pas de véhicule nommé — ne relaie pas cette ligne, réponds à la question)"; // non reconnu : on ne publie rien // Cible de l'étiquette = le branchement à confirmer : // - avec question en attente : celui du pending. diff --git a/workspace/orange-housekeeping.md b/workspace/orange-housekeeping.md index 0eac6e6..0a78a45 100644 --- a/workspace/orange-housekeeping.md +++ b/workspace/orange-housekeeping.md @@ -102,3 +102,15 @@ Total déplacés : 5 | O1.22 | Quora (relais Apple) | 2 | INBOX/TRASH | 0 | Total déplacés : 5 + +## 2026-09-30 19:45:00 — orange-menage --quotidien + +| Règle | Description | Déplacés | Destination | Écartés (whitelist) | +|---|---|---:|---|---:| +| O1.01 | Fnac (en entier) | 2 | INBOX/TRASH | 0 | +| O1.05 | Edenred Meyclub/Kadéos | 1 | INBOX/TRASH | 0 | +| O1.09 | Netflix | 1 | INBOX/TRASH | 0 | +| O1.13 | IKEA | 1 | INBOX/TRASH | 0 | +| O1.22 | Quora (relais Apple) | 1 | INBOX/TRASH | 0 | + +Total déplacés : 6