[3a] structs protocole + interfaces LoadAdapter/Scheduler (zéro comportement)
LoadAction (kind+funding+§6 fields), LoadDescriptor, SurplusContext (§5), Plan/Slot, ILoadAdapter, IScheduler — noms de champs = OPTIMIZER_PROTOCOL.md. energyplugin.pri inclut etm/etm.pri. Build Qt6 vert, aucun fichier upstream touché. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f4d5b20297
commit
4ae1939f93
@ -37,6 +37,8 @@ HEADERS += \
|
||||
$$PWD/types/smartchargingstate.h \
|
||||
$$PWD/types/timeframe.h \
|
||||
|
||||
include($$PWD/etm/etm.pri)
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/energymanagerconfiguration.cpp \
|
||||
$$PWD/energysettings.cpp \
|
||||
|
||||
37
energyplugin/etm/adapters/iloadadapter.h
Normal file
37
energyplugin/etm/adapters/iloadadapter.h
Normal file
@ -0,0 +1,37 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright (C) 2025 - 2026, Patrick Schurig / ETM PowerSync
|
||||
#pragma once
|
||||
|
||||
#include <QDateTime>
|
||||
#include "../types/loadaction.h"
|
||||
#include "../types/loaddescriptor.h"
|
||||
#include "../types/surpluscontext.h"
|
||||
|
||||
// Vue runtime minimale qu'un adaptateur expose à l'arbitre.
|
||||
struct LoadTelemetry {
|
||||
double currentPowerW = 0;
|
||||
bool available = true; // faux si l'appareil nymea est absent/erreur
|
||||
QDateTime lastActionAt;
|
||||
};
|
||||
|
||||
// Interface pure — les implémentations concrètes héritent de QObject + ILoadAdapter.
|
||||
// Signaux (telemetryChanged, descriptorChanged) déclarés dans les classes concrètes.
|
||||
class ILoadAdapter {
|
||||
public:
|
||||
virtual ~ILoadAdapter() = default;
|
||||
|
||||
// Déclaration statique : capacités, limites, priorité, needs.
|
||||
virtual LoadDescriptor descriptor() const = 0;
|
||||
|
||||
// Télémétrie runtime (courant, disponibilité, dernière action).
|
||||
virtual LoadTelemetry telemetry() const = 0;
|
||||
|
||||
// Construit l'entrée §5 loads[] pour SurplusContext.
|
||||
// Inclut declared, telemetry type-spécifique, learned courant.
|
||||
virtual LoadContext toLoadContext() const = 0;
|
||||
|
||||
// Applique l'action. Retourne ce qui a réellement été appliqué
|
||||
// (après écrêtage matériel). L'arbitre a déjà écrêté selon les limites
|
||||
// et le budget — c'est le second filet.
|
||||
virtual LoadAction applyAction(const LoadAction &action) = 0;
|
||||
};
|
||||
7
energyplugin/etm/etm.pri
Normal file
7
energyplugin/etm/etm.pri
Normal file
@ -0,0 +1,7 @@
|
||||
HEADERS += \
|
||||
$$PWD/types/loadaction.h \
|
||||
$$PWD/types/loaddescriptor.h \
|
||||
$$PWD/types/surpluscontext.h \
|
||||
$$PWD/types/plan.h \
|
||||
$$PWD/adapters/iloadadapter.h \
|
||||
$$PWD/scheduler/ischeduler.h \
|
||||
19
energyplugin/etm/scheduler/ischeduler.h
Normal file
19
energyplugin/etm/scheduler/ischeduler.h
Normal file
@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright (C) 2025 - 2026, Patrick Schurig / ETM PowerSync
|
||||
#pragma once
|
||||
|
||||
#include "../types/surpluscontext.h"
|
||||
#include "../types/plan.h"
|
||||
|
||||
// Interface pure — implémentations concrètes héritent de QObject + IScheduler.
|
||||
//
|
||||
// Règle : getPlan() DOIT retourner immédiatement (modèle cache §AGENTS invariant 5).
|
||||
// SocketScheduler renvoie son dernier plan en cache et recalcule en fond.
|
||||
// SocketScheduler embarque un RuleBasedScheduler comme fallback et renvoie
|
||||
// TOUJOURS un Plan exploitable — l'abstain du protocole n'atteint jamais l'arbitre.
|
||||
class IScheduler {
|
||||
public:
|
||||
virtual ~IScheduler() = default;
|
||||
|
||||
virtual Plan getPlan(const SurplusContext &ctx) = 0;
|
||||
};
|
||||
36
energyplugin/etm/types/loadaction.h
Normal file
36
energyplugin/etm/types/loadaction.h
Normal file
@ -0,0 +1,36 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright (C) 2025 - 2026, Patrick Schurig / ETM PowerSync
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
// Noms de champs : identiques à OPTIMIZER_PROTOCOL.md §6 (font autorité).
|
||||
// `funding` est interne à l'arbitre — absent du JSON protocole.
|
||||
struct LoadAction {
|
||||
enum Kind { Setpoint, Stage, State, Constraint };
|
||||
enum Funding { Surplus, Grid }; // interne, non sérialisé
|
||||
enum Source { Solar, GridSource }; // "solar"|"grid" — Setpoint battery
|
||||
enum Permission { Allow, Forbid }; // "allow"|"forbid" — Constraint
|
||||
|
||||
QString loadId;
|
||||
Kind kind = Setpoint;
|
||||
Funding funding = Surplus;
|
||||
|
||||
// Setpoint — evcharger
|
||||
bool chargingEnabled = false;
|
||||
double currentA = 0;
|
||||
uint phaseCount = 0;
|
||||
// Setpoint — battery
|
||||
double powerW = 0;
|
||||
Source source = Solar;
|
||||
// Stage — relay-stages (ECS)
|
||||
int stage = 0;
|
||||
// State — sg-ready
|
||||
int state = 0;
|
||||
// Constraint — battery v1
|
||||
Permission charge = Allow;
|
||||
Permission discharge = Allow;
|
||||
|
||||
QString reason; // obligatoire, non vide, français (AGENTS invariant 7)
|
||||
double estimatedPowerW = 0; // hint pour comptabilité arbitre (rempli par le scheduler)
|
||||
};
|
||||
54
energyplugin/etm/types/loaddescriptor.h
Normal file
54
energyplugin/etm/types/loaddescriptor.h
Normal file
@ -0,0 +1,54 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright (C) 2025 - 2026, Patrick Schurig / ETM PowerSync
|
||||
#pragma once
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include "loadaction.h"
|
||||
|
||||
// Capacités déclarées par l'installateur (plaque signalétique, câblage).
|
||||
// Noms de champs : OPTIMIZER_PROTOCOL.md §5 loads[].declared
|
||||
struct LoadDeclared {
|
||||
// evcharger
|
||||
double minA = 0;
|
||||
double maxA = 0;
|
||||
int phases = 0;
|
||||
// relay-stages (ECS) — puissances en W : [0, 1200, 2400]
|
||||
QList<int> stages;
|
||||
// battery
|
||||
double maxChargeW = 0;
|
||||
double maxDischargeW = 0;
|
||||
double capacityWh = 0;
|
||||
int reserveSocPercent = 0;
|
||||
// sg-ready : états toujours 1-4, pas de déclaration nécessaire
|
||||
};
|
||||
|
||||
// OPTIMIZER_PROTOCOL.md §5 loads[].limits
|
||||
struct LoadLimits {
|
||||
int minOnS = 0;
|
||||
int minOffS = 0;
|
||||
int chargingEnabledLockS = 0; // evcharger
|
||||
int currentChangeLockS = 0; // evcharger
|
||||
int minStateHoldS = 0; // sg-ready
|
||||
};
|
||||
|
||||
// OPTIMIZER_PROTOCOL.md §5 loads[].needs
|
||||
struct LoadNeeds {
|
||||
int targetSocPercent = 0;
|
||||
QDateTime deadline;
|
||||
QString dailyDeadline; // "18:00"
|
||||
int minEnergyWhPerDay = 0;
|
||||
};
|
||||
|
||||
// Déclaration statique qu'un ILoadAdapter expose à l'arbitre.
|
||||
struct LoadDescriptor {
|
||||
QString id;
|
||||
QString label;
|
||||
QString adapter; // "evcharger"|"relay-stages"|"sg-ready"|"battery"
|
||||
int priority = 0;
|
||||
LoadDeclared declared;
|
||||
LoadLimits limits;
|
||||
LoadNeeds needs;
|
||||
QList<LoadAction::Kind> supportedKinds;
|
||||
};
|
||||
33
energyplugin/etm/types/plan.h
Normal file
33
energyplugin/etm/types/plan.h
Normal file
@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright (C) 2025 - 2026, Patrick Schurig / ETM PowerSync
|
||||
#pragma once
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include "loadaction.h"
|
||||
|
||||
// OPTIMIZER_PROTOCOL.md §6 (noms de champs identiques).
|
||||
|
||||
struct Slot {
|
||||
QDateTime from;
|
||||
QDateTime to;
|
||||
QList<LoadAction> actions; // ordonnées par priorité de LoadDescriptor
|
||||
};
|
||||
|
||||
struct Plan {
|
||||
QString planId;
|
||||
QString strategy;
|
||||
QList<Slot> slots;
|
||||
|
||||
// Créneau couvrant dt — créneau vide (from==to==invalid) si aucun.
|
||||
Slot slotCovering(const QDateTime &dt) const {
|
||||
for (const Slot &s : slots) {
|
||||
if (dt >= s.from && dt < s.to)
|
||||
return s;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool isValid() const { return !slots.isEmpty(); }
|
||||
};
|
||||
95
energyplugin/etm/types/surpluscontext.h
Normal file
95
energyplugin/etm/types/surpluscontext.h
Normal file
@ -0,0 +1,95 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright (C) 2025 - 2026, Patrick Schurig / ETM PowerSync
|
||||
#pragma once
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include "loaddescriptor.h"
|
||||
|
||||
// Structures miroirs de OPTIMIZER_PROTOCOL.md §5 (noms de champs identiques).
|
||||
|
||||
struct SurplusSite {
|
||||
double contractedPowerW = 0;
|
||||
QList<double> phaseLimitA; // [63.0, 63.0, 63.0]
|
||||
};
|
||||
|
||||
struct SurplusMeter {
|
||||
double importW = 0;
|
||||
double exportW = 0;
|
||||
QList<double> perPhaseA;
|
||||
};
|
||||
|
||||
struct SurplusPv {
|
||||
double currentW = 0;
|
||||
};
|
||||
|
||||
struct SurplusBattery {
|
||||
bool present = false;
|
||||
double socPercent = 0;
|
||||
double powerW = 0;
|
||||
double capacityWh = 0;
|
||||
int reserveSocPercent = 0;
|
||||
double maxChargeW = 0;
|
||||
double maxDischargeW = 0;
|
||||
};
|
||||
|
||||
struct TariffEntry {
|
||||
QDateTime from;
|
||||
QString label;
|
||||
double priceCtkWh = 0;
|
||||
};
|
||||
|
||||
struct SurplusTariff {
|
||||
QString provider;
|
||||
TariffEntry current;
|
||||
QList<TariffEntry> next;
|
||||
};
|
||||
|
||||
// Télémétrie d'une charge dans le contexte §5 loads[].telemetry
|
||||
struct LoadContextTelemetry {
|
||||
double currentPowerW = 0;
|
||||
// evcharger
|
||||
bool pluggedIn = false;
|
||||
bool charging = false;
|
||||
double sessionWh = 0;
|
||||
// relay-stages
|
||||
int stage = 0;
|
||||
// sg-ready
|
||||
int state = 0;
|
||||
// battery / electricvehicle
|
||||
double socPercent = 0;
|
||||
QDateTime lastSwitch;
|
||||
};
|
||||
|
||||
// Données apprises par l'optimiseur §8 (renvoyées pour persistance)
|
||||
struct LoadLearned {
|
||||
double dailyEnergyWh = 0;
|
||||
double confidence = 0.0; // 0–1 ; < 0.7 → "profil en apprentissage"
|
||||
};
|
||||
|
||||
// Entrée loads[] dans le SurplusContext envoyé au scheduler.
|
||||
// Construit par l'arbitre depuis ILoadAdapter::descriptor() + telemetry().
|
||||
struct LoadContext {
|
||||
QString id;
|
||||
QString adapter; // "evcharger"|"relay-stages"|"sg-ready"|"battery"
|
||||
QString label;
|
||||
int priority = 0;
|
||||
LoadDeclared declared;
|
||||
LoadLearned learned;
|
||||
LoadContextTelemetry telemetry;
|
||||
LoadNeeds needs;
|
||||
LoadLimits limits;
|
||||
};
|
||||
|
||||
// OPTIMIZER_PROTOCOL.md §5 — transmis au scheduler à chaque cycle.
|
||||
struct SurplusContext {
|
||||
QDateTime timestamp;
|
||||
SurplusSite site;
|
||||
SurplusMeter meter;
|
||||
SurplusPv pv;
|
||||
SurplusBattery battery;
|
||||
QList<LoadContext> loads;
|
||||
SurplusTariff tariff;
|
||||
// forecast : opaque, transmis tel quel si présent — réservé V2
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user