moteur : une borne non préparée ce cycle n'a pas de ChargingProcessInfo (défaut 1)

internalHasProcessInfo() testait la table m_processInfos, qui n'est jamais vidée et que
verifyOverloadProtection() remplit par operator[] (entrée par défaut : 1 phase, pas de bascule).
Après la première surcharge, une borne triphasée sans voiture assignée devenait monophasée pour
evTargetPhases() : plafond 16 × 230 × 1, conversion W → A sur une phase, 3 680 W alloués et
attendus pour 11 040 W tirés. Même effet, sans surcharge, avec l'entrée d'une voiture
monophasée désassignée.

Le manager retient désormais les bornes qu'il prépare à chaque cycle (m_preparedChargers), et
l'accesseur dit ce que sa documentation promettait : préparée CE cycle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Patrick Schurig 2026-10-27 12:32:57 +01:00
parent f20b08a3a2
commit cf0e65abc7
2 changed files with 20 additions and 1 deletions

View File

@ -637,6 +637,12 @@ void SmartChargingManager::prepareInformation(const QDateTime &currentDateTime)
evChargers.append(evCharger);
}
// [ETM] Les bornes préparées CE cycle — exactement celles que l'étape 2 va traiter. La table
// m_processInfos ne le dit pas : elle n'est jamais vidée, et operator[] y crée une entrée par
// défaut (1 phase, pas de bascule) dès qu'on la lit ainsi, dans verifyOverloadProtection() par
// exemple. Lue par internalHasProcessInfo(), voir sa documentation.
m_preparedChargers = QSet<EvCharger *>(evChargers.constBegin(), evChargers.constEnd());
// 2. Prepare all information avaialble for each charger
foreach (EvCharger *evCharger, evChargers) {

View File

@ -27,6 +27,7 @@
#include <QObject>
#include <QTimer>
#include <QSet>
#include "energymanagerconfiguration.h"
#include "types/charginginfo.h"
@ -139,6 +140,9 @@ signals:
// protection de surcharge. Documenté ci-dessous.
// 7. setEvChargingState() — écriture ETM d'un état RUNTIME, documentée
// ci-dessous. Pas un réglage : jamais persistée.
// 9. m_preparedChargers — membre privé ETM, posé par prepareInformation() :
// les bornes préparées au dernier cycle. Seul
// lecteur : internalHasProcessInfo().
// 6. evSurplusPlannedByWaterfall(), evCommandedByWaterfall()
// — crochets ETM, virtuels, documentés ci-dessous.
// Ce sont EUX qui garantissent « une charge, un
@ -311,8 +315,16 @@ protected:
* \c EnergyArbitrator::evTargetPhases() doit le SAVOIR plutôt que de le déduire de
* valeurs par défaut — sans quoi une borne triphasée est annoncée monophasée et le
* budget du cycle est divisé par trois.
* \note **Lu sur l'ensemble des bornes préparées ce cycle, pas sur la table.** La table
* \c m_processInfos n'est jamais vidée, et l'amont la lit aussi par \c operator[], qui y
* insère une entrée par défaut : \c verifyOverloadProtection() le fait pour toute borne qu'il
* rabaisse. Tester la table rendait donc VRAI pour une borne sans voiture après sa première
* surcharge, et la borne triphasée devenait monophasée dans les comptes (relevé du
* 2026-10-27, \c testOverloadLeavesTheChargerItsPhases). De même, une voiture désassignée
* laissait son entrée de la veille (\c testAnUnassignedCarTakesItsPhasesAway).
*/
bool internalHasProcessInfo(EvCharger *evCharger) const { return m_processInfos.contains(evCharger); } // [ETM] new
bool internalHasProcessInfo(EvCharger *evCharger) const // [ETM] new
{ return m_preparedChargers.contains(evCharger) && m_processInfos.contains(evCharger); }
// [ETM] END
private slots:
@ -344,6 +356,7 @@ private:
QHash<EvCharger *, ChargingSchedules> m_chargingSchedules;
QHash<EvCharger *, ChargingProcessInfo> m_processInfos;
QSet<EvCharger *> m_preparedChargers; // [ETM] préparées au dernier prepareInformation()
QHash<EvCharger *, ChargingActions> m_chargingActions;
QDateTime m_lastSpotMarketPlanning;