Recharge reseau HC : courant ACM calcule (energie / temps restant, borne 12 kVA - maison) ; consigne non tenue quand la batterie a un manque

This commit is contained in:
Tallagrand Thierry
2026-10-07 14:22:53 +02:00
parent 3c80818966
commit b34b68408c
8 changed files with 183 additions and 5 deletions

View File

@@ -0,0 +1,58 @@
#!/usr/bin/env node
// 07/10/2026 (proprietaire) : en recharge reseau HC (takeover EVCS), le courant
// de charge n'est plus fixe a 30 A (profil night_slow, prevu pour 6 h de nuit :
// a midi 2 h x 1,4 kW = 2,8 kWh, la cible de 44 % n'etait pas atteignable, SOC
// 31 -> 35 %). Il vient de l'energie a reprendre et du temps restant dans la
// fenetre, borne par ce que l'abonnement EDF (12 kVA) laisse une fois la maison
// servie et par le chargeur des deux MultiPlus. 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('COURANT CALCULE (07/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 nightTargetSoc = num(input.night_target_soc, 35);", `const nightTargetSoc = num(input.night_target_soc, 35);
// COURANT CALCULE (07/10/2026) : entrees de la recharge reseau HC.
const houseAcPowerW = num(input.house_ac_power_w, NaN);
const gridSubscriptionVa = num(input.grid_subscription_va, NaN);
const gridEnergyNeededKwh = num(input.grid_energy_needed_kwh, NaN);`);
rep(` mode = 'evcs_takeover_recover';
effectiveProfile = 'night_slow';
targetCurrentA = cfg.profiles.night_slow.current_a;
targetVoltageV = cfg.profiles.night_slow.voltage_v;
reason.push(\`Takeover EVCS : recharge vers cible matin \${holdTargetSoc}% (SOC \${soc}%)\`);`,
` mode = 'evcs_takeover_recover';
effectiveProfile = 'night_slow';
targetCurrentA = cfg.profiles.night_slow.current_a;
targetVoltageV = cfg.profiles.night_slow.voltage_v;
// COURANT CALCULE (07/10/2026) : energie a reprendre (bilan, sinon SOC x
// 0,30 kWh/point mesure le 20/09) / temps restant dans la fenetre HC, +15 %
// de marge ; borne bas 10 A, haut = min(chargeur des 2 MultiPlus 140 A,
// (90 % de l'abonnement - maison) / tension). Recalcule a chaque cycle :
// il suit la maison et rattrape le retard en fin de fenetre.
const fin = inMiddayHC ? cfg.windows.middayHC_end : (inNightHC ? cfg.windows.nightHC_end : null);
const restantH = fin === null ? null : Math.max(0.25, ((fin - now.minNow + 1440) % 1440) / 60);
const energieKwh = Number.isFinite(gridEnergyNeededKwh) && gridEnergyNeededKwh > 0
? gridEnergyNeededKwh : Math.max(0, holdTargetSoc - soc) * 0.30;
const tensionV = Number.isFinite(batteryVoltageV) && batteryVoltageV > 40 ? batteryVoltageV : 51;
if (restantH !== null && energieKwh > 0) {
const besoinA = energieKwh * 1000 / restantH / tensionV * 1.15;
const reseauLibreW = Number.isFinite(gridSubscriptionVa) && Number.isFinite(houseAcPowerW)
? gridSubscriptionVa * 0.9 - houseAcPowerW : NaN;
const plafondA = Math.min(140, Number.isFinite(reseauLibreW) ? Math.max(0, reseauLibreW / tensionV) : 140);
targetCurrentA = Math.round(Math.max(10, Math.min(plafondA, Math.ceil(besoinA / 5) * 5)) * 10) / 10;
reason.push(\`Recharge reseau HC : \${round1(energieKwh)} kWh en \${round1(restantH)} h -> \${targetCurrentA} A\`
+ (Number.isFinite(reseauLibreW) ? \` (abonnement : \${Math.round(reseauLibreW)} W libres)\` : ''));
}
reason.push(\`Takeover EVCS : recharge vers cible matin \${holdTargetSoc}% (SOC \${soc}%)\`);`);
node.parameters.jsCode = c;
const tpl = wf.nodes.find((n) => n.name === 'HA Snapshot via Template').parameters.bodyParameters.parameters[0];
const a = ' "night_target_soc": states("input_number.victron_evcs_night_target_soc"),';
if (tpl.value.split(a).length !== 2) throw new Error('gabarit : motif introuvable');
tpl.value = tpl.value.replace(a, a + `
"house_ac_power_w": states("sensor.victron_consumption_power_l1"),
"grid_subscription_va": states("input_number.victron_grid_subscription_va"),
"grid_energy_needed_kwh": states("input_number.evcs_balance_grid_energy_needed_kwh"),`);
fs.writeFileSync(F, JSON.stringify(wf, null, 2) + '\n');
console.log('patch applique');