Patrick Schurig 4ade3e4151 tools(rpc): sondes JSON-RPC + fixtures du lot télémétrie déployé sur .75
Range dans tools/rpc/ les sondes qui vivaient dans un scratchpad volatil :
probe (appel RPC quelconque), notifications (abonnement + comptage),
locale et locale_diff (comportement o:locale et son effet réel),
loadconfig_roundtrip (aller-retour neutre §7-1). README avec usages.

loadconfig_roundtrip est le SEUL qui écrit sur la box : garde --yes ajouté
pour qu'un SetLoadConfig ne parte jamais par réflexe de flèche haut.

analysis_options : tools/** et les classes l10n générées sortent de
l'analyse — flutter analyze revient à 25 issues (ligne de base).

Fixtures : le lot plugin télémétrie EST déployé sur .75 depuis ce matin
(20 méthodes / 14 notifications). Capturé avant que ça ne se reperde :
- loadtelemetry_hems75.json : dump réel de GetLoadTelemetry
- loadconfig_hems75_v2.json : GetLoadConfig avec la clé 'domain'
- schema_hems75_v2.json     : schémas SET + télémétrie introspectés

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 14:40:03 +02:00
..

Sondes JSON-RPC — tools/rpc/

Scripts dart:io autonomes pour interroger une box nymea sans lancer l'app.

Pourquoi ils existent : sur ce poste, Flutter Linux natif est bloqué (snap sans linker ld.lld) et le web ne peut pas joindre le LAN en ws:// (CORS). Ces sondes sont donc le moyen le plus court de vérifier un comportement réel de la box — et elles font plus autorité qu'une lecture de code ou qu'un Introspect recopié de mémoire.

Aucune dépendance hors SDK : dart:io + dart:convert. Rien à installer.

dart tools/rpc/<script>.dart [host] [args…]     # host par défaut : 192.168.1.75

Les scripts

Script Ce qu'il fait Écrit ?
probe.dart Un appel RPC quelconque, réponse en JSON indenté. Le couteau suisse. non
notifications.dart S'abonne à tous les namespaces, compte et échantillonne ce qui arrive. non
locale.dart Comportement de o:locale : connexions simultanées, re-Hello, locale absurde. non
locale_diff.dart Aplatit toutes les chaînes affichables et les diffe entre locales. non
loadconfig_roundtrip.dart Aller-retour neutre Get → Set verbatim → Get. ⚠️ OUI

probe.dart

dart tools/rpc/probe.dart 192.168.1.75 NymeaEnergy.GetLoadConfig
dart tools/rpc/probe.dart 192.168.1.75 JSONRPC.Introspect > introspect.json
dart tools/rpc/probe.dart 192.168.1.75 Integrations.GetThings
dart tools/rpc/probe.dart 192.168.1.75 NymeaEnergy.GetChargingInfos '{"evChargerId":"…"}'

Le Hello part toujours en premier et son contenu va sur stderr, la réponse sur stdout — d'où le > fichier.json propre ci-dessus.

notifications.dart

dart tools/rpc/notifications.dart 192.168.1.75 90     # écoute 90 s

Utile pour répondre à « est-ce que cette information franchit la frontière RPC ? ». Un namespace qui ne produit rien pendant que le système travaille est une réponse, pas un silence à interpréter.

locale.dart / locale_diff.dart

locale.dart montre que nymea gère la locale par connexion (deux sockets, deux langues). locale_diff.dart répond à la question qui compte vraiment : est-ce que ça change quelque chose ? Relevé du 2026-08-25 sur .75 — sur 784 chaînes affichables, de_DE en change 1, fr_FR/it_IT/es_ES/nl_NL zéro.

loadconfig_roundtrip.dart — ⚠️ écrit

dart tools/rpc/loadconfig_roundtrip.dart 192.168.1.75 --yes

SetLoadConfig remplace l'ensemble des charges. Le contenu renvoyé est identique à ce qui vient d'être lu, donc l'opération est neutre — mais elle reste une écriture sur une installation vivante, et elle déclenche une réévaluation des adaptateurs. Le drapeau --yes est obligatoire pour qu'elle ne parte jamais par réflexe de flèche haut.

Pour confirmer qu'aucune reconstruction d'adaptateurs n'a lieu (ECS-412, m_builtFrom + sameHardware()), lire le journal de la box en parallèle :

ssh etm@192.168.1.75 'journalctl -u nymead -f'

Bancs

Cible Particularité
192.168.1.75 ouverte (authenticationRequired: false) — aucune auth à gérer dans les sondes. Une seule charge (chauffe-eau, relay-router).
192.168.1.120 auth requise — ces sondes ne gèrent PAS Authenticate. À étendre avant usage.