La cible du matin devient une energie a couvrir, plus un palier
La regle classait le lendemain en trois paliers a partir de son TOTAL (>= 18 kWh -> 35 %, >= 10 -> 55 %, sinon 85 %) et ignorait donc l heure d arrivee de l energie. Le 03/09 demain annoncait 33,9 kWh — donc "fort", donc 35 % — avec un matin creux (0,03 kWh a 7 h, 0,77 a 8 h) et un croisement a 9 h. Meme defaut que le plancher du soir, a l autre bout de la nuit. Releve de la nuit 02-03/09, requis contre reel : 00:30 62,4 / 53 ; 03:00 50,4 / 45 ; 04:30 41,7 / 37 ; 06:00 37,1 / 22 — cible fixe a 35 tout du long. Le required_soc decroit proprement avec la nuit qui se consomme (6,1 -> 0 kWh a couvrir), la batterie est restee sous la ligne toute la nuit, et le bilan le savait des 00:30. A 03:00 EDF a ete relache cinq points sous la ligne ; le reseau est revenu de 07:24 a 10:33 au plein tarif, 1,49 kWh. La cible vaut desormais min(90, max(palier ou advisor, required_soc)). Sens unique delibere : la direction corrigee est celle de l echec observe, et le principe unificateur des deux cablages est que le bilan ne pousse jamais dans le sens "couvre moins bien la nuit". Plafond 90 parce qu au-dela la batterie cesse d etre un puits et evince la production du matin, et parce que le bilan publie sans ecretage des valeurs superieures a 100 — sans ce plafond la cible serait inatteignable et EDF resterait allume toute la nuit. C est deja la borne du chemin advisor, aucune constante nouvelle. Pas d oscillateur : required_soc decroit de facon monotone pendant la nuit et la passe unique de recovery reste en place. Gardes et repli identiques au plancher du soir, kill-switch existant. Golden 70 -> 75. Quatre mutations font tomber chacune exactement un scenario different. Un cinquieme scenario fige une LIMITE CONNUE, mesuree par sonde : la passe unique de recovery latche le relachement pour toute la session, donc la cible dynamique n ameliore que la premiere passe. §26 avait deja designe le bon critere de re-engagement — un budget d energie restant a couvrir, qui appartient au bilan ; la suite touche la machine a etats de la nuit et fera l objet d un chantier propre. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
This commit is contained in:
@@ -1043,6 +1043,141 @@ export const scenarios = [
|
||||
},
|
||||
},
|
||||
|
||||
// ===== 03/09/2026 : la cible du matin est une energie, pas un palier =====
|
||||
// Releve de la nuit 02-03/09 a 03:00 : le bilan demandait 50,4 % pour tenir
|
||||
// jusqu'au croisement de 9 h, la regle des paliers disait 35 %, le SOC etait
|
||||
// a 45 %. EDF a ete relache 5 points sous la ligne, la batterie s'est videe
|
||||
// a 20 % vers 06:30, et le reseau est revenu de 07:24 a 10:33 AU PLEIN TARIF.
|
||||
{
|
||||
id: 'cible-bilan-tient-le-reseau',
|
||||
label: "Nuit HC 03:00 (relevé du 03/09), VW pleine, SOC 45 : le bilan demande 50,4 % → cible relevée → le réseau est MAINTENU au lieu d'être relâché",
|
||||
time: '2026-08-08T03:00:00+02:00',
|
||||
overrides: {
|
||||
...VEHICLE_NIGHT, allow_grid_hc_night: 'on',
|
||||
grid_state: 'on', victron_acin1_available: '1',
|
||||
battery_current_a: '2', night_takeover_prev: 'on',
|
||||
evcs_charging_switch: 'off',
|
||||
prev_surplus_state: 'night_session_done_idle',
|
||||
soc_percent: '45',
|
||||
balance_required_soc: '50.4', balance_energy_to_cover_kwh: '4.3',
|
||||
balance_status: 'ok', balance_last_run: '08/08 02:58',
|
||||
},
|
||||
expect: {
|
||||
profile: 'night_hc',
|
||||
state: 'night_session_done_idle',
|
||||
takeoverNeeded: true,
|
||||
takeoverHelperService: 'turn_on',
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
// CONTREFACTUEL : exactement la nuit du 03/09. Bilan indisponible => regle
|
||||
// des paliers (35 %) => SOC 45 >= 35 => relache. C'est ce qui s'est passe.
|
||||
id: 'cible-bilan-perime-relache-comme-avant',
|
||||
label: "Même relevé, bilan vieux de 2 h → repli sur le palier 35 % → EDF relâché (le comportement qui a coûté 1,49 kWh au plein tarif)",
|
||||
time: '2026-08-08T03:00:00+02:00',
|
||||
overrides: {
|
||||
...VEHICLE_NIGHT, allow_grid_hc_night: 'on',
|
||||
grid_state: 'on', victron_acin1_available: '1',
|
||||
battery_current_a: '2', night_takeover_prev: 'on',
|
||||
evcs_charging_switch: 'off',
|
||||
prev_surplus_state: 'night_session_done_idle',
|
||||
soc_percent: '45',
|
||||
balance_required_soc: '50.4', balance_energy_to_cover_kwh: '4.3',
|
||||
balance_status: 'ok', balance_last_run: '08/08 01:00',
|
||||
},
|
||||
expect: {
|
||||
profile: 'night_hc',
|
||||
state: 'night_recovery_done_idle',
|
||||
takeoverNeeded: false,
|
||||
takeoverHelperService: 'turn_off',
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
// SENS UNIQUE : le bilan ne doit jamais ABAISSER la cible.
|
||||
id: 'cible-bilan-ne-baisse-pas-la-cible',
|
||||
label: "Nuit HC, SOC 30, le bilan ne demande que 25 % → le palier 35 % reste maître → le réseau est maintenu",
|
||||
time: '2026-08-08T03:00:00+02:00',
|
||||
overrides: {
|
||||
...VEHICLE_NIGHT, allow_grid_hc_night: 'on',
|
||||
grid_state: 'on', victron_acin1_available: '1',
|
||||
battery_current_a: '2', night_takeover_prev: 'on',
|
||||
evcs_charging_switch: 'off',
|
||||
prev_surplus_state: 'night_session_done_idle',
|
||||
soc_percent: '30',
|
||||
balance_required_soc: '25', balance_energy_to_cover_kwh: '0.5',
|
||||
balance_status: 'ok', balance_last_run: '08/08 02:58',
|
||||
},
|
||||
expect: {
|
||||
profile: 'night_hc',
|
||||
state: 'night_session_done_idle',
|
||||
takeoverNeeded: true,
|
||||
takeoverHelperService: 'turn_on',
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
// PLAFOND 90 % : le bilan publie sans ecretage des valeurs > 100 (c'est
|
||||
// voulu, §26 : signal de dimensionnement). Sans plafond ici, la cible
|
||||
// deviendrait inatteignable et EDF resterait allume toute la nuit a
|
||||
// charger la batterie — en evincant au passage la production du matin.
|
||||
id: 'cible-bilan-plafonnee-a-90',
|
||||
label: "Nuit HC, SOC 92, le bilan demande 118,9 % (stockage insuffisant) → cible plafonnée à 90 % → recovery terminée, EDF relâché",
|
||||
time: '2026-08-08T03:00:00+02:00',
|
||||
overrides: {
|
||||
...VEHICLE_NIGHT, allow_grid_hc_night: 'on',
|
||||
grid_state: 'on', victron_acin1_available: '1',
|
||||
battery_current_a: '2', night_takeover_prev: 'on',
|
||||
evcs_charging_switch: 'off',
|
||||
prev_surplus_state: 'night_session_done_idle',
|
||||
soc_percent: '92',
|
||||
balance_required_soc: '118.9', balance_energy_to_cover_kwh: '14.54',
|
||||
balance_status: 'ok', balance_last_run: '08/08 02:58',
|
||||
},
|
||||
expect: {
|
||||
profile: 'night_hc',
|
||||
state: 'night_recovery_done_idle',
|
||||
takeoverNeeded: false,
|
||||
takeoverHelperService: 'turn_off',
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
// LIMITE CONNUE, FIGEE VOLONTAIREMENT (03/09/2026).
|
||||
// La passe unique de recovery (27/08, anti-oscillateur) latche
|
||||
// `nightRecoveryDone` : une fois la cible atteinte, le reseau est relache
|
||||
// DEFINITIVEMENT pour la session, meme si le SOC repasse ensuite sous la
|
||||
// ligne du bilan. La cible dynamique n'ameliore donc que la PREMIERE passe.
|
||||
// Ce scenario epingle ce comportement pour qu'un changement futur soit
|
||||
// deliberе et non accidentel. Filet restant : l'hysteresis a SOC <= 20 %,
|
||||
// mais elle peut tomber hors heures creuses (c'est ce qui a coute 1,49 kWh
|
||||
// au plein tarif le 03/09 entre 07:24 et 10:33).
|
||||
// §26 designait deja le bon critere de re-engagement : « un budget
|
||||
// d'energie restant a couvrir — il appartient au bilan energetique ».
|
||||
// Le bilan est desormais cable ; la suite est un chantier a part, car elle
|
||||
// touche la machine a etats de la nuit.
|
||||
id: 'cible-bilan-limite-passe-unique',
|
||||
label: "LIMITE FIGÉE : recovery déjà latchée, SOC 30 repasse sous le requis 37,1 % → le réseau reste relâché (passe unique, §26)",
|
||||
time: '2026-08-08T05:30:00+02:00',
|
||||
overrides: {
|
||||
...VEHICLE_NIGHT, allow_grid_hc_night: 'on',
|
||||
grid_state: 'off', victron_acin1_available: '0',
|
||||
battery_current_a: '-14', night_takeover_prev: 'off',
|
||||
evcs_charging_switch: 'off',
|
||||
prev_surplus_state: 'night_recovery_done_idle',
|
||||
soc_percent: '30',
|
||||
balance_required_soc: '37.1', balance_energy_to_cover_kwh: '2.3',
|
||||
balance_status: 'ok', balance_last_run: '08/08 05:28',
|
||||
},
|
||||
expect: {
|
||||
profile: 'night_hc',
|
||||
state: 'night_recovery_done_idle',
|
||||
takeoverNeeded: false,
|
||||
takeoverHelperService: 'turn_off',
|
||||
},
|
||||
},
|
||||
|
||||
// ===== 03/09/2026 : le plancher du soir vient de l'energie a couvrir =====
|
||||
// Tous ces scenarios ont un VRAI excedent (PV 2000 W, maison 1000 W) et des
|
||||
// chargeurs qui se retiennent : les gardes de §36 et §37 sont donc passantes,
|
||||
|
||||
Reference in New Issue
Block a user