#!/usr/bin/env node // Patch 07/08/2026 : charge HC nuit automatique quand un véhicule est branché // et que le toggle "Réseau HC nuit" (input_boolean.victron_evcs_allow_grid_hc_night) est ON. // Modifie WINDOWS_SOURCEV2 et BATTERY_CLOUD_LOCKS dans le JSON local du workflow. import fs from 'fs'; const FILE = 'workflows/evcs-surplus-controller-v2.6.json'; const wf = JSON.parse(fs.readFileSync(FILE, 'utf8')); function patchNode(nodeName, replacements) { const node = wf.nodes.find(n => n.name === nodeName); if (!node) throw new Error(`Node introuvable: ${nodeName}`); let code = node.parameters.jsCode; for (const [i, { from, to }] of replacements.entries()) { if (!code.includes(from)) { throw new Error(`${nodeName}: pattern #${i + 1} introuvable:\n---\n${from}\n---`); } if (code.split(from).length !== 2) { throw new Error(`${nodeName}: pattern #${i + 1} non unique`); } code = code.replace(from, to); } node.parameters.jsCode = code; console.log(`OK: ${nodeName} patché (${replacements.length} remplacement(s))`); } const HEADER = `// FIX 07/08/2026 : fenêtre HC nuit + véhicule branché + toggle "Réseau HC nuit" ON // => préférence réseau HC directe (la VW hybride charge sans intervention manuelle). // Toggle OFF => comportement historique (battery_assist_night puis takeover à la cible). const nightGridHcPreferred = nightSessionActive && params.allowGridHcNight; `; // ---------- WINDOWS_SOURCEV2 ---------- patchNode('WINDOWS_SOURCEV2', [ { from: `const batteryAssistAllowed = nightSessionActive && parsed.soc > batteryHardFloorPct && parsed.soc > gridTakeoverTriggerPct && !nightTakeoverLatched && !batteryRecoveryUrgent;`, to: HEADER + `const batteryAssistAllowed = nightSessionActive && !nightGridHcPreferred && parsed.soc > batteryHardFloorPct && parsed.soc > gridTakeoverTriggerPct && !nightTakeoverLatched && !batteryRecoveryUrgent;` }, { from: `const nightGridTakeoverNeeded = nightSessionActive && ( batteryBelowHardFloor || batteryAtOrBelowGridTakeoverTrigger || batteryRecoveryUrgent || nightTakeoverLatched );`, to: `const nightGridTakeoverNeeded = nightSessionActive && ( nightGridHcPreferred || batteryBelowHardFloor || batteryAtOrBelowGridTakeoverTrigger || batteryRecoveryUrgent || nightTakeoverLatched );` } ]); // ---------- BATTERY_CLOUD_LOCKS ---------- patchNode('BATTERY_CLOUD_LOCKS', [ { from: `const batteryAssistAllowed = nightSessionActive && !batteryBelowHardFloor && !batteryRecoveryUrgent && !nightTakeoverLatched && parsed.soc > gridTakeoverTriggerPct;`, to: HEADER + `const batteryAssistAllowed = nightSessionActive && !nightGridHcPreferred && !batteryBelowHardFloor && !batteryRecoveryUrgent && !nightTakeoverLatched && parsed.soc > gridTakeoverTriggerPct;` }, { from: `const nightGridTakeoverNeeded = nightSessionActive && ( batteryBelowHardFloor || batteryAtOrBelowGridTakeoverTrigger || batteryRecoveryUrgent || nightTakeoverLatched );`, to: `const nightGridTakeoverNeeded = nightSessionActive && ( nightGridHcPreferred || batteryBelowHardFloor || batteryAtOrBelowGridTakeoverTrigger || batteryRecoveryUrgent || nightTakeoverLatched );` } ]); fs.writeFileSync(FILE, JSON.stringify(wf, null, 2) + '\n'); console.log(`Écrit: ${FILE}`);