RECAP.md porte les neuf commits du jour et les trois défauts que seul l'appareil a montrés : deux cibles tactiles hors norme (26 px, 18 px), et une correction naïve laide que le test validait — c'est la capture qui a tranché, pas l'assertion. Ce qui manquait dans le suivi, et qui est écrit noir sur blanc : AUCUN BILAN JOURNALIER N'EXISTE DANS L'APP. Les quatre tuiles du tableau de bord mêlent deux natures de grandeur, et aucune n'est journalière — Autoconsommation et Autonomie sont des pourcentages instantanés, Vers réseau et Depuis réseau des kWh cumulés depuis l'origine. Les deux dernières portaient « aujourd'hui » : totalReturn n'est pas remis à zéro chaque nuit, d'où le « · cumulé ». Le bilan du jour reste à écrire, et le TODO porte les trois pièges de sa mise en œuvre — bornes à minuit local, clés de log SANS le préfixe currentPower, et les cumulés corrompus de .75. Et la question ouverte au moteur, telle qu'elle s'est posée : « ECS d'abord, batterie ensuite » n'est pas exprimable aujourd'hui, et batteryLevelConsideration fait l'inverse — il annule le budget SOUS le seuil, donc la batterie passe avant. La cause est structurelle : la batterie n'est dans aucun GetLoadConfig et le plugin ne la commande nulle part. Le levier existe pourtant, la classe SunSpec Storage de .75 déclare enableCharging, chargingRate et enableDischarging. Deux entrées du TODO étaient devenues fausses : kCodesReserveBatterie est fait, et « Zones — à ne pas entreprendre » est revu puisque le lot est cadré. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016vrTVifar2GN5rtUh89Wkq
6.3 KiB
TODO — ETM PowerSync App
Ouvert au 2026-08-27
-
🔴 Bilan JOURNALIER — il n'en existe aucun dans l'app. Les quatre tuiles du tableau de bord (
features/dashboard/widgets/kpi_row.dart) mêlent deux natures de grandeur, et aucune n'est journalière : Autoconsommation et Autonomie sont des pourcentages instantanés, Vers réseau et Depuis réseau des kWh cumulés depuis l'origine —totalReturn/totalAcquisitionne sont pas remis à zéro chaque nuit. Le libellé disait « aujourd'hui » ; il porte « · cumulé » depuis, mais le bilan du jour reste à écrire.- il passe par
Energy.GetPowerBalanceLogsavec des bornes à minuit local, jamais par les totaux deGetPowerBalance; - piège vérifié : les entrées de log portent
production/consumption/acquisition/storage, sans le préfixecurrentPowerdeGetPowerBalance. Réutiliser les mauvaises clés ne produit aucune erreur — tout tombe sur0; .75publie des cumulés corrompus (9,1e+33 kWh exportés) :EnergyData.isPlausibleKwhexiste pour ça, ne pas le contourner.
- il passe par
-
❓ « 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