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

@@ -2043,5 +2043,25 @@ douche ne sera pas a 65 °C (06:00 et 20:00, tous les jours). Journee test : le
de courant d'entree AC du MultiPlus (aucune entite HA ne l'expose, `number.gx_device_ac_input_limit` = -1) — de courant d'entree AC du MultiPlus (aucune entite HA ne l'expose, `number.gx_device_ac_input_limit` = -1) —
a 13:00 le reseau donnait deja 6,7 kW. Proposition au proprietaire en attente. a 13:00 le reseau donnait deja 6,7 kW. Proposition au proprietaire en attente.
### 07/10 14:20 — Recharge reseau HC : courant calcule (ACM) et consigne non tenue quand la batterie a un manque
Deux freins empilaient leurs effets a midi (SOC 31 -> 35 % pour ~44 % requis) :
1. **ACM** : `evcs_takeover_recover` = profil `night_slow` 30 A FIXES. **Corrige (accord du proprietaire,
deploye 14:17, `tools/patch-20261007-acm-courant-calcule.mjs`, golden-acm 23/23, +3, mutation qui mord)** :
courant = energie a reprendre (`evcs_balance_grid_energy_needed_kwh`, sinon (cible - SOC) x 0,30) / temps
restant dans la fenetre HC (fenetres du cfg ACM) / tension x 1,15, arrondi au 5 A superieur ; plancher
10 A ; plafond min(140 A chargeur des 2 MultiPlus, (90 % de l'abonnement - maison) / tension).
Abonnement : `input_number.victron_grid_subscription_va` = **12 000** (12 kVA, disjoncteur 63 A,
proprietaire ; paquet `evcs_abonnement_edf.yaml`). Gabarit ACM : maison, abonnement, energie a reprendre.
En reel 14:20 : « 2,6 kWh en 0,3 h -> 99 A (abonnement : 4912 W libres) », MaxChargeCurrent 99.
2. **Controleur** : la consigne reseau etait TENUE a sa valeur (5 198 W = la maison) des que le solaire
produit (chargeurs `mppt_active`) — protection du solaire contre une consigne trop haute — donc le terme
batterie (maison + min(manque / temps restant, DVCC)) n'etait jamais applique de jour : batterie a 3-6 A
meme avec DVCC 99 A. **Corrige (deploye 14:22, golden 144/144, +2)** : pas de maintien quand
`batterySetpointShareW > 0` (manque chiffre a reprendre en HC) -> la consigne va au plafond. Releve rejoue :
5 300 + 1 857 + marge = 7 387 W (tenue : 5 530). Mutation qui mord. La nuit n'etait pas concernee
(chargeurs off -> plafond).
⚠️ A verifier : la prochaine session HC avec manque (cette nuit, jour faible) : courant ACM calcule, consigne,
SOC atteint a 07:24 contre la cible. La fenetre de midi du 07/10 s'est fermee 2 min apres le deploiement.
--- ---
*Document mis a jour le : 07/10/2026 (~14:15) — HC de midi : AUTO ne chauffe pas (BOOST), alerte v2, Jeep (contact, relecture, zone), recharge batterie bridee a 30 A par l'ACM ; jour faible = EDF les deux fenetres HC pour le chauffe-eau, alerte BOOST, Victron Mobile refait ; 1re decision jour faible en reel, mesure ECS reparee, douches 06:00/20:00, Grafana chauffe-eau, tableaux ECS ; chauffe-eau en HC de nuit les jours faibles (decision du bilan, workflow ECS sous controle du depot, VRM, V2.3 desactive) ; garde batterie reseau : voiture bridee a 6 A au lieu d'un arret ; garde-fou concierge 2 h ; allers-retours brefs de la borne retrouves dans l'historique HA (echange VW -> JEEP de 20 s), production 14,5 kWh contre 22 prevus, defaut garde batterie en mode reseau a trancher ; voiture a midi : la batterie n'est plus comptee comme du solaire (EDF automatique les jours de depart si le surplus ne couvre pas) ; nuit 05->06 : JEEP chargee sur EDF en complete (6,32 kWh), budget 0 du a la prevision, Windy/ECMWF contre VRM, a comparer ce soir ; concierge aligne sur la preuve fin de trajet ; a verifier : nuit 05->06 et mardi faible, comparaison VRM/Forecast.Solar ; JEEP identifiee aussi par sa fin de trajet, prevision de la nuit 05->06 ; identification JEEP reussie en reel, correction humaine qui prime (refus supprime), session du 04/10 coupee ; EVCS Master en quatre onglets ; Jeep lue par Uconnect et identifiee seule, capacite JEEP 10 kWh, concierge variante (a) ; releve par photo (SPARK), hass-uconnect en attente ; ecart semaine/week-end mesure (pas de profil week-end la nuit) ; nuit du budget : budget borne au plancher prudent, sans EDF = voiture bloquee meme EDF ferme (batterie seule) ; Energie : sauts corriges ; tableau Energie complete (Sud/Ouest, batterie par integration, borne ; aucun redemarrage HA) ; kilometrage des vehicules (km/kWh, capacite, releves de reference, agent cable 15/15) ; a verifier le 04/10 au matin : nuit du budget JEEP ; concierge : vehicule non confirme demande, heure de saisie ; Grafana vehicules en tableau ; Grafana vehicules : ZERO et Invite ajoutes, session 16:46 reetiquetee ZERO ; prevision SOC 10 h ~35 % ; concierge fiable : niveau note par le script, une ligne, dedoublonnage, simulation par drapeau ; agent : message incompris = question, bourse sur demande explicite (banc final 6/6) ; a verifier : nuit du samedi 03 au dimanche 04/10 (budget < besoin JEEP), cron orange-cloture lundi 05/10 apres 17:40, comparaison VRM / Forecast.Solar lundi 05/10* *Document mis a jour le : 07/10/2026 (~14:25) — recharge reseau HC : courant calcule (12 kVA) et consigne non tenue ; HC de midi : AUTO ne chauffe pas (BOOST), alerte v2, Jeep (contact, relecture, zone), recharge batterie bridee a 30 A par l'ACM ; jour faible = EDF les deux fenetres HC pour le chauffe-eau, alerte BOOST, Victron Mobile refait ; 1re decision jour faible en reel, mesure ECS reparee, douches 06:00/20:00, Grafana chauffe-eau, tableaux ECS ; chauffe-eau en HC de nuit les jours faibles (decision du bilan, workflow ECS sous controle du depot, VRM, V2.3 desactive) ; garde batterie reseau : voiture bridee a 6 A au lieu d'un arret ; garde-fou concierge 2 h ; allers-retours brefs de la borne retrouves dans l'historique HA (echange VW -> JEEP de 20 s), production 14,5 kWh contre 22 prevus, defaut garde batterie en mode reseau a trancher ; voiture a midi : la batterie n'est plus comptee comme du solaire (EDF automatique les jours de depart si le surplus ne couvre pas) ; nuit 05->06 : JEEP chargee sur EDF en complete (6,32 kWh), budget 0 du a la prevision, Windy/ECMWF contre VRM, a comparer ce soir ; concierge aligne sur la preuve fin de trajet ; a verifier : nuit 05->06 et mardi faible, comparaison VRM/Forecast.Solar ; JEEP identifiee aussi par sa fin de trajet, prevision de la nuit 05->06 ; identification JEEP reussie en reel, correction humaine qui prime (refus supprime), session du 04/10 coupee ; EVCS Master en quatre onglets ; Jeep lue par Uconnect et identifiee seule, capacite JEEP 10 kWh, concierge variante (a) ; releve par photo (SPARK), hass-uconnect en attente ; ecart semaine/week-end mesure (pas de profil week-end la nuit) ; nuit du budget : budget borne au plancher prudent, sans EDF = voiture bloquee meme EDF ferme (batterie seule) ; Energie : sauts corriges ; tableau Energie complete (Sud/Ouest, batterie par integration, borne ; aucun redemarrage HA) ; kilometrage des vehicules (km/kWh, capacite, releves de reference, agent cable 15/15) ; a verifier le 04/10 au matin : nuit du budget JEEP ; concierge : vehicule non confirme demande, heure de saisie ; Grafana vehicules en tableau ; Grafana vehicules : ZERO et Invite ajoutes, session 16:46 reetiquetee ZERO ; prevision SOC 10 h ~35 % ; concierge fiable : niveau note par le script, une ligne, dedoublonnage, simulation par drapeau ; agent : message incompris = question, bourse sur demande explicite (banc final 6/6) ; a verifier : nuit du samedi 03 au dimanche 04/10 (budget < besoin JEEP), cron orange-cloture lundi 05/10 apres 17:40, comparaison VRM / Forecast.Solar lundi 05/10*

View File

@@ -0,0 +1,13 @@
# Abonnement EDF (07/10/2026, donne par le proprietaire) : 12 kVA, disjoncteur
# 63 A. Lu par le Victron Auto Charge Manager pour borner la recharge reseau de
# la batterie : 90 % de l'abonnement moins la maison. ⚠️ Pas d'`initial:`
# (desactive la restauration d'etat) : la valeur est posee une fois a la creation.
input_number:
victron_grid_subscription_va:
name: "Abonnement EDF (VA)"
min: 3000
max: 36000
step: 1000
unit_of_measurement: VA
mode: box
icon: mdi:transmission-tower

View File

@@ -619,8 +619,16 @@ let gridSetpointDescending = false;
if (!gridSessionActive) { if (!gridSessionActive) {
gridSetpointNeedW = params.gridSetpointIdleW; gridSetpointNeedW = params.gridSetpointIdleW;
} else if (solarProducing && !batteryPolicy.batterySoftBreachNow && gridSetpointCurrentW !== null) { } else if (solarProducing && !batteryPolicy.batterySoftBreachNow && gridSetpointCurrentW !== null
&& !(batterySetpointShareW > 0)) {
// On tient la valeur acquise, bornee par la maison et par le plafond. // On tient la valeur acquise, bornee par la maison et par le plafond.
// ⚠️ SAUF si le bilan finance la batterie (07/10/2026) : HC de midi d'un jour
// faible, SOC 31 pour 44 % requis, solaire a ~1,5 kW donc chargeurs « au
// max » -> la consigne restait tenue a 5 198 W (la maison) et la batterie ne
// prenait que 3 a 6 A, alors que l'Auto Charge Manager l'autorisait a 99 A.
// Le maintien protege le solaire d'une consigne trop haute ; quand la
// batterie a un MANQUE chiffre a reprendre en heures creuses, le solaire et
// le reseau la rechargent ENSEMBLE : on va au plafond (maison + part batterie).
gridSetpointNeedW = clamp( gridSetpointNeedW = clamp(
Math.min(gridSetpointCurrentW, gridSetpointCeilingW), Math.min(gridSetpointCurrentW, gridSetpointCeilingW),
gridSetpointHouseFloorW, gridSetpointHouseFloorW,

View File

@@ -62,6 +62,36 @@ export const scenarios = [
expect: { mode: 'evcs_takeover_recover', profil: 'night_slow', expect: { mode: 'evcs_takeover_recover', profil: 'night_slow',
courantA: 30, tensionV: 50.1 }, courantA: 30, tensionV: 50.1 },
}, },
// COURANT CALCULE (07/10/2026) : energie a reprendre / temps restant, borne
// par l'abonnement 12 kVA moins la maison. Releve du 07/10 a midi : SOC 31,
// cible 44,1, 3,91 kWh a reprendre, maison 5,3 kW (BOOST + repas).
{
id: 'acm-takeover-midi-courant-calcule',
label: 'RELEVE 07/10 12:30 : 3,91 kWh en 1,9 h -> 50 A (au lieu de 30 A fixes, qui ne donnaient que 2,8 kWh)',
time: h(ETE, '12:30'),
overrides: { ...parcNeuf, soc_percent: '31', night_takeover: 'on', edf_switch: 'on',
night_target_soc: '44.1', grid_energy_needed_kwh: '3.91', house_ac_power_w: '5300',
grid_subscription_va: '12000', battery_voltage_v: '51' },
expect: { mode: 'evcs_takeover_recover', courantA: 50 },
},
{
id: 'acm-takeover-midi-borne-par-l-abonnement',
label: 'Meme midi, maison a 9,5 kW : il ne reste que 1,3 kW sous les 90 % des 12 kVA -> 25,5 A',
time: h(ETE, '12:30'),
overrides: { ...parcNeuf, soc_percent: '31', night_takeover: 'on', edf_switch: 'on',
night_target_soc: '44.1', grid_energy_needed_kwh: '3.91', house_ac_power_w: '9500',
grid_subscription_va: '12000', battery_voltage_v: '51' },
expect: { mode: 'evcs_takeover_recover', courantA: 25.5 },
},
{
id: 'acm-takeover-nuit-petit-besoin-plancher-10a',
label: 'Nuit 01:30, 1 kWh a reprendre en 5,9 h : 3,8 A calcules -> plancher 10 A (la batterie est menagee)',
time: h(ETE, '01:30'),
overrides: { ...parcNeuf, soc_percent: '40', night_takeover: 'on', edf_switch: 'on',
night_target_soc: '44', grid_energy_needed_kwh: '1', house_ac_power_w: '700',
grid_subscription_va: '12000', battery_voltage_v: '51' },
expect: { mode: 'evcs_takeover_recover', courantA: 10 },
},
{ {
id: 'acm-takeover-maintien-a-la-cible', id: 'acm-takeover-maintien-a-la-cible',
label: 'RELEVE 06/09 05:06 : cible atteinte, la batterie est tenue a 2 A pendant que le reseau porte la maison', label: 'RELEVE 06/09 05:06 : cible atteinte, la batterie est tenue a 2 A pendant que le reseau porte la maison',

View File

@@ -2657,6 +2657,55 @@ export const scenarios = [
}, },
expect: { profile: 'midday_hc_or_solar', sessionCommittedService: 'turn_on', takeoverNeeded: true }, expect: { profile: 'midday_hc_or_solar', sessionCommittedService: 'turn_on', takeoverNeeded: true },
}, },
// CONSIGNE (07/10/2026, releve de 14:20) : HC de midi, solaire actif (chargeurs
// au max), manque batterie chiffre par le bilan, DVCC releve a 99 A par l'ACM.
// Avant : la consigne etait TENUE a 5 198 W (la maison), batterie a 3-6 A.
{
id: 'consigne-hc-midi-manque-batterie-pas-de-maintien',
label: 'MIDI 07/10 — session HC, soleil, manque batterie 2,6 kWh, DVCC 99 A : la consigne monte au plafond (maison + batterie) au lieu d etre tenue',
time: MIDDAY,
overrides: {
evcs_vehicle_connected: 'off', evcs_device_connected: 'on',
grid_state: 'on', victron_acin1_available: '1',
night_grid_session_committed_prev: 'on', night_takeover_prev: 'on',
acin1_last_changed_ts: String(Date.parse(MIDDAY) / 1000 - 1800),
grid_switch_last_changed_ts: String(Date.parse(MIDDAY) / 1000 - 1800),
soc_percent: '35', battery_current_a: '3', battery_voltage_v: '49.5',
pv_power_w: '1700', pv_power_10m_avg_w: '1700', pv_trend_w: '0',
mppt_operation_modes: 'mppt_active,mppt_active,mppt_active,mppt_active,mppt_active,mppt_active,mppt_active',
house_ac_power_w: '5300', vebus_ac_out_l1_power_w: '5300', evcs_ac_power_w: '0',
grid_setpoint_w: '5198',
balance_required_soc: '43.6', balance_energy_to_cover_kwh: '0',
balance_status: 'ok', balance_last_run: '08/08 12:50',
balance_ecs_nuit: 'on',
balance_grid_energy_needed_kwh: '2.6', dvcc_max_charge_current_a: '99',
},
// 5 300 W de maison + min(2,6 kWh / 1,4 h restantes = 1 857 W, DVCC 99 A x 49,5 V)
// + la marge d'un pas EVCS (230 W) = 7 387 W. Tenue, elle serait restee a la maison.
expect: { profile: 'midday_hc_or_solar', gridSetpointW: 7387 },
},
{
id: 'consigne-hc-midi-sans-manque-maintien-garde',
label: 'CONTREFACTUEL — meme midi sans manque batterie : la consigne reste tenue (le solaire garde la priorite)',
time: MIDDAY,
overrides: {
evcs_vehicle_connected: 'off', evcs_device_connected: 'on',
grid_state: 'on', victron_acin1_available: '1',
night_grid_session_committed_prev: 'on', night_takeover_prev: 'on',
acin1_last_changed_ts: String(Date.parse(MIDDAY) / 1000 - 1800),
grid_switch_last_changed_ts: String(Date.parse(MIDDAY) / 1000 - 1800),
soc_percent: '35', battery_current_a: '3', battery_voltage_v: '49.5',
pv_power_w: '1700', pv_power_10m_avg_w: '1700', pv_trend_w: '0',
mppt_operation_modes: 'mppt_active,mppt_active,mppt_active,mppt_active,mppt_active,mppt_active,mppt_active',
house_ac_power_w: '5300', vebus_ac_out_l1_power_w: '5300', evcs_ac_power_w: '0',
grid_setpoint_w: '5198',
balance_required_soc: '43.6', balance_energy_to_cover_kwh: '0',
balance_status: 'ok', balance_last_run: '08/08 12:50',
balance_ecs_nuit: 'on',
balance_grid_energy_needed_kwh: '0', dvcc_max_charge_current_a: '99',
},
expect: { profile: 'midday_hc_or_solar', gridSetpointW: 5530 },
},
{ {
id: 'hc-midi-jour-faible-bilan-perime-aucun-engagement', id: 'hc-midi-jour-faible-bilan-perime-aucun-engagement',
label: 'CONTREFACTUEL — jour faible mais bilan vieux de 2 h : on ne relaie pas une decision perimee', label: 'CONTREFACTUEL — jour faible mais bilan vieux de 2 h : on ne relaie pas une decision perimee',

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');

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long