Fenetre d etablissement : ne plus decider sur les mesures du transitoire
A la fermeture du contacteur, PV, import et courant batterie ne decrivent aucun regime permanent pendant ~150 s (mesure du 31/08). La boucle de 30 s y prenait cinq decisions, et la moyenne PV 10 min en gardait la trace dix minutes de plus -- le systeme lisait "plus de soleil", en concluait qu il avait besoin du reseau, et confirmait sa propre premisse. Aucun seuil nouveau : le systeme publiait deja l horodatage de la transition et personne ne le lisait. Pendant la fenetre, on ne demarre pas et on ne laisse pas une charge s arreter sur ces mesures ; les step-down restent libres. Deux asymetries voulues : la fenetre ne s ouvre qu a l ARRIVEE du reseau (a sa disparition les onduleurs reprennent tout, les gardes doivent agir plus vite), et elle suspend le confort, jamais le risque. Golden 42 -> 48, chaque cas apparie a son contrefactuel hors fenetre. Mutation : gridSettling force a false -> 2 echecs cibles, restauration -> 48/48. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
This commit is contained in:
@@ -14,6 +14,11 @@ const MIDDAY = '2026-08-08T13:00:00+02:00';
|
||||
const AFTERNOON = '2026-08-08T15:30:00+02:00';
|
||||
const EVENING = '2026-08-08T18:00:00+02:00';
|
||||
|
||||
// Fenêtre d'établissement du réseau (31/08/2026) : horodatage de la dernière
|
||||
// transition d'AC-IN, en secondes epoch. Le harnais fige l'horloge sur `time`,
|
||||
// donc on exprime l'âge de la transition par rapport à cet instant simulé.
|
||||
const MORNING_TS = Date.parse(MORNING) / 1000;
|
||||
|
||||
const VEHICLE_NIGHT = {
|
||||
evcs_vehicle_connected: 'on',
|
||||
evcs_device_connected: 'on',
|
||||
@@ -1019,4 +1024,183 @@ export const scenarios = [
|
||||
takeoverHelperService: 'turn_off',
|
||||
},
|
||||
},
|
||||
// ======= FENÊTRE D'ÉTABLISSEMENT DU RÉSEAU (31/08/2026) =======
|
||||
// Mesuré ce jour-là : à la fermeture du contacteur, le réseau reprend toute la
|
||||
// charge de la maison, le solaire bascule vers la batterie (ou se fait brider
|
||||
// s'il n'y a plus de tampon : 2663 -> 559 W), puis l'import redescend à la
|
||||
// consigne en ~150 s. Pendant ce temps la boucle de 30 s prend cinq décisions
|
||||
// sur des mesures qui ne décrivent aucun régime permanent.
|
||||
// Chaque cas est apparié à son contrefactuel hors fenêtre : sans cet appariement
|
||||
// le test ne prouverait rien.
|
||||
{
|
||||
id: 'etablissement-maintien-charge',
|
||||
label: 'Réseau fermé il y a 30 s, PV effondrée à 600 W et batterie à -15 A : la charge en cours NE DOIT PAS être arrêtée',
|
||||
time: MORNING,
|
||||
overrides: {
|
||||
evcs_vehicle_connected: 'on', evcs_device_connected: 'on',
|
||||
evcs_charging_switch: 'on', control_latch: 'on', charge_permission_now: 'on',
|
||||
last_start_at: '2026-08-08 08:00:00',
|
||||
soc_percent: '60',
|
||||
evcs_current_a: '16', evcs_set_current_a: '16', evcs_command_current_a: '16',
|
||||
evcs_ac_power_w: '3680',
|
||||
house_ac_power_w: '4400', vebus_ac_out_l1_power_w: '4400',
|
||||
pv_power_w: '600', pv_power_10m_avg_w: '3900', pv_trend_w: '-2000',
|
||||
grid_state: 'on', victron_acin1_available: '1', grid_power_w: '1800',
|
||||
battery_current_a: '-15',
|
||||
acin1_last_changed_ts: String(MORNING_TS - 30),
|
||||
grid_switch_last_changed_ts: String(MORNING_TS - 30),
|
||||
},
|
||||
expect: {
|
||||
profile: "morning_solar",
|
||||
sourceMode: "solar_only",
|
||||
state: "charging_step_down_battery",
|
||||
decision: "step_down",
|
||||
desiredCharging: true,
|
||||
currentA: 14,
|
||||
takeoverNeeded: false,
|
||||
edfOnAction: false,
|
||||
takeoverHelperService: "turn_off",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'etablissement-termine-arret-normal',
|
||||
label: 'CONTREFACTUEL : mêmes mesures, transition vieille de 400 s → fenêtre fermée, la garde de maintien reprend la main et arrête',
|
||||
time: MORNING,
|
||||
overrides: {
|
||||
evcs_vehicle_connected: 'on', evcs_device_connected: 'on',
|
||||
evcs_charging_switch: 'on', control_latch: 'on', charge_permission_now: 'on',
|
||||
last_start_at: '2026-08-08 08:00:00',
|
||||
soc_percent: '60',
|
||||
evcs_current_a: '16', evcs_set_current_a: '16', evcs_command_current_a: '16',
|
||||
evcs_ac_power_w: '3680',
|
||||
house_ac_power_w: '4400', vebus_ac_out_l1_power_w: '4400',
|
||||
pv_power_w: '600', pv_power_10m_avg_w: '3900', pv_trend_w: '-2000',
|
||||
grid_state: 'on', victron_acin1_available: '1', grid_power_w: '1800',
|
||||
battery_current_a: '-15',
|
||||
acin1_last_changed_ts: String(MORNING_TS - 400),
|
||||
grid_switch_last_changed_ts: String(MORNING_TS - 400),
|
||||
},
|
||||
expect: {
|
||||
profile: "morning_solar",
|
||||
sourceMode: "solar_only",
|
||||
state: "stop_conditions_lost",
|
||||
decision: "stop",
|
||||
desiredCharging: false,
|
||||
currentA: 6,
|
||||
takeoverNeeded: false,
|
||||
edfOnAction: false,
|
||||
takeoverHelperService: "turn_off",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'etablissement-securite-non-suspendue',
|
||||
label: "SÉCURITÉ : dans la fenêtre, batterie à -40 A → l'arrêt dur reste actif. La fenêtre suspend le confort, jamais le risque",
|
||||
time: MORNING,
|
||||
overrides: {
|
||||
evcs_vehicle_connected: 'on', evcs_device_connected: 'on',
|
||||
evcs_charging_switch: 'on', control_latch: 'on', charge_permission_now: 'on',
|
||||
last_start_at: '2026-08-08 08:00:00',
|
||||
soc_percent: '60',
|
||||
evcs_current_a: '16', evcs_set_current_a: '16', evcs_command_current_a: '16',
|
||||
evcs_ac_power_w: '3680',
|
||||
house_ac_power_w: '4400', vebus_ac_out_l1_power_w: '4400',
|
||||
pv_power_w: '600', pv_power_10m_avg_w: '3900', pv_trend_w: '-2000',
|
||||
grid_state: 'on', victron_acin1_available: '1', grid_power_w: '1800',
|
||||
battery_current_a: '-40',
|
||||
acin1_last_changed_ts: String(MORNING_TS - 30),
|
||||
grid_switch_last_changed_ts: String(MORNING_TS - 30),
|
||||
},
|
||||
expect: {
|
||||
profile: "morning_solar",
|
||||
sourceMode: "solar_only",
|
||||
state: "battery_current_hard_stop",
|
||||
decision: "stop_hard",
|
||||
desiredCharging: false,
|
||||
currentA: 6,
|
||||
takeoverNeeded: false,
|
||||
edfOnAction: false,
|
||||
takeoverHelperService: "turn_off",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'etablissement-ouverture-aucune-fenetre',
|
||||
label: "ASYMÉTRIE : réseau DISPARU il y a 30 s → aucune fenêtre. Les onduleurs reprennent tout, les gardes doivent agir plus vite, pas moins",
|
||||
time: MORNING,
|
||||
overrides: {
|
||||
evcs_vehicle_connected: 'on', evcs_device_connected: 'on',
|
||||
evcs_charging_switch: 'on', control_latch: 'on', charge_permission_now: 'on',
|
||||
last_start_at: '2026-08-08 08:00:00',
|
||||
soc_percent: '60',
|
||||
evcs_current_a: '16', evcs_set_current_a: '16', evcs_command_current_a: '16',
|
||||
evcs_ac_power_w: '3680',
|
||||
house_ac_power_w: '4400', vebus_ac_out_l1_power_w: '4400',
|
||||
pv_power_w: '600', pv_power_10m_avg_w: '3900', pv_trend_w: '-2000',
|
||||
grid_state: 'on', victron_acin1_available: '1', grid_power_w: '1800',
|
||||
battery_current_a: '-15',
|
||||
grid_state: 'off', victron_acin1_available: '0', grid_power_w: '0',
|
||||
acin1_last_changed_ts: String(MORNING_TS - 30),
|
||||
grid_switch_last_changed_ts: String(MORNING_TS - 30),
|
||||
},
|
||||
expect: {
|
||||
profile: "morning_solar",
|
||||
sourceMode: "solar_only",
|
||||
state: "stop_conditions_lost",
|
||||
decision: "stop",
|
||||
desiredCharging: false,
|
||||
currentA: 6,
|
||||
takeoverNeeded: false,
|
||||
edfOnAction: false,
|
||||
takeoverHelperService: "turn_off",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'etablissement-pas-de-demarrage',
|
||||
label: "Réseau fermé il y a 30 s, rien en charge : on ne démarre pas non plus sur des mesures d'établissement",
|
||||
time: MORNING,
|
||||
overrides: {
|
||||
evcs_vehicle_connected: 'on', evcs_device_connected: 'on',
|
||||
soc_percent: '60', pv_power_w: '4500', pv_power_10m_avg_w: '4200',
|
||||
pv_trend_w: '100', battery_current_a: '10',
|
||||
house_ac_power_w: '900', vebus_ac_out_l1_power_w: '900',
|
||||
grid_state: 'on', victron_acin1_available: '1', grid_power_w: '1800',
|
||||
acin1_last_changed_ts: String(MORNING_TS - 30),
|
||||
grid_switch_last_changed_ts: String(MORNING_TS - 30),
|
||||
},
|
||||
expect: {
|
||||
profile: "morning_solar",
|
||||
sourceMode: "solar_only",
|
||||
state: "idle_wait_conditions",
|
||||
decision: "hold",
|
||||
desiredCharging: false,
|
||||
currentA: 6,
|
||||
takeoverNeeded: false,
|
||||
edfOnAction: false,
|
||||
takeoverHelperService: "turn_off",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'etablissement-demarrage-hors-fenetre',
|
||||
label: 'CONTREFACTUEL : mêmes mesures, transition vieille de 400 s → le démarrage solaire a bien lieu',
|
||||
time: MORNING,
|
||||
overrides: {
|
||||
evcs_vehicle_connected: 'on', evcs_device_connected: 'on',
|
||||
soc_percent: '60', pv_power_w: '4500', pv_power_10m_avg_w: '4200',
|
||||
pv_trend_w: '100', battery_current_a: '10',
|
||||
house_ac_power_w: '900', vebus_ac_out_l1_power_w: '900',
|
||||
grid_state: 'on', victron_acin1_available: '1', grid_power_w: '1800',
|
||||
acin1_last_changed_ts: String(MORNING_TS - 400),
|
||||
grid_switch_last_changed_ts: String(MORNING_TS - 400),
|
||||
},
|
||||
expect: {
|
||||
profile: "morning_solar",
|
||||
sourceMode: "solar_only",
|
||||
state: "start_min_current",
|
||||
decision: "start",
|
||||
desiredCharging: true,
|
||||
currentA: 6,
|
||||
takeoverNeeded: false,
|
||||
edfOnAction: false,
|
||||
takeoverHelperService: "turn_off",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user