Premier passage de l'app sur matériel (Redmi Note 9S). MIUI refuse INJECT_EVENTS :
Patrick a piloté, l'agent a observé. Captures et trace dans screenshots/ (ignoré).
Acquis à l'écran :
- §7-9 : trois Hello, tous « demandée fr_FR → retenue fr_FR », la valeur relue venant
de m_clientLocales côté box. Mais la locale de l'APPAREIL (en-GB) ne part pas :
_requestedLocale est figé à fr_FR et rien ne câble l'un sur l'autre.
- §7-5 : l'écran suit l'arbitre sans un geste — budget, allocation, motif recomposé,
et le recrédit anti-clignotement visible en clair.
- Écriture de domaine faite au doigt, confirmée par la box et le fichier persisté.
- SetLoadConfig 19:53:46.007 → LoadConfigChanged .288 → ack .303 : la confirmation
a battu l'acquittement de 15 ms. Conclure sur l'ack, c'est courir après sa propre
notification.
§7-6 : l'état « données anciennes » est INATTEIGNABLE par perte de lien — la garde de
routage évacue vers /installations une seconde après la coupure, bien avant le seuil de
180 s. Le compteur de fraîcheur, lui, a été vu vivre. Seul sinceCycleAdvanced peut donc
réellement déclencher le bandeau : l'arbitre figé socket vivante.
Huit défauts constatés, aucun corrigé (constat d'abord) : pas de reconnexion
automatique, /energy/setup qui décrit une autre installation que la vraie, cumuls
aberrants venus de la box, thème ignoré, débordements, titre dupliqué, instantané
effacé hors connexion, bruit de transport.
Décisions de Patrick : l'ordre se règle dans « Charges pilotables » au glisser-déposer,
/energy/loads disparaît, deux niveaux conservés, chip « À déclarer » → bouton
Configurer ouvrant le mécanisme et ses Things.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XPUo3RMr8SzK6qbFtfBm8H
Patrick a relancé le service à 18:23:45. LoadConfigStore recharge 2 configs depuis
/var/lib/nymea/energy-load-configuration.json et la relecture RPC est identique clé
par clé à celle d'avant l'arrêt : chauffe-eau→ecs, pac-terrain→hvac.
Le redémarrage montre aussi la reprise à froid vue du dehors (ECS-411-b) : les
adaptateurs journalisent ce qu'ils ont LU sur les contacts, avec la mention
« correspondance exacte » — l'état de départ est constaté, pas supposé.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XPUo3RMr8SzK6qbFtfBm8H
Trois sondes permanentes, et le relevé de ce qu'elles ont montré sur .75.
- telemetry_watch.dart (lecture seule) : cadence du battement de cœur et avancée
du cycle. C'est la seule mesure qui distingue une installation stable d'un
moteur arrêté — les deux produisent le même flux de trames.
- domain_assign.dart (écrit, --yes) : classe des charges en important le code
d'écriture de l'app. Une sonde qui sérialiserait à sa façon ne prouverait rien
sur l'app.
- fault_probe.dart (écrit, --yes) : provoque une charge en défaut, éprouve
ClearLoadFault, restaure. La config d'origine part sur le disque AVANT la
première écriture et la restauration rejoue ce fichier verbatim — filtrer la
sonde hors d'une relecture serait une reconstruction, c'est-à-dire le chemin
qui a failli écraser la config du banc via persist(). La config relue est
ensuite comparée clé par clé, pas seulement « la sonde a disparu ».
Ce que le banc a appris, et qui ne se déduisait pas du code :
- ClearLoadFault lève RÉELLEMENT le verrou (journal : « défaut LEVÉ ») et le
cycle suivant reverrouille, la cause n'ayant pas disparu. La télémétrie ne
repasse jamais à available:true. Une app qui aurait cru l'acquittement aurait
menti deux secondes plus tard.
- Le défaut publié est WRITE_FAILED, pas THING_MISSING : l'écriture est tentée,
échoue, l'échelle s'épuise, et m_faulted masque le second code.
- SetLoadConfig refuse en bloc et le motif n'est PAS dans la réponse RPC — il est
au journal. L'app ne peut que rapporter un refus, pas l'expliquer.
- ECS-412 confirmé au journal : une écriture de domaine ne reconstruit aucun
adaptateur (« 2 inchangée(s), 0 retirée(s) »). Le §7-1bis n'est plus une
lecture de code.
.75 est laissé classé (chauffe-eau→ecs, pac-terrain→hvac) : métadonnée que
l'arbitre ne lit pas, et le multi-domaines y devient exerçable. Retour arrière :
domain_assign.dart --clear --yes
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XPUo3RMr8SzK6qbFtfBm8H
Le bloqueur consigné en fin de session précédente est levé : GetLoadTelemetry,
LoadTelemetryChanged et o:domain sont sur .75 (20 méthodes / 14 notifications).
Mais consigne explicite de Patrick : ne PAS enchaîner sur la moitié télémétrie
tant que l'agent plugin n'a pas fini son travail sur pac-terrain. L'écart
GetLoadTelemetry (2 charges) / GetLoadConfig (1 charge) est ce travail en
cours, pas une anomalie à remonter — coder contre cet état serait coder contre
une cible mouvante.
Consigne aussi que l'arbitre tourne bien (timestamp +1 min/cycle), ce qui fixe
le plancher du seuil de fraîcheur §7-6 à plus de 60 s.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Point d'arrêt avant redémarrage machine. Consigne l'état du lot B app, le
bloqueur (lot plugin non déployé sur .75), le partage vérifié/non-vérifié,
et la question ouverte sur la fusion /energy/setup ↔ /energy/loads.
Note l'accès ssh au banc désormais documenté dans CLAUDE.md : il lève la
limite qui rendait le critère 7-1bis (non-reconstruction des adaptateurs)
invérifiable faute de journal.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>