[brief] AGENTS.md = version définitive (architecture+workflow), statut phases 0-3a, décision TARGET drop-in actée
This commit is contained in:
parent
4ae1939f93
commit
9017a880ac
122
AGENTS.md
122
AGENTS.md
@ -1,21 +1,117 @@
|
||||
# AGENTS.md — etm-powersync-energy-plugin-etm
|
||||
|
||||
Moteur HEMS. Fork GPL de `nymea-energy-plugin-nymea`, étendu de l'optimisation EV
|
||||
vers un gestionnaire d'énergie complet (ECS, PAC, batterie, relais).
|
||||
vers un gestionnaire d'énergie complet (EV, ECS, PAC SG-Ready, batterie).
|
||||
|
||||
- **Licence** : GPL-3.0 · **Miroir public** : OUI
|
||||
- **Agent** : energy-etm · **Branche** : feature/beta-rulebased · **Scope** : energyplugin/
|
||||
- **Branche de travail** : `feature/beta-rulebased`
|
||||
- **Document d'interface faisant autorité** : `docs/OPTIMIZER_PROTOCOL.md` (le contrat
|
||||
stratégie/arbitrage — interne ET socket). `INTERFACE.md` fait autorité sur l'API JSON-RPC.
|
||||
|
||||
## Invariants locaux
|
||||
1. Tourne SANS `etm-powersync-optimizer` (socket absent → repli stratégie règles).
|
||||
2. Sécurité jamais déléguée : `verifyOverloadProtection()` (temps réel) borne toute sortie de l'optimiseur.
|
||||
3. Pas de boucle de feedback : surplus = PV mesurée + compteur, jamais le net.
|
||||
4. `decisionReason` non vide, en français, sur chaque décision.
|
||||
5. Aucun composant propriétaire ici (Héos vit dans `etm-powersync-optimizer`).
|
||||
6. Première tâche (revue) : renommer `nymea-energy-plugin-nymea.pro` → `.pro` ETM
|
||||
(+ TARGET, debian/). NE PAS toucher aux noms de paquets publiés.
|
||||
> ⚠️ Tout plan antérieur mentionnant « créer etm/ avec PowerSyncClient et
|
||||
> StaticHcHpProvider comme première étape » ou « injecter l'optimiseur dans
|
||||
> SmartChargingManager » est **INVALIDE et ABANDONNÉ**. Ne pas le reprendre,
|
||||
> quelle qu'en soit la source (fichier, mémoire de session, contexte).
|
||||
|
||||
## Références
|
||||
- `README.md` (architecture), `INTERFACE.md` (fait autorité sur l'API), `etm_powersync_energy.svg`.
|
||||
---
|
||||
|
||||
Carte globale et frontières : voir `../AGENTS.md`.
|
||||
## ARCHITECTURE CIBLE (non négociable)
|
||||
|
||||
```
|
||||
┌──────────────────────────────┐
|
||||
│ ARBITRAGE CENTRAL │ ← généralisation du
|
||||
│ budget de surplus UNIQUE │ SmartChargingManager amont
|
||||
│ waterfall par priorités │
|
||||
└──────┬───────────────────────┘
|
||||
│ IScheduler (= contrat OPTIMIZER_PROTOCOL)
|
||||
┌───────────┴───────────┐
|
||||
RuleBasedScheduler SocketScheduler
|
||||
(in-process, V1, GPL) (client unix://|tcp://, V1 aussi —
|
||||
plan à 1 créneau personne en face en beta : repli rules)
|
||||
│
|
||||
│ distribue le budget en LoadAction typées
|
||||
┌──────────┬────┴─────┬──────────────┐
|
||||
EvAdapter EcsRelayAdapter SgReadyAdapter BatteryAdapter
|
||||
(setpoint, (stage 0/1/2) (state 1-4) (constraint +
|
||||
iface setpoint W réseau)
|
||||
evcharger
|
||||
nymea)
|
||||
```
|
||||
|
||||
Règles absolues :
|
||||
1. **UN seul arbitre.** Le budget de surplus est une ressource unique, arbitrée à UN
|
||||
endroit. **INTERDIT : managers frères par type de charge** (EcsManager,
|
||||
BatteryManager à côté du SmartChargingManager) — deux décideurs sur le même surplus
|
||||
= sur-engagement et oscillations.
|
||||
2. **Les LoadAdapters exécutent, ils ne décident pas.** Un adaptateur : parle à son
|
||||
matériel, déclare ses capacités/contraintes (`declared`, `limits`, types d'action),
|
||||
expose sa télémétrie, applique les `LoadAction` reçues. Aucune logique de
|
||||
répartition dedans.
|
||||
3. **Le SmartChargingManager amont est EV-spécifique** : il se GÉNÉRALISE en arbitrage
|
||||
multi-charges (`ChargingAction` → `LoadAction`, bornes EV → adaptateurs). On ne
|
||||
branche PAS l'optimiseur dans le manager EV tel quel.
|
||||
4. **La boucle de sécurité est intouchable** : `verifyOverloadProtection()` (temps
|
||||
réel) + bornes par adaptateur écrêtent TOUTE sortie de stratégie, interne ou socket.
|
||||
5. **Plan par créneaux** (OPTIMIZER_PROTOCOL §6) : seul le créneau courant est exécuté.
|
||||
Le rule-based répond un plan à 1 créneau. Modèle async = **cache** : le plan du
|
||||
cycle précédent s'applique, le recalcul se fait en fond. Jamais d'attente dans
|
||||
`update()`.
|
||||
6. **Repli toujours fonctionnel** : optimiseur absent/mort/abstain → rule-based.
|
||||
Capabilities (`tier`, `optimizerExpected`, `optimizerAlive`, `activeStrategy`)
|
||||
reflètent l'état en continu.
|
||||
7. **`decisionReason` non vide, en français, sur chaque action.** Action sans reason
|
||||
= rejetée.
|
||||
8. **Pas de boucle de feedback** : surplus = PV mesurée + compteur, jamais le net
|
||||
après pilotage.
|
||||
9. **Aucun composant propriétaire ici** (Héos = repo privé `etm-powersync-optimizer`).
|
||||
Ce repo doit compiler et tourner seul, GPL pur.
|
||||
|
||||
## RÉPONSES FIGÉES (ne plus poser ces questions)
|
||||
|
||||
- Plages HC/HP et tarifs : **configuration JSON**, jamais hardcodé. Prévoir Tempo
|
||||
(6 types de jours), pas seulement HC/HP.
|
||||
- Async : **modèle cache** (cf. règle 5).
|
||||
- Bugs upstream : **commits séparés** du code ETM, message préfixé `[upstream-fix]`.
|
||||
Candidats PR nymea (fix phases EV, Keba) = patchs isolés, propres, upstreamables.
|
||||
- `protocolVersion` : **constante `"1.0"`**, pas un paramètre de config.
|
||||
- Renommage : FAIT (Phase 1, commit f4d5b20). TARGET et noms de paquets debian
|
||||
INCHANGÉS (.so drop-in remplaçant l.amont — garantit un seul plugin énergie chargé).
|
||||
|
||||
## WORKFLOW OBLIGATOIRE
|
||||
|
||||
Chaque phase produit un livrable VALIDÉ PAR PATRICK avant la suivante. Jamais de code
|
||||
avant validation du design de la phase.
|
||||
|
||||
- **Phase 0 — Analyse (en cours)** : répondre par écrit, code lu à l'appui :
|
||||
(a) quelles charges SmartChargingManager pilote-t-il (types manipulés) ;
|
||||
(b) ChargingAction peut-il exprimer « ECS palier 1 » / « batterie décharge
|
||||
interdite » — citer ses champs ; (c) avec des managers séparés, où vivrait le
|
||||
budget unique. Zéro code, zéro plan d'implémentation.
|
||||
- **Phase 1 — Renommage** : `git mv` du `.pro`, TARGET, debian/. Un commit, revue.
|
||||
- **Phase 2 — Design de l'arbitrage généralisé** : interface `LoadAdapter` (méthodes,
|
||||
ce qu'un adaptateur déclare), flux du budget, mapping `LoadAction`→adaptateurs,
|
||||
où vit `IScheduler`. Texte + signatures, pas d'implémentation. Validation Patrick.
|
||||
- **Phase 3 — Implémentation par étapes** (chacune : compile amd64 + cross arm64,
|
||||
et un scénario `docker-simulation.sh` qui la prouve = DoD) :
|
||||
3a. structs du protocole (contexte, plan, actions) ;
|
||||
3b. arbitre + RuleBasedScheduler + EvAdapter (iso-fonctionnel avec l'amont sur EV) ;
|
||||
3c. EcsRelayAdapter (paliers) ; 3d. SocketScheduler (handshake/heartbeat/repli,
|
||||
testé contre un optimiseur factice ~50 lignes) ; 3e. SgReadyAdapter ;
|
||||
3f. BatteryAdapter (constraints + charge réseau plafonnée).
|
||||
- **Bugs upstream** : au fil de l'eau, commits `[upstream-fix]` séparés.
|
||||
|
||||
## DÉFINITION DE FAIT (par étape de phase 3)
|
||||
|
||||
1. Compile amd64 et cross arm64.
|
||||
2. Scénario de simulation ajouté/étendu qui démontre le comportement (le harnais
|
||||
`docker-simulation.sh` + `tests/auto` hérités sont le banc de test).
|
||||
3. `decisionReason` visibles dans les logs de simulation.
|
||||
4. Aucune régression des tests amont existants.
|
||||
|
||||
## RÉFÉRENCES
|
||||
|
||||
- `docs/OPTIMIZER_PROTOCOL.md` — le contrat. §5 (SurplusContext), §6 (plan/actions),
|
||||
§7 (repli), annexe C (priorités).
|
||||
- `README.md` — architecture (deux boucles, frontière), `etm_powersync_energy.svg`.
|
||||
- `INTERFACE.md` — API JSON-RPC existante (`NymeaEnergy`, cible future `Ems`).
|
||||
- Carte globale du workspace : `../AGENTS.md`.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user