powersync-energy-plugin-nymea (1.15.2+etm14) trixie; urgency=medium * Contrat : loads[] de GetLoadTelemetry n'est PAS en correspondance 1:1 avec GetLoadConfig. Une charge peut être arbitrée et publiée sans exister dans la configuration. Cas réel, vérifié au banc : « pac-terrain » est la PAC SG-Ready CODÉE EN DUR d'energypluginnymea.cpp (contacts K1/K2 = Relay4/Relay5, états {3: 1500 W, 4: 3000 W}, minStateHoldS 300), donc pleinement arbitrée — elle consomme du budget, porte des verrous, apparaît en télémétrie — et pourtant inconfigurable : ni renommage, ni rang, ni domain, ni enabled:false. Un client qui suppose la correspondance affichera une charge sans nom ni domaine, ou cherchera une configuration inexistante. INTERFACE.md porte désormais la règle de détection : un loadId de loads[] sans équivalent dans GetLoadConfig est une charge NON CONFIGURABLE — afficher le loadId, la traiter comme non classée, ne proposer aucun écran de réglage. Aucun champ n'est ajouté à la charge utile pour le signaler : « configurable: false » préjugerait du sort de cette charge, qui n'est pas tranché. * Aucun changement de comportement moteur. Seuls la documentation de contrat, le journal de vérification et les tests bougent — le binaire est fonctionnellement identique à +etm13, dont il ne se distingue que par ce changelog. La version est incrémentée parce qu'un artefact publié doit se relire dans sa propre source : livrer +etm13 avec un changelog embarqué différent de celui du dépôt aurait recréé, en petit, la divergence que ce lot passe son temps à fermer. * Test : runtimeView() est SUBSTANTIELLE pour les quatre adaptateurs, et c'est prouvé par mutation. La pure virtuelle force à RÉPONDRE, pas à répondre quelque chose : un « return LoadRuntimeView{}; » compilerait, passerait le dispatch, et sortirait de la télémétrie sans bruit — le client verrait une charge sans mécanisme ni verrou, indistinguable d'une charge libre. testRuntimeViewIsSubstantial() amène chaque adaptateur dans un état non trivial puis exige les valeurs runtime réelles (palier appliqué, consigne, état normé, pourcentage dérivé à 75 % — ni 0, ni 100, ni la consigne), les verrous en secondes restantes ET leur expiration, et les codes de défaut THING_MISSING et UNUSABLE_ENCODING. Deux mutants « vue vide » ont été introduits puis retirés : le test échoue sur chacun. * Le déploiement sur box entre au dépôt : etm-powersync-deploy/deploy.sh, après l'incident du 2026-08-25 où .75 a été rétrogradée de +etm12 à +etm9. Trois causes composées — un glob sur un répertoire de dépôt qui accumulait quatre paquets périmés, un dpkg -i qui autorise la rétrogradation par défaut, et aucune relecture de version après coup. La recette fautive figurait aussi dans docs/TEST_TERRAIN.md §b ; elle est remplacée. Le verrou décisif est l'ARCHIVAGE avant dépôt : la règle sudoers de la box porte elle-même un « *.deb » et ne peut pas être resserrée sans root, mais avec un seul paquet dans le répertoire ce glob ne peut plus désigner qu'un fichier — y compris pour un geste fait à la main. -- Patrick Schurig Tue, 25 Aug 2026 14:00:00 +0200 powersync-energy-plugin-nymea (1.15.2+etm13) trixie; urgency=medium * Frontière de télémétrie d'arbitrage. Constat d'origine, vérifié au banc : 90 s d'écoute, arbitre actif, ~2,9 kW produits et ~2 kW exportés — ZÉRO notification NymeaEnergy.*. L'état runtime de l'arbitre (allocation, budget, verrous, paliers, disponibilité, motifs) ne franchissait aucune frontière RPC : il vivait exclusivement dans qCInfo(dcNymeaEnergy). Expliquer les décisions au client — promesse présente dans les deux versions de gamme — n'avait donc aucun transport. Ajout de NymeaEnergy.GetLoadTelemetry et de sa notification LoadTelemetryChanged, MÊME charge utile pour les deux. * Aucune phrase composée par la box. La box transporte un CODE et des PARAMÈTRES ; la phrase est fabriquée par le client, dans la langue de son utilisateur. Justification vérifiée : la locale nymea est PAR CONNEXION (JSONRPC.Hello o:locale), donc deux utilisateurs d'une même box peuvent avoir deux langues — impossible à servir avec une phrase composée en C++ ; et NymeaEnergyJsonHandler est un JsonHandler sans pluginId, donc structurellement hors du catalogue de traduction nymea : rien ne rattraperait une phrase française émise là. * LoadAction::reason devient {code, params}. La ligne FRANÇAISE du journal est désormais RENDUE à partir du code par une fonction de rendu unique (renderFr), et non maintenue en parallèle : deux écritures parallèles divergeraient, et c'est le diagnostic terrain qui deviendrait faux. Le catalogue de 19 codes est EXTRAIT des sites existants, pas inventé ; les motifs d'ECS-309 et ECS-309-b sont repris mot pour mot. Prouvé par comparaison de traces (1726 lignes de journal identiques en simulation) et par un test de rendu à table d'or qui échoue au premier code ajouté sans phrase attendue. * Le libellé de la charge n'entre PAS dans la charge utile RPC : c'est de la langue naturelle saisie par l'installateur. Il est substitué au moment du RENDU, par l'appelant qui le connaît. Le client résout le sien via GetLoadConfig. * Les verrous sortent en SECONDES RESTANTES, pas en watts. lockMinPowerW/lockMaxPowerW sont un artefact du mécanisme d'allocation, illisible pour un utilisateur. Ceci n'enfreint pas ECS-306 : cette exigence interdit qu'un index de PALIER franchisse la frontière d'ALLOCATION ; une valeur d'AFFICHAGE sortante est un autre chemin. * Le mécanisme sort en union discriminée (relay | variable | sgReady), comme LoadConfig : kind discrimine, chaque variante porte SA charge utile et seulement la sienne. Toutes les clés internes optionnelles au schéma (règle LM-302). ILoadAdapter::runtimeView() est PURE VIRTUELLE à dessein : un mécanisme ajouté qui hériterait d'un défaut vide sortirait de la télémétrie sans bruit, et le client verrait une charge sans mécanisme ni verrou — indistinguable d'une charge libre. * budget publié : surplusW, evReservedW, recreditedW, allocatedW, remainingW, avec l'identité surplus + recrédit − alloué == restant. recreditedW n'est pas décoratif : le waterfall rend à chaque charge sa consommation de début de cycle avant d'arrondir (anti-clignotement, correction B). Sans ce terme, l'identité serait fausse DÈS QU'UNE CHARGE CONSOMME, c'est-à- dire dans le cas normal, et le client chercherait un écart inexplicable. Il rend aussi lisible l'artefact de banc documenté dans AGENTS.md (relais sans mesure + rootmeter aveugle → recrédit du nominal commandé). * Champs omis, jamais nuls (règle maison) : timestamp absent = aucun cycle d'arbitrage depuis le démarrage — en forger un se lirait « cycle exécuté, rien à allouer », soit le mensonge même que ce champ existe pour empêcher ; budget absent = mode dégradé L2, où la planification est suspendue et où publier des zéros se lirait « rien à allouer ». * Cadence : émission sur changement QUALITATIF ou variation d'allocation > 50 W, plus un battement de cœur de 60 s même sans changement. C'est le battement qui rend un arbitre FIGÉ détectable : les notifications continuent d'arriver tandis que le timestamp cesse d'avancer. Sans lui, « installation stable » et « moteur arrêté » sont le même silence. Toute notification relance le décompte : la cadence totale reste d'environ une par minute. * GetChargingSchedules rend désormais degradedMode. Il était POUSSÉ en notification seule : un client connecté après la bascule ne pouvait pas savoir dans quel état il se trouvait. Règle : tout élément runtime a un Get* ET un *Changed, jamais une notification seule. La bascule ET la sortie du mode dégradé publient aussi la télémétrie immédiatement. * LoadConfig : champ optionnel domain, énumération FERMÉE (ecs · ev · heating · hvac · battery). PURE métadonnée d'intention — l'arbitre ne la lit pas, aucun comportement moteur ne change ; elle enregistre le choix de l'installateur. Codes, jamais libellés. Valeur absente = charge non classée : le plugin ne la range pas d'office, parce qu'un classement inventé serait indistinguable d'un classement choisi. Valeur hors énumération rejetée en bloc. Elle ne préempte pas la couche domaine à venir : elle en deviendra le discriminant. * Règle 7-c, deux silences fermés : le retour idempotent du RelayRouter et celui du SgReadyAdapter étaient MUETS, si bien que « consigne reçue, palier déjà bon » ne se distinguait pas de « l'action n'est jamais parvenue à l'adaptateur » — et c'est justement le cas ordinaire qu'on vient vérifier quand une charge ne bouge pas. Journalisés au même niveau que la branche qui commute (7-d, symétrie). * Tests : rendu français à table d'or (19 codes + repli d'un code hors catalogue), télémétrie de bout en bout (notification non nulle, snapshot ≡ notification, union de mécanisme entière, verrous en secondes, seuil qui ne mord pas sur 10 W, battement à timestamp figé, reprise à froid du mode dégradé par les DEUX portes, contrôle mécanique « zéro langue naturelle »), et domain (aller-retour, rejet hors énumération, charge non classée, absence d'effet sur l'arbitrage). Suites : simulation 37/37, charging 46/46, spotmarket 32/32. -- Patrick Schurig Tue, 25 Aug 2026 12:00:00 +0200 powersync-energy-plugin-nymea (1.15.2+etm12) trixie; urgency=medium * ECS-411-b — la reprise du palier au démarrage s'annonce toujours, et publie ce qu'elle a LU : l'état de chaque relais avec sa puissance déclarée, le palier retenu, la branche de déduction et la somme lue. La correspondance exacte ne journalisait qu'au palier non nul ; au palier 0 — le cas de l'armement minOff, celui qu'on vient précisément observer — le journal était muet, et « relais lus, tous ouverts » ne se distinguait pas de « reprise non exécutée ». Une reprise avec relais injoignable passe en avertissement : le palier déduit est plausible mais la lecture est incertaine. * Défaut de fond trouvé PAR ce relevé, et corrigé. La puissance nominale de chaque relais était redéduite des encodages solo de la table de paliers, or la déduplication par puissance peut évincer un encodage solo : avec un câblage 500/1000/1500, le palier 1500 est encodé {500,1000} et le relais 1500 n'apparaît seul nulle part. Sa nominale valait 0, donc un démarrage sur ce seul relais annonçait palier 0 pendant que 1500 W circulaient — l'annonce en sous-estimation qu'ECS-411 existe pour interdire, que le silence au palier 0 couvrait. La nominale est prise à la déclaration. * Règle 7-c d'AGENTS.md : un silence ne doit jamais être ambigu. Journaliser l'issue, pas seulement l'issue remarquable ; journaliser ce qui a été lu, pas seulement ce qui en est déduit. Trois autres endroits signalés dans spec_ecs.md, non corrigés. * Protocole de mesure (RELEVE_ECS306 §3.0) : un état nymea n'émet changed() que si la valeur bouge, donc une grandeur forcée constante déclenche le watchdog L2 en 90 s et fait mesurer le watchdog au lieu de l'arbitrage. Constaté au banc. * ECS-410-b — l'issue de ClearLoadFault est journalisée, et par l'ARBITRE. Elle distingue trois cas : défaut levé, aucun défaut à lever, adaptateur introuvable. C'est le seul levier de reprise à distance : ECS-410 pose un verrou collant que seuls ce RPC ou une reconstruction lèvent, et sans issue lisible l'opérateur ne sait pas si son geste a agi — il relance, puis conclut que le système est cassé. Écrite au niveau de l'arbitre, la ligne couvre les quatre adaptateurs d'un coup et ne peut pas être oubliée par un adaptateur futur. ILoadAdapter::clearFault() rend désormais un bool plutôt que void : le type de retour force chaque implémentation à répondre à la question, là où une consigne de journalisation se serait oubliée à la cinquième. * Règle 7-d d'AGENTS.md : un refus DOIT être au moins aussi visible que l'application correspondante. Le refus par verrou minStateHold de SgReadyAdapter était en qCDebug quand l'application, dix lignes plus bas, était en qCInfo — un resserrement de la journalisation aurait fait disparaître le refus AVANT le succès, ne laissant au journal que les décisions abouties. Or un refus est plus informatif : il dit qu'une décision a été prise et n'a pas été exécutée. Les autres qCDebug du moteur ont été vérifiés symétriques. * Retour idempotent du routeur (relayrouter.cpp:228) : DIFFÉRÉ, et en qCDebug le jour venu. C'est le cas le plus fréquent — plusieurs milliers de lignes par jour — et l'ambiguïté y est partiellement couverte, le scheduler journalisant sa décision et l'armement à froid s'exécutant avant ce retour. * Suite complète : 112 tests, 0 échec. Tous les correctifs sont vérifiés échouant sans eux. -- Patrick Schurig Thu, 13 Aug 2026 21:00:00 +0200 powersync-energy-plugin-nymea (1.15.2+etm11) trixie; urgency=medium * ECS-309-b — le motif ne nomme un verrou que si ce verrou a déplacé la consigne. Le critère était « consigne > budget », vrai dès que le budget passe sous zéro à palier nul : 0 > -389. Le motif annonçait alors « Verrou minOn — chauffe-eau maintenue à 0 W (puissance engagée, budget -389 W) » — un verrou qui ne mordait pas, sur une puissance engagée nulle, quand le soutirage était la seule cause. Le critère compare désormais la consigne appliquée à la consigne VOULUE avant écrêtage : relevée → minOn, rabaissée → minOff, inchangée → le budget. Les deux branches se lisent sur le même axe. * Constaté au banc le 2026-08-13 sur +etm10, sept fois en quatre heures, toujours au cycle suivant un palier 0. Le défaut est antérieur à ECS-309, qui a ajouté la branche minOff après lui sans voir que la première capturait déjà un cas étranger. * Il ne s'agissait pas que de lisibilité. La branche minOn étant évaluée en premier, ce défaut masquait le motif d'armement à froid d'ECS-412 chaque fois que le budget était négatif au redémarrage — soit au fond du creux, précisément l'instant où il faut redémarrer pour observer minOff. La campagne aurait mesuré le mauvais verrou. * Suite complète : 112 tests, 0 échec. Le cas est vérifié échouant sans le correctif, où il reproduit le texte exact relevé sur la machine. -- Patrick Schurig Thu, 13 Aug 2026 08:00:00 +0200 powersync-energy-plugin-nymea (1.15.2+etm10) trixie; urgency=medium * ECS-309 — motif de décision fidèle au mécanisme. Lorsqu'un verrou, et non le budget, produit le palier appliqué, le decisionReason nomme le verrou et la contrainte qu'il impose. Le chemin minOff — celui de l'armement à froid d'ECS-412 — publiait « Surplus insuffisant (7706 W) » alors que 7706 W étaient précisément disponibles : la décision était juste, le motif accusait le budget. Il cite maintenant le budget DISPONIBLE, pour couper court à l'explication budgétaire. * Les trois causes sont distinguables à la lecture : budget réellement insuffisant, verrou minOn maintenant un palier au-dessus du budget, verrou minOff empêchant l'enclenchement. Les cas minOn et minStateHold (PAC) étaient déjà fidèles. * La règle 7 d'AGENTS.md exigeait un motif non vide ; ECS-309 l'étend de la présence à la fidélité, et exige que les tests portent sur le mécanisme annoncé plutôt que sur la non-vacuité de la chaîne — un test « motif non vide » n'aurait rien vu. -- Patrick Schurig Tue, 11 Aug 2026 10:00:00 +0200 powersync-energy-plugin-nymea (1.15.2+etm9) trixie; urgency=medium * Corrige le va-et-vient JSON-RPC cassé par l'union LM-300. GetLoadConfig sérialise une charge 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 SetLoadConfig exigeant « states » dès que la clé est présente, nymea rejetait la requête AVANT le handler : lire puis réécrire une configuration relay-router était impossible. « states » et « minStateHoldS » passent en optionnels ; l'exigence réelle (states non vide, état 2 présent) reste tenue par LoadConfig::isValid(). * Constaté au banc à la première tentative réelle de SetLoadConfig. Aucun test ne rejouait le geste de l'app — lire, modifier un champ, réécrire. C'est désormais le cas (testLoadConfigRpc §3bis, vérifié échouant sans le correctif). -- Patrick Schurig Mon, 10 Aug 2026 09:00:00 +0200 powersync-energy-plugin-nymea (1.15.2+etm8) trixie; urgency=medium * ECS-110-b — un Thing n'appartient qu'à UNE charge active. Le cas général n'était pas couvert : deux charges de configuration pouvaient revendiquer le même relais (déclaré à la fois dans la charge ECS et dans un état SG-Ready), soit deux commandes contradictoires sur un organe et sa puissance comptée deux fois dans le budget. LoadConfig::isValid() s'arrête au bord d'une charge ; la vérification d'ensemble est portée par LoadConfigStore::validateSet(). * Deux doublons intra-charge également refusés : deux étages relay-router sur le même Thing (le routeur les fusionnait en silence en annonçant le double de la puissance) et un relais répété dans un même état SG-Ready. Un relais présent dans PLUSIEURS états reste légitime — l'état 4 est l'union des états 1 et 3. * Identifiants de charge dupliqués refusés : la seconde entrée était perdue en silence à la construction. ThingIds normalisés via QUuid, « {uuid} » et « UUID » désignant le même organe. * Au chargement du fichier, une entrée en conflit est écartée plutôt que de perdre toute la configuration : écarter une charge ne commande rien, la charger commanderait faux. -- Patrick Schurig Sun, 09 Aug 2026 15:00:00 +0200 powersync-energy-plugin-nymea (1.15.2+etm7) trixie; urgency=medium * SG-Ready configurable — première implémentation réelle de spec_loadmodel.md §3. LoadConfig devient une union discriminée par mécanisme (LM-300) : le champ `adapter` est le discriminant, chaque mécanisme a une charge utile et valide la sienne. `sg-ready` porte states[] { state, relays[], estimatedPowerW } et minStateHoldS ; les paliers de la PAC ne sont plus codés en dur. * Une configuration sg-ready dépourvue de l'état 2 est REFUSÉE, pas construite : l'état 2 est le plancher de repli du mode dégradé L2 et de la désactivation. Les deux Q_ASSERT de SgReadyAdapter, absents du binaire release, sont retirés au profit de ce refus et d'un drapeau m_usable (ECS-110). * La PAC de configuration vit dans la même table que les autres charges : elle hérite d'ECS-412 (reconstruction incrémentale) et d'ECS-413 (état sûr = état 2) sans code dédié. * Garde de double propriété : si une PAC de configuration vise les contacts de la PAC de banc enregistrée en dur, cette dernière est retirée — deux adaptateurs sur un même contact commanderaient en contradiction et compteraient la charge deux fois dans le budget. * spec_loadmodel.md 0.1.2 — LM-104 : supposer conservateur pour annoncer, tenter systématiquement pour agir. Vaut pour tout mécanisme, pas pour l'ECS seul. -- Patrick Schurig Sun, 09 Aug 2026 12:00:00 +0200 powersync-energy-plugin-nymea (1.15.2+etm6) trixie; urgency=medium * ECS-414 — l'échelle d'échec d'écriture (ECS-410) est généralisée à SgReadyAdapter et EtmVariableLoadAdapter : suivi asynchrone des acquittements, échelle bornée, défaut collant levé par NymeaEnergy.ClearLoadFault. * Plancher propre à chaque adaptateur : consigne 0 W pour la charge continue, ÉTAT 2 pour la PAC SG-Ready — jamais « contacts ouverts », qui est une commande et peut valoir le blocage selon l'encodage câblé. * Le repli SG-Ready honore le même contrat d'atomicité que le chemin aller : il part du motif de contacts RÉELLEMENT lu et ordonne les commutations par transientHarm, de sorte que la récupération ne traverse pas le blocage. Il contourne minStateHoldS (900 s). * Un contact injoignable est supposé FERMÉ pour la télémétrie (cohérence ECS-411) mais TOUJOURS commandé : sans quoi l'hypothèse conservatrice masquerait l'échec. * Test : testSgReadyPartialFailure. Suite 18/18. -- Patrick Schurig Sun, 09 Aug 2026 21:00:00 +0200 powersync-energy-plugin-nymea (1.15.2+etm5) trixie; urgency=medium * ECS-410 — échec d'écriture relais : l'adaptateur suit désormais l'acquittement de chaque executeAction, sans jamais bloquer le cycle (AGENTS règle 5). Échelle bornée à trois barreaux — cible, retour arrière, arrêt total — puis état de défaut COLLANT, levé seulement par le nouvel appel NymeaEnergy.ClearLoadFault. * Pendant une transition, la télémétrie annonce max(palier précédent, palier cible) : ne jamais annoncer moins que ce qui peut être appliqué (même direction qu'ECS-411). * LoadContext.available ajouté — il gouverne l'ALLOCATION, pas la COMPTABILITÉ : une charge en défaut ne reçoit plus de consigne mais reste comptée au budget. OPTIMIZER_PROTOCOL.md mis à jour dans le même lot. * ECS-413 — désactiver une charge (enabled: false) la laisse dans l'état SÛR de son adaptateur, appliqué AVANT destruction : relais ouverts pour un routeur, 0 W pour une charge continue, état 2 pour une PAC SG-Ready — jamais le blocage. Un rebuild sans désactivation ne coupe rien (ECS-412 préservé). * Tests : testEcsPartialFailure, testEcsDisableLeavesSafeState. Suite 17/17. -- Patrick Schurig Sun, 09 Aug 2026 18:00:00 +0200 powersync-energy-plugin-nymea (1.15.2+etm4) trixie; urgency=medium * ECS-412 — correction d'un blocage circulaire du verrou au démarrage à froid, constaté AU BANC (charge figée à 0 W sous 4 kW de surplus disponible). Un horodatage de dernière commutation nul servait de sentinelle « écoulé = 0 » à chaque cycle : toute charge relay-router démarrant relais ouverts avec minOffS > 0 ne pouvait jamais s'enclencher, donc jamais commuter, donc jamais valider son horodatage. * L'armement du verrou devient PARESSEUX et TRANSITOIRE : posé au premier temps de cycle reçu par applyAction(), il expire après sa durée configurée. L'invariant « temps = paramètre, jamais l'horloge » est préservé. * Test : testEcsColdStartLockExpires — palier 0 au départ, minOffS = 120, budget 5000 W ; éteinte pendant le verrou, enclenchée après. Suite 15/15. -- Patrick Schurig Sun, 09 Aug 2026 10:00:00 +0200 powersync-energy-plugin-nymea (1.15.2+etm3) trixie; urgency=medium * Étape 1 (specs/spec_ecs.md) — trois corrections de comportement sur les charges pilotées à relais : * ECS-306 : le budget décrémenté par le scheduler suit le palier RÉELLEMENT applicable. La fenêtre de verrou est de nouveau exposée à l'arbitre, en watts (lockMinPowerW/lockMaxPowerW) — aucun index de palier ne franchit la frontière. Sans ce canal, les charges de priorité suivante recevaient un résidu surestimé pendant toute la fenêtre minOn, donc soutirage réseau. * ECS-411 : le palier courant est déduit de l'état réel des Things relais au démarrage, au lieu de repartir de 0 — le moteur ne croit plus 0 W pendant que le ballon chauffe. * ECS-412 : rebuild incrémental des adaptateurs. Un SetLoadConfig qui ne change qu'un rang ne détruit plus l'adaptateur, donc ne réarme plus les verrous : sur un ballon thermodynamique à minOn de 300-600 s, réordonner ses priorités depuis l'app pouvait faire court-cycler le compresseur. Au démarrage à froid, le verrou est ARMÉ (défaut sûr), jamais purgé. * Tests : testEcsBudgetUnderLock, testEcsRestartRecovery, testEcsRebuildPreservesLock. Suite simulation 14/14. -- Patrick Schurig Sat, 08 Aug 2026 14:40:00 +0200 powersync-energy-plugin-nymea (1.15.2+etm2) trixie; urgency=medium * Charge pilotée rév. 3 — frontière optimiseur (watt-pur) ↔ routeur (watts→relais, experience-plugin). * RelayRouter : combinatoire watts→relais ; paliers DÉRIVÉS des relais (things "power"), verrous minOn/minOff internes, off-before-on, agrégation currentPowerW (mesuré sinon nominal commandé). * Optimiseur watt-pur : suppression du kind Stage ; buildSetpointAction (arrondi powerLevels / résidu). * LoadConfig : forme relay-router (relays[]=[{thingId,powerW}] + minOnS/minOffS), validation conditionnelle ; Get/SetLoadConfig (schéma SET "o:" pour les deux formes exclusives). * Repli L2 unifié : compteur muet → Setpoint(0) force=true sur tous les ILoadAdapter (RelayRouter coupe TOUS les relais). EtmVariableLoadAdapter (continu/triac) conservé. * Tests : combinatoire/off-before-on/déduplication, repli L2 relais, chaîne config→routeur, RPC. -- Patrick Schurig Sun, 28 Jun 2026 13:38:36 +0200 powersync-energy-plugin-nymea (1.15.2+etm1) trixie; urgency=medium * Build contre nymea 1.15.2. EcsRelayAdapter + SgReadyAdapter dans init() (§1.d banc hems). -- Patrick Schurig Thu, 25 Jun 2026 15:30:00 +0200 powersync-energy-plugin-nymea (1.15.0+etm1) trixie; urgency=medium * Renommage paquet powersync-* + version 1.15.0 alignée sur libnymea-energy cible hems * EnergyArbitrator : waterfall ECS+PAC, RuleBasedScheduler, watchdog L2 * EcsRelayAdapter : 8 paliers binaires, off-before-on, verrous minOn/minOff * SgReadyAdapter : 4 états SG-Ready, hystérésis kForceMargin=1.2, zone morte * §1.d banc hems : enregistrement EcsRelayAdapter+SgReadyAdapter dans init() * Build deb : tests exclus (CONFIG+=build_tests requis séparément) -- Patrick Schurig / ETM PowerSync Wed, 25 Jun 2026 12:00:00 +0200 nymea-energy-plugin-nymea (1.13.0+etm1) jammy; urgency=medium * Fork ETM PowerSync de nymea-energy-plugin-nymea -- Patrick Schurig / ETM PowerSync Sun, 07 Jun 2026 21:38:25 +0200 nymea-energy-plugin-nymea (1.13.0) jammy; urgency=medium [ Simon Stürz ] * Update license text and add SPDX identifier -- jenkins Tue, 02 Dec 2025 10:40:27 +0100 nymea-energy-plugin-nymea (1.12.4) jammy; urgency=medium -- jenkins Thu, 27 Nov 2025 11:21:05 +0100 nymea-energy-plugin-nymea (1.12.3) jammy; urgency=medium -- jenkins Tue, 04 Nov 2025 11:39:56 +0100 nymea-energy-plugin-nymea (1.12.2) jammy; urgency=medium [ Simon Stürz ] * debian: Fix debian packaging for Qt6 packages -- jenkins Wed, 29 Oct 2025 12:29:18 +0100 nymea-energy-plugin-nymea (1.12.1) jammy; urgency=medium -- jenkins Mon, 13 Oct 2025 15:29:39 +0200 nymea-energy-plugin-nymea (1.12.0) jammy; urgency=medium [ Simon Stürz ] * Add Qt6 support * Fix phase switching available logic -- jenkins Thu, 11 Sep 2025 14:27:01 +0200 nymea-energy-plugin-nymea (1.11.1) jammy; urgency=medium [ Simon Stürz ] * Stop charging if the battery is under the consideration point * Fix wrong warning regarding configuration ENV loading -- jenkins Thu, 22 May 2025 15:29:54 +0200 nymea-energy-plugin-nymea (1.11.0) jammy; urgency=medium [ Martin Lukas ] * Add support for houshold battery level consideration [ Simon Stürz ] * Update permissions in order to allow a non admin system user * Improve overload protection * Improve phase switching logic * Fix invalid max phase count calculation on single phase car with phase switching charger -- jenkins Thu, 20 Mar 2025 14:17:07 +0100 nymea-energy-plugin-nymea (1.10.0) jammy; urgency=medium [ Simon Stürz ] * Add spot market charing -- jenkins Tue, 26 Nov 2024 20:53:11 +0100 nymea-energy-plugin-nymea (1.9.5) jammy; urgency=medium -- jenkins Mon, 21 Oct 2024 21:05:52 +0200 nymea-energy-plugin-nymea (1.9.4) jammy; urgency=medium -- jenkins Wed, 14 Aug 2024 18:36:34 +0200 nymea-energy-plugin-nymea (1.9.3) jammy; urgency=medium [ Simon Stürz ] * Update debian packaging and compat level -- jenkins Fri, 19 Jul 2024 21:07:54 +0200 nymea-energy-plugin-nymea (1.9.2) jammy; urgency=medium -- jenkins Thu, 11 Apr 2024 15:47:40 +0200 nymea-energy-plugin-nymea (1.9.1) jammy; urgency=medium -- jenkins Thu, 04 Jan 2024 19:14:46 +0100 nymea-energy-plugin-nymea (1.9.0) jammy; urgency=medium -- jenkins Thu, 23 Nov 2023 09:55:12 +0100 nymea-energy-plugin-nymea (1.8.4) jammy; urgency=medium [ Michael Zanetti ] * Don't use acquisitiontolerance to determine wheter to switcht to 3 phases * Fix minimum car amps not being regarded in ECO mode -- jenkins Tue, 14 Nov 2023 09:12:06 +0100 nymea-energy-plugin-nymea (1.8.2) jammy; urgency=medium [ Michael Zanetti ] * Fix effective phase count after switching phases -- jenkins Wed, 28 Jun 2023 09:49:36 +0200 nymea-energy-plugin-nymea (1.8.1) jammy; urgency=medium [ Michael Zanetti ] * Include car minimum amps in calculation for enoughFor3PhaseCharging -- jenkins Tue, 13 Jun 2023 10:20:45 +0200 nymea-energy-plugin-nymea (1.8.0) jammy; urgency=medium [ Michael Zanetti ] * Add support for dynamically setting the phase count * Use currentPower instead of current for calculating the allowance * Don't drain batteries during daytime if solar power fluctuates * Also regard minimum charging amps for the assigned car -- jenkins Tue, 16 May 2023 16:53:01 +0200 nymea-energy-plugin-nymea (1.7.0) jammy; urgency=medium [ Simon Stürz ] * Make sure effective phase count will be evaluated in any case for the charger * Fix time calculation for immediately charging required * Fix running tests in dpkg [ Michael Zanetti ] * Add a lockOnUnplug setting -- jenkins Thu, 09 Mar 2023 15:13:24 +0100 nymea-energy-plugin-nymea (1.6.3) jammy; urgency=medium -- jenkins Wed, 01 Feb 2023 12:19:29 +0100 nymea-energy-plugin-nymea (1.6.2) jammy; urgency=medium -- jenkins Mon, 16 Jan 2023 14:37:17 +0100 nymea-energy-plugin-nymea (1.6.1) jammy; urgency=medium [ Michael Zanetti ] * Allow ECO mode without time restriction * No notification for normal charging -- jenkins Fri, 23 Dec 2022 11:33:56 +0100 nymea-energy-plugin-nymea (1.6.0) jammy; urgency=medium [ Simon Stürz ] * Introduce tests and simulations [ Michael Zanetti ] * Allow ECO mode without time restriction * No notification for normal charging -- jenkins Sat, 10 Dec 2022 14:56:05 +0100 nymea-energy-plugin-nymea (1.5.1) jammy; urgency=medium -- jenkins Mon, 07 Nov 2022 12:49:43 +0100 nymea-energy-plugin-nymea (1.5.0) jammy; urgency=medium [ Michael Zanetti ] * Fix current power calculation for evchargers without meter -- jenkins Mon, 17 Oct 2022 14:06:35 +0200 nymea-energy-plugin-nymea (1.4.1) jammy; urgency=medium [ Michael Zanetti ] * Fix a crash when the root meter is removed * Fixes for the automatic SoC calculation * Fix acquisition tolerance -- jenkins Thu, 29 Sep 2022 20:11:39 +0200 nymea-energy-plugin-nymea (1.4.0) jammy; urgency=medium [ Michael Zanetti ] * Add deep linking data to plugged in push notification * Add acquisitionTolerance setting -- jenkins Mon, 22 Aug 2022 17:00:54 +0200 nymea-energy-plugin-nymea (1.3.1) jammy; urgency=medium [ Michael Zanetti ] * Fix SoC calculation -- jenkins Mon, 11 Jul 2022 15:36:45 +0200 nymea-energy-plugin-nymea (1.3.0) jammy; urgency=medium [ Michael Zanetti ] * Count up manual SoC while charging * Add translations [ Simon Stürz ] * Update business logic behavior -- jenkins Fri, 01 Jul 2022 22:50:18 +0200 nymea-energy-plugin-nymea (1.2.0) jammy; urgency=medium -- jenkins Tue, 07 Jun 2022 19:45:44 +0200 nymea-energy-plugin-nymea (1.1.0) jammy; urgency=medium [ Michael Zanetti ] * Add CharingState information to API * Fix calculation of remaining charging time if SoC is higher than TSoC * Some fixes in the smart charging logic -- jenkins Tue, 10 May 2022 12:47:01 +0200 nymea-energy-plugin-nymea (1.0.0) xenial; urgency=medium [ Michael Zanetti ] * Improve calculation for charging power [ Jenkins ] -- Jenkins Thu, 10 Mar 2022 17:55:05 +0100 nymea-energy-plugin-nymea (0.1) xenial; urgency=medium [ Michael Zanetti ] * Import code from nymea-experience-plugin-energy -- Jenkins Wed, 15 Dec 2021 11:54:55 +0100