diff --git a/energyplugin/nymeaenergyjsonhandler.cpp b/energyplugin/nymeaenergyjsonhandler.cpp index 9421e14..4e38786 100644 --- a/energyplugin/nymeaenergyjsonhandler.cpp +++ b/energyplugin/nymeaenergyjsonhandler.cpp @@ -187,7 +187,13 @@ NymeaEnergyJsonHandler::NymeaEnergyJsonHandler(SpotMarketManager *spotMarketMana sgStateItem.insert("relays", QVariantList() << enumValueName(String)); sgStateItem.insert("estimatedPowerW", enumValueName(Double)); QVariantMap sgItem; - sgItem.insert("states", QVariantList() << sgStateItem); + // « states » est OPTIONNEL ici, et c'est le mur documenté en LM-302 : GET sérialise la + // charge via le méta-objet, donc TOUTES les propriétés déclarées — y compris un sgReady + // VIDE pour un relay-router. Exiger « states » à l'intérieur casserait le va-et-vient + // Get → Set de l'app sur toute charge non SG-Ready. Défaut constaté au banc le + // 2026-08-10, sur la première tentative réelle de SetLoadConfig. + // L'exigence réelle (states non vide, état 2 présent) est tenue par LoadConfig::isValid(). + sgItem.insert("o:states", QVariantList() << sgStateItem); sgItem.insert("o:minStateHoldS", enumValueName(Uint)); loadItem.insert("o:sgReady", sgItem); // sg-ready (LM-300) loadItem.insert("o:minOnS", enumValueName(Uint)); diff --git a/tests/auto/simulation/simulation.cpp b/tests/auto/simulation/simulation.cpp index 8c32140..26b73d4 100644 --- a/tests/auto/simulation/simulation.cpp +++ b/tests/auto/simulation/simulation.cpp @@ -486,6 +486,17 @@ void Simulation::testLoadConfigRpc() QCOMPARE(relays.last().toMap().value("powerW").toInt(), 1500); QCOMPARE(relayGot.value("minOnS").toInt(), 60); + // 3bis. VA-ET-VIENT : réinjecter tel quel ce que GET vient de rendre. C'est le geste réel + // de l'app — lire, modifier un champ, réécrire — et il échouait : GET sérialise via le + // méta-objet, donc TOUTES les propriétés déclarées, y compris un « sgReady » VIDE sur une + // charge qui n'est pas SG-Ready. Le schéma SET exigeait « states » dès que la clé était + // présente, et nymea rejetait AVANT le handler. Constaté au banc le 2026-08-10, sur la + // première tentative réelle de SetLoadConfig — aucun test ne faisait ce va-et-vient. + resp = injectAndWait("NymeaEnergy.SetLoadConfig", {{"loadConfigs", got}}); + QCOMPARE(resp.toMap().value("params").toMap().value("energyError").toString(), QString("EnergyErrorNoError")); + resp = injectAndWait("NymeaEnergy.GetLoadConfig"); + QCOMPARE(resp.toMap().value("params").toMap().value("loadConfigs").toList().size(), 3); + // 4. Fichier persisté. QVERIFY(QFileInfo::exists(cfgPath));