Controleur : trois ecritures jamais relayees (budget, verrou P12, reset borne) + garde-fou ; verrou P12 leve en fin de session
This commit is contained in:
29
HANDOFF.md
29
HANDOFF.md
@@ -1317,5 +1317,32 @@ autoriser une charge complete avec EDF.** Decisions (30/09) : profil **prudent +
|
|||||||
integration de la puissance, le compteur fait foi). Charge dans Grafana, requetes OK
|
integration de la puissance, le compteur fait foi). Charge dans Grafana, requetes OK
|
||||||
(la courbe « donne » se remplit a partir de 01:24).
|
(la courbe « donne » se remplit a partir de 01:24).
|
||||||
|
|
||||||
|
### 01/10 matin — Premiere nuit du budget : il n'a pas joue, et deux defauts anciens
|
||||||
|
**Constat** : JEEP chargee de 01:25 a 06:37 en « Assistance batterie nuit », **7,5 kWh**
|
||||||
|
(pleine, 8,9 kWh au compteur depuis 17:29) ; batterie 64 % a 01:00 -> 37 % a 06:00 ; EDF
|
||||||
|
ferme **06:00 -> 06:38** (2,15 kWh importes, HC). Mode sans_edf, budget publie 5,93 kWh a
|
||||||
|
01:25.
|
||||||
|
1. **Le budget n'a jamais ete fige** : `input_text.victron_evcs_night_budget` est reste
|
||||||
|
« unknown ». Cause : « Build EVCS Surplus Controller V2.0 Actions » ne relaie QUE les
|
||||||
|
appels qu'il nomme. **Trois ecritures produites n'etaient jamais executees** : le budget
|
||||||
|
(30/09), le **verrou P12 `night_battery_done` (depuis le 15/09)** et l'acquittement du
|
||||||
|
bouton reset borne (depuis le 19/09). Les golden s'arretent a HA_SERVICE_CALLS_OUTPUT et ne
|
||||||
|
le voyaient pas. Corrige (`src/nodes/BUILD_ACTIONS.js`) + **garde-fou golden
|
||||||
|
`build-actions-transmet-tout`** (tout appel produit doit etre nomme dans le Build : 51/51,
|
||||||
|
echouait sur les trois avant).
|
||||||
|
2. **Le verrou P12 ne se relachait jamais** (`prev || …`) : invisible tant qu'il n'etait pas
|
||||||
|
ecrit ; avec l'ecriture retablie, P12 serait mort pour toutes les nuits suivantes. Il ne
|
||||||
|
vaut plus que pendant la session de nuit. Golden **132/132** (+2 : verrou pose au budget,
|
||||||
|
leve en fin de session), mutation qui mord. Deploye 07:22 ; **verifie en reel** : budget
|
||||||
|
fige « 2,76|4016,2 » a 07:23 (fin de fenetre, JEEP pleine, sans effet), efface a 07:24.
|
||||||
|
3. **EDF a 06:00 = faux positif de `batteryRecoveryUrgent`** (WINDOWS_SOURCEV2 l.390) : depart
|
||||||
|
JEEP du matin `input_datetime.victron_evcs_departure_time_jeep` = 06:30, marge
|
||||||
|
`evcs_night_departure_safety_min` = 30 min -> a 06:00, 0 min de recharge necessaire + 30
|
||||||
|
>= 30 = « urgent », alors qu'il manquait **0 kWh** (SOC 37 > cible 35). `grid_forced` :
|
||||||
|
maison ET voiture sur EDF. **Recurrent** : fermeture vers 06:00 les 21, 22, 25, 27/09 et
|
||||||
|
01/10. Mon exception « EDF deja engage pour la batterie » l'a laisse passer en sans_edf.
|
||||||
|
Correctif propose (exiger un manque > 0), **decision du proprietaire en attente**, ainsi
|
||||||
|
que la realite du depart de la JEEP a 06:30.
|
||||||
|
|
||||||
---
|
---
|
||||||
*Document mis a jour le : 30/09/2026 (~18:30) — commande vocale du mode de nuit validee, premiere nuit budget a suivre ; budget voiture de la nuit sans EDF (bilan + controleur) ; fiche de l'agent allegee (25 831 car.), concierge sans silence, calendrier JEEP mar/sam ; nuit du 28-29 verifiee, achat EDF annonce = maison en HC + manque batterie ; regle HC active, vehicule branche a midi (JEEP/VW/ZERO), prevision de nuit a trois verdicts, nuits superposees et bilan recale sur la soiree*
|
*Document mis a jour le : 01/10/2026 (~07:35) — premiere nuit du budget : ecritures perdues et verrou P12 corriges, faux positif de depart a 06:00 ; commande vocale du mode de nuit validee, premiere nuit budget a suivre ; budget voiture de la nuit sans EDF (bilan + controleur) ; fiche de l'agent allegee (25 831 car.), concierge sans silence, calendrier JEEP mar/sam ; nuit du 28-29 verifiee, achat EDF annonce = maison en HC + manque batterie ; regle HC active, vehicule branche a midi (JEEP/VW/ZERO), prevision de nuit a trois verdicts, nuits superposees et bilan recale sur la soiree*
|
||||||
|
|||||||
@@ -127,6 +127,34 @@ pushAction(
|
|||||||
!!calls.helper_evcs_no_demand_filter_eval_at?.execute
|
!!calls.helper_evcs_no_demand_filter_eval_at?.execute
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// ECRITURES CONDITIONNELLES OUBLIEES (01/10/2026)
|
||||||
|
// Produites par HA_SERVICE_CALLS_OUTPUT mais jamais relayees jusqu'ici :
|
||||||
|
// - verrou P12 (`night_battery_done`, une seule passe sur batterie) depuis
|
||||||
|
// le 15/09 ;
|
||||||
|
// - acquittement du bouton reset borne (momentane) depuis le 19/09 ;
|
||||||
|
// - budget voiture de la nuit fige (30/09) : la nuit du 30/09 la JEEP a pris
|
||||||
|
// 7,5 kWh sur la batterie au lieu du budget.
|
||||||
|
// Garde-fou : tests/golden/run.mjs verifie que tout appel produit est nomme ici.
|
||||||
|
// =====================================================
|
||||||
|
pushAction(
|
||||||
|
'helper_night_battery_done',
|
||||||
|
calls.helper_night_battery_done,
|
||||||
|
!!calls.helper_night_battery_done?.execute
|
||||||
|
);
|
||||||
|
|
||||||
|
pushAction(
|
||||||
|
'helper_reset_borne_ack',
|
||||||
|
calls.helper_reset_borne_ack,
|
||||||
|
!!calls.helper_reset_borne_ack?.execute
|
||||||
|
);
|
||||||
|
|
||||||
|
pushAction(
|
||||||
|
'helper_night_budget',
|
||||||
|
calls.helper_night_budget,
|
||||||
|
!!calls.helper_night_budget?.execute
|
||||||
|
);
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// DEMANDE RÉSEAU EDF SI SOURCE GRID
|
// DEMANDE RÉSEAU EDF SI SOURCE GRID
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|||||||
@@ -659,10 +659,16 @@ const nightBudgetReached =
|
|||||||
nightBudgetDeliveredKwh >= nightBudget.budgetKwh - 0.05;
|
nightBudgetDeliveredKwh >= nightBudget.budgetKwh - 0.05;
|
||||||
const nightChargeComplete = params.nightChargeMode === 'complete';
|
const nightChargeComplete = params.nightChargeMode === 'complete';
|
||||||
|
|
||||||
|
// Le verrou ne vaut QUE pendant la session de nuit (01/10/2026). Ecrit sous la
|
||||||
|
// forme `prev || …`, il restait vrai pour toujours une fois pose ; invisible
|
||||||
|
// tant que son ecriture n'atteignait pas HA (jamais relayee du 15/09 au 01/10).
|
||||||
|
// Fin de session (debranchement ou fin de fenetre HC) = verrou leve.
|
||||||
const nightBatterySurplusExhausted =
|
const nightBatterySurplusExhausted =
|
||||||
params.nightBatteryDonePrev ||
|
nightSessionActive && (
|
||||||
(nightSessionActive && parsed.soc <= nightBatterySurplusFloorPct) ||
|
params.nightBatteryDonePrev ||
|
||||||
(nightSessionActive && nightBudgetReached);
|
parsed.soc <= nightBatterySurplusFloorPct ||
|
||||||
|
nightBudgetReached
|
||||||
|
);
|
||||||
|
|
||||||
const nightBatterySurplusAvailable =
|
const nightBatterySurplusAvailable =
|
||||||
nightSessionActive &&
|
nightSessionActive &&
|
||||||
|
|||||||
@@ -40,6 +40,22 @@ const nodeCode = Object.fromEntries(
|
|||||||
CHAIN.map(n => [n, wf.nodes.find(x => x.name === n).parameters.jsCode])
|
CHAIN.map(n => [n, wf.nodes.find(x => x.name === n).parameters.jsCode])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// GARDE-FOU (01/10/2026) : tout appel produit par HA_SERVICE_CALLS_OUTPUT doit
|
||||||
|
// etre transmis par « Build … Actions », qui ne relaie QUE les appels qu'il
|
||||||
|
// nomme. Trois ecritures ne partaient jamais (le verrou P12 depuis le 15/09,
|
||||||
|
// l'acquittement du bouton reset borne, le budget voiture du 30/09) : les
|
||||||
|
// scenarios s'arretent a HA_SERVICE_CALLS_OUTPUT et ne pouvaient pas le voir.
|
||||||
|
const BUILD_CODE = wf.nodes.find(x => x.name === 'Build EVCS Surplus Controller V2.0 Actions').parameters.jsCode;
|
||||||
|
const appelsProduits = [...nodeCode.HA_SERVICE_CALLS_OUTPUT.matchAll(/^ {6}([a-z_0-9]+): \{/gm)].map(m => m[1]);
|
||||||
|
const appelsPerdus = [...new Set(appelsProduits)].filter(n => !BUILD_CODE.includes(`'${n}'`));
|
||||||
|
let gardeFou = 0;
|
||||||
|
if (appelsPerdus.length) {
|
||||||
|
gardeFou = 1;
|
||||||
|
console.log(`❌ build-actions-transmet-tout | appels produits mais jamais executes : ${appelsPerdus.join(', ')}`);
|
||||||
|
} else {
|
||||||
|
console.log(`✅ build-actions-transmet-tout (${new Set(appelsProduits).size} appels)`);
|
||||||
|
}
|
||||||
|
|
||||||
// Horloge simulée : Date épinglée à l'instant du scénario dans la sandbox.
|
// Horloge simulée : Date épinglée à l'instant du scénario dans la sandbox.
|
||||||
function makeFakeDate(fixedMs) {
|
function makeFakeDate(fixedMs) {
|
||||||
return class FakeDate extends Date {
|
return class FakeDate extends Date {
|
||||||
@@ -122,6 +138,8 @@ function summarize(out) {
|
|||||||
sessionCommittedService: calls.helper_night_grid_session_committed?.execute
|
sessionCommittedService: calls.helper_night_grid_session_committed?.execute
|
||||||
? calls.helper_night_grid_session_committed.service
|
? calls.helper_night_grid_session_committed.service
|
||||||
: null,
|
: null,
|
||||||
|
// Verrou P12 : service ecrit ce cycle (turn_on/turn_off), null sinon.
|
||||||
|
nightBatteryDoneService: calls.helper_night_battery_done?.execute ? calls.helper_night_battery_done.service : null,
|
||||||
// Budget voiture de la nuit (30/09) : valeur ecrite ce cycle, null sinon.
|
// Budget voiture de la nuit (30/09) : valeur ecrite ce cycle, null sinon.
|
||||||
nightBudgetWrite: calls.helper_night_budget?.execute ? calls.helper_night_budget.data.value : null,
|
nightBudgetWrite: calls.helper_night_budget?.execute ? calls.helper_night_budget.data.value : null,
|
||||||
// Consigne de puissance reseau ecrite ce cycle (null = aucune ecriture).
|
// Consigne de puissance reseau ecrite ce cycle (null = aucune ecriture).
|
||||||
@@ -132,7 +150,7 @@ function summarize(out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const jsonResults = {};
|
const jsonResults = {};
|
||||||
let failures = 0, ran = 0;
|
let failures = gardeFou, ran = 0;
|
||||||
for (const sc of scenarios) {
|
for (const sc of scenarios) {
|
||||||
if (only && !sc.id.includes(only)) continue;
|
if (only && !sc.id.includes(only)) continue;
|
||||||
ran++;
|
ran++;
|
||||||
|
|||||||
@@ -3132,6 +3132,21 @@ export const scenarios = [
|
|||||||
expect: { sourceMode: 'blocked', desiredCharging: false, nightBudgetWrite: null,
|
expect: { sourceMode: 'blocked', desiredCharging: false, nightBudgetWrite: null,
|
||||||
takeoverNeeded: false, edfOnAction: false },
|
takeoverNeeded: false, edfOnAction: false },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'p12-verrou-pose-quand-le-budget-est-atteint',
|
||||||
|
label: 'Budget atteint en session : le verrou P12 est ecrit (une seule passe sur batterie)',
|
||||||
|
time: '2026-09-30T02:30:00+02:00',
|
||||||
|
overrides: { ...BUDGET_NUIT, ...EN_CHARGE_BATTERIE, balance_last_run: '30/09 02:25', soc_percent: '50',
|
||||||
|
night_charge_mode: 'sans_edf', night_budget_prev: '3.7|4000', evcs_total_energy_kwh: '4003.75' },
|
||||||
|
expect: { nightBatteryDoneService: 'turn_on' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'p12-verrou-leve-en-fin-de-session',
|
||||||
|
label: '08:00, verrou encore pose : il est leve (sinon la charge sur batterie mourait pour toutes les nuits suivantes)',
|
||||||
|
time: '2026-09-30T08:00:00+02:00',
|
||||||
|
overrides: { ...BUDGET_NUIT, balance_last_run: '30/09 07:55', night_battery_done_prev: 'on' },
|
||||||
|
expect: { nightBatteryDoneService: 'turn_off' },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'budget-efface-en-fin-de-session',
|
id: 'budget-efface-en-fin-de-session',
|
||||||
label: 'Fin de fenetre HC (08:00) : le budget fige est efface',
|
label: 'Fin de fenetre HC (08:00) : le budget fige est efface',
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user