- AGENTS.md : nouvelle entrée "3b révisé — délégation EV à l'amont" (beta hybride assumée, ETM réel en 3c, transplantation EV en 3g) ; modèle sécurité L0-L4 avec double déclenchement verifyOverloadProtection documenté (signal ligne 127 + appel cyclique ligne 313 SCM.cpp). - docs/SAFETY.md : document normatif 5 couches + signalisation locale optionnelle ; Variante B confirmée pour le repli L2 (EV au minimum + notification nymea + risque 1,4 kW accepté) ; table défaillances/couches corrigée (L1 ne couvre pas compteur hors ligne). - energyarbitrator.cpp update() : commentaire explicitant la correspondance exacte avec l'ordre SCM (1-4 parent, ETM entre 4 et 7, planSpot+planSurplus via getPlan). - rulebasedscheduler.h : Doxygen getPlan() marqué "PROXY AMONT POUR L'EV (beta)". - evadapter.h : Doxygen applyAction() marqué "Inactif jusqu'à 3g". Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
81 lines
3.3 KiB
C++
81 lines
3.3 KiB
C++
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
// Copyright (C) 2025 - 2026, Patrick Schurig / ETM PowerSync
|
|
#pragma once
|
|
|
|
#include <QObject>
|
|
#include "ischeduler.h"
|
|
|
|
class EvCharger;
|
|
class ChargingAction;
|
|
class EnergyArbitrator;
|
|
|
|
/*!
|
|
* \brief Planificateur basé sur les règles GPL (EV surplus + aWATTar).
|
|
*
|
|
* **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.
|
|
*
|
|
* À 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é".
|
|
*
|
|
* \invariant getPlan() retourne IMMÉDIATEMENT (AGENTS invariant 5).
|
|
* \invariant getPlan() retourne toujours un Plan valide (isValid() == true).
|
|
* \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.
|
|
*/
|
|
class RuleBasedScheduler : public QObject, public IScheduler
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
/*!
|
|
* \brief Constructeur.
|
|
* \param arbitrator Arbitre propriétaire — fournit l'accès à la planification et à l'état.
|
|
* \param parent Propriétaire Qt.
|
|
*/
|
|
explicit RuleBasedScheduler(EnergyArbitrator *arbitrator, QObject *parent = nullptr);
|
|
|
|
/*!
|
|
* \brief Retourne le plan pour le slot courant.
|
|
*
|
|
* **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.
|
|
*
|
|
* \param ctx SurplusContext courant. En 3b : seul \c ctx.timestamp est utilisé.
|
|
* \return Plan à 1 créneau couvrant \c ctx.timestamp + 60 s.
|
|
*/
|
|
Plan getPlan(const SurplusContext &ctx) override;
|
|
|
|
private:
|
|
/*!
|
|
* \brief Construit un LoadAction pour le cas "délai requis" (TimeRequirement).
|
|
* \param ev EvCharger concerné.
|
|
* \param ca ChargingAction planifiée (courant et phases déjà calculés par planSurplusCharging).
|
|
* \return LoadAction avec funding=Grid et reason "Deadline VE".
|
|
*/
|
|
LoadAction buildTimeRequirementAction(EvCharger *ev, const ChargingAction &ca) const;
|
|
|
|
/*!
|
|
* \brief Construit un LoadAction "courant minimum" pour les modes EcoMin.
|
|
* \param ev EvCharger concerné.
|
|
* \return LoadAction avec funding=Surplus, chargingEnabled=true, currentA=min.
|
|
*/
|
|
LoadAction buildMinCurrentAction(EvCharger *ev) const;
|
|
|
|
/*!
|
|
* \brief Construit un LoadAction "idle" (recharge désactivée, aucun surplus).
|
|
* \param ev EvCharger concerné.
|
|
* \return LoadAction avec chargingEnabled=false et reason appropriée.
|
|
*/
|
|
LoadAction buildIdleAction(EvCharger *ev) const;
|
|
|
|
EnergyArbitrator *m_arbitrator;
|
|
};
|