diff --git a/docs/INVENTAIRE_MOCK.md b/docs/INVENTAIRE_MOCK.md index eb2e26e..e6e1bb9 100644 --- a/docs/INVENTAIRE_MOCK.md +++ b/docs/INVENTAIRE_MOCK.md @@ -221,7 +221,7 @@ qui ne mesure qu'une charge. | Classe | Porte | Ce qu'elle ouvre | |---|---|---| -| `pvPlane` | état `forecastCurveTransport` ; paramètres `kwp`, `performanceRatio`, `tempCoeffPctPerK`, `noctC` *(paramètres ajoutés au brief 3 T2)* | une courbe de prévision par le RPC (D2) ; la lecture des paramètres de conversion **sur le Thing**, par leur nom | +| `pvPlane` | état `forecastCurveTransport` ; paramètres `kwp`, `performanceRatio`, `tempCoeffPctPerK`, `noctC` *(paramètres ajoutés au brief 3 T2)* ; états `observedGti` (W/m², défaut 0) et `observedGtiTime` (epoch s, défaut 0), noms d'openmeteo *(etm68)* | une courbe de prévision par le RPC (D2) ; la lecture des paramètres de conversion **sur le Thing**, par leur nom ; le GTI observé par satellite rattaché à son pas (design §31.7) | | `solarInverter` | interface `smartmeterproducer` (`currentPower`, `totalEnergyProduced`) *(ajoutée au brief 3 T2)* | le seul producteur du mock : sans lui, « le site a-t-il un producteur ? » valait toujours non, et la production mesurée de l'enregistrement pour l'apprentissage n'était jamais publiée | **Ce qui reste introuvable ici** : un Thing **site** portant `snowfall` (le compteur fait office de diff --git a/energyplugin/etm/energyarbitrator.cpp b/energyplugin/etm/energyarbitrator.cpp index 04a6953..704f44b 100644 --- a/energyplugin/etm/energyarbitrator.cpp +++ b/energyplugin/etm/energyarbitrator.cpp @@ -2571,6 +2571,18 @@ void EnergyArbitrator::observerPourApprentissage(const QDateTime &now) if (!refus.isEmpty()) continue; // déjà journalisé par lireCourbePrevision() obs.planId = thing->id().toString(); + // LE GTI OBSERVÉ par satellite — deux états du Thing plan, lus par leur NOM comme + // `kwp`. `observedGtiTime == 0` est le défaut de l'état : rien n'a été publié. + if (thing->thingClass().hasStateType("observedGti") + && thing->thingClass().hasStateType("observedGtiTime")) { + const qint64 instant = thing->stateValue("observedGtiTime").toLongLong(); + bool ok = false; + const double gti = thing->stateValue("observedGti").toDouble(&ok); + if (instant > 0 && ok) { + obs.gtiObserved = gti; + obs.gtiObservedAt = instant; + } + } plans.append(obs); } // LA NEIGE QUI TOMBE, lue sur le site (état `snowfall`, une valeur de modèle) — pas la diff --git a/tests/auto/simulation/simulation.cpp b/tests/auto/simulation/simulation.cpp index d934493..67cb6cb 100644 --- a/tests/auto/simulation/simulation.cpp +++ b/tests/auto/simulation/simulation.cpp @@ -9220,6 +9220,32 @@ void Simulation::testTheLearningLogIsFedByTheCycle() QCOMPARE(r.value("measuredSource").toString(), QStringLiteral("power-balance-1min")); QCOMPARE(r.value("curtailed").toInt(), 0); QCOMPARE(r.value("valid").toInt(), 1); + // Les états observedGti* du mock sont à leur défaut (instant 0) : rien d'observé. + QVERIFY(r.value("gtiObserved").isNull()); + QVERIFY(r.value("gtiObservedAt").isNull()); } + + // 3. LE GTI OBSERVÉ (etm68), lu sur le Thing plan par le NOM de ses états. Publié pour + // t0 + 1 h, il moyenne la PREMIÈRE heure : il complète la ligne déjà écrite du pas t0, + // sur le plan qui le publie seulement. + const int complements0 = log->complementsTraites(); + tSud->setStateValue("observedGti", 640.0); + tSud->setStateValue("observedGtiTime", quint32(t0s + 3600)); + cycle(t0.addSecs(7200 + 300)); + QTRY_COMPARE(log->complementsTraites(), complements0 + 1); + l = lignes(t0s); + QCOMPARE(l.count(), 2); + for (const QVariantMap &r : l) { + if (r.value("planId").toString() == ThingId(sud).toString()) { + QCOMPARE(r.value("gtiObserved").toDouble(), 640.0); + QCOMPARE(r.value("gtiObservedSource").toString(), QStringLiteral("openmeteo-satellite-state")); + QCOMPARE(r.value("gtiObservedAt").toLongLong(), t0s + 3600); + } else { + QVERIFY(r.value("gtiObserved").isNull()); + } + QCOMPARE(r.value("valid").toInt(), 0); // inchangé : valid n'en dépend pas + } + for (const QVariantMap &r : lignes(t0s + 3600)) + QVERIFY(r.value("gtiObserved").isNull()); #endif } diff --git a/tests/mocks/plugins/energymocks/integrationpluginenergymocks.json b/tests/mocks/plugins/energymocks/integrationpluginenergymocks.json index a0fc9ea..c3d2e6a 100644 --- a/tests/mocks/plugins/energymocks/integrationpluginenergymocks.json +++ b/tests/mocks/plugins/energymocks/integrationpluginenergymocks.json @@ -1257,6 +1257,21 @@ "type": "QVariantMap", "defaultValue": {}, "cached": false + }, + { + "id": "dcc47d5e-a1bb-4059-b977-4a9f14eff63a", + "name": "observedGti", + "displayName": "Observed GTI (satellite, W/m²)", + "type": "double", + "defaultValue": 0 + }, + { + "id": "2663f64b-e4a8-435d-9ef9-75c09c8e1055", + "name": "observedGtiTime", + "displayName": "Observed GTI time (end of the averaged hour)", + "type": "uint", + "unit": "UnixTime", + "defaultValue": 0 } ] },