Budget de nuit borne au plancher prudent ; sans EDF : voiture bloquee meme quand EDF se ferme pour la batterie (session batterie seule)

This commit is contained in:
Tallagrand Thierry
2026-10-04 06:09:39 +02:00
parent 09ab5ce771
commit 43b650ee51
9 changed files with 96 additions and 20 deletions

View File

@@ -460,7 +460,17 @@ if (nightHcActive && Number.isFinite(socPct)) {
if (coupes[i + 1] >= depuis) creux = Math.min(creux, reserve);
}
}
nightVehicleBudgetKwh = Number.isFinite(creux) ? Math.max(0, creux) : null;
// BORNE PAR LE PLANCHER PRUDENT (04/10/2026). Nuit du 03-04/10 : SOC 47,
// prudent 43,6 -> ~1,0 kWh de marge, mais le creux a donne 1,41 kWh. La
// voiture a pris toute la marge, la batterie a touche la cible du matin a
// 02:57 et la reprise reseau a ferme EDF. Le budget ne peut donc jamais
// depasser l'energie au-dessus du SOC requis PRUDENT, celui-la meme que la
// voiture n'a pas le droit de franchir en assistance batterie (P12) : les
// deux criteres sont desormais les memes par construction.
const margePrudente = Number.isFinite(prudent.requiredSocPct)
? (socPct > prudent.requiredSocPct ? energyBetweenSoc(prudent.requiredSocPct, socPct) : 0)
: 0;
nightVehicleBudgetKwh = Number.isFinite(creux) ? Math.max(0, Math.min(creux, margePrudente)) : null;
}
// ---------------------------------------------------------------------

View File

@@ -1134,6 +1134,7 @@ return [{
nightBudgetToWrite: nightPrev.nightBudgetToWrite ?? null,
nightChargeMode: nightPrev.nightChargeMode || 'sans_edf',
nightCarWaitsNoGrid: !!nightPrev.nightCarWaitsNoGrid,
nightBatteryGridOnly: !!nightPrev.nightBatteryGridOnly,
maxBatteryDischargePoints,
gridTakeoverTriggerPct,

View File

@@ -304,7 +304,8 @@ const reason = [...decision.reason];
if (night.nightBudgetKwh !== null && night.nightBudgetKwh !== undefined) {
const f = (x) => String(Math.round(x * 100) / 100).replace('.', ',');
reason.push(`Budget batterie nuit ${f(night.nightBudgetDeliveredKwh ?? 0)}/${f(night.nightBudgetKwh)} kWh` +
(night.nightCarWaitsNoGrid ? ' — atteint, sans EDF : la voiture attend le soleil'
(night.nightBatteryGridOnly ? ' — sans EDF : EDF ferme pour la batterie seule, la voiture attend le soleil'
: night.nightCarWaitsNoGrid ? ' — atteint, sans EDF : la voiture attend le soleil'
: night.nightBudgetReached ? ' — atteint, EDF finit la charge' : ''));
} else if (night.nightCarWaitsNoGrid) {
reason.push('Pas de budget batterie exploitable, sans EDF : la voiture attend le soleil');
@@ -365,7 +366,9 @@ const gridSessionActive =
(
context.sourceMode === 'grid_forced' ||
context.sourceMode === 'grid_hc_allowed' ||
night.nightGridSessionCommitted === true
night.nightGridSessionCommitted === true ||
// Batterie seule sur le reseau, voiture bloquee « sans EDF » (04/10).
night.nightBatteryGridOnly === true
);
// =====================================================
@@ -1471,7 +1474,8 @@ return [{
// =================================================
edf_general_ok_on: {
execute:
['grid_forced', 'grid_hc_allowed'].includes(context.sourceMode) &&
(['grid_forced', 'grid_hc_allowed'].includes(context.sourceMode) ||
night.nightBatteryGridOnly === true) &&
!parsed.gridAvailable,
domain: 'switch',
service: 'turn_on',

View File

@@ -859,11 +859,14 @@ const nightPreferredSourceMode =
? 'blocked'
: vehicleChargeCompleted
? 'blocked'
// « Sans EDF » ne bloque la voiture que si EDF n'est PAS deja engage pour
// la batterie (plancher dur, cible du matin, session du bilan, verrou) :
// proteger le materiel prime (regle du proprietaire, 05/09), et EDF deja
// ferme en HC, la voiture en profite au meme tarif.
: nightCarWaitsNoGrid && !nightGridTakeoverNeeded
// « Sans EDF » : la voiture ne prend JAMAIS le reseau la nuit, MEME quand
// EDF se ferme pour la batterie (plancher dur, cible du matin, session du
// bilan, verrou). Decision du proprietaire le 04/10 (option A) : la nuit du
// 03-04/10, EDF ferme a 02:57 pour la batterie, l'ancienne exception a
// laisse la JEEP prendre 4,7 kWh au reseau jusqu'au plein. La protection
// du materiel reste entiere : EDF se ferme quand meme (takeover), seule la
// voiture attend le soleil.
: nightCarWaitsNoGrid
? 'blocked'
: batteryAssistAllowed
? 'battery_assist_night'
@@ -875,6 +878,16 @@ const nightPreferredSourceMode =
? 'grid_forced'
: 'grid_hc_allowed';
// « Sans EDF » ET EDF necessaire pour la BATTERIE (04/10/2026, option A du
// proprietaire) : la voiture reste bloquee, mais la batterie a sa session
// reseau. Sans ce drapeau, la fermeture d'EDF et la consigne de recharge, qui
// suivent la source de la VOITURE, seraient perdues avec elle (golden
// budget-sans-edf-plancher-dur-edf-protege, depart-matin-…-sous-la-cible).
const nightBatteryGridOnly =
nightSessionActive &&
nightCarWaitsNoGrid &&
nightGridTakeoverNeeded;
const batteryRecoveryAllowedNow =
nightSessionActive &&
nightGridTakeoverNeeded &&
@@ -1265,6 +1278,7 @@ return [{
nightBudgetToWrite,
nightChargeMode: params.nightChargeMode,
nightCarWaitsNoGrid,
nightBatteryGridOnly,
nightGridSessionCommitted,
middayVehicleGridNeeded,
nightGridSessionUncovered,