feat(prévision PV): le cycle lit observedGti/observedGtiTime sur le Thing plan
Lus par leur nom, comme kwp. observedGtiTime == 0 ou états absents : rien. Copies seulement (§11) : aucune décision ne lit ces valeurs, valid n'en dépend pas. Mock : pvPlane porte les états observedGti et observedGtiTime (noms d'openmeteo). testTheLearningLogIsFedByTheCycle : le GTI observé publié pour t0 + 1 h complète la ligne déjà écrite du pas t0, sur son plan seulement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
dd24cda445
commit
d80b7d02d6
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user