etm-powersync-energy-plugin.../tests/tools/data/etm-powersync-trace-optimiseur.ndjson
Patrick Schurig 64a864bfaa feat(tools): etm-powersync-trace-replay, rejeu des traces vers un optimiseur (brief 4 T6)
Python 3, bibliothèque standard seule. unix:// par défaut (unix:///run/powersync/optimizer.sock),
tcp:// accepté ; token lu dans un fichier (--token-file), jamais en argument ni affiché.
Réponses écrites à côté de la trace, jamais d'écrasement ; résumé : requêtes, taux
d'abstention, computeMs médian et max, cycles non comparables, cycles dont les actions du
créneau courant diffèrent du plan enregistré. --fail-on-divergence : code 1.

Test (unittest) contre un serveur Unix minimal qui renvoie les réponses enregistrées (ce n'est
pas l'optimiseur de référence) : trace synthétique et trois traces réelles du moteur → zéro
divergence ; réponse modifiée → divergence vue, code 1 ; tcp://, refus d'écraser, endpoint
absent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 12:12:25 +02:00

3 lines
4.5 KiB
Plaintext

{"executed":[{"clamped":false,"kind":"setpoint","loadId":"ecs","powerW":1000},{"clamped":false,"kind":"setpoint","loadId":"{86decdd5-de6d-414a-8389-c7c59e998309}","powerW":2000}],"latencyMs":1,"request":{"battery":{"present":false},"forecast":{"baseload":{"model":"none","p50W":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"quality":{"commandedMinutes":0,"computedAt":"2026-10-17T09:36:18Z","daysCovered":{"weekend":0,"workday":0},"incompleteMinutes":0,"loads":[],"minDays":7,"minutes":0,"negativeMinutes":0,"resolutionS":3600,"windowDays":28}},"price":null,"pv":null,"resolutionS":3600,"start":"2026-06-07T22:00:00Z","steps":48,"weather":null},"loads":[{"adapter":"etmvariableload","declared":{"maxPowerW":3000,"minPowerW":0},"id":"{86decdd5-de6d-414a-8389-c7c59e998309}","label":"Routeur","limits":{"minOffS":0,"minOnS":0},"priority":2,"telemetry":{"available":true,"currentPowerW":0,"lockMaxPowerW":-1,"lockMinPowerW":0,"measurement":{"powerW":0,"source":"device"}}},{"adapter":"relay-router","declared":{"maxPowerW":1000,"minPowerW":1000},"id":"ecs","label":"ECS","limits":{"minOffS":0,"minOnS":0},"priority":1,"telemetry":{"available":true,"currentPowerW":0,"lockMaxPowerW":1000,"lockMinPowerW":0,"measurement":{"powerW":0,"source":"device"}}}],"meter":{"exportW":3000,"importW":0,"perPhaseA":[0,0,0],"source":"{c3f0f4f0-7f1d-408d-a30d-b919a0b564f3}"},"pv":{"currentW":null},"site":{"contractedPowerW":null,"gridCapW":null,"phaseLimitA":null},"tariff":null,"timestamp":"2026-06-08T13:00:00Z","trigger":"cycle"},"response":{"result":{"diagnostics":{"computeMs":3,"status":"optimal"},"planId":"plan-test","slots":[{"actions":[{"kind":"setpoint","loadId":"ecs","powerW":1000,"reason":"Texte LIBRE de l'optimiseur, qui ne doit jamais sortir"},{"kind":"setpoint","loadId":"{86decdd5-de6d-414a-8389-c7c59e998309}","powerW":500,"reason":"Texte LIBRE de l'optimiseur, qui ne doit jamais sortir"}],"expected":{"gridImportW":0},"from":"2026-06-08T12:59:00Z","to":"2026-06-08T13:15:00Z"}],"strategy":"faux","validUntil":"2026-06-08T13:30:00Z"}},"strategy":"rules","t":"2026-06-08T15:00:00+02:00"}
{"executed":[{"clamped":false,"kind":"setpoint","loadId":"ecs","powerW":1000},{"clamped":false,"kind":"setpoint","loadId":"{86decdd5-de6d-414a-8389-c7c59e998309}","powerW":500}],"latencyMs":0,"request":{"battery":{"present":false},"forecast":{"baseload":{"model":"none","p50W":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"quality":{"commandedMinutes":0,"computedAt":"2026-10-17T09:36:18Z","daysCovered":{"weekend":0,"workday":0},"incompleteMinutes":0,"loads":[],"minDays":7,"minutes":0,"negativeMinutes":0,"resolutionS":3600,"windowDays":28}},"price":null,"pv":null,"resolutionS":3600,"start":"2026-06-07T22:00:00Z","steps":48,"weather":null},"loads":[{"adapter":"etmvariableload","declared":{"maxPowerW":3000,"minPowerW":0},"id":"{86decdd5-de6d-414a-8389-c7c59e998309}","label":"Routeur","limits":{"minOffS":0,"minOnS":0},"priority":2,"telemetry":{"available":true,"currentPowerW":0,"lockMaxPowerW":-1,"lockMinPowerW":0,"measurement":{"powerW":0,"source":"device"}}},{"adapter":"relay-router","declared":{"maxPowerW":1000,"minPowerW":1000},"id":"ecs","label":"ECS","limits":{"minOffS":0,"minOnS":0},"priority":1,"telemetry":{"available":true,"currentPowerW":1000,"lockMaxPowerW":1000,"lockMinPowerW":0,"measurement":{"powerW":1000,"source":"device"}}}],"meter":{"exportW":3000,"importW":0,"perPhaseA":[0,0,0],"source":"{c3f0f4f0-7f1d-408d-a30d-b919a0b564f3}"},"pv":{"currentW":null},"site":{"contractedPowerW":null,"gridCapW":null,"phaseLimitA":null},"tariff":null,"timestamp":"2026-06-08T13:01:00Z","trigger":"cycle"},"response":{"result":{"diagnostics":{"computeMs":3,"status":"optimal"},"planId":"plan-test","slots":[{"actions":[{"kind":"setpoint","loadId":"ecs","powerW":1000,"reason":"Texte LIBRE de l'optimiseur, qui ne doit jamais sortir"},{"kind":"setpoint","loadId":"{86decdd5-de6d-414a-8389-c7c59e998309}","powerW":500,"reason":"Texte LIBRE de l'optimiseur, qui ne doit jamais sortir"}],"expected":{"gridImportW":0},"from":"2026-06-08T13:00:00Z","to":"2026-06-08T13:16:00Z"}],"strategy":"faux","validUntil":"2026-06-08T13:31:00Z"}},"strategy":"optimizer","t":"2026-06-08T15:01:00+02:00"}