etm-powersync-app/CLAUDE.md
etm d5dc0c7ca5 Initial commit : Flutter app nymea energy monitor
- NymeaService : auth complète (Hello → Authenticate → SetNotificationStatus)
- Token top-level dans chaque requête JSON-RPC (fix critique GetThings)
- Persistance token via shared_preferences par hôte
- Dashboard : champs utilisateur/mot de passe dans le dialog de connexion
- ThingDetailScreen : renommer, réglages (settingsTypes) et supprimer
- NymeaThingClass : champ settingsTypes parsé depuis l'API
- NymeaThing : copyWith(name) + settingValue()
- Fix overflow _StateChip dans ThingsScreen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 16:57:46 +01:00

5.1 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Contexte général

Dossier parent de tous les projets : /home/etm/Projects/

  • etm_powersync_app/ (ce projet) — application Flutter HEMS, client mobile
  • etm-nymea/ — serveur nymea et plugins associés (C++/Qt), le backend

Ce projet est le client Flutter qui communique avec le serveur nymea via JSON-RPC 2.0.


Commandes

flutter pub get          # installer/mettre à jour les dépendances
flutter run              # lancer sur device/émulateur connecté
flutter build apk        # build Android release
flutter analyze          # analyse statique Dart
flutter test             # lancer les tests

Architecture

State management — un seul Provider

NymeaService (lib/services/nymea_service.dart) est le seul ChangeNotifier. Il est fourni à la racine dans main.dart via ChangeNotifierProvider. Tous les écrans le consomment avec context.watch<NymeaService>() ou context.read<NymeaService>(). Il n'y a aucune autre couche de state management.

Navigation

MainShell dans main.dart utilise un IndexedStack de 5 écrans (l'état est préservé entre les onglets) :

Index Écran Fichier
0 Dashboard lib/screens/dashboard_screen.dart
1 Énergie lib/screens/energy_screen.dart
2 Things lib/screens/things_screen.dart
3 A/C lib/screens/ac_screen.dart
4 Favoris lib/screens/favorites_screen.dart

Communication avec nymea

NymeaService.connect() supporte deux transports :

  • TCP brut port 2222 (défaut) : nymea parle en premier (JSON délimité par \n). La fragmentation est gérée via StringBuffer.
  • WebSocket port 4444 : c'est le client qui parle en premier en envoyant JSONRPC.Hello.

Les requêtes utilisent des IDs auto-incrémentés stockés dans _pendingRequests: Map<int, Completer>. Timeout global : 15 secondes. Les notifications push nymea (pas de champ id, ont un champ notification) sont dispatchées dans _handleNotification().

Convention nymea énergie importante : currentPowerProduction est négatif (producteur = négatif). Le service convertit en positif dans _parsePowerBalance().

Mode simulation

NymeaService.startSimulation() déconnecte toute connexion live, active _isSimulation = true, génère des things fictifs et une production PV simulée en sinus (timer 2 s). Le dashboard démarre automatiquement la simulation au premier affichage si non connecté. Toutes les méthodes du service font un garde if (_isSimulation) return … pour éviter les vrais appels RPC.

Modèles de données

  • EnergyData (lib/models/energy_data.dart) — objet immutable avec copyWith, regroupe toutes les métriques énergie temps-réel et journalières + état de la borne EV.
  • NymeaThing / NymeaThingClass / NymeaStateType / NymeaActionType (lib/models/nymea_models.dart) — miroir de l'API Integrations nymea. NymeaThingClass.primaryStateType détermine l'état affiché sur les cards.
  • ThingCategory + interfaceToCategoryMap (lib/models/thing_category.dart) — mappe les interfaces nymea (ex. "evcharger", "solarinverter") vers des catégories d'affichage utilisées par ThingsScreen.
  • FavoriteWidget (lib/models/nymea_models.dart) — descripteurs de widgets stockés en mémoire dans NymeaService._favoriteWidgets.

Thème

AppTheme (lib/theme/app_theme.dart) expose des constantes Color nommées : primaryGreen, solarYellow, gridGray, homeBlue, batteryGreen, boostRed, pvGreen, minPvBlue, etc. Toujours utiliser ces constantes plutôt que des valeurs hex brutes.

Conventions

  • Code : anglais — Commentaires : français
  • Nommage : camelCase variables, PascalCase classes
  • Les écrans utilisent Consumer<NymeaService> ou context.watch — ne jamais dupliquer l'état du service dans un State
  • Unités : Watts (W) pour les puissances instantanées, Wh pour les énergies journalières. L'API nymea retourne des totaux en kWh que le service multiplie par 1000.

Méthodes nymea principales

Méthode Rôle
JSONRPC.Hello Handshake (WebSocket uniquement — envoyé par le client)
Integrations.GetThings Charger les devices configurés
Integrations.GetThingClasses Charger les définitions de classes (filtre thingClassIds supporté)
Integrations.ExecuteAction Exécuter une action sur un thing
Integrations.GetStateValue Lire une valeur d'état
Energy.GetPowerBalance Snapshot du flux énergétique actuel
Energy.GetEnergyLogs Historique énergie (échantillons horaires)
Energy.SetChargingMode Mode borne EV : pv, minpv, boost

Notifications push gérées : Energy.PowerBalanceChanged, Energy.RootMeterChanged, Integrations.StateChanged, Integrations.ThingAdded, Integrations.ThingRemoved.

Documentation API

  • docs/nymea_api.md — introspection complète de l'API nymea
  • docs/nymea_integrations.md — namespace Integrations en détail