Patrick Schurig eb7d727d17 docs(optimiseur): liens vers le moteur sur Gitea, plus de renvoi à INTERFACE.md, « optimizer » en anglais
Le miroir GitHub n'est pas encore synchronisé : les liens pointent sur git.etm-powersync.fr.
INTERFACE.md n'est plus dans le dépôt public : la forme des méthodes NymeaEnergy.* se lit sur
la box (JSONRPC.Introspect) ; GetOptimizerStatus n'est pas réservée à l'administrateur.
Orthographe anglaise unifiée : optimizer, optimization.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ry3vBrJT1tHdxAaXdCWi6L
2026-10-18 13:48:22 +02:00

102 lines
5.2 KiB
Markdown

# Écrire un optimiseur
Un optimiseur est un **serveur** qui parle le [protocole](protocole.md) : 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](contrat.md)) :
```text
→ {"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, en français : 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 {#reference}
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/`](https://git.etm-powersync.fr/ETM-Schurig/etm-powersync-energy-plugin-etm/src/branch/main/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`](https://git.etm-powersync.fr/ETM-Schurig/etm-powersync-energy-plugin-etm/src/branch/main/tools/etm-powersync-ref-optimizer/README.md).
## Brancher le moteur sur son optimiseur {#brancher}
Trois méthodes JSON-RPC de la box (les deux premières réservées à l'administrateur) ; la box
en rend la forme exacte par `JSONRPC.Introspect` :
- `NymeaEnergy.SetOptimizerEndpoint` — où se connecter (`unix:///…` ou `tcp://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é {#conformite}
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 :
1. le handshake est accepté ;
2. chaque `GetPlan` reçoit sa réponse dans le délai du moteur ;
3. la session entière, dans les deux sens, est conforme au contrat embarqué par le moteur,
règles de validation comprises ;
4. chaque plan est appliqué : c'est l'optimiseur qui commande ;
5. 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 :
```sh
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](https://git.etm-powersync.fr/ETM-Schurig/etm-powersync-energy-plugin-etm/src/branch/main/tests/auto/conformance/README.md).
### Mode attendu : `plan` ou `abstain` {#mode-attendu}
`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 {#traces}
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.