[doc] audit Doxygen : \param 'now' + docs périmées après refactors 3c/3e
Audit manuel (doxygen non installé, pas de Doxyfile). 5 findings corrigés : - EvAdapter::applyAction : \param now manquant (param partiellement documenté → warning) ; toLoadContext : \param now ajouté. - EnergyArbitrator::buildContext : mention SG-Ready + \param now (source unique verrous). - applyActionsToAdapters : dispatch State→SG-Ready documenté (était ECS/Stage seul). - onMeterWatchdogTick : doc alignée sur le refactor 7c (délègue à evaluateMeterFreshness, QTimer sous #ifndef ENERGY_SIMULATION). - RuleBasedScheduler (classe + getPlan) : décrivait seulement le proxy EV → ajout du waterfall non-EV (budget net signé, priorité ASC, recrédit, clamp lock-aware) et correction "seul ctx.timestamp utilisé" (faux : meter + loads aussi). Concepts 3c/3e vérifiés documentés : seam de temps/lockWindow, minStage/maxStage, atomicité 2 bits (transientHarm), mode dégradé L2, waterfall unifié + ordre EV→ECS/SG-Ready, hystérésis SG-Ready. Build 0/0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e641f289db
commit
51760a7f61
@ -46,6 +46,8 @@ public:
|
||||
|
||||
/*!
|
||||
* \brief Construit l'entrée loads[] §5 du SurplusContext.
|
||||
* \param now Temps de cycle (\c ctx.timestamp). Inutilisé ici : l'EV n'a pas de verrou
|
||||
* de palier (hors waterfall ECS/SG-Ready). Présent pour l'uniformité de \c ILoadAdapter.
|
||||
* \return LoadContext incluant declared, limits, needs et télémétrie EV.
|
||||
*/
|
||||
LoadContext toLoadContext(const QDateTime &now) const override;
|
||||
@ -59,6 +61,8 @@ public:
|
||||
* \c descriptor() et \c telemetry() sont eux actifs dès maintenant pour le SurplusContext.
|
||||
*
|
||||
* \param action LoadAction de kind Setpoint. Autres kinds : retour sans effet.
|
||||
* \param now Temps de cycle (\c ctx.timestamp) — passé à \c doExecuteChargingAction()
|
||||
* (locks anti-rebond de la borne). MÊME source que toLoadContext() (contrat ILoadAdapter).
|
||||
* \return L'action après écrêtage matériel (currentA, phaseCount bornés).
|
||||
*
|
||||
* \invariant action.reason non vide requis — log warning et retour sans effet sinon.
|
||||
|
||||
@ -141,10 +141,13 @@ protected:
|
||||
|
||||
private:
|
||||
/*!
|
||||
* \brief Construit le SurplusContext §5 : meter brut + loads EV + loads ECS.
|
||||
* \brief Construit le SurplusContext §5 : meter brut + loads EV + ECS + SG-Ready.
|
||||
*
|
||||
* \c ctx.meter.exportW = mesure brute du compteur (AGENTS invariant 8 — aucune
|
||||
* déduction interne). La déduction evReservedW est faite dans le scheduler.
|
||||
* \param now Temps de cycle (\c ctx.timestamp) : pose \c ctx.timestamp et sert de SOURCE
|
||||
* UNIQUE aux fenêtres de verrou (\c minStage/maxStage, \c minState/maxState) calculées
|
||||
* par chaque adaptateur — cohérence décision (scheduler) / exécution (applyAction).
|
||||
*/
|
||||
SurplusContext buildContext(const QDateTime &now) const;
|
||||
|
||||
@ -157,11 +160,11 @@ private:
|
||||
void syncAdapters();
|
||||
|
||||
/*!
|
||||
* \brief Applique les actions d'un Slot aux LoadAdapters non-EV (ECS en 3c).
|
||||
* \brief Applique les actions d'un Slot aux LoadAdapters non-EV (ECS + SG-Ready).
|
||||
*
|
||||
* 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.
|
||||
* Itère \c slot.actions et dispatche selon le kind : \c Stage → \c m_ecsAdapters
|
||||
* (EcsRelayAdapter) ; \c State → \c m_sgReadyAdapters (SgReadyAdapter). Les actions EV
|
||||
* (\c 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.
|
||||
@ -171,13 +174,14 @@ private:
|
||||
void applyActionsToAdapters(const Slot &slot, const QDateTime &now);
|
||||
|
||||
/*!
|
||||
* \brief Tick du watchdog L2 (SAFETY.md §L2) — piloté par \c m_meterWatchdog (QTimer 30 s).
|
||||
* \brief Déclencheur RÉEL du watchdog L2 (SAFETY.md §L2) — slot de \c m_meterWatchdog
|
||||
* (QTimer 30 s, horloge murale ; câblé sous \c \#ifndef ENERGY_SIMULATION).
|
||||
*
|
||||
* Si \c QDateTime::currentDateTime() − \c m_lastMeterUpdate dépasse 90 s, déclenche
|
||||
* \c applyDegradedMode(). Indépendant des signaux compteur : reste actif précisément
|
||||
* quand le compteur est muet (le signal \c powerBalanceChanged ne fire plus).
|
||||
* \note Tant que \c m_lastMeterUpdate est invalide (aucune mesure reçue depuis le
|
||||
* démarrage), aucun mode dégradé n'est déclenché (invariant root meter absent).
|
||||
* Délègue simplement à \c evaluateMeterFreshness(QDateTime::currentDateTime()) : la
|
||||
* LOGIQUE (seuil 90 s, bascule en dégradé) est dans cette méthode injectable, le QTimer
|
||||
* n'est que le battement. Indépendant des signaux compteur : reste actif précisément
|
||||
* quand le compteur est muet (le signal \c powerBalanceChanged ne fire plus, et
|
||||
* \c update() — piloté par le compteur — s'arrête aussi). Voir \c evaluateMeterFreshness().
|
||||
*/
|
||||
void onMeterWatchdogTick();
|
||||
|
||||
|
||||
@ -10,23 +10,30 @@ class ChargingAction;
|
||||
class EnergyArbitrator;
|
||||
|
||||
/*!
|
||||
* \brief Planificateur basé sur les règles GPL (EV surplus + aWATTar).
|
||||
* \brief Planificateur règles GPL : EV (proxy amont) + waterfall surplus ECS / SG-Ready.
|
||||
*
|
||||
* **Rôle en beta (jusqu'à 3g)** : PROXY AMONT POUR L'EV — délègue toute la
|
||||
* planification EV à \c planSurplusCharging() et \c planSpotMarketCharging()
|
||||
* héritées de SmartChargingManager. Ces méthodes décident (acquisitionTolerance,
|
||||
* batteryLevelConsideration, waterfall, spot market) ; ce scheduler relit leurs
|
||||
* sorties (m_chargingActions) et les reformate en LoadAction annotées d'un
|
||||
* \c reason français — pour le log [Arbitre] uniquement.
|
||||
* \c getPlan() produit un plan à 1 créneau en DEUX temps :
|
||||
*
|
||||
* À partir de **3g** : la logique de surplus sera transplantée ici (waterfall
|
||||
* unifié sur toutes les charges, EV inclus). Voir AGENTS.md § "3b révisé".
|
||||
* 1. **EV — proxy amont (beta, jusqu'à 3g)** : délègue la planification EV à
|
||||
* \c planSurplusCharging() / \c planSpotMarketCharging() héritées de SmartChargingManager,
|
||||
* relit \c m_chargingActions et les reformate en LoadAction(Setpoint) annotées d'un
|
||||
* \c reason français. Le dispatch EV réel reste dans \c adjustEvChargers() amont.
|
||||
*
|
||||
* \invariant getPlan() retourne IMMÉDIATEMENT (AGENTS invariant 5).
|
||||
* \invariant getPlan() retourne toujours un Plan valide (isValid() == true).
|
||||
* 2. **Waterfall non-EV (3c/3e)** : un budget de surplus UNIQUE — net SIGNÉ
|
||||
* \c (exportW − importW) − evReservedW — cascade par **priorité ASC** (rang, 1 = premier
|
||||
* servi) à travers les charges \c relay-stages (ECS, \c buildEcsStageAction) ET
|
||||
* \c sg-ready (PAC, \c buildSgReadyStateAction). Anti-clignotement par **recrédit** de la
|
||||
* conso allouée ; **clamp lock-aware** \c minStage/maxStage et \c minState/maxState (verrous
|
||||
* minOn/minOff/minStateHold, protection compresseur) — la fenêtre est calculée au MÊME
|
||||
* \c ctx.timestamp que l'exécution (cf. \c ILoadAdapter). Ces LoadAction sont RÉELLEMENT
|
||||
* dispatchées par \c EnergyArbitrator::applyActionsToAdapters().
|
||||
*
|
||||
* À partir de **3g** : l'EV rejoindra le waterfall unifié (toutes charges classables ensemble).
|
||||
*
|
||||
* \invariant getPlan() retourne IMMÉDIATEMENT (AGENTS invariant 5) et toujours un Plan valide.
|
||||
* \invariant Toute LoadAction a un \c reason non vide, en français.
|
||||
* \invariant Priorité : Deadline VE > Surplus PV > aWATTar > Min courant > Idle.
|
||||
* Identique à adjustEvChargers() amont — iso-fonctionnel 3b.
|
||||
* \invariant EV (étape 1) : priorité Deadline VE > Surplus PV > aWATTar > Min courant > Idle
|
||||
* (iso-fonctionnel amont 3b). Non-EV (étape 2) : ordre = \c priority croissant.
|
||||
*/
|
||||
class RuleBasedScheduler : public QObject, public IScheduler
|
||||
{
|
||||
@ -40,15 +47,15 @@ public:
|
||||
explicit RuleBasedScheduler(EnergyArbitrator *arbitrator, QObject *parent = nullptr);
|
||||
|
||||
/*!
|
||||
* \brief Retourne le plan pour le slot courant.
|
||||
* \brief Retourne le plan pour le slot courant (EV proxy + waterfall non-EV).
|
||||
*
|
||||
* **Beta (proxy)** : appelle \c runSpotMarketPlanning() puis \c runSurplusPlanning()
|
||||
* (qui écrivent dans m_chargingActions via les méthodes parent), lit le résultat
|
||||
* via \c scheduledActions(), et construit les LoadAction correspondantes.
|
||||
* Les LoadAction servent uniquement au log [Arbitre] — le dispatch réel reste dans
|
||||
* \c adjustEvChargers() amont.
|
||||
* Étape 1 (EV) : \c runSpotMarketPlanning() + \c runSurplusPlanning() puis reformatage
|
||||
* de \c scheduledActions() en LoadAction(Setpoint) — log [Arbitre], dispatch amont.
|
||||
* Étape 2 (non-EV) : waterfall surplus sur les charges \c relay-stages / \c sg-ready
|
||||
* triées par priorité — LoadAction(Stage/State) réellement dispatchées.
|
||||
*
|
||||
* \param ctx SurplusContext courant. En 3b : seul \c ctx.timestamp est utilisé.
|
||||
* \param ctx SurplusContext courant. Utilisé : \c ctx.timestamp (temps de cycle / verrous),
|
||||
* \c ctx.meter (surplus net signé), \c ctx.loads (déclarés, télémétrie, fenêtres de verrou).
|
||||
* \return Plan à 1 créneau couvrant \c ctx.timestamp + 60 s.
|
||||
*/
|
||||
Plan getPlan(const SurplusContext &ctx) override;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user