etm-powersync-app/docs/archive/BRIEF_agent_app.md
Patrick Schurig 0ebbde49da chore(docs): range specs/contrats/refs dans docs/, track l'autorité
- specs -> docs/ (DASHBOARD_SPEC compagnon du contrat)
- ref introspection nymea-jsonRPC -> docs/reference/
- mockups HTML -> docs/mockups/ ; briefs consommés -> docs/archive/
- track AGENTS.md + INTERFACE_etmvariableload.md (étaient untracked)
- INTERFACE_*: marqué miroir, canonique = repo plugin
2026-06-28 12:49:57 +02:00

69 lines
4.3 KiB
Markdown

# BRIEF — Agent App (`etm-powersync-app`)
Écran **Rôles & appareils** + écran **Configurer une charge pilotée**.
## Fichiers de référence (joints)
1. **`INTERFACE_etmvariableload.md`** — le **contrat**. Source de vérité.
2. **`roles_appareils_mockup.html`** — écran 1 : liste, deux zones, drag-priorité, tri-état.
3. **`config_ecs_mockup.html`** — écran 2 : config Dynamique/Fixe + assistant résistances.
> **Règle d'or : le contrat (`.md`) PRIME sur les maquettes.** Les `.html` sont l'intention
> visuelle (look, structure, interactions). En cas de conflit entre une maquette et le `.md`,
> **le `.md` gagne.** Ne reproduis pas un pixel au détriment d'une décision du contrat.
## ⚠️ La maquette écran 1 est partiellement périmée
Elle a été produite avant plusieurs décisions. **Ne la suis pas aveuglément** sur ces 3 points —
applique la version ci-dessous :
1. **Paliers ≠ config matérielle.** L'écran 1 affiche les paliers comme une propriété « matériel »
de l'ECS. **Faux.** Ce sont une **déclaration** (`powerLevels`), éditée dans l'écran 2. Sur la
carte de liste, ne montre qu'un résumé (ex. « 5 paliers · max 2400 W »), pas un éditeur.
2. **Auto-détection solaire/batterie.** Les rôles **inférés** par interface (production solaire,
batterie) apparaissent **directement en zone définitive** avec un badge « détecté » — ils ne
passent **pas** par « À configurer ». La batterie garde sa carte (priorité + `needs`), mais
n'est jamais « à configurer » au sens bloquant.
3. **Compteur `X / 6`.** Comptage : inférés (solaire, batterie) = configurés d'office ;
pickés (réseau, EV, ECS, PAC) = comptés quand **assignés** *ou* actés **« Pas d'appareil »**.
« Complet » = aucun rôle en non-configuré bloquant.
## Décisions verrouillées (ne pas re-débattre)
- **Tri-état par rôle** : `present(thingId)` / `absent({status:"absent"})` / non-configuré
(clé absente). Jamais `thingId:null`.
- **Trois destinations** : Compteurs (réseau→rootMeter, solaire→détecté) · Charges pilotables
(EV/ECS/PAC/batterie, priorisables) · Absent.
- **Cycle de vie** : « À configurer » → assigné (remonte dans Compteurs *ou* Charges pilotables
selon le rôle) **ou** « Pas d'appareil » (acté absent). Trois états d'écran : vierge (tout à
configurer, zones du haut vides + invite) / en cours / complet.
- **Drag = priorité.** Réordonner les cartes de charges pilotables écrit `priority` (rang 1 =
servi en premier). Les cartes compteur ne sont **pas** draggables. L'ordre est **indicatif**
(le scheduler le bouscule sur Tempo rouge / deadline) — le signaler dans l'UI, pas le présenter
comme rigide.
- **Config charge pilotée** (écran 2) émet un `LoadDescriptor` au format du contrat §3 :
`mode` (dynamic|fixed), `powerLevels[]` **ou** `maxPowerW`, `priority`, `enabled`, `needs`.
- **Assistant résistances = UI-only.** Il additionne les unités et pré-remplit `powerLevels`,
puis disparaît. **Aucune résistance n'est stockée ni envoyée.** Ne calcule la combinatoire
**nulle part ailleurs**.
## Plomberie / état du repo
- Base de départ fournie : `energy_setup_provider.dart` (modèle tri-état + routage des sinks)
est une **intention**, à adapter aux signatures réelles du repo — pas à coller tel quel.
- **Persistance = côté plugin**, pas SharedPreferences. L'app appelle `NymeaEnergy.GetLoadConfig`
/ `SetLoadConfig`. **Ces méthodes n'existent pas encore****stub** : logger le JSON du
`LoadDescriptor` qui partira, ne rien casser. Le câblage réel arrive quand l'agent energymanager
les expose.
- `gridMeter``Energy.SetRootMeter` (natif, testable contre `hems` maintenant).
- **Bug à corriger au passage** : `nymea_service.dart` appelle `EnergyPlugin.SetChargingInfo`
doit être `NymeaEnergy.SetChargingInfo` ; et les champs `ChargingInfo` sont faux
(`mode``chargingMode`, `targetSoc``targetPercentage`, `endTime``endDateTime`,
`minCurrent` n'existe pas). Réf : introspect `jsonRpc.txt`.
## Périmètre de CE brief
Les écrans Rôles & appareils + Configurer charge pilotée **uniquement**. Pas le wizard Things
(autre lot), pas Système/Réseau/ModbusRTU (autre lot), pas la decision card. Lis `jsonRpc.txt`
(l'introspect) avant tout appel nymea — ne devine pas les signatures.