// SPDX-License-Identifier: GPL-3.0-or-later // Copyright (C) 2025 - 2026, Patrick Schurig / ETM PowerSync #pragma once #include #include #include "iloadadapter.h" class EvCharger; class EnergyArbitrator; /*! * \brief Adaptateur pour une borne de recharge VE (interface evcharger nymea). * * Traduit les LoadAction(Setpoint) en appels matériels via * EnergyArbitrator::doExecuteChargingAction() — le seul chemin d'exécution. * * \invariant applyAction() rejette silencieusement toute LoadAction dont \c reason est vide. * \invariant currentA est écrêté à [maxChargingCurrentMinValue, maxChargingCurrentMaxValue]. * \invariant phaseCount est écrêté selon canSetPhaseCount() et phaseCount() du EvCharger. * \invariant Les kinds autres que Setpoint sont retournés sans effet. */ class EvAdapter : public QObject, public ILoadAdapter { Q_OBJECT public: /*! * \brief Constructeur. * \param evCharger Borne VE à piloter (doit rester valide tant que l'adaptateur existe). * \param parent EnergyArbitrator propriétaire — utilisé pour l'exécution matérielle. */ explicit EvAdapter(EvCharger *evCharger, EnergyArbitrator *parent); /*! * \brief Retourne la description statique de la charge. * \return LoadDescriptor construit depuis les capacités actuelles du EvCharger. * \note Recalculé à chaque appel depuis l'état nymea du Thing. */ LoadDescriptor descriptor() const override; /*! * \brief Retourne la télémétrie runtime (puissance mesurée, disponibilité). * \return LoadTelemetry avec currentPowerW, available et lastActionAt. */ LoadTelemetry telemetry() const override; /*! * \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; /*! * \brief Applique une consigne Setpoint sur la borne VE. * * **Inactif jusqu'à 3g** : non appelée par \c EnergyArbitrator::update() en beta. * Le dispatch EV passe par \c adjustEvChargers() amont (hérité). Cette méthode * sera câblée lors de la transplantation EV dans \c RuleBasedScheduler (phase 3g). * \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. * \invariant currentA écrêté à [minValue, maxValue] avant envoi à executeChargingAction. * \invariant phaseCount ajusté selon canSetPhaseCount() du EvCharger. */ LoadAction applyAction(const LoadAction &action, const QDateTime &now) override; /*! \brief Borne VE sous-jacente (lecture). */ EvCharger *evCharger() const { return m_charger; } private: EvCharger *m_charger; EnergyArbitrator *m_parent; QDateTime m_lastActionAt; };