# Contrat `optimize` — v0.1 (draft) - **Producteur** : `etm-powersync-optimizer` (propriétaire) - **Consommateur** : `etm-powersync-plugin-etm` → `OptimizerManager` (GPL, transport pur) - **Transport** : HTTP REST, `POST {optimizerUrl}/optimize` ## Principe Le plugin envoie un **instantané** de l'état temps réel et des contraintes ; l'optimiseur renvoie un **planning** sur l'horizon. L'optimiseur possède déjà ses séries (météo Open-Meteo, prix/`rank` du `tarif-provider`) et la configuration matérielle du site (capacité batterie, `c_batt`, `η`). Ces dernières **ne sont pas** renvoyées à chaque appel. ## Requête ```jsonc { "timestamp": 0, // epoch (s) de l'instantané "site": { "gridPower": 0, // W, signé (+ = soutirage, − = injection) "pvPower": 0, // W produits "batterySoc": 0, // %, état de charge courant "batteryPower": 0 // W, signé (+ = charge, − = décharge) — TODO confirmer signe }, "loads": [ { "id": "keba1", "type": "evcharger", // evcharger | heatpump | waterheater | relay | ... "controllable": true, "min": 6, // borne basse (A ou W selon type) — TODO unifier unité "max": 16, // borne haute "constraints": {} // TODO schéma (échéance VE, température cible PAC, etc.) } ] } ``` ## Réponse ```jsonc { "valid_until": 0, // epoch (s) — au-delà, le plugin retombe sur le rule-based "mode": "optimized", // optimized | fallback — TODO utilité ? "setpoints": [ { "id": "keba1", "current": 10, // consigne (A ou W selon type) "from": 0, // epoch (s) début d'application "to": 0 // epoch (s) fin } ], "battery": { // optionnel — consigne batterie si arbitrage actif "power": 0, // W, signé (+ = charge, − = décharge) "from": 0, "to": 0 } } ``` ## Règles de consommation (côté plugin) - Le plugin applique les `setpoints` **tels quels** (transport pur, aucune logique d'optimisation). - **Le load-management reste prioritaire** : toute consigne qui ferait dépasser `ISOUSC` est écrêtée localement par le plugin, après réception. L'optimiseur propose, le plugin garantit la sécurité. - Si `valid_until` est dépassé, si la réponse est invalide, ou si l'optimiseur est injoignable → repli immédiat sur la stratégie rule-based locale. ## Points ouverts (à figer pour v1) - Représentation des bornes `min`/`max` : ampères vs watts selon le type de charge — unifier ou typer explicitement. - Schéma des `constraints` par type de charge (échéance et SoC cible VE, consigne thermique PAC…). - Signe et sémantique de `batteryPower` (requête) et `battery.power` (réponse). - Utilité réelle du champ `mode`.