La consigne de puissance reseau appartient au controleur
Fermer le contacteur ne suffit pas : au-dessus du SOC minimal, l ESS en autoconsommation ne preleve que sa consigne et laisse la batterie porter maison et voiture. Nuit du 01/09 : charge HC demarree a 01:25, arretee a 01:26 par le garde batterie, contacteur ferme et inerte jusqu a 02:00. La consigne a 4200 W du proprietaire n etait pas decorative : c est elle qui faisait fonctionner la prise de relais nocturne depuis le 07/08. La retirer le 31/08 a supprime la substitution de journee et casse la nuit. Le controleur ecrit desormais la consigne lui-meme, a partir du besoin mesure, seulement pendant une session reseau deliberee, avec une bande asymetrique : trop basse se corrige tout de suite, trop haute ne coute rien. Deux ecritures en 25 minutes au lieu d une toutes les 30 s. Golden 51 -> 56. Verifie en reel : batterie a 0 A, voiture a 3500 W. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
This commit is contained in:
96
HANDOFF.md
96
HANDOFF.md
@@ -2026,3 +2026,99 @@ Preuve par mutation, les deux volets séparément :
|
|||||||
|
|
||||||
---
|
---
|
||||||
*Document mis à jour le : 31/08/2026 (~19:00) — séquence d'ouverture corrigée, golden 51/51, PUT n8n en attente de validation*
|
*Document mis à jour le : 31/08/2026 (~19:00) — séquence d'ouverture corrigée, golden 51/51, PUT n8n en attente de validation*
|
||||||
|
|
||||||
|
## 31. Session du 01/09/2026 (nuit) — La consigne réseau appartient désormais au contrôleur
|
||||||
|
|
||||||
|
### L'incident : charge HC démarrée puis morte en soixante secondes
|
||||||
|
Fenêtre HC ouverte normalement, tout notre pilotage a fait son travail :
|
||||||
|
|
||||||
|
| 01:24:03-04 | latch hystérésis ON, EDF fermé, AC-IN présent |
|
||||||
|
| 01:24:00 | takeover nuit ON, source `grid_hc_allowed` (P7) |
|
||||||
|
| 01:25:15 | ACM en `evcs_takeover_hold`, DVCC à 2 A |
|
||||||
|
| 01:25:30 | `start_grid_hc_min_current` — la charge démarre |
|
||||||
|
| 01:25:42 | le réseau prend la voiture : import **1 450 W** |
|
||||||
|
| 01:26:33 | import retombé à 763 W puis **négatif**, batterie de −7 à **−25 A** |
|
||||||
|
| 01:26:30 | garde « batterie trop sollicitée (−21,5 A) » → arrêt + verrou 17 min |
|
||||||
|
| 01:44 → 01:47 | `battery_current_hard_stop` puis `idle_wait_conditions` |
|
||||||
|
|
||||||
|
### Cause : l'ESS n'utilise le réseau que si on le lui demande
|
||||||
|
`ac_power_setpoint` = **50 W** (corrigé le 31/08 depuis 4 200 W),
|
||||||
|
`ess_min_soc_limit` = 20 %, SOC = 50 % ⇒
|
||||||
|
`ess_batterylife_state` = `self_consumption_soc_above_min`. Au-dessus du SOC
|
||||||
|
minimal, l'ESS fait servir la batterie et ignore le réseau. Le pic à 1 450 W
|
||||||
|
était le transitoire de reprise, pas le régime : en 50 s le régulateur a rendu
|
||||||
|
la charge à la batterie en convergeant vers les 50 W.
|
||||||
|
|
||||||
|
Preuve indépendante, à 01:49 sans voiture : contacteur fermé, maison 761 W,
|
||||||
|
tuile Réseau « – », **batterie −803 W**. Le réseau était branché et inerte.
|
||||||
|
|
||||||
|
**Le garde a eu raison** : la pente était monotone, sa fin était « la batterie
|
||||||
|
porte la voiture toute la nuit ». Le neutraliser aurait été pire.
|
||||||
|
|
||||||
|
**Et la consigne à 4 200 W du propriétaire était PORTEUSE** : c'est elle qui
|
||||||
|
faisait fonctionner toute la mécanique de prise de relais nocturne (P4/P7).
|
||||||
|
J'avais écrit en la retirant que le besoin couvert restait entier et devait être
|
||||||
|
repris ailleurs ; je ne l'avais pas repris. Règle qui en découle, désormais en
|
||||||
|
mémoire : ne jamais retirer un de ces contournements avant d'avoir mis son
|
||||||
|
remplaçant adaptable en production.
|
||||||
|
|
||||||
|
### Correctif (déployé 01/09 02:10, golden 56/56)
|
||||||
|
Le contrôleur écrit lui-même `number.gx_device_ac_power_setpoint`.
|
||||||
|
|
||||||
|
- **Snapshot** : `grid_setpoint_w`, `grid_setpoint_idle_w` (helper optionnel
|
||||||
|
`input_number.evcs_grid_setpoint_idle_w`, absent → 50 W, le défaut Victron).
|
||||||
|
- **INPUT_PARSE** : `parsed.gridSetpointW`, `params.gridSetpointIdleW` [0, 500].
|
||||||
|
- **HA_SERVICE_CALLS_OUTPUT** :
|
||||||
|
`gridSessionActive = acInAvailable && sourceMode ∈ {grid_forced, grid_hc_allowed}`
|
||||||
|
— donc P7 nuit, P9 départ et `force_grid_now`, et rien d'autre.
|
||||||
|
Besoin = `houseNonEvcsW + physicalCapA × acVoltageRef` : une grandeur
|
||||||
|
**mesurée**, pas une constante. Hors session, retour à la valeur de repos.
|
||||||
|
- **BUILD_ACTIONS** : appel `grid_power_setpoint` (`number.set_value`).
|
||||||
|
- Trace `Consigne reseau=XW` dans la raison pendant une session.
|
||||||
|
|
||||||
|
**La bande d'écriture est ASYMÉTRIQUE, et c'est le point.** Une consigne trop
|
||||||
|
basse fait porter la différence par la batterie — c'est le défaut de cette nuit,
|
||||||
|
corrigé sans attendre. Une consigne trop haute ne coûte rien : l'ESS ne prélève
|
||||||
|
que ce qu'il peut placer. On écrit donc avec une marge d'**un pas de courant
|
||||||
|
EVCS** (`currentStepUpA × acVoltageRef` ≈ 230 W — grandeur du système, pas un
|
||||||
|
chiffre inventé) et on ne redescend qu'au-delà de deux marges. Première version
|
||||||
|
sans cette asymétrie : réécriture toutes les 30 s en poursuivant le bruit de la
|
||||||
|
maison. Après : **deux écritures en 25 minutes**.
|
||||||
|
|
||||||
|
⚠️ **Deux leviers, deux rôles, à ne pas confondre** : la consigne dit ce que le
|
||||||
|
réseau a le DROIT de servir ; **DVCC (Auto Charge Manager) dit ce que la batterie
|
||||||
|
a le droit de prendre**. C'est DVCC à 2 A qui empêche une consigne généreuse de
|
||||||
|
gaver la batterie pendant un `evcs_takeover_hold`, et c'est DVCC à 30 A qui
|
||||||
|
autorise la recharge pendant un `evcs_takeover_recover`. Le couple se compose
|
||||||
|
correctement, mais la générosité de la consigne DÉPEND de ce cap : ne pas
|
||||||
|
supprimer l'un sans revoir l'autre.
|
||||||
|
|
||||||
|
### Golden 51 → 56
|
||||||
|
`summarize()` expose `gridSetpointW` (valeur écrite ce cycle, `null` si aucune
|
||||||
|
écriture). Scénarios : session HC → 5 525 W · contrefactuel hors session → 50 W ·
|
||||||
|
consigne déjà généreuse (5 600) → aucune écriture · **consigne 45 W sous le
|
||||||
|
besoin → correction immédiate** (le défaut de la nuit) · dérive externe à
|
||||||
|
4 000 W hors session → ramenée à 50 W.
|
||||||
|
Preuve par mutation : consigne figée au repos → 2 échecs ciblés ; branche
|
||||||
|
« trop basse » neutralisée → 1 échec ciblé ; restauration → 56/56.
|
||||||
|
|
||||||
|
### Vérification en réel
|
||||||
|
02:10 → 02:13, contacteur fermé : grid 4 350 W, **batterie ~0 A**, EVCS 3 500 W,
|
||||||
|
SOC stable à 49 %, consigne écrite à 5 276 puis 5 616 W. La voiture charge sur
|
||||||
|
le réseau en HC sans toucher à la réserve — ce que P7 était censé faire depuis
|
||||||
|
le 07/08 et qui ne tenait que par un réglage manuel.
|
||||||
|
|
||||||
|
### Risque résiduel assumé
|
||||||
|
Si le contrôleur s'arrête en pleine session (SPOF Synology, cf. §3), la consigne
|
||||||
|
reste haute et la substitution de journée peut revenir. C'est le même mode de
|
||||||
|
défaillance que le reste de la chaîne, mais il est nouveau pour ce paramètre :
|
||||||
|
à reprendre le jour où le SPOF sera traité.
|
||||||
|
|
||||||
|
### Non fait volontairement
|
||||||
|
La fenêtre d'établissement (§29) ne couvre que le chemin solaire ; les gardes
|
||||||
|
réseau ne sont pas gardés. Ce n'est pas la cause de cet incident et, la consigne
|
||||||
|
étant désormais correcte, le transitoire observé au redémarrage de 01:58 était
|
||||||
|
de 20 s avec la batterie à −1,6 A. À traiter séparément si un cas se présente.
|
||||||
|
|
||||||
|
---
|
||||||
|
*Document mis à jour le : 01/09/2026 (~02:15) — consigne de puissance réseau pilotée par le contrôleur, golden 56/56, charge HC vérifiée en réel*
|
||||||
|
|||||||
@@ -124,6 +124,17 @@ pushAction(
|
|||||||
context.sourceMode === 'grid_hc_allowed' || context.sourceMode === 'grid_forced'
|
context.sourceMode === 'grid_hc_allowed' || context.sourceMode === 'grid_forced'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// CONSIGNE DE PUISSANCE RESEAU
|
||||||
|
// Fermer le contacteur ne suffit pas : sans consigne, l'ESS laisse la
|
||||||
|
// batterie porter la maison et la voiture (nuit du 01/09/2026).
|
||||||
|
// =====================================================
|
||||||
|
pushAction(
|
||||||
|
'grid_power_setpoint',
|
||||||
|
calls.grid_power_setpoint,
|
||||||
|
!!calls.grid_power_setpoint?.execute
|
||||||
|
);
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// AUTO START OFF SI BESOIN
|
// AUTO START OFF SI BESOIN
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
// Bornes de la consigne de puissance reseau. Le maximum est celui declare par
|
||||||
|
// l'entite elle-meme (number.airtria_mpii_v1_ac_power_setpoint_l1, max 10000 W),
|
||||||
|
// pas un chiffre choisi ici. La bande morte evite de reecrire la meme valeur
|
||||||
|
// toutes les 30 s sans empecher la correction d'une derive externe.
|
||||||
|
const GRID_SETPOINT_MAX_W = 10000;
|
||||||
|
const GRID_SETPOINT_DEADBAND_W = 100;
|
||||||
|
|
||||||
function round1(v) {
|
function round1(v) {
|
||||||
return Math.round(v * 10) / 10;
|
return Math.round(v * 10) / 10;
|
||||||
}
|
}
|
||||||
@@ -309,6 +316,67 @@ reason.push(`SOC=${round1(parsed.soc)}%`);
|
|||||||
reason.push(`Batt=${round1(parsed.batteryCurrentA)}A`);
|
reason.push(`Batt=${round1(parsed.batteryCurrentA)}A`);
|
||||||
reason.push(`PV=${Math.round(parsed.pvPowerW)}W`);
|
reason.push(`PV=${Math.round(parsed.pvPowerW)}W`);
|
||||||
reason.push(`PV10=${Math.round(parsed.pvPowerAvg10mW)}W`);
|
reason.push(`PV10=${Math.round(parsed.pvPowerAvg10mW)}W`);
|
||||||
|
// =====================================================
|
||||||
|
// CONSIGNE DE PUISSANCE RESEAU (01/09/2026)
|
||||||
|
// =====================================================
|
||||||
|
// Fermer le contacteur ne suffit PAS. Au-dessus du SOC minimal, l'ESS en
|
||||||
|
// autoconsommation ne preleve que `ac_power_setpoint` et laisse la batterie
|
||||||
|
// porter tout le reste : nuit du 01/09, contacteur ferme, consigne 50 W,
|
||||||
|
// batterie a -803 W pour 761 W de maison, voiture arretee par le garde
|
||||||
|
// "batterie trop sollicitee". La consigne est donc le levier qui rend une
|
||||||
|
// session reseau REELLE, et il doit appartenir au controleur, pas rester un
|
||||||
|
// reglage manuel permanent (celui-ci provoquait la substitution du solaire
|
||||||
|
// par le reseau en journee, cf. HANDOFF 27/28).
|
||||||
|
//
|
||||||
|
// La valeur n'est pas une constante : c'est le besoin mesure du moment, la
|
||||||
|
// maison telle qu'elle consomme plus la voiture au courant que le controleur
|
||||||
|
// s'autorise. Le plafond joue le role de marge : quand la voiture n'est pas a
|
||||||
|
// son plafond, la consigne est deja genereuse, et l'exces ne peut pas partir
|
||||||
|
// dans la batterie (DVCC tenue a 2 A par l'Auto Charge Manager pendant un
|
||||||
|
// takeover). Hors session, retour a la valeur de repos.
|
||||||
|
const gridSessionActive =
|
||||||
|
parsed.acInAvailable &&
|
||||||
|
(context.sourceMode === 'grid_forced' || context.sourceMode === 'grid_hc_allowed');
|
||||||
|
|
||||||
|
const gridSetpointNeedW = gridSessionActive
|
||||||
|
? clamp(
|
||||||
|
Math.round(derived.houseNonEvcsW + derived.physicalCapA * derived.acVoltageRef),
|
||||||
|
params.gridSetpointIdleW,
|
||||||
|
GRID_SETPOINT_MAX_W
|
||||||
|
)
|
||||||
|
: params.gridSetpointIdleW;
|
||||||
|
|
||||||
|
// La bande est ASYMETRIQUE, et c'est le point. Une consigne trop BASSE fait
|
||||||
|
// porter la difference par la batterie : c'est le defaut de la nuit du 01/09,
|
||||||
|
// il se corrige immediatement. Une consigne trop HAUTE ne coute rien : l'ESS
|
||||||
|
// ne preleve que ce qu'il peut placer, et le courant de charge de la batterie
|
||||||
|
// est tenu par ailleurs (DVCC, Auto Charge Manager). Deux leviers, deux roles
|
||||||
|
// -- la consigne dit ce que le reseau a le DROIT de servir, DVCC dit ce que la
|
||||||
|
// batterie a le droit de prendre. Ne pas confondre les deux.
|
||||||
|
//
|
||||||
|
// On ecrit donc avec une marge d'un pas de courant EVCS (grandeur du systeme,
|
||||||
|
// pas une constante inventee) pour que le bruit de la maison ne rende pas la
|
||||||
|
// consigne insuffisante au cycle suivant, et on ne redescend que si elle est
|
||||||
|
// devenue franchement inutile. Sans cela la boucle 30 s reecrivait a chaque
|
||||||
|
// cycle en poursuivant le bruit.
|
||||||
|
const gridSetpointSlackW = gridSessionActive
|
||||||
|
? Math.max(GRID_SETPOINT_DEADBAND_W, Math.round(params.currentStepUpA * derived.acVoltageRef))
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
const gridSetpointTargetW = clamp(
|
||||||
|
gridSetpointNeedW + gridSetpointSlackW,
|
||||||
|
0,
|
||||||
|
GRID_SETPOINT_MAX_W
|
||||||
|
);
|
||||||
|
|
||||||
|
const gridSetpointCurrentW = Number.isFinite(parsed.gridSetpointW)
|
||||||
|
? parsed.gridSetpointW
|
||||||
|
: null;
|
||||||
|
const gridSetpointNeedsWrite =
|
||||||
|
gridSetpointCurrentW === null ||
|
||||||
|
gridSetpointCurrentW < gridSetpointNeedW ||
|
||||||
|
gridSetpointCurrentW > gridSetpointNeedW + 2 * gridSetpointSlackW + GRID_SETPOINT_DEADBAND_W;
|
||||||
|
|
||||||
reason.push(`Grid=${parsed.gridAvailable ? 'on' : 'off'} (${Math.round(parsed.gridPowerW)}W)`);
|
reason.push(`Grid=${parsed.gridAvailable ? 'on' : 'off'} (${Math.round(parsed.gridPowerW)}W)`);
|
||||||
// Trace de la fenetre d'etablissement : sans elle, une lecture du logbook
|
// Trace de la fenetre d'etablissement : sans elle, une lecture du logbook
|
||||||
// pendant le transitoire donne l'impression que le systeme decide n'importe
|
// pendant le transitoire donne l'impression que le systeme decide n'importe
|
||||||
@@ -316,6 +384,9 @@ reason.push(`Grid=${parsed.gridAvailable ? 'on' : 'off'} (${Math.round(parsed.gr
|
|||||||
if (derived.gridSettling) {
|
if (derived.gridSettling) {
|
||||||
reason.push(`ETABLISSEMENT reseau ${Math.round(parsed.gridTransitionAgeSec)}s/${params.gridSettleSeconds}s (mesures PV/batterie non fiables)`);
|
reason.push(`ETABLISSEMENT reseau ${Math.round(parsed.gridTransitionAgeSec)}s/${params.gridSettleSeconds}s (mesures PV/batterie non fiables)`);
|
||||||
}
|
}
|
||||||
|
if (gridSessionActive) {
|
||||||
|
reason.push(`Consigne reseau=${gridSetpointTargetW}W`);
|
||||||
|
}
|
||||||
reason.push(`Cap=${derived.physicalCapA}A`);
|
reason.push(`Cap=${derived.physicalCapA}A`);
|
||||||
reason.push(`Ref=${round1(derived.currentReferenceA)}A`);
|
reason.push(`Ref=${round1(derived.currentReferenceA)}A`);
|
||||||
reason.push(`Target=${round1(desiredCurrentA)}A`);
|
reason.push(`Target=${round1(desiredCurrentA)}A`);
|
||||||
@@ -1001,6 +1072,16 @@ return [{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
grid_power_setpoint: {
|
||||||
|
execute: gridSetpointNeedsWrite,
|
||||||
|
domain: 'number',
|
||||||
|
service: 'set_value',
|
||||||
|
data: {
|
||||||
|
entity_id: 'number.gx_device_ac_power_setpoint',
|
||||||
|
value: gridSetpointTargetW
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
evcs_auto_start_off: {
|
evcs_auto_start_off: {
|
||||||
execute: autoStartAction === 'turn_off',
|
execute: autoStartAction === 'turn_off',
|
||||||
domain: 'switch',
|
domain: 'switch',
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
"acin1_last_changed_ts": as_timestamp(states.sensor.victron_ac_in1_available.last_changed, 0) if states.sensor.victron_ac_in1_available is not none else 0,
|
"acin1_last_changed_ts": as_timestamp(states.sensor.victron_ac_in1_available.last_changed, 0) if states.sensor.victron_ac_in1_available is not none else 0,
|
||||||
"grid_switch_last_changed_ts": as_timestamp(states.switch.edf_general_ok_switch.last_changed, 0) if states.switch.edf_general_ok_switch is not none else 0,
|
"grid_switch_last_changed_ts": as_timestamp(states.switch.edf_general_ok_switch.last_changed, 0) if states.switch.edf_general_ok_switch is not none else 0,
|
||||||
"grid_settle_seconds": states("input_number.evcs_grid_settle_seconds"),
|
"grid_settle_seconds": states("input_number.evcs_grid_settle_seconds"),
|
||||||
|
"grid_setpoint_w": states("number.gx_device_ac_power_setpoint"),
|
||||||
|
"grid_setpoint_idle_w": states("input_number.evcs_grid_setpoint_idle_w"),
|
||||||
|
|
||||||
"today_remaining_kwh": states("sensor.energy_production_today_remaining"),
|
"today_remaining_kwh": states("sensor.energy_production_today_remaining"),
|
||||||
"tomorrow_kwh": states("sensor.energy_production_tomorrow"),
|
"tomorrow_kwh": states("sensor.energy_production_tomorrow"),
|
||||||
|
|||||||
@@ -245,6 +245,13 @@ const parsed = {
|
|||||||
|
|
||||||
gridIsOn: low(input.grid_state || 'off') === 'on',
|
gridIsOn: low(input.grid_state || 'off') === 'on',
|
||||||
acInAvailable: num(input.victron_acin1_available ?? input.ac_in1_available, 0) === 1,
|
acInAvailable: num(input.victron_acin1_available ?? input.ac_in1_available, 0) === 1,
|
||||||
|
|
||||||
|
// Consigne de puissance réseau de l'ESS, lue telle qu'elle est appliquée.
|
||||||
|
// C'est ELLE qui décide si un contacteur fermé sert à quelque chose : au-dessus
|
||||||
|
// du SOC minimal, l'ESS en autoconsommation ne prélève que cette puissance et
|
||||||
|
// laisse la batterie porter le reste. Nuit du 01/09 : contacteur fermé,
|
||||||
|
// consigne 50 W, batterie à -803 W pour 761 W de maison.
|
||||||
|
gridSetpointW: num(input.grid_setpoint_w, NaN),
|
||||||
gridAvailable:
|
gridAvailable:
|
||||||
(low(input.grid_state || 'off') === 'on') ||
|
(low(input.grid_state || 'off') === 'on') ||
|
||||||
(num(input.victron_acin1_available ?? input.ac_in1_available, 0) === 1),
|
(num(input.victron_acin1_available ?? input.ac_in1_available, 0) === 1),
|
||||||
@@ -419,6 +426,10 @@ const params = {
|
|||||||
// input_number.evcs_grid_settle_seconds ; absent => 180.
|
// input_number.evcs_grid_settle_seconds ; absent => 180.
|
||||||
gridSettleSeconds: clamp(num(input.grid_settle_seconds, 180), 0, 900),
|
gridSettleSeconds: clamp(num(input.grid_settle_seconds, 180), 0, 900),
|
||||||
|
|
||||||
|
// Consigne réseau au repos. 50 W est le défaut Victron (légèrement positif
|
||||||
|
// pour ne jamais injecter), pas une valeur choisie ici.
|
||||||
|
gridSetpointIdleW: clamp(num(input.grid_setpoint_idle_w, 50), 0, 500),
|
||||||
|
|
||||||
probeEnabled: low(input.probe_enabled || 'off') === 'on',
|
probeEnabled: low(input.probe_enabled || 'off') === 'on',
|
||||||
probeMinutes: Math.max(1, num(input.probe_minutes, 3)),
|
probeMinutes: Math.max(1, num(input.probe_minutes, 3)),
|
||||||
probeRetryMinutes: Math.max(5, num(input.probe_retry_minutes, 45)),
|
probeRetryMinutes: Math.max(5, num(input.probe_retry_minutes, 45)),
|
||||||
|
|||||||
@@ -116,6 +116,10 @@ function summarize(out) {
|
|||||||
takeoverNeeded: !!c.night_grid_takeover_needed,
|
takeoverNeeded: !!c.night_grid_takeover_needed,
|
||||||
edfOnAction: !!calls.edf_general_ok_on?.execute,
|
edfOnAction: !!calls.edf_general_ok_on?.execute,
|
||||||
takeoverHelperService: calls.helper_night_grid_takeover_needed?.service || null,
|
takeoverHelperService: calls.helper_night_grid_takeover_needed?.service || null,
|
||||||
|
// Consigne de puissance reseau ecrite ce cycle (null = aucune ecriture).
|
||||||
|
gridSetpointW: calls.grid_power_setpoint?.execute
|
||||||
|
? calls.grid_power_setpoint.data.value
|
||||||
|
: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1306,4 +1306,92 @@ export const scenarios = [
|
|||||||
takeoverHelperService: "turn_off",
|
takeoverHelperService: "turn_off",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ===================================================================
|
||||||
|
// CONSIGNE DE PUISSANCE RESEAU (01/09/2026)
|
||||||
|
// Fermer le contacteur ne suffit pas : au-dessus du SOC minimal, l'ESS en
|
||||||
|
// autoconsommation ne preleve que `ac_power_setpoint` et laisse la batterie
|
||||||
|
// porter maison + voiture. Incident de la nuit du 01/09 : consigne a 50 W,
|
||||||
|
// charge HC demarree puis arretee en 60 s par le garde batterie.
|
||||||
|
// ===================================================================
|
||||||
|
{
|
||||||
|
id: 'consigne-session-hc-reseau-porte-la-charge',
|
||||||
|
label: 'Nuit HC, reseau present, session reseau : la consigne monte au besoin mesure (maison hors EVCS + voiture au plafond)',
|
||||||
|
time: NIGHT,
|
||||||
|
overrides: {
|
||||||
|
...VEHICLE_NIGHT,
|
||||||
|
soc_percent: '50',
|
||||||
|
allow_grid_hc_night: 'on',
|
||||||
|
grid_state: 'on',
|
||||||
|
victron_acin1_available: '1',
|
||||||
|
grid_setpoint_w: '50',
|
||||||
|
},
|
||||||
|
expect: {
|
||||||
|
sourceMode: 'grid_hc_allowed',
|
||||||
|
gridSetpointW: 5525,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'consigne-hors-session-retour-au-repos',
|
||||||
|
label: 'CONTREFACTUEL — meme nuit sans session reseau : la consigne redescend a la valeur de repos',
|
||||||
|
time: NIGHT,
|
||||||
|
overrides: {
|
||||||
|
...VEHICLE_NIGHT,
|
||||||
|
soc_percent: '50',
|
||||||
|
allow_grid_hc_night: 'off',
|
||||||
|
grid_state: 'off',
|
||||||
|
victron_acin1_available: '0',
|
||||||
|
grid_setpoint_w: '4000',
|
||||||
|
},
|
||||||
|
expect: {
|
||||||
|
gridSetpointW: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'consigne-deja-genereuse-aucune-ecriture',
|
||||||
|
label: 'Session reseau, consigne a 5600 W pour un besoin de 5295 W : deja suffisante, aucune reecriture (le bruit de la maison ne la fait pas courir)',
|
||||||
|
time: NIGHT,
|
||||||
|
overrides: {
|
||||||
|
...VEHICLE_NIGHT,
|
||||||
|
soc_percent: '50',
|
||||||
|
allow_grid_hc_night: 'on',
|
||||||
|
grid_state: 'on',
|
||||||
|
victron_acin1_available: '1',
|
||||||
|
grid_setpoint_w: '5600',
|
||||||
|
},
|
||||||
|
expect: {
|
||||||
|
gridSetpointW: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'consigne-insuffisante-corrigee-immediatement',
|
||||||
|
label: "LE DEFAUT DE LA NUIT DU 01/09 — consigne 45 W sous le besoin : la batterie porterait la difference, correction sans attendre",
|
||||||
|
time: NIGHT,
|
||||||
|
overrides: {
|
||||||
|
...VEHICLE_NIGHT,
|
||||||
|
soc_percent: '50',
|
||||||
|
allow_grid_hc_night: 'on',
|
||||||
|
grid_state: 'on',
|
||||||
|
victron_acin1_available: '1',
|
||||||
|
grid_setpoint_w: '5250',
|
||||||
|
},
|
||||||
|
expect: {
|
||||||
|
sourceMode: 'grid_hc_allowed',
|
||||||
|
gridSetpointW: 5525,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'consigne-derive-externe-corrigee',
|
||||||
|
label: 'Hors session mais consigne laissee a 4000 W par un tiers : corrigee au cycle suivant',
|
||||||
|
time: MORNING,
|
||||||
|
overrides: {
|
||||||
|
soc_percent: '60',
|
||||||
|
grid_state: 'off',
|
||||||
|
victron_acin1_available: '0',
|
||||||
|
grid_setpoint_w: '4000',
|
||||||
|
},
|
||||||
|
expect: {
|
||||||
|
gridSetpointW: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user