- 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
69 lines
4.3 KiB
Markdown
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.
|