Point d'arrêt avant redémarrage machine. Consigne l'état du lot B app, le bloqueur (lot plugin non déployé sur .75), le partage vérifié/non-vérifié, et la question ouverte sur la fusion /energy/setup ↔ /energy/loads. Note l'accès ssh au banc désormais documenté dans CLAUDE.md : il lève la limite qui rendait le critère 7-1bis (non-reconstruction des adaptateurs) invérifiable faute de journal. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
13 KiB
RECAP — etm-powersync-app · reprise de session
Session 2026-08-25. Branche
feature/beta-add-config. Rien n'est poussé. La section « État au 2026-06-30 » plus bas reste valable pour tout ce qu'elle décrit.
Session 2026-08-25 — ce qui a été fait
Commits ajoutés
| Commit | Contenu |
|---|---|
7ca4297 |
Lot B app — ordre de service des charges, locale, ossature i18n |
40ac3b2 |
Fixtures : dump réel GetLoadConfig + schéma introspecté de .75 |
1. Menus (demande initiale)
- « Rôles & appareils » et « Options développeur » → section MODE INSTALLATEUR uniquement.
- Groupes / Scènes / Médias / Garages → masqués par défaut. Le drawer lit désormais
AppSettingsProvider.visibleScreens(ces 4 écrans y étaient déjà àvisible: false; le drawer les affichait en dur et ignorait le réglage). - Garde de routeur
_isInstallerRoute(main.dart:41) :/settings/system*,/settings/app/developer,/energy/setup,/energy/loads→ redirection vers/si le mode installateur est verrouillé. Couvre l'URL directe, le deep-link et l'auto-lock 10 min. - Liens SUPPORT corrigés : doc →
https://docs.etm-powersync.fr/, Telegram →https://t.me/etm_powersync_support, Discord retiré (commenté sur place).
2. Investigations rendues (constats factuels, pas de code)
- Locale nymea : gérée PAR CONNEXION (
o:localedansHello,m_clientLocales). Pas de forçageLANG/LC_ALLdans l'unité systemd. Mais sur 784 chaînes affichables de.75, l'allemand en change 1, le français 0 : aucun catalogue.qmfr n'est livré. LesdisplayName= identifiants anglais. - Frontière RPC / runtime de l'arbitre : quasi rien ne sort. Seuls
degradedMode(notificationChargingSchedulesChangeduniquement — pas relisable parGet), les deux ratios d'énergie,chargingStatede l'EV et le plan de recharge franchissent. Allocation, budget, verrous, paliers,available, motifs : journal seulement.SurplusContext/LoadContextTelemetryn'ont aucune sérialisation sortante.
3. Lot B app — livré
models/load_config_entry.dart— vue en lecture au-dessus de la map brute ; écriture parpatched()depuis la map d'origine, jamais de re-sérialisation.services/load_priority.dart—groupByDomain/flattenToPayload/applyDefaultDomainOrder/ miroir client devalidateSet().providers/load_config_provider.dart— séquencepending → LoadConfigChanged → confirmed|diverged. Ne conclut jamais sur l'acquittement du RPC.screens/energy/load_order_screen.dart— route/energy/loads, gatée installateur.- i18n :
flutter_localizations+intl+lib/l10n/app_fr.arb+l10n.yaml. Extensioncontext.l10n. Français seul. NymeaEnergy.GetLoadConfig/SetLoadConfigdeviennent réels (c'étaient des stubs).- Locale envoyée à chaque
Hello, demandée + retenue journalisées.
4. ⚠️ Piège désamorcé — à ne pas réintroduire
EnergySetupProvider.persist() appelait setLoadConfig(buildLoadDescriptors()), une
reconstruction depuis le modèle typé, et _commit() l'appelle à chaque changement d'UI.
Inoffensif tant que le RPC était un stub ; destructeur une fois réel (SetLoadConfig
remplace tout l'ensemble → la charge chauffe-eau de .75 aurait été écrasée).
Émission débranchée, raison documentée sur place.
⛔ BLOQUEUR PRINCIPAL À LA REPRISE
Le lot plugin brief-plugin-lotB-telemetrie.md n'est PAS déployé sur .75.
Introspect au 2026-08-25 : toujours 19 méthodes / 13 notifications.
GetLoadTelemetry : ABSENT
LoadTelemetryChanged : ABSENT
o:domain : ABSENT du schéma SetLoadConfig
Conséquence : critères 4 à 8 du brief lot B hors d'atteinte (domaine, télémétrie
vivante, fraîcheur, défaut/ClearLoadFault, code inconnu réel). Tant que ce lot n'est pas
sur la box, il n'y a plus rien d'utile à faire côté app sur ce périmètre.
Vérifié / non vérifié (lot B app)
| Critère | Statut |
|---|---|
| §7-1 aller-retour neutre | ✅ sur .75 en vrai — SetLoadConfig verbatim → relecture identique |
| §7-1bis non-rebuild ECS-412 | ⚠️ lecture de code seulement (sameHardware()), journal non consulté |
| §7-2 aplatissement réversible | ✅ test unitaire seul — .75 n'a qu'une charge |
| §7-3 config non contiguë | ✅ test unitaire seul — fixture synthétique |
| §7-4 à §7-8 | ❌ bloqués (lot plugin) |
| §7-9 locale | ✅ protocole vérifié sur .75 ; ⚠️ chemin app jamais exécuté sur appareil (adb refusé) |
| §7-10 analyze / tests / gating | ✅ 25 issues = ligne de base, 30/30 tests |
Question ouverte à trancher
Le brief désignait « Rôles & appareils » (/energy/setup) comme écran cible, mais cet écran
est bâti sur le modèle inverse (il construit des LoadDescriptor depuis des EmsRole).
J'ai créé /energy/loads à côté et laissé /energy/setup intact. Fusionner les deux est
une refonte, pas un câblage — décision Patrick attendue.
Nouveauté à exploiter à la reprise
CLAUDE.md documente désormais l'accès banc : ssh etm@192.168.1.75 (clé installée),
journal via journalctl -u nymead. Cela lève la limite qui rendait §7-1bis invérifiable
— au prochain aller-retour neutre, lire le journal pour confirmer qu'aucune reconstruction
d'adaptateurs n'a lieu.
RECAP — etm-powersync-app · reprise de session
État au 2026-06-30. Branche
feature/beta-add-config(9 commits au-dessus demaster). 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 viaflutter_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,.75ouvert, switch, déverrouillage installateur.
Rôles & appareils
EnergySetupProvidertri-état (present/absent/non-configuré), écranroles_devices_screen,LoadDescriptor(rév.2 : PAC exclue → SG-Ready),Energy.SetRootMeterréel, Get/SetLoadConfig en stub loggé.
Energy — Phase 1 (interim)
services/energy_ratios.dart= SEAM UNIQUEEnergyRatiosInterim: ratios autoconso/autonomie par Δ-de-cumuls (reseed jour/non-monotone, gardes n/a, clamp).selfConsumptionPowernet-signé sans.abs(). Test :test/energy_ratios_test.dart.- Calcul ratios app-side retiré de
_parsePowerBalance+ getterautoconsommationWsupprimé.
Installateur — Modbus RTU (validé live)
models/modbus_models.dart, 5 RPCModbusRtu.*dansnymea_service, écranprotocols_screen(CRUD), route/settings/system/protocols.
Installateur — Catalogue things lot A (validé live)
getVendors()+getAllThingClasses(), écranthing_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/ttyUSB0estconnected:false). 3 points marquésÀ REVALIDER SUR SDM RÉELdansthing_discovery_screen.dart/nymea_service.dart:- résolution master/slave par heuristique de nom de paramTypes (
'master'/'modbus'/'slave') ; - timeout scan (
_sendRequest= 15 s, à allonger si bus réel plus lent) ; title/descriptiondu descriptor (peuvent être vides/génériques).
- résolution master/slave par heuristique de nom de paramTypes (
- 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 (modbusMasterUuidvsrtuMaster). 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émoireweb-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:ioWebSocket.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é) :
productionpositif,consumptionNÉGATIF,acquisitionnet-signé (négatif = export).currentPowerthing-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 =
slaveAddressuniquement (Int, déf 1). Le master n'est PAS une entrée — il ressort dansdescriptor.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
- Brancher un SDM sur
.75→ sonde discovery réelle → lever les 3 points + débloquer le merge du lot C. - Puis lot B (ABB + génériques) ou lot D (pairing).
- Côté energy : ouvrir la session dédiée Phase 4 (contrat
docs/UI_data_contract.md). - Décider du push de
feature/beta-add-config.
Mémoires persistantes liées :
web-lan-cors,energy-chart-redesign,deploy.