Patrick Schurig 1056d6c746 docs: RECAP état session (reprise dans quelques jours)
État branche feature/beta-add-config (9 commits) : lots livrés, bloqueur lot C
(descriptor SDM réel), file d'attente (lots B/D, mDNS, energy Phase 2-4), banc
de test (.75/.120/Influx/tél), faits techniques (signes nymea, discovery SDM).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 07:57:02 +02:00

7.7 KiB

RECAP — etm-powersync-app · reprise de session

État au 2026-06-30. Branche feature/beta-add-config (9 commits au-dessus de master). Rien n'est poussé (push différé). Aucun merge vers master/silo.


1. Où on en est (commits, du plus récent au plus ancien)

Commit Contenu
b4a6c97 Lot C — squelette discovery de things (⚠️ pending SDM réel)
b7a7213 Catalogue de things (lecture seule) + filtres (lot A)
3a535e0 Écran Protocoles — CRUD masters Modbus RTU
0ebbde4 chore(docs) — specs/contrats/refs rangés dans docs/
be6694c chore — ignore /screenshots
f755c72 docs — contrat UI rev.5 (réserve décision-2 levée)
3821bf3 refactor(energy) — retrait calcul ratios app-side → seam EnergyRatiosInterim
b5abe42 docs — contrat UI rev.4
c638ec6 Connexions multi-HEMS + Rôles & appareils (gros commit fondateur)

Source de vérité contrats : docs/UI_data_contract.md (rev.5), docs/reference/jsonRPC.txt (introspection — fait foi pour les RPC).


2. Ce qui est LIVRÉ et fonctionnel

Connexions multi-HEMS (validé live)

  • models/installation.dart, services/installation_store.dart (token par UUID via flutter_secure_storage, métadonnées SharedPreferences).
  • services/connection_manager.dart : mono-connexion, switchTo, connectNew, enterDemo (démo = active factice), contrôle d'identité DHCP, invalidation des caches au switch.
  • nymea_service : connect() réveillé (ws://4444, token par UUID), capture Hello (uuid/name/initialSetupRequired), authenticate/createUser, resetState.
  • Écran Installations (3 états) + écran Connexion (auth 2 branches, détection auto).
  • Gate de routage (buildAppRouter, redirect + refreshListenable: merge([cm,svc])), hasActiveConnection = isSimulation || (connected && authenticated).
  • En-tête drawer cliquable → Installations.
  • Testé en vrai : login auth contre .120, .75 ouvert, switch, déverrouillage installateur.

Rôles & appareils

  • EnergySetupProvider tri-état (present/absent/non-configuré), écran roles_devices_screen, LoadDescriptor (rév.2 : PAC exclue → SG-Ready), Energy.SetRootMeter réel, Get/SetLoadConfig en stub loggé.

Energy — Phase 1 (interim)

  • services/energy_ratios.dart = SEAM UNIQUE EnergyRatiosInterim : ratios autoconso/autonomie par Δ-de-cumuls (reseed jour/non-monotone, gardes n/a, clamp). selfConsumptionPower net-signé sans .abs(). Test : test/energy_ratios_test.dart.
  • Calcul ratios app-side retiré de _parsePowerBalance + getter autoconsommationW supprimé.

Installateur — Modbus RTU (validé live)

  • models/modbus_models.dart, 5 RPC ModbusRtu.* dans nymea_service, écran protocols_screen (CRUD), route /settings/system/protocols.

Installateur — Catalogue things lot A (validé live)

  • getVendors() + getAllThingClasses(), écran thing_catalog_screen (liste groupée + 3 filtres : fabricant/type/recherche + détail read-only), route /settings/system/things.

Installateur — Discovery lot C (SQUELETTE, NON validé matériel)

  • ThingDescriptor, discoverThings(), addThingFromDescriptor(), thing_discovery_screen (form slaveAddress → scan → descriptors → AddThing).

3. ⚠️ BLOQUEURS / EN ATTENTE

  • Lot C — merge bloqué tant qu'on n'a pas un descriptor SDM réel sur le bus de hems .75 (besoin : adaptateur USB-RS485 + un vrai compteur SDM branché ; aujourd'hui le master /dev/ttyUSB0 est connected:false). 3 points marqués À REVALIDER SUR SDM RÉEL dans thing_discovery_screen.dart / nymea_service.dart :
    1. résolution master/slave par heuristique de nom de paramTypes ('master'/'modbus'/'slave') ;
    2. timeout scan (_sendRequest = 15 s, à allonger si bus réel plus lent) ;
    3. title/description du descriptor (peuvent être vides/génériques).
  • Push : jamais fait (volontaire).

4. Lots / phases NON FAITS (file d'attente)

  • Lot B — ajout direct CreateMethodUser + JustAdd (form paramTypes). Sous-ensemble = 22 classes (ABB B2x, ABB Terra AC RTU/TCP, génériques/simulés nymea). ⚠️ Les Eastron SDM N'EN SONT PAS (ils sont Discovery → lot C). Piège param : nom du master varie (modbusMasterUuid vs rtuMaster). Reporté après C.
  • Lot D — discovery → pairing (OAuth/PushButton/UserAndPassword).
  • Connexions Étape 3 — découverte mDNS native (multicast_dns, natif only ; web = ajout manuel). Différée.
  • Connexions — branche CreateUser (box neuve) : codée mais non testée live (pas de box vierge/factory-reset sous la main).
  • Energy Phase 2/3/4 (session dédiée, voir mémoire) : Phase 2 = states ratios côté energymanager (autre repo) ; Phase 3 = persistance Influx ; Phase 4 = refonte flow-card §1.1 + bandes + retrait définitif du calcul app-side. Contrat = docs/UI_data_contract.md.

Bugs latents notés (hors lot)

  • dashboard_screen.dart : onRefresh: () => service.startSimulation() → sur box réelle, pull-to-refresh bascule en démo. À corriger au câblage du refresh réel.
  • Affichage signe : sans .abs(), conso reste net-signée → Maison (flow-card) & ligne conso (graphe) montrent le signe brut jusqu'à la Phase 4 (voulu).

5. Banc de test

Cible Détail
hems .75 nymea 1.15.2, ouverte (authenticationRequired:false). Master RTU /dev/ttyUSB0 présent mais bus hors-ligne. Sert aux sondes read-only sans auth.
box 2 192.168.1.120 auth requise (initialSetupRequired:false → login). Vraie installation avec SDM120 PV.
InfluxDB local sur etm-powersync-dev, v1.6.7 (PAS Influx 3 Core), DB nymeatest, RP tiers déjà présentes.
Tél Android Redmi Note 9S, adb WiFi 192.168.1.107:5555.

PIN installateur par défaut = 1234.

Comment lancer / tester

  • Réel (réseau) : flutter run -d 192.168.1.107:5555 (Android WiFi). Pas Chrome pour le réseau (CORS LAN). Voir mémoire web-lan-cors.
  • Linux natif : bloqué (Flutter snap sans linker ld.lld). Web headless = page blanche (CanvasKit). Captures fiables = adb exec-out screencap -p.
  • Sonde RPC sans GUI : script dart:io WebSocket.connect('ws://<host>:4444') + JSON-RPC (ex. utilisé pour valider Modbus/discovery contre .75).

6. Faits techniques à ne pas reperdre

  • Signes nymea (power balance agrégé) : production positif, consumption NÉGATIF, acquisition net-signé (négatif = export). currentPower thing-level = négatif pour un producteur (convention conso). Ne jamais deviner/.abs() le signe.
  • Cumuls (totalAcquisition / totalReturn) séparés → autoconso/autonomie dérivables des logs. UUID Hello brace-wrapped {...} (normalisé dans _finishConnect).
  • Discovery SDM : discoveryParam = slaveAddress uniquement (Int, déf 1). Le master n'est PAS une entrée — il ressort dans descriptor.params. Ajout final = AddThing(thingDescriptorId).
  • CreateMethod = {User, Auto, Discovery} · SetupMethod = {JustAdd, DisplayPin, EnterPin, PushButton, UserAndPassword, OAuth}. Orthogonaux (une classe JustAdd peut exiger Discovery).

7. Reprise — prochaines actions probables

  1. Brancher un SDM sur .75 → sonde discovery réelle → lever les 3 points + débloquer le merge du lot C.
  2. Puis lot B (ABB + génériques) ou lot D (pairing).
  3. Côté energy : ouvrir la session dédiée Phase 4 (contrat docs/UI_data_contract.md).
  4. Décider du push de feature/beta-add-config.

Mémoires persistantes liées : web-lan-cors, energy-chart-redesign, deploy.