#!/usr/bin/env node // Patch 09/08/2026 — P9 : étend la coupure immédiate (bypass min_on) à l'état // collant 'departure_done_idle' (charge terminée pendant la fenêtre départ, // jour). Même sûreté que night_recovery_done_idle : état collant, le takeover // ne revient pas. Prérequis : patch-20260809-e2-recovery-done-cut.mjs. // Rejouable. import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); const FILE = path.join(ROOT, 'workflows/victron-grid-hysteresis-v1.json'); const wf = JSON.parse(fs.readFileSync(FILE, 'utf8')); const node = wf.nodes.find(n => n.name === 'Compute Grid Hysteresis'); if (!node) throw new Error('Node "Compute Grid Hysteresis" introuvable'); let code = node.parameters.jsCode; if (code.includes("departure_done_idle")) { console.log('Déjà appliqué — rien à faire.'); process.exit(0); } const anchor = ` evcsSurplusState === 'night_recovery_done_idle' && soc >= gridSocOff ) {`; const insertion = ` ( evcsSurplusState === 'night_recovery_done_idle' || evcsSurplusState === 'departure_done_idle' ) && soc >= gridSocOff ) {`; if (!code.includes(anchor)) throw new Error('Ancre E2 introuvable — appliquer d abord patch-20260809-e2-recovery-done-cut.mjs'); code = code.replace(anchor, insertion); node.parameters.jsCode = code; fs.writeFileSync(FILE, JSON.stringify(wf, null, 2) + '\n'); console.log('Patch appliqué →', FILE, `(jsCode ${code.length} chars)`);