P12 — la voiture se charge sur le solaire d hier, pas sur le reseau
Idee du proprietaire, apres la nuit du 14 au 15/09 : 8 kWh achetes au reseau, la batterie encore a 69 % a 5 h du matin, et une prevision de 38,7 kWh le lendemain dont 10,5 auraient ete ecretes faute de place. Payer du reseau la nuit pour ecreter le solaire le lendemain, c est perdre deux fois. Le mode `battery_assist_night` existait pour exactement ca, et etait MORT depuis toujours : il exige `batteryCurrentA >= plancher de decharge` (0 A), impossible la nuit puisque la maison tire sur la batterie. On ne cree donc pas un chemin, on rend viable celui qui existe — en remplacant un test de COURANT impossible par un test d ENERGIE. Le plancher n est PAS une constante nouvelle : c est `required_soc_prudent`, que le bilan publie deja en profil p80. La voiture descend la batterie jusqu au niveau qui lui permet encore de tenir jusqu au croisement PV, et pas plus bas. La bascule vers le reseau est automatique quand le surplus est epuise — la soupape decrite par le proprietaire, sans aucune regle horaire. ⚠️ Verrou anti-oscillateur, et il n est pas decoratif. Le plancher descend pendant la nuit et le SOC aussi : voiture en charge le SOC perd 7,1 pt/h contre 3,7 pour le plancher, mais voiture ARRETEE il n en perd que 2,6. Le surplus reapparaitrait tout seul et la charge repartirait. Une seule passe par session de nuit, comme la recovery batterie depuis le 27/08. Les gardes de courant restent : commonSafety, l arret dur, et la garde souple avec sa tolerance temporelle — c est elle qui arretera la charge quand la bande de SOC deviendra trop basse pour le courant tire. Ce qu on retire est uniquement le plancher de PROFIL, qui interdisait de demarrer des que la batterie n etait pas a l equilibre. Cinq scenarios, six mutations qui mordent chacune sur un jeu different. Deux d entre elles ont trouve de vraies faiblesses : les attendus ne verifiaient que le choix du mode et pas que la voiture charge, et la garde de fraicheur du bilan n etait couverte par aucun scenario. Rien n est deploye et le toggle est a off. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
This commit is contained in:
@@ -820,14 +820,44 @@ const gridHoldOk =
|
||||
parsed.gridAvailable &&
|
||||
parsed.batteryCurrentA >= gridBatteryHardDynamicA;
|
||||
|
||||
// P12 (15/09/2026) — le mode `battery_assist_night` etait MORT depuis toujours.
|
||||
// Il exige `batteryCurrentA >= plancher de decharge du profil` (0 A), condition
|
||||
// impossible la nuit puisque la maison tire sur la batterie (§11, ~ -14 A). Il
|
||||
// n'a donc jamais demarre une seule fois.
|
||||
//
|
||||
// Quand P12 est actif, on remplace ce test de COURANT par un test d'ENERGIE :
|
||||
// rester au-dessus de ce qu'il faut pour tenir jusqu'au croisement PV. Le
|
||||
// plancher vient du bilan (`required_soc_prudent`, profil p80), il est calcule
|
||||
// dans WINDOWS_SOURCEV2 et transmis ici — ce node CONSOMME, il ne recalcule pas.
|
||||
//
|
||||
// ⚠️ LES GARDES DE COURANT NE SONT PAS SUPPRIMEES POUR AUTANT :
|
||||
// - `commonSafetyStartOk` / `commonSafetyHoldOk` restent evalues normalement ;
|
||||
// - le MAINTIEN garde `batteryDischargeHardDynamicA`, l'arret dur, qui n'est
|
||||
// jamais contourne ;
|
||||
// - la garde SOUPLE et sa tolerance temporelle (§35) continuent de s'appliquer
|
||||
// par `batterySoftDischargeHoldOk` en aval, et c'est elle qui arretera la
|
||||
// charge quand la bande de SOC deviendra trop basse pour le courant tire.
|
||||
// Ce qu'on retire, c'est uniquement le plancher de PROFIL, qui interdisait de
|
||||
// demarrer quoi que ce soit des que la batterie n'etait pas a l'equilibre.
|
||||
const nightBatterySurplusAvailable = !!nightPrev.nightBatterySurplusAvailable;
|
||||
const nightBatterySurplusFloorPct = Number.isFinite(nightPrev.nightBatterySurplusFloorPct)
|
||||
? nightPrev.nightBatterySurplusFloorPct
|
||||
: Infinity;
|
||||
|
||||
const batteryAssistNightStartOk =
|
||||
context.sourceMode === 'battery_assist_night' &&
|
||||
commonSafetyStartOk &&
|
||||
nightSessionActive &&
|
||||
batteryAssistAllowed &&
|
||||
parsed.soc > batteryHardFloorPct &&
|
||||
parsed.soc > gridTakeoverTriggerPct &&
|
||||
parsed.batteryCurrentA >= profileBatteryDischargeFloorA;
|
||||
(
|
||||
nightBatterySurplusAvailable
|
||||
? parsed.soc > nightBatterySurplusFloorPct
|
||||
: (
|
||||
parsed.soc > gridTakeoverTriggerPct &&
|
||||
parsed.batteryCurrentA >= profileBatteryDischargeFloorA
|
||||
)
|
||||
);
|
||||
|
||||
const batteryAssistNightHoldOk =
|
||||
context.sourceMode === 'battery_assist_night' &&
|
||||
@@ -835,8 +865,12 @@ const batteryAssistNightHoldOk =
|
||||
nightSessionActive &&
|
||||
batteryAssistAllowed &&
|
||||
parsed.soc > batteryHardFloorPct &&
|
||||
parsed.soc > gridTakeoverTriggerPct &&
|
||||
parsed.batteryCurrentA >= batteryDischargeHardDynamicA;
|
||||
parsed.batteryCurrentA >= batteryDischargeHardDynamicA &&
|
||||
(
|
||||
nightBatterySurplusAvailable
|
||||
? parsed.soc > nightBatterySurplusFloorPct
|
||||
: parsed.soc > gridTakeoverTriggerPct
|
||||
);
|
||||
|
||||
// =====================================================
|
||||
// PROBE LOGIC — STRICTEMENT LIMITÉE AU MODE PROBE
|
||||
@@ -1082,6 +1116,9 @@ return [{
|
||||
batteryMorningTargetPct,
|
||||
balanceMorningTargetApplied,
|
||||
nightGridSessionCommitted,
|
||||
// P12 — passe-plat du verrou anti-oscillateur vers la sortie.
|
||||
nightBatterySurplusExhausted: !!nightPrev.nightBatterySurplusExhausted,
|
||||
nightBatterySurplusAvailable: !!nightPrev.nightBatterySurplusAvailable,
|
||||
maxBatteryDischargePoints,
|
||||
gridTakeoverTriggerPct,
|
||||
|
||||
@@ -1156,6 +1193,8 @@ return [{
|
||||
gridHoldOk,
|
||||
|
||||
batteryAssistNightStartOk,
|
||||
nightBatterySurplusAvailable,
|
||||
nightBatterySurplusFloorPct,
|
||||
batteryAssistNightHoldOk,
|
||||
|
||||
probeStartOk,
|
||||
|
||||
@@ -1163,6 +1163,26 @@ return [{
|
||||
}
|
||||
},
|
||||
|
||||
// P12 — LE VERROU ANTI-OSCILLATEUR.
|
||||
//
|
||||
// Le plancher de surplus (`required_soc_prudent`) DESCEND pendant la nuit,
|
||||
// et le SOC aussi. Mesure du 15/09 : voiture en charge, le SOC descend de
|
||||
// 7,1 pt/h et le plancher de 3,7 ; voiture ARRETEE, le SOC ne descend plus
|
||||
// que de 2,6 pt/h quand le plancher continue a 3,7. Le surplus
|
||||
// REAPPARAITRAIT donc tout seul et la charge repartirait — cinquieme
|
||||
// oscillateur du projet, par construction.
|
||||
//
|
||||
// Une seule passe de surplus par session de nuit, comme la recovery
|
||||
// batterie depuis le 27/08. Ecrit uniquement sur changement reel.
|
||||
helper_night_battery_done: {
|
||||
execute: !!night.nightBatterySurplusExhausted !== !!params.nightBatteryDonePrev,
|
||||
domain: 'input_boolean',
|
||||
service: night.nightBatterySurplusExhausted ? 'turn_on' : 'turn_off',
|
||||
data: {
|
||||
entity_id: 'input_boolean.victron_evcs_night_battery_done'
|
||||
}
|
||||
},
|
||||
|
||||
helper_night_grid_takeover_needed: {
|
||||
execute: true,
|
||||
domain: 'input_boolean',
|
||||
|
||||
@@ -604,8 +604,10 @@ const nightBatterySurplusAvailable =
|
||||
balanceMorningTargetApplied &&
|
||||
Number.isFinite(params.balanceRequiredSocPrudentPct) &&
|
||||
!vehicleChargeCompleted &&
|
||||
!nightBatterySurplusExhausted &&
|
||||
parsed.soc > nightBatterySurplusFloorPct;
|
||||
// Le plancher est teste UNE SEULE FOIS, dans `nightBatterySurplusExhausted`.
|
||||
// Le retester ici serait redondant — et une redondance ne se teste pas : la
|
||||
// mutation du 15/09 l'a montre en ne cassant aucun scenario.
|
||||
!nightBatterySurplusExhausted;
|
||||
|
||||
// La batterie d'abord, le reseau quand le surplus est epuise. C'est la soupape
|
||||
// decrite par le proprietaire — « quitte a fermer EDF entre 6h et 7h24 pour
|
||||
|
||||
Reference in New Issue
Block a user