fix(3g-1): la bascule de phases se décide sur le courant POSSIBLE
Deuxième défaut latent de 3g-1, corrigé à part du lot 3g-2 pour la même raison que le précédent. EvAdapter passait `currentPower / 230` comme courant de référence à la règle de bascule 1↔3 phases, au motif — écrit dans le commentaire — que l'allocation n'est pas encore connue à cet instant. Mais la bascule ne se décide pas sur ce que la borne TIRE : elle se décide sur ce qu'elle POURRAIT tirer. C'est la formule du proxy, `currentPower/230 + allowance`, et c'est la seule qui puisse répondre « redescends en monophasé, il n'y a plus que 800 W ». Avec le seul courant courant, une borne passée en triphasé y restait quel que soit l'effondrement du surplus — et son plancher publié restait à 4,1 kW, donc plus rien ne pouvait la servir. Le surplus, lui, EST connu avant l'allocation : c'est la mesure du compteur. Le terme de stockage de planSurplusCharging() (tampon de 500 W, réinjection au-dessus du seuil) n'entre volontairement pas dans cette référence : il la déplace à la marge et n'a d'effet que sur le choix 1↔3, jamais sur l'allocation — laquelle est faite par le waterfall, avec un budget qui tient compte du stockage. Suite simulation `run` 16/16, charging vert. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017TVywtayEeoRJ2yWUW4iZj
This commit is contained in:
parent
99ad9a04cb
commit
4f987e5b1d
@ -61,14 +61,15 @@ LoadContext EvAdapter::toLoadContext(const QDateTime &now) const
|
||||
// vers un autre produirait un défaut silencieux — le waterfall allouerait 2 kW en croyant
|
||||
// démarrer une borne qui en exige 4,1, et se croirait servi.
|
||||
//
|
||||
// Le courant de référence pour ce choix est ce que la borne tire DÉJÀ : c'est la seule
|
||||
// grandeur connue avant l'allocation, et c'est celle que le proxy utilisait aussi.
|
||||
// Plus de test canSetPhaseCount() ici : la question « cette borne peut-elle basculer,
|
||||
// 3g-2 — la référence est ce que la borne POURRAIT tirer : son courant actuel PLUS le
|
||||
// surplus disponible. C'est la formule du proxy, et c'est la seule qui sache redescendre
|
||||
// en monophasé quand le surplus s'effondre (voir evReferenceCurrentA()).
|
||||
// 3g-2 — plus de test canSetPhaseCount() ici : la question « cette borne peut-elle basculer,
|
||||
// avec CETTE voiture » est tranchée une fois par le manager, et evTargetPhases() la lit.
|
||||
// Le prédicat local n'en voyait qu'une moitié (l'état existe-t-il) et retombait sur le
|
||||
// nombre de phases COURANT, sans la voiture.
|
||||
const double courantActuelA = m_charger->currentPower() / 230.0;
|
||||
m_targetPhases = m_parent->evTargetPhases(m_charger, courantActuelA);
|
||||
const double courantReferenceA = m_parent->evReferenceCurrentA(m_charger);
|
||||
m_targetPhases = m_parent->evTargetPhases(m_charger, courantReferenceA);
|
||||
if (m_targetPhases == 0)
|
||||
m_targetPhases = 1;
|
||||
|
||||
|
||||
@ -435,6 +435,16 @@ double EnergyArbitrator::evFloorW(EvCharger *ev, uint phaseCount) const
|
||||
return minA * acquisitionTolerance() * 230.0 * phaseCount;
|
||||
}
|
||||
|
||||
double EnergyArbitrator::evReferenceCurrentA(EvCharger *ev) const
|
||||
{
|
||||
if (!ev)
|
||||
return 0;
|
||||
double a = ev->currentPower() / 230.0;
|
||||
if (RootMeter *meter = internalRootMeter())
|
||||
a += -meter->currentPower() / 230.0; // < 0 au compteur = export = surplus
|
||||
return a;
|
||||
}
|
||||
|
||||
uint EnergyArbitrator::evTargetPhases(EvCharger *ev, double referenceA)
|
||||
{
|
||||
if (!ev)
|
||||
|
||||
@ -233,6 +233,29 @@ public:
|
||||
*/
|
||||
uint evTargetPhases(EvCharger *ev, double referenceA);
|
||||
|
||||
/*!
|
||||
* \brief [3g-2] Courant de référence (A) pour choisir le nombre de phases d'une borne.
|
||||
*
|
||||
* \param ev Borne. \return Somme du courant qu'elle tire DÉJÀ et du surplus disponible,
|
||||
* en ampères totaux (toutes phases confondues). Négatif possible : en soutirage, la
|
||||
* référence descend, et la règle de bascule vise le monophasé.
|
||||
*
|
||||
* \par Pourquoi la référence n'est pas le seul courant courant
|
||||
* 3g-1 passait \c currentPower / 230, au motif que l'allocation n'est pas encore connue.
|
||||
* Mais la bascule 1↔3 phases ne se décide pas sur ce que la borne tire : elle se décide
|
||||
* sur ce qu'elle POURRAIT tirer — c'est la formule du proxy (`currentPower/230 +
|
||||
* allowance`), et c'est la seule qui puisse répondre « redescends en monophasé, il n'y a
|
||||
* plus que 800 W ». Avec le seul courant courant, une borne en triphasé restait en
|
||||
* triphasé quel que soit l'effondrement du surplus, et son plancher publié restait à
|
||||
* 4,1 kW — donc plus rien ne pouvait la servir.
|
||||
*
|
||||
* \note Le terme de stockage de \c planSurplusCharging() (tampon 500 W, réinjection au-
|
||||
* dessus du seuil) n'entre PAS ici : il déplace la référence à la marge et n'a d'effet
|
||||
* que sur le choix 1↔3, jamais sur l'allocation, qui est faite par le waterfall avec un
|
||||
* budget qui, lui, tient compte du stockage.
|
||||
*/
|
||||
double evReferenceCurrentA(EvCharger *ev) const;
|
||||
|
||||
/*!
|
||||
* \brief [3g-1] Plancher de modulation d'une borne, en watts, pour le nombre de phases VISÉ.
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user