# RECAP — Phase 2 ratios (autoconsommation / autonomie) > Point de reprise. Dernière session : 2026-07-03. Branche : `feature/beta-rulebased`. > Commit feature : **`444b13d`** (poussé sur `origin/feature/beta-rulebased`, > **pas encore sur `landing-silo`**, **non mergé**). ## 1. Objectif (rappel) Exposer **autoconsommation** + **autonomie** comme **source canonique de l'energymanager**, pour remplacer le seam interim app-side `EnergyRatiosInterim.compute()` (`etm-powersync-app/lib/services/energy_ratios.dart`). ## 2. Décision d'architecture — voie (c) (actée) Comparé **(a)** champs sur `Energy.PowerBalance` vs **(c)** méthode/notif sur le handler `NymeaEnergy` de NOTRE plugin. **Retenu : (c).** - (a) aurait imposé de **forker `nymea-experience-plugin-energy`** (plugin **cœur**), passage mirror→build + rebase 1.14.2→1.15.2 + **rebase perpétuel** à chaque bump nymea. Coût d'infra que Patrick fuit. - (c) vit dans `powersync-energy-plugin-nymea` (déjà forké/buildé), calcule depuis l'**interface abstraite stable** `EnergyManager` (`totalProduction/Return/ Consumption/Acquisition` + signal `powerBalanceChanged()`). **Valeurs identiques** à (a) ; seul le canal diffère. **Zéro fork du cœur.** - Coût app : un appel `GetEnergyRatios` + un abonnement `EnergyRatiosChanged` (vs lire 2 champs `PowerBalance`). Borné, ponctuel, dans un repo qu'on contrôle. - **Feature request upstream** nymea (champs sur `PowerBalance`) à ouvrir **séparément** — PAS besoin de forker pour la demander. Si acceptée → migration app triviale. ## 3. Ce qui est FAIT (commit 444b13d, 11 fichiers) | Fichier | Rôle | |---|---| | `energyplugin/etm/ratios/energyratioscalculator.{h,cpp}` | **Calc GPL pur mesure**, porté 1:1 de l'interim | | `energyplugin/etm/etm.pri` | Sources | | `energyplugin/nymeaenergyjsonhandler.{h,cpp}` | Méthode + notif + ctor `EnergyManager*` | | `energyplugin/energypluginnymea.cpp` | Câblage `energyManager()` | | `tests/auto/simulation/experience/energyexperienceenergymock.cpp` | Câblage mock | | `tests/auto/simulation/simulation.{h,cpp}` | `testEnergyRatiosAlignment` | | `docs/INTERFACE_energyratios.md` | **Contrat pour l'agent app** | ### Contrat exposé (namespace `NymeaEnergy`) - `GetEnergyRatios` → `{o:selfConsumptionRate, o:autonomyRate}` Double (%). **Champ OMIS si n/a** (dénominateur ≤ 0). **Jamais `null`.** - `EnergyRatiosChanged` → mêmes champs ; branchée sur `powerBalanceChanged()` ; émise **seulement si une valeur (ou sa disponibilité) change**. ### Sémantique (1:1 interim) Δ de cumuls sur la **journée locale** (minuit local). Reseed si 1er appel / nouveau jour / **non-monotone** (Δ<0 : restart nymead / re-add / rollover). `den≤0 → n/a`. Clamp `[0,100]`. Unité %. ``` autonomie = (Δ totalConsumption − Δ totalAcquisition) / Δ totalConsumption autoconsommation = (Δ totalProduction − Δ totalReturn) / Δ totalProduction ``` ### Validation (session) - Build **prod 0/0**, `energyratioscalculator.o` linké dans le `.so`. - `testEnergyRatiosAlignment` **PASS** (seed, normal, clamp-bas, den≤0→n/a, non-monotone, nouveau jour). - Suite simulation **25/0** (`testLoadConfigRpc` traverse le handler → pas de régression). ## 4. RESTE À FAIRE (reprise) 1. **Merge `landing-silo`** — Patrick le fait lui-même, **quand validé**. (Workflow : `git push origin feature/beta-rulebased:landing-silo`, NE PAS toucher master/stable.) Le commit ratios `444b13d` est **poussé sur `origin/feature/beta-rulebased`**, mais `landing-silo` est resté à `ad385ca` (bump `.deb` d'avant les ratios) — reste à landing + merger. 2. **`.deb`** : pas rebuildé. hems tourne `1.15.2+etm2` (rév.3 validée live). Quand on voudra livrer les ratios sur hems → cross-build arm64 + bump version + publier APT (voir DEPLOY.md). À décider au moment voulu. 3. **Côté repo app** (`etm-powersync-app`, séparé, Patrick) : - Mirrorer `docs/INTERFACE_energyratios.md`. - Swap : `GetEnergyRatios` au boot + abonnement `EnergyRatiosChanged` ; **supprimer** `EnergyRatiosInterim.compute()` + état baseline ; mapper champ-absent → `null`. 4. **Feature request upstream nymea** (champs `PowerBalance`) — à ouvrir, séparé. ### Dette/notes non bloquantes (héritées) - Worktrees git cassés `landing-silo`/`experimental-silo` (`git worktree prune/repair`). - `docs/TEST_TERRAIN.md` stale (dit `[EcsRelayAdapter]` → devrait être `[RelayRouter]`). - Mirror `docs/INTERFACE_etmvariableload.md` rév.3 vers le repo app (manuel). ## 5. Build & test (commandes vérifiées en sandbox amd64) ```bash # --- Build prod (0/0 attendu) --- BD=/tmp/build-prod; rm -rf $BD; mkdir -p $BD; cd $BD qmake6 /etm-powersync-energy-plugin-etm.pro && make -j$(nproc) # --- Build suite simulation --- BD=/tmp/build-sim; rm -rf $BD; mkdir -p $BD; cd $BD qmake6 CONFIG+=build_tests /tests/auto/simulation/simulation.pro && make -j$(nproc) # --- PIÈGE : rebuild du .so mock si stale (sinon les tests ETM échouent au setup # de création de thing : !ecsId.isNull(), relayA && relayB, "valid ThingId") --- cd /tests/mocks/plugins/energymocks qmake6 energymocks.pro && make -j$(nproc) # régénère aussi plugininfo.h si besoin # --- Run (NYMEA_PLUGINS_PATH = energymocks + plugins système nymea) --- cd /tmp/build-sim export NYMEA_PLUGINS_PATH="/usr/lib/x86_64-linux-gnu/nymea/plugins:/tests/mocks/plugins/energymocks" rm -rf /tmp/nymea-test ./nymea-energy-simulation # suite complète → 25/0 ./nymea-energy-simulation testEnergyRatiosAlignment # ratios seul → 3/3 ``` ## 6. Garde-fous projet (ne pas oublier) - **Frontière GPL** : ratios = pur mesure (Δ compteurs). Aucun optim/forecast/ pondération dans le GPL — ça reste dans l'optimiseur propriétaire. - **Remotes** : `origin` = travail ; `etm-public` = miroir, **jamais** push direct ; `etm-pro` = reliquat, ne pas utiliser. - **Jamais** merger vers master/stable depuis cette branche ; rév.3 + ratios = testing.