#!/usr/bin/env node // 08/10/2026 (proprietaire) : jour faible, la HC de midi charge au MAXIMUM // possible (cible 100 % du bilan). Le plafond du courant calcule (07/10) ne // comptait que le reseau libre sous l'abonnement ; le solaire charge la batterie // EN PLUS, par les chargeurs MPPT (courant continu), sans passer par l'entree // reseau. Plafond = min(140 A, (90 % de l'abonnement - maison + PV) / tension). // L'import reste borne par la consigne reseau du controleur (10 kW maximum). // Rejouable (idempotent). import fs from 'fs'; const F = 'workflows/victron-auto-charge-manager-v1.2.json'; const wf = JSON.parse(fs.readFileSync(F, 'utf8')); const node = wf.nodes.find((n) => n.name === 'Compute Charge Targets'); let c = node.parameters.jsCode; if (c.includes('PLAFOND SOLAIRE (08/10/2026)')) { console.log('deja applique'); process.exit(0); } const rep = (a, b) => { if (c.split(a).length !== 2) throw new Error('motif introuvable ou multiple : ' + a.slice(0, 60)); c = c.replace(a, b); }; rep(` const reseauLibreW = Number.isFinite(gridSubscriptionVa) && Number.isFinite(houseAcPowerW) ? gridSubscriptionVa * 0.9 - houseAcPowerW : NaN;`, ` // PLAFOND SOLAIRE (08/10/2026) : le solaire (MPPT, courant continu) charge // la batterie en plus de ce que l'entree reseau laisse libre. const reseauLibreW = Number.isFinite(gridSubscriptionVa) && Number.isFinite(houseAcPowerW) ? gridSubscriptionVa * 0.9 - houseAcPowerW + Math.max(0, pvPowerW) : NaN;`); rep(`(abonnement : \${Math.round(reseauLibreW)} W libres)`, `(abonnement + solaire : \${Math.round(reseauLibreW)} W libres)`); node.parameters.jsCode = c; fs.writeFileSync(F, JSON.stringify(wf, null, 2) + '\n'); console.log('patch applique');