Deux fermetures ce dimanche midi. Mesurees a l instant de la decision, contacteur encore ouvert donc production non censuree : maison 4025 et 4981 W, mais parc reellement sollicite 1132 et 772 W pour un plafond de 5100. La decharge batterie mesuree aux memes instants — 1345 et 1223 W — colle a maison moins PV, pas a la maison brute. Le solaire couvrait la cuisson ; la regle a ferme le contacteur pour rien, 0,50 kWh importes en plein soleil. Elle n avait bien fonctionne hier soir que parce qu il n y avait plus de PV. Les deux seuils portent desormais sur max(0, maison - PV). Contacteur ouvert cette grandeur EST la decharge batterie ; ferme, un bridage du MPPT la fait surestimer, donc l erreur pousse a rester ferme et jamais a relacher tot. Golden 20 -> 24, dont les deux releves de midi et le contrefactuel du nuage. Le test de mutation a montre que la premiere serie ne couvrait que le seuil de fermeture : il a fallu ecrire le cas du soleil revenu pour qu elle morde. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
571 lines
19 KiB
JavaScript
571 lines
19 KiB
JavaScript
// Scénarios golden pour le node "Compute Grid Hysteresis"
|
|
// (workflow "Victron - Battery / Grid Hysteresis Fix V1").
|
|
//
|
|
// Seuils du fixture = valeurs RÉELLES de production (vérifiées via MCP
|
|
// ha-get-state le 24/08/2026) : grid_soc_on = 20, grid_soc_off = 30,
|
|
// min_on = 25 min, cooldown = 15 min. Ne PAS utiliser les valeurs de repli
|
|
// codées dans le node (22/35) : elles ne correspondent à rien en production
|
|
// et masquent les bugs de bande.
|
|
//
|
|
// Historique : cette suite a été créée le 22/08/2026 pour valider "Fix G"
|
|
// (coupure immédiate dès que l'override EVCS disparaissait et que
|
|
// SOC > grid_soc_on). Fix G a été RETIRÉ le 24/08/2026 : son garde SOC ne
|
|
// protégeait que l'instant de l'engagement sur SOC bas, pas la phase de
|
|
// remontée grid_soc_on -> grid_soc_off, ce qui transformait l'hystérésis
|
|
// 20/30 en hystérésis 20/20,1 et produisait un yoyo EDF de 2 à 4 minutes.
|
|
// Les scénarios `h-recovery-band-*` ci-dessous sont les garde-fous qui
|
|
// auraient attrapé cette régression : ils vérifient que la remontée de la
|
|
// batterie sur réseau n'est JAMAIS interrompue tant que grid_soc_off n'est
|
|
// pas atteint.
|
|
|
|
function stamp(ms) {
|
|
const p = new Intl.DateTimeFormat('fr-FR', {
|
|
timeZone: 'Europe/Paris', year: 'numeric', month: '2-digit', day: '2-digit',
|
|
hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false,
|
|
}).formatToParts(new Date(ms));
|
|
const g = t => p.find(x => x.type === t).value;
|
|
return `${g('year')}-${g('month')}-${g('day')} ${g('hour')}:${g('minute')}:${g('second')}`;
|
|
}
|
|
|
|
function minutesAgo(fixedMs, minutes) {
|
|
return stamp(fixedMs - minutes * 60000);
|
|
}
|
|
|
|
// Le bilan energetique publie son horodatage au format "DD/MM HH:mm".
|
|
function bilanRunAgo(fixedMs, minutes) {
|
|
const p = new Intl.DateTimeFormat('fr-FR', {
|
|
timeZone: 'Europe/Paris', month: '2-digit', day: '2-digit',
|
|
hour: '2-digit', minute: '2-digit', hour12: false,
|
|
}).formatToParts(new Date(fixedMs - minutes * 60000));
|
|
const g = t => p.find(x => x.type === t).value;
|
|
return `${g('day')}/${g('month')} ${g('hour')}:${g('minute')}`;
|
|
}
|
|
|
|
const T = '2026-08-24T06:45:00+02:00'; // heure de l'incident de yoyo du 24/08
|
|
const T_MS = new Date(T).getTime();
|
|
|
|
// Base commune : EDF ON sous latch, aucun override EVCS (véhicule débranché),
|
|
// lecture HA saine. C'est la situation "remontée batterie sur réseau".
|
|
const recoveryBase = {
|
|
grid_latch: 'on',
|
|
grid_state: 'on',
|
|
night_grid_takeover_needed: 'off',
|
|
evcs_priority_active: 'off',
|
|
evcs_source_mode: 'Bloqué',
|
|
evcs_surplus_state: 'vehicle_not_connected',
|
|
user_strategy: 'auto_solar_plus',
|
|
};
|
|
|
|
// Plafond de decharge REEL depuis le retrait du pack ancien (05/09/2026) :
|
|
// quatre modules, 100 A annonces par le BMS sous 51 V, soit 5100 W. Les seuils
|
|
// en decoulent — 4080 W pour fermer, 2550 W pour relacher — et se deplaceront
|
|
// tout seuls le jour ou le parc changera.
|
|
const parcQuatreModules = {
|
|
battery_max_discharge_a: '100',
|
|
battery_voltage_v: '51',
|
|
// ⚠️ PV NULLE, ET C'EST STRUCTUREL. Depuis le 06/09 les deux seuils portent
|
|
// sur `max(0, maison - PV)`, ce que le parc est REELLEMENT sollicite de
|
|
// fournir, et non sur la maison brute. Les scenarios de protection decrivent
|
|
// le soir : le parc est seul, la maison brute EST la demande sur le parc. Les
|
|
// scenarios `h-midi-*` couvrent le cas diurne, ou le solaire couvre la
|
|
// cuisson et ou la regle ne doit PAS fermer.
|
|
pv_power_w: '0',
|
|
};
|
|
|
|
export const scenarios = [
|
|
{
|
|
id: 'h-charge-au-dessus-du-parc-ferme',
|
|
label: 'Cuisson a 4500 W contre 5100 W de plafond BMS : le reseau vient prendre la difference',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
...parcQuatreModules,
|
|
grid_latch: 'off',
|
|
grid_state: 'off',
|
|
soc_percent: '91',
|
|
house_ac_power_w: '4500',
|
|
},
|
|
expect: {
|
|
state: 'turn_on_charge_au_dessus_du_parc',
|
|
gridAction: 'turn_on',
|
|
latchAction: 'turn_on',
|
|
},
|
|
},
|
|
{
|
|
id: 'h-charge-encore-elevee-maintient',
|
|
label: 'Charge retombee a 3000 W, entre les deux seuils : on garde le reseau au lieu de le lacher',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
...parcQuatreModules,
|
|
soc_percent: '91',
|
|
house_ac_power_w: '3000',
|
|
last_on_at: minutesAgo(T_MS, 40),
|
|
},
|
|
expect: {
|
|
state: 'hold_on_charge_encore_elevee',
|
|
gridAction: 'none',
|
|
},
|
|
},
|
|
{
|
|
id: 'h-charge-retombee-relache',
|
|
label: 'CONTREFACTUEL : meme situation a 2000 W, sous le seuil de relachement — le reseau est rendu (ici par Fix C, le vehicule etant debranche)',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
...parcQuatreModules,
|
|
soc_percent: '91',
|
|
house_ac_power_w: '2000',
|
|
last_on_at: minutesAgo(T_MS, 40),
|
|
},
|
|
expect: {
|
|
state: 'turn_off_vehicle_unplugged',
|
|
gridAction: 'turn_off',
|
|
},
|
|
},
|
|
{
|
|
id: 'h-plafond-inconnu-aucune-action',
|
|
label: 'Plafond BMS illisible : la regle est inerte, le comportement historique tient',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
soc_percent: '91',
|
|
house_ac_power_w: '4500',
|
|
last_on_at: minutesAgo(T_MS, 40),
|
|
},
|
|
expect: {
|
|
state: 'turn_off_vehicle_unplugged',
|
|
gridAction: 'turn_off',
|
|
},
|
|
},
|
|
{
|
|
id: 'h-engage-low-soc',
|
|
label: 'SOC 18% <= seuil ON 20% : EDF maintenu (engagement batterie basse)',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
evcs_surplus_state: '',
|
|
evcs_source_mode: '',
|
|
soc_percent: '18',
|
|
last_on_at: minutesAgo(T_MS, 5),
|
|
},
|
|
expect: {
|
|
state: 'hold_on_low_soc',
|
|
gridAction: 'none',
|
|
latchAction: 'none',
|
|
},
|
|
},
|
|
{
|
|
id: 'h-recovery-band-no-cut-21',
|
|
label: 'ANTI-YOYO : SOC 21% (juste au-dessus du seuil ON), min_on non écoulé — aucune coupure',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
// véhicule débranché mais SOC < seuil OFF : Fix C ne doit pas couper,
|
|
// et rien d'autre ne doit couper non plus. C'est LE point exact où
|
|
// Fix G coupait et provoquait le yoyo de 2-4 min du 24/08.
|
|
soc_percent: '21',
|
|
last_on_at: minutesAgo(T_MS, 5),
|
|
},
|
|
expect: {
|
|
state: 'hold_on_min_runtime',
|
|
gridAction: 'none',
|
|
latchAction: 'none',
|
|
evcsGridOverride: false,
|
|
},
|
|
},
|
|
{
|
|
id: 'h-recovery-band-no-cut-25',
|
|
label: 'ANTI-YOYO : SOC 25% en pleine bande, min_on écoulé — la remontée doit continuer',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
soc_percent: '25',
|
|
last_on_at: minutesAgo(T_MS, 120), // min_on largement écoulé
|
|
},
|
|
expect: {
|
|
state: 'hold_on_until_soc_off',
|
|
gridAction: 'none',
|
|
latchAction: 'none',
|
|
evcsGridOverride: false,
|
|
},
|
|
},
|
|
{
|
|
id: 'h-recovery-complete',
|
|
label: 'SOC 30% = seuil OFF, min_on écoulé : coupure normale de fin de remontée',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
// véhicule branché mais au repos : on teste la coupure GÉNÉRIQUE de fin
|
|
// de remontée, pas le raccourci Fix C (débranchement).
|
|
evcs_surplus_state: 'idle_wait_conditions',
|
|
soc_percent: '30',
|
|
last_on_at: minutesAgo(T_MS, 120),
|
|
},
|
|
expect: {
|
|
state: 'turn_off_recovered',
|
|
gridAction: 'turn_off',
|
|
latchAction: 'turn_off',
|
|
},
|
|
},
|
|
{
|
|
id: 'h-override-released-soc-ok',
|
|
label: 'Override EVCS relâché avec SOC 34% >= seuil OFF : la boucle générique coupe déjà (aucun fix dédié requis)',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
// Cas de l'incident du 21-22/08 tel qu'il aurait dû se présenter :
|
|
// état transitoire non énuméré, mais SOC au-dessus du seuil OFF.
|
|
evcs_surplus_state: 'stop_source_lost',
|
|
soc_percent: '34',
|
|
last_on_at: minutesAgo(T_MS, 120),
|
|
},
|
|
expect: {
|
|
state: 'turn_off_recovered',
|
|
gridAction: 'turn_off',
|
|
latchAction: 'turn_off',
|
|
},
|
|
},
|
|
{
|
|
id: 'g-regression-fixc-unplugged',
|
|
label: 'Véhicule débranché + SOC 40% >= seuil OFF : Fix C coupe immédiatement (bypass min_on)',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
soc_percent: '40',
|
|
last_on_at: minutesAgo(T_MS, 5),
|
|
},
|
|
expect: {
|
|
state: 'turn_off_vehicle_unplugged',
|
|
gridAction: 'turn_off',
|
|
},
|
|
},
|
|
{
|
|
id: 'g-regression-fixe2-recovery-done',
|
|
label: 'Recovery done + SOC 40% : Fix E2 coupe immédiatement (bypass min_on)',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
evcs_surplus_state: 'night_recovery_done_idle',
|
|
soc_percent: '40',
|
|
last_on_at: minutesAgo(T_MS, 5),
|
|
},
|
|
expect: {
|
|
state: 'turn_off_recovery_done',
|
|
gridAction: 'turn_off',
|
|
},
|
|
},
|
|
// =====================================================
|
|
// RELACHEMENT SUR UNE DUREE (06/09/2026)
|
|
// =====================================================
|
|
// Mesure de la soiree du 05/09, seuil de relachement 2550 W, pas d'une
|
|
// minute : pendant la cuisson (20:33 -> 21:37) treize accalmies, la plus
|
|
// longue de CINQ minutes ; apres la cuisson (21:40 -> 01:00) une seule
|
|
// accalmie de 201 minutes. La distribution est bimodale, le fosse est net,
|
|
// et le relachement instantane tombait treize fois dedans.
|
|
//
|
|
// Le releve exact de cette soiree : SOC 65 %, bilan exigeant 92 % pour
|
|
// atteindre le croisement PV — la reserve est deja condamnee, donc le
|
|
// reseau du soir est du de toute facon et le long dwell s'applique.
|
|
{
|
|
id: 'h-dwell-accalmie-de-cuisson-ne-relache-pas',
|
|
label: "LE CAS REEL : accalmie de 5 min au milieu du service (la plus longue mesuree) — le reseau n'est PAS rendu",
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
...parcQuatreModules,
|
|
soc_percent: '65',
|
|
house_ac_power_w: '2000',
|
|
last_on_at: minutesAgo(T_MS, 40),
|
|
charge_high_last_at: minutesAgo(T_MS, 5),
|
|
balance_required_soc: '92',
|
|
balance_last_run: bilanRunAgo(T_MS, 3),
|
|
},
|
|
expect: {
|
|
state: 'hold_on_charge_encore_elevee',
|
|
gridAction: 'none',
|
|
dwellMinutes: 20,
|
|
dwellEcoule: false,
|
|
reserveDejaCondamnee: true,
|
|
setChargeHighLastAt: false,
|
|
},
|
|
},
|
|
{
|
|
id: 'h-dwell-ecoule-relache',
|
|
label: 'CONTREFACTUEL : meme soiree, mais la maison est calme depuis 25 min — le reseau est rendu',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
...parcQuatreModules,
|
|
soc_percent: '65',
|
|
house_ac_power_w: '2000',
|
|
last_on_at: minutesAgo(T_MS, 40),
|
|
charge_high_last_at: minutesAgo(T_MS, 25),
|
|
balance_required_soc: '92',
|
|
balance_last_run: bilanRunAgo(T_MS, 3),
|
|
},
|
|
expect: {
|
|
state: 'turn_off_vehicle_unplugged',
|
|
gridAction: 'turn_off',
|
|
dwellMinutes: 20,
|
|
dwellEcoule: true,
|
|
reserveDejaCondamnee: true,
|
|
},
|
|
},
|
|
|
|
// Les trois scenarios suivants sont a 8 MINUTES de calme, entre le dwell
|
|
// court (6) et le long (20) : seul l'etat du bilan les separe.
|
|
{
|
|
id: 'h-dwell-long-quand-la-reserve-est-condamnee',
|
|
label: 'Bilan frais, SOC 65 % sous les 92 % requis : dwell long, on garde le reseau a 8 min',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
...parcQuatreModules,
|
|
soc_percent: '65',
|
|
house_ac_power_w: '2000',
|
|
last_on_at: minutesAgo(T_MS, 40),
|
|
charge_high_last_at: minutesAgo(T_MS, 8),
|
|
balance_required_soc: '92',
|
|
balance_last_run: bilanRunAgo(T_MS, 3),
|
|
},
|
|
expect: {
|
|
state: 'hold_on_charge_encore_elevee',
|
|
gridAction: 'none',
|
|
dwellMinutes: 20,
|
|
reserveDejaCondamnee: true,
|
|
},
|
|
},
|
|
{
|
|
id: 'h-dwell-court-quand-la-reserve-tient',
|
|
label: 'PAIRE : bilan frais mais SOC 80 % au-dessus des 40 % requis — chaque kWh du soir couterait, dwell court, on rend a 8 min',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
...parcQuatreModules,
|
|
soc_percent: '80',
|
|
house_ac_power_w: '2000',
|
|
last_on_at: minutesAgo(T_MS, 40),
|
|
charge_high_last_at: minutesAgo(T_MS, 8),
|
|
balance_required_soc: '40',
|
|
balance_last_run: bilanRunAgo(T_MS, 3),
|
|
},
|
|
expect: {
|
|
state: 'turn_off_vehicle_unplugged',
|
|
gridAction: 'turn_off',
|
|
dwellMinutes: 6,
|
|
reserveDejaCondamnee: false,
|
|
},
|
|
},
|
|
{
|
|
id: 'h-dwell-bilan-perime-duree-courte',
|
|
label: 'GARDE DE FRAICHEUR : memes chiffres que le dwell long, mais bilan vieux de 2 h — on retombe sur la duree courte',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
...parcQuatreModules,
|
|
soc_percent: '65',
|
|
house_ac_power_w: '2000',
|
|
last_on_at: minutesAgo(T_MS, 40),
|
|
charge_high_last_at: minutesAgo(T_MS, 8),
|
|
balance_required_soc: '92',
|
|
balance_last_run: bilanRunAgo(T_MS, 120),
|
|
},
|
|
expect: {
|
|
state: 'turn_off_vehicle_unplugged',
|
|
gridAction: 'turn_off',
|
|
dwellMinutes: 6,
|
|
reserveDejaCondamnee: false,
|
|
},
|
|
},
|
|
{
|
|
id: 'h-dwell-horodatage-ecrit-quand-la-charge-est-haute',
|
|
label: "L'horodatage suit la MAISON : charge haute contacteur OUVERT — il est ecrit quand meme",
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
...parcQuatreModules,
|
|
grid_latch: 'off',
|
|
grid_state: 'off',
|
|
soc_percent: '65',
|
|
house_ac_power_w: '3000',
|
|
charge_high_last_at: minutesAgo(T_MS, 30),
|
|
},
|
|
expect: {
|
|
setChargeHighLastAt: true,
|
|
},
|
|
},
|
|
// =====================================================
|
|
// CAPTEURS MUETS (releve du 05/09/2026)
|
|
// =====================================================
|
|
// De 21:22:21 a 21:49:35, `sensor.victron_battery_current` et
|
|
// `sensor.victron_battery_voltage` n'ont RIEN publie — 27 minutes — pendant
|
|
// que `sensor.victron_consumption_power_l1` continuait normalement. Un
|
|
// courant fige a -73,2 A pendant que la maison oscille entre 1,4 et 3,4 kW
|
|
// est physiquement impossible : la valeur etait perimee. Sans repli, la
|
|
// protection s'evanouissait pile a l'heure du diner.
|
|
{
|
|
id: 'h-capteur-tension-muette-la-regle-tient',
|
|
label: 'Tension du parc muette, plafond en amperes lisible : nominal 51 V, la regle continue',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
battery_max_discharge_a: '100',
|
|
battery_voltage_v: 'unavailable',
|
|
pv_power_w: '0',
|
|
soc_percent: '65',
|
|
house_ac_power_w: '2000',
|
|
last_on_at: minutesAgo(T_MS, 40),
|
|
charge_high_last_at: minutesAgo(T_MS, 5),
|
|
balance_required_soc: '92',
|
|
balance_last_run: bilanRunAgo(T_MS, 3),
|
|
},
|
|
expect: {
|
|
state: 'hold_on_charge_encore_elevee',
|
|
gridAction: 'none',
|
|
plafondDechargeW: 5100,
|
|
},
|
|
},
|
|
{
|
|
id: 'h-capteur-tout-muet-le-dwell-tient',
|
|
label: 'Plafond ET tension muets en pleine protection : l horodatage persiste, on tient jusqu au bout du dwell',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
battery_max_discharge_a: 'unavailable',
|
|
battery_voltage_v: 'unavailable',
|
|
pv_power_w: '0',
|
|
soc_percent: '65',
|
|
house_ac_power_w: '2000',
|
|
last_on_at: minutesAgo(T_MS, 40),
|
|
charge_high_last_at: minutesAgo(T_MS, 5),
|
|
balance_required_soc: '92',
|
|
balance_last_run: bilanRunAgo(T_MS, 3),
|
|
},
|
|
expect: {
|
|
state: 'hold_on_charge_encore_elevee',
|
|
gridAction: 'none',
|
|
plafondDechargeW: 0,
|
|
},
|
|
},
|
|
{
|
|
id: 'h-capteur-tout-muet-memoire-expiree',
|
|
label: 'CONTREFACTUEL : memes capteurs muets mais derniere charge haute il y a 30 min — la memoire a expire, le reseau est rendu',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
battery_max_discharge_a: 'unavailable',
|
|
battery_voltage_v: 'unavailable',
|
|
pv_power_w: '0',
|
|
soc_percent: '65',
|
|
house_ac_power_w: '2000',
|
|
last_on_at: minutesAgo(T_MS, 40),
|
|
charge_high_last_at: minutesAgo(T_MS, 30),
|
|
balance_required_soc: '92',
|
|
balance_last_run: bilanRunAgo(T_MS, 3),
|
|
},
|
|
expect: {
|
|
state: 'turn_off_vehicle_unplugged',
|
|
gridAction: 'turn_off',
|
|
},
|
|
},
|
|
// =====================================================
|
|
// MIDI ENSOLEILLE : LE SOLAIRE COUVRE LA CUISSON (06/09/2026)
|
|
// =====================================================
|
|
// Deux fermetures ce dimanche, mesurees a la resolution native A L'INSTANT
|
|
// DE LA DECISION, contacteur encore ouvert donc production non censuree :
|
|
//
|
|
// 12:07, cuisson seule maison 4 025 W parc sollicite 1 132 W
|
|
// 13:34, cuisson + JEEP maison 4 981 W parc sollicite 772 W
|
|
//
|
|
// Controle croise : la decharge batterie valait 1 345 et 1 223 W aux memes
|
|
// instants — elle colle a `maison - PV`, pas a la maison brute. Le plafond du
|
|
// parc est de 5 100 W : il etait a 22 % et 15 % de sa limite, et la regle a
|
|
// ferme le contacteur pour rien.
|
|
{
|
|
id: 'h-midi-solaire-couvre-la-cuisson',
|
|
label: 'RELEVE 06/09 12:07 : maison 4025 W mais PV 2893 W, le parc ne fournit que 1132 W — aucune fermeture',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
...parcQuatreModules,
|
|
grid_latch: 'off',
|
|
grid_state: 'off',
|
|
soc_percent: '69',
|
|
house_ac_power_w: '4025',
|
|
pv_power_w: '2893',
|
|
},
|
|
expect: {
|
|
state: 'observe_only',
|
|
gridAction: 'none',
|
|
latchAction: 'none',
|
|
demandeParcW: 1132,
|
|
},
|
|
},
|
|
{
|
|
id: 'h-midi-jeep-en-plus-solaire-couvre-encore',
|
|
label: 'RELEVE 06/09 13:34 : maison 4981 W dont la JEEP, PV 4209 W, parc a 772 W — aucune fermeture non plus',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
...parcQuatreModules,
|
|
grid_latch: 'off',
|
|
grid_state: 'off',
|
|
soc_percent: '86',
|
|
house_ac_power_w: '4981',
|
|
pv_power_w: '4209',
|
|
evcs_ac_power_w: '1621',
|
|
evcs_charging: 'on',
|
|
evcs_surplus_state: 'charging_step_up_battery',
|
|
evcs_source_mode: 'Solaire',
|
|
},
|
|
expect: {
|
|
state: 'observe_only',
|
|
gridAction: 'none',
|
|
demandeParcW: 772,
|
|
},
|
|
},
|
|
{
|
|
id: 'h-midi-nuage-le-parc-encaisse-tout',
|
|
label: 'CONTREFACTUEL : meme cuisson a 4500 W mais le nuage passe, PV 200 W — le parc encaisse 4300 W, on ferme',
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
...parcQuatreModules,
|
|
grid_latch: 'off',
|
|
grid_state: 'off',
|
|
soc_percent: '69',
|
|
house_ac_power_w: '4500',
|
|
pv_power_w: '200',
|
|
},
|
|
expect: {
|
|
state: 'turn_on_charge_au_dessus_du_parc',
|
|
gridAction: 'turn_on',
|
|
latchAction: 'turn_on',
|
|
demandeParcW: 4300,
|
|
},
|
|
},
|
|
{
|
|
id: 'h-midi-soleil-revenu-relache',
|
|
label: "Le nuage est passe, contacteur ferme : la cuisson continue a 3000 W mais le PV en couvre 2000 — le parc n'est plus sollicite qu'a 1000 W, on rend le reseau",
|
|
time: T,
|
|
overrides: {
|
|
...recoveryBase,
|
|
...parcQuatreModules,
|
|
soc_percent: '69',
|
|
house_ac_power_w: '3000',
|
|
pv_power_w: '2000',
|
|
last_on_at: minutesAgo(T_MS, 40),
|
|
charge_high_last_at: minutesAgo(T_MS, 25),
|
|
balance_required_soc: '92',
|
|
balance_last_run: bilanRunAgo(T_MS, 3),
|
|
},
|
|
expect: {
|
|
state: 'turn_off_vehicle_unplugged',
|
|
gridAction: 'turn_off',
|
|
demandeParcW: 1000,
|
|
setChargeHighLastAt: false,
|
|
},
|
|
},
|
|
];
|