[3c-4] dispatch ECS : applyActionsToAdapters(Slot) dans update()

Itère slot.actions, dispatche les kind==Stage vers m_ecsAdapters (position 7,
avant adjustEvChargers). EV (Setpoint) reste sur le proxy amont jusqu'à 3g.
Build 0 erreur / 0 warning.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Patrick Schurig 2026-06-08 16:26:49 +02:00
parent 6298d5d42f
commit 0615e5f39d
2 changed files with 32 additions and 2 deletions

View File

@ -97,7 +97,8 @@ void EnergyArbitrator::update(const QDateTime &currentDateTime)
}
// 7 : dispatch matériel (même position que l'amont — m_chargingActions rempli par getPlan())
adjustEvChargers(currentDateTime);
applyActionsToAdapters(slot); // ECS (kind==Stage) → m_ecsAdapters
adjustEvChargers(currentDateTime); // EV (kind==Setpoint) → proxy amont jusqu'à 3g
}
SurplusContext EnergyArbitrator::buildContext(const QDateTime &now) const
@ -146,3 +147,20 @@ void EnergyArbitrator::syncAdapters()
m_adapters.take(id)->deleteLater();
}
}
void EnergyArbitrator::applyActionsToAdapters(const Slot &slot)
{
for (const LoadAction &action : slot.actions) {
// EV (Setpoint) : dispatché par adjustEvChargers() amont jusqu'à 3g.
if (action.kind != LoadAction::Stage)
continue;
EcsRelayAdapter *adapter = m_ecsAdapters.value(action.loadId);
if (!adapter) {
qCWarning(dcNymeaEnergy()) << "[Arbitre] action Stage sans adaptateur ECS:" << action.loadId;
continue;
}
// L'adaptateur applique, écrête et verrouille (anti-rebond) — il ne décide pas.
adapter->applyAction(action);
}
}

View File

@ -89,7 +89,7 @@ protected:
* 2. prepareInformation()
* 3. verifyOverloadProtection() + verifyOverloadProtectionRecovery()
* 4. m_scheduler->getPlan() log des decisionReason
* 5. adjustEvChargers() dispatch matériel + mise à jour états
* 5. applyActionsToAdapters() (ECS Stage) + adjustEvChargers() (EV) dispatch matériel
*
* \param currentDateTime Instant courant (timer ou simulation).
*/
@ -112,6 +112,18 @@ private:
*/
void syncAdapters();
/*!
* \brief Applique les actions d'un Slot aux LoadAdapters non-EV (ECS en 3c).
*
* Itère \c slot.actions et dispatche chaque action \c kind==Stage vers le
* EcsRelayAdapter correspondant (\c m_ecsAdapters[action.loadId]). Les actions EV
* (\c kind==Setpoint) restent dispatchées par \c adjustEvChargers() amont jusqu'à 3g.
* L'adaptateur écrête/verrouille lui-même (anti-rebond) et ignore toute action sans
* \c reason ou de kind non supporté aucune décision ici (règle 2).
* \param slot Créneau courant retourné par le scheduler.
*/
void applyActionsToAdapters(const Slot &slot);
RuleBasedScheduler *m_scheduler = nullptr;
QHash<QString, EvAdapter *> m_adapters; //!< loadId (ThingId string) → EvAdapter*.
QHash<QString, EcsRelayAdapter *> m_ecsAdapters; //!< loadId → EcsRelayAdapter*.