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>
46 lines
1.5 KiB
Dart
46 lines
1.5 KiB
Dart
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
// Sonde JSON-RPC read-only contre le HEMS .75.
|
|
// Usage: dart probe.dart <host> <method> [jsonParams]
|
|
Future<void> main(List<String> args) async {
|
|
final host = args.isNotEmpty ? args[0] : '192.168.1.75';
|
|
final method = args.length > 1 ? args[1] : 'NymeaEnergy.GetLoadConfig';
|
|
final params = args.length > 2
|
|
? jsonDecode(args[2]) as Map<String, dynamic>
|
|
: <String, dynamic>{};
|
|
|
|
final ws = await WebSocket.connect('ws://$host:4444')
|
|
.timeout(const Duration(seconds: 8));
|
|
var id = 0;
|
|
final pending = <int, Completer<Map<String, dynamic>>>{};
|
|
|
|
ws.listen((raw) {
|
|
final m = jsonDecode(raw as String) as Map<String, dynamic>;
|
|
final rid = m['id'];
|
|
if (rid is int && pending.containsKey(rid)) {
|
|
pending.remove(rid)!.complete(m);
|
|
} else if (m['notification'] != null) {
|
|
stderr.writeln('[notif] ${m['notification']}');
|
|
}
|
|
});
|
|
|
|
Future<Map<String, dynamic>> call(String m, [Map<String, dynamic> p = const {}]) {
|
|
final myId = ++id;
|
|
final c = Completer<Map<String, dynamic>>();
|
|
pending[myId] = c;
|
|
ws.add(jsonEncode({'id': myId, 'method': m, 'params': p}));
|
|
return c.future.timeout(const Duration(seconds: 15));
|
|
}
|
|
|
|
final hello = await call('JSONRPC.Hello');
|
|
stderr.writeln('--- JSONRPC.Hello ---');
|
|
stderr.writeln(const JsonEncoder.withIndent(' ').convert(hello['params']));
|
|
|
|
final res = await call(method, params);
|
|
stdout.writeln(const JsonEncoder.withIndent(' ').convert(res));
|
|
|
|
await ws.close();
|
|
}
|