From 2a201d626e9fd382df9e5bd703aff7f668e1e219 Mon Sep 17 00:00:00 2001 From: Patrick Schurig Date: Mon, 29 Jun 2026 06:20:12 +0200 Subject: [PATCH] =?UTF-8?q?T=C3=A9l=C3=A9verser=20les=20fichiers=20vers=20?= =?UTF-8?q?"/"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UPSTREAM_NYMEA.md | 86 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 UPSTREAM_NYMEA.md diff --git a/UPSTREAM_NYMEA.md b/UPSTREAM_NYMEA.md new file mode 100644 index 0000000..635b0a7 --- /dev/null +++ b/UPSTREAM_NYMEA.md @@ -0,0 +1,86 @@ +# Suivi des points à remonter à nymea (upstream) + +> Registre transverse des feature requests, bugs, clarifications et divergences +> identifiés vis-à-vis de nymea upstream (cœur, experience-plugin-energy, libnymea, +> protocole JSON-RPC). Source unique de vérité pour ce qui doit être communiqué à +> nymea, et pour nos contournements en attendant. +> +> **Repo d'accueil :** `etm-powersync-docs` (autorité transverse). +> **Mise à jour :** à chaque interaction upstream (issue ouverte, PR, réponse, contournement). + +--- + +## Légende + +| Champ | Valeurs | +|---|---| +| **Type** | `feature` · `bug` · `question` · `divergence/observation` | +| **Statut** | `à formuler` · `à investiguer` · `issue ouverte` · `PR soumise` · `accepté` · `refusé` · `contourné` | + +--- + +## Entrées + +### 1. [feature] Exposer `selfConsumptionRate` / `autonomyRate` sur `PowerBalance` + +- **Type :** feature request +- **Statut :** à formuler +- **Sujet :** Exposer les deux taux canoniques d'un HEMS — autoconsommation et autonomie — directement sur la réponse `Energy.GetPowerBalance` (+ notification `PowerBalanceChanged`). +- **Pourquoi ça compte :** Ce sont les KPI de base de tout système de gestion d'énergie domestique. Ils sont entièrement dérivables des cumuls déjà présents dans `PowerBalance` (`totalConsumption`, `totalProduction`, `totalAcquisition`, `totalReturn`). Aujourd'hui chaque client (app) doit les recalculer côté UI — duplication et risque d'incohérence entre clients. +- **Formules (bilan pur, mesure) :** + - `autonomie = (Δ totalConsumption − Δ totalAcquisition) / Δ totalConsumption` + - `autoconsommation = (Δ totalProduction − Δ totalReturn) / Δ totalProduction` + - Unité : % dans [0, 100]. Fenêtre : depuis minuit local (baseline quotidienne). Reseed si compteur non-monotone (`Δ < 0` : restart, re-add thing, rollover). Garde : dénominateur ≤ 0 → valeur non disponible (champ omis). +- **Argument upstream :** générique (pas un besoin ETM spécifique), pure mesure/bilan (pas d'optimisation), faible surface de patch (handler JSON-RPC uniquement, aucun changement d'ABI dans `libnymea-energy`). +- **Notre contournement actuel :** calculé dans notre experience-plugin (`powersync-energy-plugin-nymea`) via une méthode RPC `NymeaEnergy.GetEnergyRatios` + notification `NymeaEnergy.EnergyRatiosChanged`, à partir des mêmes cumuls canoniques (`energyManager()->totalX()`). Si upstream expose ces champs sur `PowerBalance` → migration triviale côté app (lire 2 champs au lieu d'appeler notre RPC), et on peut retirer notre contournement. +- **Référence pour la PR :** notre implémentation validée servira de référence (code + formules + alignement testé contre le calcul historique de l'app). + +--- + +### 2. [bug?] `Logging.GetLogEntries` rejette `sortOrder="Qt::AscendingOrder"` + +- **Type :** bug à confirmer (app vs API) +- **Statut :** à investiguer +- **Sujet :** Appel `Logging.GetLogEntries` rejeté : `"Expected enum value for SortOrder but got Qt::AscendingOrder" in "Logging.GetLogEntries, param sortOrder."` +- **Contexte :** observé dans les logs de la box `hems` (nymead 1.15.2). Le client envoie `"Qt::AscendingOrder"` comme valeur de `sortOrder`, là où l'API attend une valeur d'enum nymea (ex. `"SortOrderAscending"` ou équivalent). +- **À trancher :** est-ce un bug côté client (mauvaise sérialisation de l'enum Qt au lieu de l'enum API), ou une incohérence/documentation manquante côté nymea sur les valeurs acceptées de `sortOrder` ? +- **Contournement actuel :** N/A (n'a pas bloqué le travail en cours ; à corriger côté client si c'est bien une erreur de sérialisation). + +--- + +### 3. [question] `Hello` obligatoire avant le premier appel sur une session WebSocket neuve + +- **Type :** question / clarification +- **Statut :** à clarifier +- **Sujet :** Sur une session WebSocket fraîche, un appel direct (ex. `NymeaEnergy.SetLoadConfig`) sans `JSONRPC.Hello` préalable provoque : `TransportRouter: Unsupported initial method from client ... "NymeaEnergy.SetLoadConfig"` et fermeture de la connexion. +- **Contexte :** rencontré en poussant `SetLoadConfig` via un client WS minimal sur `hems`. Le même appel passe une fois `JSONRPC.Hello` envoyé en premier (initialisation de session). Box ouverte (`authenticationRequired: false`), donc ce n'est pas une question d'auth. +- **À clarifier :** est-ce un comportement attendu (le premier message d'une session DOIT être `Hello`) ? Si oui, à documenter explicitement côté nymea (protocole JSON-RPC). Le message d'erreur `"Unsupported initial method"` gagnerait à être plus explicite (ex. « session must start with JSONRPC.Hello »). +- **Contournement actuel :** toujours envoyer `JSONRPC.Hello` en premier sur une nouvelle connexion WS. (Appliqué dans nos scripts/clients.) + +--- + +### 4. [divergence/observation] Un integration-plugin ne peut pas commander les things d'un autre plugin + +- **Type :** divergence / observation structurante (pas forcément un bug) +- **Statut :** observé, contournement en place +- **Sujet :** Un `IntegrationPlugin` n'a pas accès au `ThingManager` global pour exécuter une action sur un thing appartenant à un autre plugin. `m_thingManager` est privé, sans accesseur ; le protected n'expose que `myThings()`, `hardwareManager()`, `pluginStorage()`. Seuls les experience-plugins (`ExperiencePlugin::thingManager()`) et le cœur (rule engine, script engine) peuvent commander des things tiers via `ThingManager::executeAction`. +- **Contexte :** a conditionné toute notre architecture ECS (charge pilotée multipalier). Comme l'orchestration de relais `power` appartenant au plugin GPIO/Modbus/MQTT nécessite de commander des things tiers, elle ne peut vivre que côté experience-plugin (là où le `ThingManager` est accessible). D'où notre `RelayRouter` implémenté dans l'experience-plugin energy, et non comme integration-plugin séparé. +- **À remonter (optionnel) :** ce n'est pas nécessairement un défaut — c'est une frontière de conception nymea (isolation des integration-plugins). Mais elle mérite d'être documentée clairement pour les développeurs de plugins, car elle détermine où peut vivre toute logique d'orchestration cross-thing. Une discussion upstream pourrait clarifier le pattern recommandé pour l'orchestration cross-plugin (experience-plugin ? autre mécanisme ?). +- **Contournement actuel :** orchestration (RelayRouter, watts→relais) implémentée dans l'experience-plugin energy, qui détient le `ThingManager` et peut commander les things `power` de n'importe quel transport. + +--- + +## À ajouter au fil de l'eau + +