etm-powersync-app/tools/rpc/notifications.dart
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

56 lines
1.7 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'dart:io';
Future<void> main(List<String> args) async {
final host = args.isNotEmpty ? args[0] : '192.168.1.75';
final secs = args.length > 1 ? int.parse(args[1]) : 90;
final ws = await WebSocket.connect('ws://$host:4444');
var id = 0;
final pending = <int, Completer<Map<String, dynamic>>>{};
final counts = <String, int>{};
final samples = <String, String>{};
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);
return;
}
final n = m['notification'] as String?;
if (n != null) {
counts[n] = (counts[n] ?? 0) + 1;
samples.putIfAbsent(n, () => jsonEncode(m['params']));
}
});
Future<Map<String, dynamic>> call(String meth, [Map<String, dynamic> p = const {}]) {
final i = ++id;
final c = Completer<Map<String, dynamic>>();
pending[i] = c;
ws.add(jsonEncode({'id': i, 'method': meth, 'params': p}));
return c.future.timeout(const Duration(seconds: 15));
}
await call('JSONRPC.Hello');
final r = await call('JSONRPC.SetNotificationStatus', {'enabled': true});
print('Namespaces abonnés: ${r['params']['namespaces']}');
print('Écoute ${secs}s…\n');
await Future<void>.delayed(Duration(seconds: secs));
print('--- notifications reçues en ${secs}s ---');
final keys = counts.keys.toList()..sort();
for (final k in keys) {
print('${counts[k]!.toString().padLeft(4)} $k');
}
print('\n--- premier échantillon par type ---');
for (final k in keys) {
var s = samples[k]!;
if (s.length > 260) s = '${s.substring(0, 260)}…';
print('$k\n $s');
}
await ws.close();
}