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

@@ -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,