docs(etm): contrats Doxygen — types de config/contexte et adaptateurs stables
Couverture des fichiers non visés par la restructuration à venir : l'extraction du noyau de calcul (étape 2) et celle de m_relayMapping (étape 3) ne les touchent pas. relayrouter.h et energyarbitrator.h sont volontairement DIFFÉRÉS — documenter ce qui va changer produirait du bruit d'historique. Mesure sur la config du Doxyfile : 113 → 31 avertissements. loadconfig.h 41→0 · surpluscontext.h 30→0 · sgreadyadapter.h 4→1 (le \return restant relève du lot suivant) · etmvariableloadadapter.h 2→0 · evadapter.h 1→0 Ce sont des contrats, pas des étiquettes : enabled dit qu'une charge déclarée mais exclue n'est JAMAIS pilotée ; priority qu'il s'agit d'un rang ascendant et non d'un poids ; timestamp qu'il est la source unique du temps, dont dérivent verrous et fenêtres ; setPowerLevels qu'il trie et déduplique ; fromMap qu'il retourne une config NON validée ; internalRootMeter() qu'il peut être nul. Ajouts « // [ETM] » hors etm/ (smartchargingmanager.h) : ils échappent au périmètre du Doxyfile, la frontière étant un répertoire. Un inventaire explicite est posé au marqueur [ETM] BEGIN, distinguant les trois cas — degradedMode() et les trois accesseurs internal* sont des ajouts ETM et sont documentés ; les huit changements de visibilité seule gardent la documentation de l'amont. La définition de fait d'AGENTS.md renvoie à cet inventaire et l'étend explicitement aux ajouts hors etm/. Build amd64 0 erreur. Simulation : 7/7. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0fefbc509e
commit
e70a60c180
@ -488,6 +488,10 @@ supérieures n'affecte pas les couches inférieures. Voir `docs/SAFETY.md` pour
|
||||
`\brief`, `\param`, `\return`, et surtout le **contrat de comportement**
|
||||
(invariants, écrêtage, hypothèses que l'appelant peut faire).
|
||||
Les headers 3a servent de modèle — les convertir au format Doxygen lors du passage 3b.
|
||||
**Y compris les ajouts `// [ETM]` hors `etm/`** : ils échappent au périmètre du
|
||||
`Doxyfile` (frontière = un répertoire) et se documentent à la main. Leur inventaire
|
||||
est tenu dans `energyplugin/smartchargingmanager.h`, au marqueur `[ETM] BEGIN` —
|
||||
toute nouvelle marque `[ETM]` dans un en-tête amont s'y ajoute.
|
||||
|
||||
## ROADMAP — configuration des priorités par l'utilisateur (post-beta)
|
||||
|
||||
|
||||
@ -80,6 +80,8 @@ public:
|
||||
/*!
|
||||
* \brief Télémétrie runtime. \c currentPowerW = state \c currentPowerW MESURÉ du thing
|
||||
* (juge de quantification, contrat §4) ; \c available faux si le thing est absent.
|
||||
* \return LoadTelemetry ; \c currentPowerW vaut 0 si le thing est absent ou n'expose
|
||||
* pas l'état \c currentPowerW (jamais de puissance fantôme).
|
||||
*/
|
||||
LoadTelemetry telemetry() const override;
|
||||
|
||||
@ -104,7 +106,11 @@ public:
|
||||
*/
|
||||
LoadAction applyAction(const LoadAction &action, const QDateTime &now) override;
|
||||
|
||||
/*! \brief Dernière consigne (W) effectivement écrite (avant écrêtage thing). */
|
||||
/*!
|
||||
* \brief Dernière consigne (W) effectivement écrite (avant écrêtage thing).
|
||||
* \return Consigne commandée en W, bornée à \c maxPowerW ; 0 tant qu'aucune action
|
||||
* n'a été appliquée. C'est le COMMANDÉ, pas le mesuré.
|
||||
*/
|
||||
double currentSetpointW() const { return m_currentSetpointW; }
|
||||
|
||||
private:
|
||||
|
||||
@ -71,7 +71,10 @@ public:
|
||||
*/
|
||||
LoadAction applyAction(const LoadAction &action, const QDateTime &now) override;
|
||||
|
||||
/*! \brief Borne VE sous-jacente (lecture). */
|
||||
/*!
|
||||
* \brief Borne VE sous-jacente (lecture).
|
||||
* \return Pointeur non-propriétaire vers l'EvCharger ; jamais nul (fixé à la construction).
|
||||
*/
|
||||
EvCharger *evCharger() const { return m_charger; }
|
||||
|
||||
private:
|
||||
|
||||
@ -68,12 +68,16 @@ public:
|
||||
* (\c declared.estimatedPowerW : 0 pour états 1/2, P3/P4 pour 3/4). C'est la base du
|
||||
* recrédit budget — PAS la conso mesurée de la PAC (l'état 2 autonome est déjà au
|
||||
* compteur, invariant 8 : la recréditer double-compterait).
|
||||
* \return LoadTelemetry ; \c available toujours vrai (l'encodage relais ne dépend pas
|
||||
* d'une liaison montante), \c lastActionAt nul tant qu'aucune transition n'a eu lieu.
|
||||
*/
|
||||
LoadTelemetry telemetry() const override;
|
||||
|
||||
/*!
|
||||
* \brief Construit l'entrée loads[] §5 (adapter="sg-ready").
|
||||
* \param now Temps de cycle (\c ctx.timestamp) — source unique de la fenêtre minState/maxState.
|
||||
* \return LoadContext incluant \c telemetry.state et la fenêtre \c minState/\c maxState
|
||||
* évaluée à \p now : c'est sur elle que le scheduler clampe sa cible.
|
||||
*/
|
||||
LoadContext toLoadContext(const QDateTime &now) const override;
|
||||
|
||||
@ -85,7 +89,11 @@ public:
|
||||
*/
|
||||
LoadAction applyAction(const LoadAction &action, const QDateTime &now) override;
|
||||
|
||||
/*! \brief État SG-Ready courant (1-4). */
|
||||
/*!
|
||||
* \brief État SG-Ready courant (1-4).
|
||||
* \return Dernier état réellement commuté ; valeur initiale tant qu'aucune transition
|
||||
* n'a eu lieu. Reflète le COMMANDÉ — la PAC reste seule juge de son fonctionnement.
|
||||
*/
|
||||
int currentState() const { return m_currentState; }
|
||||
|
||||
private:
|
||||
|
||||
@ -20,14 +20,22 @@ class LoadConfigNeeds
|
||||
Q_PROPERTY(QString dailyDeadline READ dailyDeadline WRITE setDailyDeadline)
|
||||
Q_PROPERTY(int minEnergyWhPerDay READ minEnergyWhPerDay WRITE setMinEnergyWhPerDay)
|
||||
public:
|
||||
//! \brief Construit des besoins vides : aucune échéance, aucune énergie minimale.
|
||||
LoadConfigNeeds() {}
|
||||
|
||||
//! \return Heure limite quotidienne "HH:MM" ; chaîne vide = pas d'échéance.
|
||||
QString dailyDeadline() const { return m_dailyDeadline; }
|
||||
//! \param v Heure limite "HH:MM", ou chaîne vide pour retirer l'échéance.
|
||||
void setDailyDeadline(const QString &v) { m_dailyDeadline = v; }
|
||||
//! \return Énergie minimale à fournir par jour (Wh) ; 0 = aucune exigence.
|
||||
int minEnergyWhPerDay() const { return m_minEnergyWhPerDay; }
|
||||
//! \param v Énergie minimale par jour (Wh) ; 0 pour retirer l'exigence.
|
||||
void setMinEnergyWhPerDay(int v) { m_minEnergyWhPerDay = v; }
|
||||
|
||||
//! \return Forme sérialisée ; les champs à leur valeur par défaut sont OMIS (jamais nuls).
|
||||
QVariantMap toMap() const;
|
||||
//! \brief Construit depuis la forme sérialisée. \param map Map §4 \c needs.
|
||||
//! \return Besoins ; les clés absentes prennent leur valeur par défaut.
|
||||
static LoadConfigNeeds fromMap(const QVariantMap &map);
|
||||
|
||||
private:
|
||||
@ -46,7 +54,11 @@ struct LoadConfigRelay
|
||||
QString thingId; //!< ThingId du thing implémentant l'interface \c power.
|
||||
int powerW = 0; //!< Puissance nominale de ce relais (W).
|
||||
|
||||
//! \return Forme sérialisée \c {thingId, powerW}.
|
||||
QVariantMap toMap() const;
|
||||
//! \brief Construit depuis la forme sérialisée. \param map Map \c {thingId, powerW}.
|
||||
//! \return Relais ; \c thingId vide et \c powerW nul si les clés manquent — c'est
|
||||
//! \c LoadConfig::isValid() qui rejette ces cas, pas ce constructeur.
|
||||
static LoadConfigRelay fromMap(const QVariantMap &map);
|
||||
};
|
||||
|
||||
@ -78,45 +90,77 @@ class LoadConfig
|
||||
Q_PROPERTY(int minOnS READ minOnS WRITE setMinOnS)
|
||||
Q_PROPERTY(int minOffS READ minOffS WRITE setMinOffS)
|
||||
public:
|
||||
//! \brief Construit une config vide — \c adapter vaut "etmvariableload", \c enabled vrai.
|
||||
LoadConfig() {}
|
||||
|
||||
//! \return Identifiant logique de la charge (clé de dispatch). Requis, non vide.
|
||||
QString id() const { return m_id; }
|
||||
//! \param v Identifiant logique ; une valeur vide fait échouer isValid().
|
||||
void setId(const QString &v) { m_id = v; }
|
||||
//! \return Nom lisible affiché dans les logs et l'app.
|
||||
QString label() const { return m_label; }
|
||||
//! \param v Nom lisible.
|
||||
void setLabel(const QString &v) { m_label = v; }
|
||||
//! \return Type d'adaptateur : "relay-router" ou "etmvariableload".
|
||||
QString adapter() const { return m_adapter; }
|
||||
//! \param v Type d'adaptateur ; toute autre valeur fait échouer isValid().
|
||||
void setAdapter(const QString &v) { m_adapter = v; }
|
||||
//! \return Mode : "fixed" (paliers) ou "dynamic" (modulation continue).
|
||||
QString mode() const { return m_mode; }
|
||||
//! \param v Mode "fixed" ou "dynamic" ; toute autre valeur fait échouer isValid().
|
||||
void setMode(const QString &v) { m_mode = v; }
|
||||
|
||||
//! powerLevels en QVariantList (introspection) ; trié + dédupliqué à l'écriture.
|
||||
//! \return Paliers déclarés (W), triés croissants. Vide en *dynamic*.
|
||||
QVariantList powerLevels() const;
|
||||
//! \param v Paliers (W) dans un ordre quelconque : ils sont TRIÉS et DÉDUPLIQUÉS ici
|
||||
//! (contrat §6, l'energymanager re-trie par sécurité).
|
||||
void setPowerLevels(const QVariantList &v);
|
||||
//! Accès typé pour la construction de l'adaptateur.
|
||||
//! \return Les mêmes paliers, typés, triés croissants.
|
||||
QList<int> powerLevelsInt() const { return m_powerLevels; }
|
||||
|
||||
//! \return Plafond physique de la charge (W). Requis (> 0) en *dynamic*.
|
||||
int maxPowerW() const { return m_maxPowerW; }
|
||||
//! \param v Plafond physique (W).
|
||||
void setMaxPowerW(int v) { m_maxPowerW = v; }
|
||||
//! \return Rang dans le waterfall, ASCENDANT : 1 = servi en premier. Un rang, pas un poids.
|
||||
int priority() const { return m_priority; }
|
||||
//! \param v Rang de service (1 = premier servi).
|
||||
void setPriority(int v) { m_priority = v; }
|
||||
//! \return Faux si la charge est déclarée mais EXCLUE de l'arbitrage (contrat §9) :
|
||||
//! aucun adaptateur n'est construit, elle n'est jamais pilotée.
|
||||
bool enabled() const { return m_enabled; }
|
||||
//! \param v Faux pour exclure la charge de l'arbitrage sans supprimer sa config.
|
||||
void setEnabled(bool v) { m_enabled = v; }
|
||||
//! \return Besoins déclarés par l'utilisateur (échéance, énergie minimale).
|
||||
LoadConfigNeeds needs() const { return m_needs; }
|
||||
//! \param v Besoins déclarés.
|
||||
void setNeeds(const LoadConfigNeeds &v) { m_needs = v; }
|
||||
|
||||
//! relays en QVariantList (introspection / sérialisation) ; typé via relaysList().
|
||||
//! \return Relais sérialisés \c [{thingId, powerW}] ; vide hors cas relay-router.
|
||||
QVariantList relays() const;
|
||||
//! \param v Relais \c [{thingId, powerW}] ; réservé à \c relay-router (isValid() rejette
|
||||
//! une liste non vide sur \c etmvariableload).
|
||||
void setRelays(const QVariantList &v);
|
||||
//! \return Les mêmes relais, typés — source de la combinatoire du RelayRouter.
|
||||
QList<LoadConfigRelay> relaysList() const { return m_relays; }
|
||||
|
||||
//! \return Durée minimale ON (s) — protection relais/compresseur. 0 = pas de verrou.
|
||||
int minOnS() const { return m_minOnS; }
|
||||
//! \param v Durée minimale ON (s), ≥ 0.
|
||||
void setMinOnS(int v) { m_minOnS = v; }
|
||||
//! \return Durée minimale OFF (s) — anti court-cycling. 0 = pas de verrou.
|
||||
int minOffS() const { return m_minOffS; }
|
||||
//! \param v Durée minimale OFF (s), ≥ 0.
|
||||
void setMinOffS(int v) { m_minOffS = v; }
|
||||
|
||||
//! Vrai si la charge est un routeur de relais (rév. 3 : combinatoire watts→relais côté routeur).
|
||||
//! \return Vrai si \c adapter == "relay-router" — décide de la classe construite au rebuild.
|
||||
bool isRelayRouter() const { return m_adapter == QStringLiteral("relay-router"); }
|
||||
//! Vrai si *dynamic* (modulation continue). Sinon *fixed*.
|
||||
//! \return Vrai si \c mode == "dynamic".
|
||||
bool isDynamic() const { return m_mode == QStringLiteral("dynamic"); }
|
||||
|
||||
/*!
|
||||
@ -126,7 +170,13 @@ public:
|
||||
*/
|
||||
bool isValid(QString *error = nullptr) const;
|
||||
|
||||
//! \return Forme sérialisée §4. Les champs \c relays/\c minOnS/\c minOffS ne sont émis
|
||||
//! que s'il existe au moins un relais ; \c powerLevels que s'il est non vide.
|
||||
QVariantMap toMap() const;
|
||||
//! \brief Construit depuis la forme sérialisée §4 (ce que reçoit \c SetLoadConfig).
|
||||
//! \param map Map §4. Clés absentes → valeurs par défaut (\c adapter "etmvariableload",
|
||||
//! \c enabled vrai). \c powerLevels est trié et dédupliqué au passage.
|
||||
//! \return Config NON validée — appeler \c isValid() avant usage.
|
||||
static LoadConfig fromMap(const QVariantMap &map);
|
||||
|
||||
private:
|
||||
@ -151,9 +201,16 @@ class LoadConfigs : public QList<LoadConfig>
|
||||
Q_GADGET
|
||||
Q_PROPERTY(int count READ count)
|
||||
public:
|
||||
//! \brief Liste vide.
|
||||
LoadConfigs() {}
|
||||
//! \brief Conversion depuis une QList typée. \param other Configs à reprendre.
|
||||
LoadConfigs(const QList<LoadConfig> &other) : QList(other) {}
|
||||
//! \brief Accès indexé pour l'introspection JSON-RPC.
|
||||
//! \param index Position, 0-based ; doit être valide (aucun contrôle de borne).
|
||||
//! \return La config à \p index, encapsulée en QVariant.
|
||||
Q_INVOKABLE QVariant get(int index) const;
|
||||
//! \brief Ajout pour l'introspection JSON-RPC.
|
||||
//! \param variant Config à ajouter ; un QVariant d'un autre type ajoute une config vide.
|
||||
Q_INVOKABLE void put(const QVariant &variant);
|
||||
};
|
||||
Q_DECLARE_METATYPE(LoadConfigs)
|
||||
|
||||
@ -29,26 +29,26 @@ struct SurplusPv {
|
||||
|
||||
/*! \brief État courant du système de stockage (batterie). */
|
||||
struct SurplusBattery {
|
||||
bool present = false;
|
||||
double socPercent = 0;
|
||||
bool present = false; //!< Faux si aucun stockage déclaré — les autres champs sont alors sans objet.
|
||||
double socPercent = 0; //!< État de charge (%), 0-100.
|
||||
double powerW = 0; //!< Positif = charge, négatif = décharge.
|
||||
double capacityWh = 0;
|
||||
int reserveSocPercent = 0;
|
||||
double maxChargeW = 0;
|
||||
double maxDischargeW = 0;
|
||||
double capacityWh = 0; //!< Capacité nominale (Wh), plaque signalétique.
|
||||
int reserveSocPercent = 0; //!< SOC plancher (%) non déchargeable (réserve de secours).
|
||||
double maxChargeW = 0; //!< Puissance de charge maximale admissible (W).
|
||||
double maxDischargeW = 0; //!< Puissance de décharge maximale admissible (W).
|
||||
};
|
||||
|
||||
/*! \brief Entrée tarifaire (créneau HP/HC ou spot market). */
|
||||
struct TariffEntry {
|
||||
QDateTime from;
|
||||
QDateTime from; //!< Début du créneau ; il court jusqu'au \c from du suivant.
|
||||
QString label; //!< "HP", "HC", "Tempo-Rouge", ...
|
||||
double priceCtkWh = 0; //!< Prix en ct€/kWh.
|
||||
};
|
||||
|
||||
/*! \brief Contexte tarifaire : créneau courant + prochains créneaux. */
|
||||
struct SurplusTariff {
|
||||
QString provider;
|
||||
TariffEntry current;
|
||||
QString provider; //!< Fournisseur/offre ("aWATTar", "Tempo", ...) ; vide si inconnu.
|
||||
TariffEntry current; //!< Créneau en cours à \c SurplusContext::timestamp.
|
||||
QList<TariffEntry> next; //!< Créneaux suivants, ordre chronologique.
|
||||
};
|
||||
|
||||
@ -56,27 +56,29 @@ struct SurplusTariff {
|
||||
struct LoadContextTelemetry {
|
||||
double currentPowerW = 0; //!< Puissance mesurée (W).
|
||||
// --- evcharger ---
|
||||
bool pluggedIn = false;
|
||||
bool charging = false;
|
||||
bool pluggedIn = false; //!< Véhicule branché. Une borne non branchée est ignorée du plan.
|
||||
bool charging = false; //!< Charge effectivement en cours (courant non nul côté borne).
|
||||
double sessionWh = 0; //!< Énergie chargée dans la session courante (Wh).
|
||||
// --- etmvariableload (EV/ECS/routeur) : pas de fenêtre de verrou côté moteur —
|
||||
// l'anti-rebond (minOn/minOff) vit dans le thing (contrat rév. 2 §3). Seul
|
||||
// currentPowerW (ci-dessus) sert au résidu de la règle d'arrondi (contrat §5).
|
||||
// --- sg-ready ---
|
||||
int state = 0;
|
||||
int state = 0; //!< État SG-Ready courant commandé (1-4) ; 0 = non applicable.
|
||||
//! Fenêtre d'états autorisée MAINTENANT par le verrou minStateHold (protection
|
||||
//! court-cycling PAC) : gel total (minState == maxState == state) si non écoulé,
|
||||
//! sinon [1, 4]. Même mécanique que minStage/maxStage de l'ECS, source = temps de cycle.
|
||||
//! sinon [1, 4]. Source = temps de cycle. Borne BASSE de cette fenêtre.
|
||||
int minState = 0;
|
||||
//! Borne HAUTE de la même fenêtre de verrou. Le scheduler clampe sa cible sur
|
||||
//! [minState, maxState] ; décision et exécution partagent donc le même verrou.
|
||||
int maxState = 0;
|
||||
// --- battery / electricvehicle ---
|
||||
double socPercent = 0;
|
||||
double socPercent = 0; //!< État de charge (%) de la batterie ou du véhicule.
|
||||
QDateTime lastSwitch; //!< Dernier changement d'état.
|
||||
};
|
||||
|
||||
/*! \brief Données apprises par l'optimiseur §8 (renvoyées pour persistance). */
|
||||
struct LoadLearned {
|
||||
double dailyEnergyWh = 0;
|
||||
double dailyEnergyWh = 0; //!< Énergie quotidienne apprise (Wh) ; 0 tant qu'aucun profil.
|
||||
//! Confiance 0–1 ; < 0.7 = "profil en apprentissage".
|
||||
double confidence = 0.0;
|
||||
};
|
||||
@ -86,15 +88,17 @@ struct LoadLearned {
|
||||
* Construit par l'arbitre depuis ILoadAdapter::descriptor() + toLoadContext().
|
||||
*/
|
||||
struct LoadContext {
|
||||
QString id;
|
||||
QString id; //!< Identifiant logique de la charge — clé de dispatch des LoadAction.
|
||||
QString adapter; //!< "evcharger"|"etmvariableload"|"sg-ready"|"battery".
|
||||
QString label;
|
||||
QString label; //!< Nom lisible (logs, decisionReason, app).
|
||||
//! Rang dans le waterfall, ASCENDANT : 1 = servi en premier (protocole §5 + annexe C).
|
||||
//! C'est un rang, pas un poids.
|
||||
int priority = 0;
|
||||
LoadDeclared declared;
|
||||
LoadLearned learned;
|
||||
LoadContextTelemetry telemetry;
|
||||
LoadNeeds needs;
|
||||
LoadLimits limits;
|
||||
LoadDeclared declared; //!< Capacités déclarées par l'installateur (référence de planification).
|
||||
LoadLearned learned; //!< Profil appris §8, renvoyé pour persistance ; jamais une consigne.
|
||||
LoadContextTelemetry telemetry;//!< État runtime au \c timestamp du contexte.
|
||||
LoadNeeds needs; //!< Besoins déclarés par l'utilisateur (échéance, énergie minimale).
|
||||
LoadLimits limits; //!< Contraintes anti-rebond et verrous temporels.
|
||||
};
|
||||
|
||||
/*!
|
||||
@ -105,12 +109,15 @@ struct LoadContext {
|
||||
* (AGENTS invariant 8 : pas de boucle de feedback).
|
||||
*/
|
||||
struct SurplusContext {
|
||||
//! Instant de début de cycle. SOURCE UNIQUE du temps : verrous, fenêtres et estampilles
|
||||
//! en dérivent, jamais \c QDateTime::currentDateTime() — c'est ce qui rend décision et
|
||||
//! exécution impossibles à désynchroniser, et la logique injectable en simulation.
|
||||
QDateTime timestamp;
|
||||
SurplusSite site;
|
||||
SurplusMeter meter;
|
||||
SurplusPv pv;
|
||||
SurplusBattery battery;
|
||||
QList<LoadContext> loads;
|
||||
SurplusTariff tariff;
|
||||
SurplusSite site; //!< Paramètres fixes du site (puissance souscrite, limites par phase).
|
||||
SurplusMeter meter; //!< Mesures BRUTES du compteur principal (invariant 8).
|
||||
SurplusPv pv; //!< Production PV mesurée brute.
|
||||
SurplusBattery battery; //!< État du stockage ; \c present faux si absent.
|
||||
QList<LoadContext> loads; //!< Une entrée par charge pilotable, tous types confondus.
|
||||
SurplusTariff tariff; //!< Contexte tarifaire (créneau courant + suivants).
|
||||
// forecast : opaque, transmis tel quel si présent — réservé V2
|
||||
};
|
||||
|
||||
@ -72,8 +72,16 @@ public:
|
||||
|
||||
ChargingSchedules chargingSchedules() const;
|
||||
|
||||
// [ETM] Mode dégradé L2 (watchdog fraîcheur compteur). Base = false ;
|
||||
// overridé dans EnergyArbitrator. Exposé pour la notification JSON-RPC.
|
||||
/*!
|
||||
* \brief [ETM] Mode dégradé L2 — le compteur principal est muet depuis plus de 90 s.
|
||||
*
|
||||
* Base amont : toujours faux (l'amont n'a pas de watchdog). Redéfini par
|
||||
* \c EnergyArbitrator, qui le pose depuis \c applyDegradedMode() (SAFETY.md §L2).
|
||||
* Exposé publiquement pour la notification JSON-RPC \c ChargingSchedulesChanged.
|
||||
*
|
||||
* \return Vrai si la planification est suspendue et les consignes de repli posées.
|
||||
* La sécurité L4 (\c verifyOverloadProtection) reste active dans cet état.
|
||||
*/
|
||||
virtual bool degradedMode() const { return false; }
|
||||
|
||||
SpotMarketManager *spotMarketManager() const;
|
||||
@ -100,6 +108,22 @@ signals:
|
||||
// [ETM] BEGIN — SmartChargingManager protected API for EnergyArbitrator (etm/).
|
||||
// All changes below are visibility-only (private → protected / virtual added).
|
||||
// Zero logic change. Revert by deleting this block and restoring private slots.
|
||||
//
|
||||
// INVENTAIRE des ajouts ETM de ce fichier — ils vivent HORS de energyplugin/etm/ et
|
||||
// échappent donc au périmètre du Doxyfile ; ils sont documentés à la main, et la
|
||||
// définition de fait d'AGENTS.md les couvre explicitement. Toute nouvelle marque
|
||||
// [ETM] dans un en-tête amont DOIT être ajoutée ici :
|
||||
//
|
||||
// 1. degradedMode() — ajout ETM, virtuel, documenté ci-dessus.
|
||||
// 2. update() — virtual ajouté (le corps reste amont).
|
||||
// 3. prepareInformation, planSpotMarketCharging, planSurplusCharging,
|
||||
// adjustEvChargers, updateManualSoCsWithoutMeter, verifyOverloadProtection,
|
||||
// verifyOverloadProtectionRecovery, executeChargingAction
|
||||
// — visibilité seule (private → protected).
|
||||
// Sémantique amont inchangée : NON documentés
|
||||
// ici, la doc appartient à l'amont.
|
||||
// 4. internalEvChargers(), internalChargingActions(), internalRootMeter()
|
||||
// — accesseurs ETM neufs, documentés ci-dessous.
|
||||
protected slots:
|
||||
virtual void update(const QDateTime ¤tDateTime); // [ETM] virtual added
|
||||
void prepareInformation(const QDateTime ¤tDateTime); // [ETM] private → protected
|
||||
@ -114,8 +138,26 @@ protected:
|
||||
void executeChargingAction(EvCharger *evCharger, const ChargingAction &chargingAction, const QDateTime ¤tDateTime); // [ETM] private → protected
|
||||
|
||||
// [ETM] Read-only state accessors — inline, no copies, no logic.
|
||||
|
||||
/*!
|
||||
* \brief [ETM] Bornes VE enregistrées, en lecture seule.
|
||||
* \return Référence sur la table interne — aucune copie. Valide tant que le manager
|
||||
* vit ; ne pas conserver au-delà d'un cycle \c update().
|
||||
*/
|
||||
const QHash<ThingId, EvCharger *> &internalEvChargers() const { return m_evChargers; } // [ETM] new
|
||||
|
||||
/*!
|
||||
* \brief [ETM] Consignes de charge du cycle courant, en lecture seule.
|
||||
* \return Référence sur la table remplie par \c planSurplusCharging() /
|
||||
* \c planSpotMarketCharging(). N'a de sens qu'APRÈS ces appels dans le même cycle.
|
||||
*/
|
||||
const QHash<EvCharger *, ChargingActions> &internalChargingActions() const { return m_chargingActions; } // [ETM] new
|
||||
|
||||
/*!
|
||||
* \brief [ETM] Compteur principal du site, en lecture seule.
|
||||
* \return Pointeur non-propriétaire ; **peut être nul** si aucun root meter n'est
|
||||
* configuré — tout appelant doit le tester.
|
||||
*/
|
||||
RootMeter *internalRootMeter() const { return m_rootMeter; } // [ETM] new
|
||||
// [ETM] END
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user