Navigation : « EMS — moteur à règles » (pages de fonctionnalités, précédées de « Comment le moteur décide »), « Optimiseur » (Présentation, Protocole, Contrat, Écrire un optimiseur), « API » (ex-« Référence »). Aucun fichier existant déplacé : les URL publiées restent valides. Protocole : prose courte qui renvoie à OPTIMIZER_PROTOCOL.md du moteur pour le sens ; tableaux, listes fermées et règles nommées générés depuis le contrat. Contrat servi tel quel (copie octet pour octet). reference.md, resté un bouchon, devient l'accueil de la section API. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5.2 KiB
Écrire un optimiseur
Un optimiseur est un serveur qui parle le protocole : il répond au
handshake, puis à chaque GetPlan par un plan à un ou plusieurs créneaux, ou par une
abstention. Le langage est libre. Un optimiseur minimal tient en une cinquantaine de
lignes de Python.
Session minimale, à titre d'illustration (la forme exacte est dans le contrat) :
→ {"jsonrpc":"2.0","id":1,"method":"Handshake","params":{"protocolVersion":"1.1","engine":"etm-powersync-energy-plugin-etm/…"}}
← {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"1.1","name":"mon-optimiseur","planning":false}}
→ {"jsonrpc":"2.0","id":2,"method":"GetPlan","params":{ …contexte… }}
← {"jsonrpc":"2.0","id":2,"result":{"abstain":true,"reason":"premier calcul en cours"}}
Trois points à ne pas manquer :
- une action par charge disponible dans le créneau en cours, chacune avec son motif en texte : sinon le plan entier est refusé ;
- répondre vite : servir le dernier plan en cache, ou s'abstenir, et calculer en tâche de fond ;
- ne rien aller chercher ailleurs : tout ce dont l'optimiseur a besoin, prévisions comprises, est dans le contexte.
L'optimiseur de référence
Le dépôt du moteur contient un optimiseur de référence libre (GPL-3.0), en Python,
bibliothèque standard seule :
tools/etm-powersync-ref-optimizer/.
Il répond un plan à un créneau qui reproduit la cascade des règles du moteur, en ne lisant
que le contexte. Il s'annonce powersync-optimizer au handshake.
C'est un point de départ pour écrire le sien, et un point de comparaison : il écoute sur
le socket local par défaut, ou sur tcp:// avec un secret partagé lu dans un fichier. Il
sait aussi injecter des défauts (abstention, lenteur, plan invalide, majeure différente…)
pour tester le repli du moteur. Mode d'emploi :
son README.md.
Brancher le moteur sur son optimiseur
Trois méthodes JSON-RPC de la box, réservées à l'administrateur, décrites dans
INTERFACE.md :
NymeaEnergy.SetOptimizerEndpoint— où se connecter (unix:///…outcp://hôte:port) ;NymeaEnergy.SetOptimizerToken— le secret partagé, le même que celui de l'optimiseur ;NymeaEnergy.GetOptimizerStatus— l'état de la connexion : optimiseur vivant, stratégie active, nom annoncé, dernier code d'erreur.
Sur tcp:// sans chiffrement, le secret circule en clair sur le réseau local.
La suite de conformité
La suite etm-powersync-optimizer-conformance lance votre optimiseur et branche dessus
le vrai moteur, sur des appareils simulés. Elle vérifie, une fonction par point :
- le handshake est accepté ;
- chaque
GetPlanreçoit sa réponse dans le délai du moteur ; - la session entière, dans les deux sens, est conforme au contrat embarqué par le moteur, règles de validation comprises ;
- chaque plan est appliqué : c'est l'optimiseur qui commande ;
- la boucle de sécurité reste au-dessus : une consigne hors bornes est écrêtée, une surcharge de phase est délestée.
Elle ne juge pas la qualité des plans.
La lancer contre son optimiseur
Construire le moteur avec ses tests, puis indiquer la commande qui démarre votre serveur ;
{endpoint} y est remplacé par l'adresse où écouter :
export ETM_POWERSYNC_OPTIMIZER_CMD='exec /chemin/de/mon-optimiseur --listen {endpoint}'
export ETM_POWERSYNC_CONFORMANCE_EXPECT=plan # ou abstain
Chaque fonction se lance dans son propre processus. La commande complète (isolement
réseau recommandé), les autres variables (secret partagé, délai de démarrage…) et la
lecture des échecs sont dans le
README.md de la suite.
Mode attendu : plan ou abstain
ETM_POWERSYNC_CONFORMANCE_EXPECT dit à la suite ce que fait votre optimiseur :
plan(par défaut) : il commande. Chaque cycle doit appliquer son plan.abstain: il s'abstient à chaque cycle — c'est permis, et conforme. La suite vérifie alors que le moteur pilote par ses règles à chaque cycle, sans compter d'échec, et que la sécurité tient toujours ; le contrôle d'écrêtage est sauté, faute de consigne à écrêter.
Toute autre valeur fait échouer la suite. Le mode ne se déduit pas du handshake :
planning et capabilities décrivent la forme des plans, pas le fait d'en produire. Le
mode se donne, il ne se devine pas.
Comparer sur les mêmes entrées
Le moteur peut enregistrer, sur la box, une trace de chaque cycle (désactivée par défaut,
NymeaEnergy.SetOptimizerTrace). L'outil tools/etm-powersync-trace-replay rejoue ces
traces sur un optimiseur candidat et résume les écarts avec le plan enregistré. Les traces
restent sur le site.