Fonctions pures (ni E/S ni horloge, « maintenant » = ctx.timestamp) qui portent toute la sémantique du plan reçu ; le SocketScheduler les enchaînera. - valider() : JSON → plan interne ou verdict à code stable. Créneaux à décalage horaire explicite, ordonnés, sans chevauchement ; loadId connu et unique ; kind cohérent avec le mécanisme et annoncé dans capabilities.kinds ; reason non vide ; valeurs dans leur domaine ; validUntil ; créneau courant ; COUVERTURE Q1 (toute charge disponible nommée). Abstention / expiré / invalide distingués ; un plan invalide n'est jamais converti en partie. `force` et champs réservés (annexe F) ignorés et listés. - motifFiltre() : code hors liste blanche → OPTIMIZER_DECISION sans paramètres ; sinon seules les clés documentées (optimizerParamKeys, testé contre le tableau d'INTERFACE.md), valeurs nombre/booléen/code [A-Za-z]+. Le texte libre reste dans ActionRecue::texte, assaini, jamais dans le motif. - substituer() : le créneau courant remplace les actions de l'ombre à leur place ; charges indisponibles → action de l'ombre ; bornes commandées sorties du proxy (waterfallEvIds) ; budget/draw de l'ombre jamais gardés. - finaliser() : après dispatch, puissance APPLIQUÉE, niveau unique « optimizer », financement dérivé de la mesure (surplus puis réseau), counts cohérents, budget et draw recalculés (Q3, Q4), `clamped`. LoadAction::clamped ajouté (interne, non publié dans ce lot). Aucun appelant dans ce commit : le moteur est inchangé. Tests (loadmodel) : 7 fonctions, dont 31 verdicts data-driven. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
32 lines
1.5 KiB
Prolog
32 lines
1.5 KiB
Prolog
include(../common/common.pri)
|
|
include(../../../energyplugin/energyplugin.pri)
|
|
|
|
CONFIG += testcase
|
|
|
|
TARGET = nymea-energy-loadmodel
|
|
|
|
# Cible VOLONTAIREMENT légère : aucun serveur nymea, aucun EnergyTestBase.
|
|
# La table de paliers et sameHardware() sont de la logique pure — les éprouver ici les rend
|
|
# rejouables en quelques millisecondes, là où la suite de simulation coûte un serveur complet
|
|
# par test (cf. AGENTS.md, « NE JAMAIS lancer la suite de simulation en un seul processus »).
|
|
|
|
HEADERS += testloadmodel.h
|
|
SOURCES += testloadmodel.cpp \
|
|
testoptimizerprotocol.cpp \
|
|
testdecisioncatalogue.cpp \
|
|
testoptimizerplan.cpp
|
|
# Fichiers de référence du sérialiseur GetPlan (brief 4 T1), lus et — sous ETM_REGENERER_GOLDEN=1 —
|
|
# réécrits DANS LES SOURCES : une régénération se relit en diff avant d'être commitée.
|
|
DEFINES += ETM_GOLDEN_DIR=\\\"$$PWD/data/optimizer\\\"
|
|
# Le test anti-dérive du catalogue (brief 4 T5) lit l'EN-TÊTE, pas une copie de sa liste.
|
|
DEFINES += ETM_DECISIONREASON_H=\\\"$$PWD/../../../energyplugin/etm/types/decisionreason.h\\\"
|
|
# Les clés de paramètres qu'un optimiseur peut transmettre (brief 4 T3) sont confrontées au TABLEAU
|
|
# d'INTERFACE.md, pas à une copie.
|
|
DEFINES += ETM_INTERFACE_MD=\\\"$$PWD/../../../INTERFACE.md\\\"
|
|
# Une base energy-forecast.sqlite ÉCRITE PAR etm67 (b7317f3) : la migration s'éprouve sur le
|
|
# vrai fichier, pas sur une imitation (testTheLearningLogMigratesAnEtm67TableInPlace).
|
|
RESOURCES += loadmodel.qrc
|
|
|
|
target.path = $$[QT_INSTALL_PREFIX]/bin
|
|
INSTALLS += target
|