Patrick Schurig 0311766b2b docs(todo): le bilan journalier est fait, avec les deux bugs d'unité qu'il a révélés
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016vrTVifar2GN5rtUh89Wkq
2026-08-28 07:58:50 +02:00

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 nommait Wh. 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 .75 en lecture seule. Le passage a trouvé quatre libellés tronqués qu'aucun des 138 tests unitaires ne pouvait voir.
  • ❓ « ECS d'abord, batterie ensuite » — à porter au moteur. Demandé le 2026-08-27, et pas exprimable aujourd'hui. batteryLevelConsideration fait l'inverse : il annule le budget sous le seuil, donc la batterie passe avant. La batterie n'est pas dans le waterfall — aucune entrée GetLoadConfig, et enableCharging / chargingRate / enableDischarging n'apparaissent nulle part dans le plugin ETM. Le levier existe pourtant : la classe SunSpec Storage de .75 déclare ces cinq actions. Question : le stockage est-il une charge arbitrable, ou reste-t-il hors du budget ? Une règle Rules.* 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 porte thermostat, closablesensor, temperaturesensor ni notifications — 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à.

  • EVChargingCard n'est montée par AUCUN écran (constaté le 2026-08-27 — le tableau de bord utilise features/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.dart est le harnais. Rappel MIUI : la confirmation d'installation est redemandée à chaque fois — faire un adb install -r -t préalable, puis lancer le test.

Charges pilotables — ce qui attend la box (2026-08-26)

  • kCodesReserveBatterie — fait le 2026-08-27. Le motif est publié : BATTERY_RESERVE, params socPercent / 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 == null sans véhicule branché — couvert en test unitaire (test/ev_runtime_test.dart), pas exercé sur appareil : la borne n'entre pas dans loads[] avant 3g. À 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.dart reste 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 un Future.delayed fictif
    • 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 thingClass pour les installations réelles
  • Vérifier les interfaces nymea sur serveur réel (comparer avec docs/nymea_integrations.md)
  • Energy.GetSchedule / Energy.SetSchedule si l'API le supporte

Technique / dette

  • Ajouter des tests unitaires pour TariffProvider et EnergySetupProvider
  • Gérer le cas où NymeaService.thingClasses est vide en mode live (classes non chargées)
  • Revoir _Step1ThingList : passer en context.watch pour réactivité si les things changent