Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016vrTVifar2GN5rtUh89Wkq
6.1 KiB
TODO — ETM PowerSync App
Ouvert au 2026-08-27
-
🔴 Bilan JOURNALIER— fait le 2026-08-28. Les quatre tuiles montrent la journée, sous un en-tête « Aujourd'hui » qui le dit une fois. Méthode : différence des compteurs entre minuit local et maintenant, jamais l'intégration des puissances — mesurée contre estimée, 0,8 % d'écart sur.75. Le contrôle qui la valide est l'identité production + soutiré == consommation + injecté, vérifiée exactement sur le banc.- Deux bugs d'unité trouvés en chemin : les compteurs
total*sont en kWh et le modèle les nommaitWh. L'écran Énergie les divisait donc encore par mille — une journée de 78 kWh s'y lisait « 78 Wh » — et la simulation accumulait des Wh. - Vérifié sur appareil contre
.75en lecture seule. Le passage a trouvé quatre libellés tronqués qu'aucun des 138 tests unitaires ne pouvait voir.
- Deux bugs d'unité trouvés en chemin : les compteurs
-
❓ « ECS d'abord, batterie ensuite » — à porter au moteur. Demandé le 2026-08-27, et pas exprimable aujourd'hui.
batteryLevelConsiderationfait l'inverse : il annule le budget sous le seuil, donc la batterie passe avant. La batterie n'est pas dans le waterfall — aucune entréeGetLoadConfig, etenableCharging/chargingRate/enableDischargingn'apparaissent nulle part dans le plugin ETM. Le levier existe pourtant : la classe SunSpec Storage de.75déclare ces cinq actions. Question : le stockage est-il une charge arbitrable, ou reste-t-il hors du budget ? Une règleRules.*serait un contournement — deux commandeurs sur la batterie, exactement le défaut que 3g-2 vient de supprimer sur les bornes. -
Zones de climatisation — cadrage écrit, banc à préparer. Voir
docs/CADRAGE_zones_clim.md. Le blocage n'est pas « aucune zone déclarée » : sur les 58 classes de.75, aucune ne portethermostat,closablesensor,temperaturesensorninotifications— aucun plugin installé ne sait en créer une. Deux paquets du dépôt apt du banc suffisent (nymea-plugin-generic-heatingcooling,nymea-plugin-generic-sensors). Six décisions à prendre avant de coder. -
EV_GRID_START/PHASE_LIMIT— éprouvés par test seulement. Les clés ARB sont prêtes, les motifs n'ont jamais été vus sur machine. Signaler la première occurrence réelle. Ne rien bâtir autour d'ici là. -
EVChargingCardn'est montée par AUCUN écran (constaté le 2026-08-27 — le tableau de bord utilisefeatures/dashboard/widgets/). Soit elle rejoint un écran, soit elle part ; en l'état c'est du code mort qui a l'air vivant. -
Le passage sur appareil doit devenir une habitude, pas un rattrapage. Il a glissé deux fois, et au premier passage il a trouvé deux cibles tactiles hors norme (26 px, 18 px) qu'aucun des 129 tests unitaires ne pouvait voir.
integration_test/ui_3g2_on_device_test.dartest le harnais. Rappel MIUI : la confirmation d'installation est redemandée à chaque fois — faire unadb install -r -tpréalable, puis lancer le test.
Charges pilotables — ce qui attend la box (2026-08-26)
— fait le 2026-08-27. Le motif est publié :kCodesReserveBatterieBATTERY_RESERVE, paramssocPercent/reservePercent/withheldW. Les clés que le fichier cherchait (batteryLevel,threshold) n'avaient jamais existé côté plugin — le motif sortait donc en repli anglais sur le seul cas qu'aucune mesure ne révèle.minPowerW == nullsans véhicule branché — couvert en test unitaire (test/ev_runtime_test.dart), pas exercé sur appareil : la borne n'entre pas dansloads[]avant3g. À reprendre quand l'arbitrage prendra la recharge en charge.- Réserve batterie — portée élargie. Le jour où le seuil gouverne tout le budget,
reprendre le texte de
BatteryReserveCard: il annonce aujourd'hui un futur, il devra décrire un présent. Zones — à ne pas entreprendre— décision revue le 2026-08-27 : le lot est cadré (docs/CADRAGE_zones_clim.md), voir l'entrée en tête de ce fichier.ac_screen.dartreste de la donnée fictive — quatre pièces, huit températures crédibles affichées comme des mesures.
En cours / priorité haute
-
TariffProvider — connexion RPC réelle
load()appelle encore unFuture.delayedfictif- Brancher sur nymea JSON-RPC pour récupérer les prix live (ENTSO-E, Tibber, etc.)
-
EnergySetupProvider — persistance
- Les assignations de rôles (EV, PAC, batterie…) ne survivent pas au redémarrage
- Sérialiser en SharedPreferences ou JSON local
-
SchedulerProvider — exécution réelle
forceRecalc()ne fait rien pour l'instant- Brancher sur l'API nymea Energy Scheduler (si disponible)
Screens à implémenter
- DeveloperScreen — logs, introspection JSON-RPC, test ping nymea
- AboutScreen — version app, version nymea, licences
- SystemSettingsScreen — adresse serveur nymea, port, transport (TCP/WS)
Amélioration UX
- Timeline — remplacer la simulation bell-curve par les vraies créneaux du scheduler nymea
- RoleConfigFlow Step 3 — test de connexion sur RPC réel au lieu du délai simulé
- InstallerModeProvider — persister le hash PIN dans SharedPreferences (actuellement en mémoire)
- AppSettingsProvider — persister les préférences (thème, densité, écrans actifs) dans SharedPreferences
Intégration nymea live
- Mapping
EmsRole → nymea thingClasspour les installations réelles - Vérifier les interfaces nymea sur serveur réel (comparer avec
docs/nymea_integrations.md) Energy.GetSchedule/Energy.SetSchedulesi l'API le supporte
Technique / dette
- Ajouter des tests unitaires pour
TariffProvideretEnergySetupProvider - Gérer le cas où
NymeaService.thingClassesest vide en mode live (classes non chargées) - Revoir
_Step1ThingList: passer encontext.watchpour réactivité si les things changent