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>
78 lines
3.0 KiB
Dart
78 lines
3.0 KiB
Dart
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
// §7-1 — aller-retour neutre : GetLoadConfig -> SetLoadConfig verbatim -> GetLoadConfig.
|
|
//
|
|
// ⚠️ SEUL SCRIPT DE tools/rpc/ QUI ÉCRIT SUR LA BOX.
|
|
// `SetLoadConfig` remplace l'ENSEMBLE des charges et déclenche une réévaluation
|
|
// des adaptateurs. 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.
|
|
// Le drapeau --yes est obligatoire, précisément pour qu'elle ne parte jamais par
|
|
// réflexe de flèche haut dans un terminal.
|
|
//
|
|
// Usage : dart tools/rpc/loadconfig_roundtrip.dart <host> --yes
|
|
Future<void> main(List<String> args) async {
|
|
if (!args.contains('--yes')) {
|
|
stderr.writeln('Ce script ÉCRIT sur la box (NymeaEnergy.SetLoadConfig).');
|
|
stderr.writeln('Relancer avec --yes pour confirmer :');
|
|
stderr.writeln(' dart tools/rpc/loadconfig_roundtrip.dart '
|
|
'${args.isNotEmpty ? args[0] : "192.168.1.75"} --yes');
|
|
exitCode = 2;
|
|
return;
|
|
}
|
|
final host = args.isNotEmpty && !args.first.startsWith('--')
|
|
? args.first
|
|
: '192.168.1.75';
|
|
final ws = await WebSocket.connect('ws://$host:4444');
|
|
var id = 0;
|
|
final pending = <int, Completer<Map<String, dynamic>>>{};
|
|
final notifs = <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);
|
|
} else if (m['notification'] != null) {
|
|
notifs.add(m['notification'] as String);
|
|
}
|
|
});
|
|
Future<Map<String, dynamic>> call(String me, [Map<String, dynamic> p = const {}]) {
|
|
final i = ++id;
|
|
final c = Completer<Map<String, dynamic>>();
|
|
pending[i] = c;
|
|
ws.add(jsonEncode({'id': i, 'method': me, 'params': p}));
|
|
return c.future.timeout(const Duration(seconds: 20));
|
|
}
|
|
|
|
await call('JSONRPC.Hello', {'locale': 'fr_FR'});
|
|
await call('JSONRPC.SetNotificationStatus', {'enabled': true});
|
|
|
|
final before = await call('NymeaEnergy.GetLoadConfig');
|
|
final cfgBefore = before['params']['loadConfigs'] as List;
|
|
final jsonBefore = const JsonEncoder.withIndent(' ').convert(cfgBefore);
|
|
print('--- AVANT ---\n$jsonBefore\n');
|
|
|
|
print('--- SetLoadConfig VERBATIM (aucune modification) ---');
|
|
final set = await call('NymeaEnergy.SetLoadConfig', {'loadConfigs': cfgBefore});
|
|
print('réponse: ${jsonEncode(set)}\n');
|
|
|
|
await Future<void>.delayed(const Duration(seconds: 3));
|
|
|
|
final after = await call('NymeaEnergy.GetLoadConfig');
|
|
final cfgAfter = after['params']['loadConfigs'] as List;
|
|
final jsonAfter = const JsonEncoder.withIndent(' ').convert(cfgAfter);
|
|
|
|
print('--- notifications reçues pendant l\'opération ---');
|
|
print(notifs.isEmpty ? '(aucune)' : notifs.join('\n'));
|
|
|
|
print('\n--- VERDICT ---');
|
|
if (jsonBefore == jsonAfter) {
|
|
print('IDENTIQUE — aller-retour neutre OK');
|
|
} else {
|
|
print('DIVERGENCE :');
|
|
print('APRES:\n$jsonAfter');
|
|
}
|
|
await ws.close();
|
|
}
|