Sequence d ouverture : baisser le courant avant que le reseau parte

Le plafond majore (28 A en BOOST) n est legitime que tant que le reseau alimente
AC-IN : sinon les deux MultiPlus portent seuls la voiture plus la maison, le
mecanisme du W-105. Personne ne baissait avant l ouverture -- c est l hysteresis
qui ouvre, l EVCS l apprenait apres coup -- et quand il l apprenait, la reduction
attendait le cooldown de courant et descendait d un pas a la fois.

Correctif sans poignee de main ni helper nouveau : le plafond majore exige que
l EVCS DEMANDE lui-meme le reseau. Sa demande tombe au cycle ou la fenetre se
ferme (30 s), l hysteresis ne peut ouvrir qu ensuite (override disparu PUIS
min_on, cycle 1 min) : l EVCS baisse toujours avant, mecaniquement.

Second volet : un plafond n est pas une cible qu on approche. Reduction
immediate et directe au plafond, sans cooldown.

Le calcul du plafond a ete deplace apres sourceMode dans WINDOWS_SOURCEV2 ; rien
entre les deux ne le lisait, verifie avant de bouger.

Helper a 20 A par defaut : comportement inchange. Le correctif ne mord que sur
le BOOST 28 A, le cas dangereux.

Golden 48 -> 51, chaque cas apparie a son contrefactuel. Mutations des deux
volets separement : 1 puis 2 echecs cibles, restauration 51/51.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
This commit is contained in:
Tallagrand Thierry
2026-08-31 20:03:23 +02:00
parent f0479945c4
commit fc49e6c31a
5 changed files with 238 additions and 32 deletions

View File

@@ -834,18 +834,20 @@ else if (cloud.sessionObservedActive) {
}
}
else if ((derived.currentReferenceA > derived.physicalCapA) && lifecycle.currentCooldownElapsed) {
// SÉQUENCE D'OUVERTURE (31/08/2026) : un plafond n'est pas une cible qu'on
// approche, c'est une limite qu'on respecte. Cette réduction attendait le
// cooldown de courant — un compteur de confort — et ne descendait que d'un
// pas à la fois : de 28 A à 20 A elle prenait plusieurs cooldowns, pendant
// lesquels les onduleurs portaient un courant qu'ils n'ont plus le droit de
// porter (le plafond retombe à la disparition du réseau). Désormais :
// descente IMMÉDIATE et DIRECTE au plafond. Réduire est toujours sûr ; c'est
// la montée qui doit être temporisée, et elle l'est.
else if (derived.currentReferenceA > derived.physicalCapA) {
setOn({
stateName: 'charging_step_down_system_cap',
decisionName: 'step_down',
currentA: Math.max(
params.currentMinA,
Math.min(
derived.currentReferenceA - Math.max(params.currentStepDownA, 2),
derived.physicalCapA
)
),
reasonText: 'Réduction pour respecter la capacité système',
decisionName: 'step_down_fast',
currentA: Math.max(params.currentMinA, derived.physicalCapA),
reasonText: `Réduction immédiate au plafond système ${derived.physicalCapA}A`,
dynamic: true,
mustStopFlag: false,
});

View File

@@ -117,25 +117,6 @@ const vebusNonEvcsW = Math.max(0, parsed.vebusAcOutPowerW - parsed.evcsAcPowerW)
const totalVebusSoftCeilingW = Math.max(6500, params.acLoadsMaxSafeW || 8500);
const totalVebusHardCeilingW = totalVebusSoftCeilingW + 400;
// P5 : plafond EVCS configurable quand le réseau alimente réellement AC-IN
// (input_number.evcs_plafond_courant_edf_on). Hors réseau : plafond câblé prudent.
const evcsDedicatedCapBaseW = Math.max(0, cfg.evcsDedicatedMaxW - cfg.systemReserveW);
const safeEvcsByDedicatedCapW = parsed.acInAvailable
? Math.max(0, params.gridCurrentMaxA * acVoltageRef)
: evcsDedicatedCapBaseW;
const safeEvcsByVebusW = Math.max(0, totalVebusSoftCeilingW - vebusNonEvcsW - cfg.systemReserveW);
const safeEvcsCombinedW = Math.max(0, Math.min(safeEvcsByDedicatedCapW, safeEvcsByVebusW));
const systemCapCurrentA = Math.max(0, Math.floor(safeEvcsCombinedW / acVoltageRef));
const physicalCapA = clamp(
systemCapCurrentA,
0,
parsed.acInAvailable
? Math.max(params.currentMaxAutoA, params.gridCurrentMaxA)
: params.currentMaxAutoA
);
const canRunAtMinCurrent = physicalCapA >= params.currentMinA;
// =====================================================
// FENETRE D'ETABLISSEMENT DU RESEAU (31/08/2026)
// =====================================================
@@ -779,6 +760,50 @@ if (dayVehicleFullIdle && profile !== 'night_hc') {
sourceMode = 'blocked';
}
// =====================================================
// PLAFOND DE COURANT EVCS — calculé APRÈS sourceMode (31/08/2026)
// =====================================================
// P5 : plafond majoré (input_number.evcs_plafond_courant_edf_on, jusqu'à 28 A
// en BOOST) quand le réseau alimente réellement AC-IN ; sinon plafond câblé
// prudent, celui que les deux MultiPlus peuvent porter SEULS.
//
// SÉQUENCE D'OUVERTURE (31/08/2026) — pourquoi ce bloc a été déplacé ici.
// Le plafond majoré n'est légitime que tant que le réseau est là. Or c'est
// l'hystérésis (cycle 1 min) qui ouvre le contacteur, et le contrôleur EVCS ne
// l'apprenait qu'après coup : pendant ce temps les deux onduleurs portaient
// seuls la voiture au courant majoré plus la maison — le mécanisme du W-105.
//
// Correctif sans poignée de main entre les deux automates : le plafond majoré
// exige désormais que l'EVCS DEMANDE lui-même le réseau. Sa demande tombe au
// cycle où la fenêtre se ferme (30 s), alors que l'hystérésis ne peut ouvrir
// qu'ensuite (override disparu ET min_on écoulé, cycle 1 min). L'EVCS baisse
// donc AVANT, mécaniquement, sans rien coordonner.
// Le calcul doit venir après sourceMode ; rien entre les deux ne l'utilisait.
const evcsGridCeilingAllowed =
parsed.acInAvailable &&
(
sourceMode === 'grid_forced' ||
sourceMode === 'grid_hc_allowed' ||
forceGridRequested
);
const evcsDedicatedCapBaseW = Math.max(0, cfg.evcsDedicatedMaxW - cfg.systemReserveW);
const safeEvcsByDedicatedCapW = evcsGridCeilingAllowed
? Math.max(0, params.gridCurrentMaxA * acVoltageRef)
: evcsDedicatedCapBaseW;
const safeEvcsByVebusW = Math.max(0, totalVebusSoftCeilingW - vebusNonEvcsW - cfg.systemReserveW);
const safeEvcsCombinedW = Math.max(0, Math.min(safeEvcsByDedicatedCapW, safeEvcsByVebusW));
const systemCapCurrentA = Math.max(0, Math.floor(safeEvcsCombinedW / acVoltageRef));
const physicalCapA = clamp(
systemCapCurrentA,
0,
evcsGridCeilingAllowed
? Math.max(params.currentMaxAutoA, params.gridCurrentMaxA)
: params.currentMaxAutoA
);
const canRunAtMinCurrent = physicalCapA >= params.currentMinA;
const operatingMode = profile;
// =====================================================
@@ -827,6 +852,7 @@ return [{
systemCapCurrentA,
physicalCapA,
canRunAtMinCurrent,
evcsGridCeilingAllowed,
gridSettling,
gridTransitionAgeSec: parsed.gridTransitionAgeSec,
endDayGuardSoc,