powersync-docs/UPSTREAM_NYMEA.md
Patrick Schurig 2a201d626e
All checks were successful
Build & Deploy docs / build-deploy (push) Successful in 2m29s
Téléverser les fichiers vers "/"
2026-06-29 06:20:12 +02:00

87 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
<!--
Modèle d'entrée :
### N. [type] Titre court
- **Type :** feature | bug | question | divergence/observation
- **Statut :** à formuler | à investiguer | issue ouverte (#) | PR soumise (#) | accepté | refusé | contourné
- **Sujet :** …
- **Contexte :** où/quand rencontré, pourquoi ça compte
- **À trancher / à remonter :** …
- **Contournement actuel :** …
-->