// ============================================================ // examples_usage.dart // Exemples d'utilisation du NymeaClient depuis etm_powersync_app // ============================================================ import 'nymea_client.dart'; // UUIDs des stateTypes du chargeur mock (interface evcharger) // À remplacer par les UUIDs réels de votre plugin d'intégration const kStatePluggedIn = '13f8f008-aa70-4772-9fb8-81a9674dd6ad'; const kStateCharging = '63879844-6342-45ed-8e97-276e0f3092e5'; const kStatePower = '13672543-9344-4d55-afd6-6393ae052f18'; const kStateMaxCurrent = 'e7566b5b-8258-486e-b0ed-42a1bee332d9'; // UUID fournisseurs spot market const kProviderAwattarAustria = '5196b3cc-b2ee-46d6-b63a-7af2cf70ba67'; const kProviderAwattarGermany = '0ca6ad88-e243-438d-a0f8-986cecf61834'; // ───────────────────────────────────────────────────────────── // EXEMPLE 1 — Connexion et authentification complète // ───────────────────────────────────────────────────────────── Future example1_connect() async { print('\n=== Exemple 1 : Connexion à nymea ==='); final client = NymeaClient(host: '192.168.1.100', port: 2222); try { await client.connect(); // Première utilisation : créer l'utilisateur // await client.createUser('admin@etm.local', 'MonMotDePasse!'); // Authentification (récupère un token) final token = await client.authenticate( 'admin@etm.local', 'MonMotDePasse!', 'etm_powersync_app', ); if (token == null) { print('Échec de l\'authentification'); return null; } // Conserver le token en stockage sécurisé (FlutterSecureStorage, etc.) // await secureStorage.write(key: 'nymea_token', value: token); print('Connecté avec succès ! Token : ${token.substring(0, 8)}...'); return client; } catch (e) { print('Erreur : $e'); return null; } } // ───────────────────────────────────────────────────────────── // EXEMPLE 2 — Récupérer tous les chargeurs VE du plugin // ───────────────────────────────────────────────────────────── Future example2_getEvChargers(NymeaClient client) async { print('\n=== Exemple 2 : Récupération des chargeurs VE ==='); // Récupère tous les Things qui implémentent l'interface "evcharger" final chargers = await client.getThingsByInterface('evcharger'); print('${chargers.length} chargeur(s) trouvé(s) :'); for (final charger in chargers) { print(' - ${charger['name']} (id: ${charger['id']})'); print(' thingClassId: ${charger['thingClassId']}'); } // Récupère les infos de smart charging via NymeaEnergy final chargingInfos = await client.getChargingInfos(); print('\nInfos de charge :'); for (final info in chargingInfos) { print(' Chargeur ${info.evChargerId}'); print(' Mode : ${info.chargingMode}'); print(' État : ${info.chargingState}'); print(' Spot market: ${info.spotMarketChargingEnabled}'); print(' Cible : ${info.targetPercentage}%'); } } // ───────────────────────────────────────────────────────────── // EXEMPLE 3 — Lire un State spécifique (puissance actuelle) // ───────────────────────────────────────────────────────────── Future example3_readState(NymeaClient client, String chargerId) async { print('\n=== Exemple 3 : Lecture d\'un State ==='); // Lire si une voiture est branchée final pluggedIn = await client.getStateValue(chargerId, kStatePluggedIn); print('Voiture branchée : $pluggedIn'); // Lire l'état de charge final charging = await client.getStateValue(chargerId, kStateCharging); print('En charge : $charging'); // Lire la limite de courant max configurée par le SmartChargingManager final maxCurrent = await client.getStateValue(chargerId, kStateMaxCurrent); print('Courant max actuel : ${maxCurrent}A'); // Lire la limite de phase via NymeaEnergy final phasePowerLimit = await client.getPhasePowerLimit(); print('Limite par phase : ${phasePowerLimit}A'); } // ───────────────────────────────────────────────────────────── // EXEMPLE 4 — Exécuter des Actions et configurer le smart charging // ───────────────────────────────────────────────────────────── Future example4_executeActions(NymeaClient client, String chargerId) async { print('\n=== Exemple 4 : Exécution d\'Actions ==='); // 4a) Définir la limite de puissance par phase (25A) var result = await client.setPhasePowerLimit(25); print('SetPhasePowerLimit(25A) → $result'); // 4b) Activer le mode Eco avec heure cible pour un chargeur result = await client.setChargingInfo( evChargerId: chargerId, mode: ChargingMode.ecoWithTargetTime, targetPercentage: 80, // Heure cible : demain matin 7h00 endDateTime: DateTime.now() .copyWith(hour: 7, minute: 0, second: 0) .add(const Duration(days: 1)) .toIso8601String(), spotMarketEnabled: true, dailySpotMarketPercentage: 80, ); print('SetChargingInfo(EcoWithTargetTime) → $result'); // 4c) Activer le spot market avec aWATTar Autriche result = await client.setSpotMarketConfiguration( enabled: true, providerId: kProviderAwattarAustria, ); print('SetSpotMarketConfiguration(aWATTar AT) → $result'); // 4d) Exécuter une Action native nymea sur un Thing // (ex : forcer l'activation de la charge via le state writable "power") final actionResult = await client.executeAction( thingId: chargerId, actionTypeId: kStatePower, // stateTypeId writable = actionTypeId implicite params: {kStatePower: true}, // activer la charge ); print('ExecuteAction(power=true) → $actionResult'); } // ───────────────────────────────────────────────────────────── // EXEMPLE 5 — Écouter les Events en temps réel (WebSocket push) // ───────────────────────────────────────────────────────────── Future example5_listenToEvents(NymeaClient client) async { print('\n=== Exemple 5 : Écoute des Events en temps réel ==='); // S'abonner aux namespaces qui nous intéressent await client.subscribeToNotifications(['NymeaEnergy', 'Integrations']); // Écouter les changements de config de charge client.onChargingInfoChanged.listen((info) { print('[EVENT] ChargingInfoChanged:'); print(' Chargeur : ${info.evChargerId}'); print(' Nouvel état : ${info.chargingState}'); print(' Mode : ${info.chargingMode}'); }); // Écouter les mises à jour des prix spot client.onSpotMarketScoreEntriesChanged.listen((entries) { print('[EVENT] SpotMarketScoreEntriesChanged: ${entries.length} créneaux'); // Trouver le meilleur créneau (weighting le plus élevé) if (entries.isNotEmpty) { final best = entries.reduce((a, b) => a.weighting > b.weighting ? a : b); print(' Meilleur créneau: ${best.startDateTime} → ${best.endDateTime}'); print(' Score: ${best.weighting.toStringAsFixed(2)} / Prix: ${best.value}€/MWh'); } }); // Écouter les changements de plannings de charge client.onChargingSchedulesChanged.listen((schedules) { print('[EVENT] ChargingSchedulesChanged: ${schedules.length} créneaux planifiés'); for (final s in schedules) { print(' ${s['startDateTime']} → ${s['endDateTime']}'); } }); // Écouter toutes les notifications brutes (debug) client.notifications.listen((msg) { if (msg['notification']?.toString().startsWith('NymeaEnergy') ?? false) { // Log toutes les notifs NymeaEnergy print('[NOTIF] ${msg['notification']}'); } }); print('En écoute... (Ctrl+C pour arrêter)'); // Dans une vraie app Flutter, cette écoute dure toute la vie du widget await Future.delayed(const Duration(minutes: 5)); } // ───────────────────────────────────────────────────────────── // EXEMPLE 6 — Consultation des prix spot + plannings // ───────────────────────────────────────────────────────────── Future example6_spotMarket(NymeaClient client) async { print('\n=== Exemple 6 : Consultation du marché spot ==='); // Fournisseurs disponibles final providers = await client.getAvailableSpotMarketProviders(); print('Fournisseurs disponibles :'); for (final p in providers) { print(' ${p['name']} (${p['id']}) — ${p['country']}'); } // Scores de prix pondérés pour aujourd'hui final scores = await client.getSpotMarketScoreEntries(); print('\n${scores.length} créneaux de prix disponibles :'); // Trier par pondération (meilleur en premier) scores.sort((a, b) => b.weighting.compareTo(a.weighting)); for (final s in scores.take(5)) { print( ' ${s.startDateTime.hour}h–${s.endDateTime.hour}h : ' '${s.value.toStringAsFixed(1)}€/MWh ' '(score: ${(s.weighting * 100).round()}%)', ); } // Plannings de charge calculés par le SmartChargingManager final schedules = await client.getChargingSchedules(); print('\nPlannings de charge :'); for (final s in schedules) { print(' ${s['startDateTime']} → ${s['endDateTime']}'); final action = s['action'] as Map?; if (action != null) { print(' Activé: ${action['chargingEnabled']} ' 'Courant: ${action['maxChargingCurrent']}A ' 'Phases: ${action['desiredPhaseCount']}'); } } } // ───────────────────────────────────────────────────────────── // MAIN — Démonstration complète // ───────────────────────────────────────────────────────────── Future main() async { // 1. Connexion final client = await example1_connect(); if (client == null) return; // 2. Récupération des chargeurs await example2_getEvChargers(client); // Pour les exemples suivants, on prend le premier chargeur trouvé final chargers = await client.getThingsByInterface('evcharger'); if (chargers.isEmpty) { print('Aucun chargeur trouvé.'); await client.disconnect(); return; } final chargerId = chargers.first['id'] as String; // 3. Lecture d'un state await example3_readState(client, chargerId); // 4. Exécution d'actions await example4_executeActions(client, chargerId); // 5. Écoute événements // await example5_listenToEvents(client); // 6. Spot market await example6_spotMarket(client); await client.disconnect(); }