- 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>
96 lines
5.1 KiB
Markdown
96 lines
5.1 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
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
|