# Télécommande LED chambre — Home Assistant ## Objectif Permettre à ma fille de piloter le ruban LED de sa chambre depuis son lecteur MP3 Android, via une page web ultra simple, **sans lui donner accès au reste de Home Assistant**. ## Matériel - Ruban LED **RGB non adressable** : toute la longueur affiche la même couleur. Aucun effet de « vague » spatiale n'est possible, seulement des effets globaux (cycles, fondus, respiration). - Driver **Zigbee Iderwel** (PWM), intégré à Home Assistant. - **Dépôt public** : aucune valeur réelle (IP, ID du webhook, entité, prénom, identifiant Android) dans les fichiers versionnés. Elles sont dans `config.local.env` (non versionné, modèle : `config.example.env`). Les fichiers versionnés sont des modèles avec des marqueurs `__HA_IP__`, `__HA_PORT__`, `__WEBHOOK_ID__`, `__ENTITE__`, `__PRENOM__` ; `deploy.sh` génère `dist/` et déploie, `android/build.sh` génère `Config.java` et la config réseau. Ne jamais réintroduire de valeur réelle dans un fichier versionné. - entity_id du ruban : `ENTITE` dans `config.local.env` (mode couleur `xy` ; `hs_color` accepté, converti par HA) - intégration Zigbee : **Zigbee2MQTT** - HA : HAOS sur Odroid N2, adresse `HA_IP:HA_PORT` ; accès SSH via l'alias `SSH_HOST` (**root** : lecture seule par défaut). Jeton HA de dev dans `.env` (non versionné). - **Effets natifs du driver (`colorloop`, `breathe`…) peu fiables** : testés, ne pas les utiliser. Les effets passent par des scripts HA. Couleurs fixes, luminosité et `transition` fonctionnent bien. - Le driver ne remonte pas l'attribut `effect` (toujours `None` dans HA). - MP3 : **Fanvace M36, Android 13**, écran 640×1136 à 300 dpi (≈ 341 px CSS de large), WebView 108. Branché en ADB. - **Pas de navigateur accessible** (app lock) : la page est affichée par un mini APK WebView (`android/`, code dans le paquet `app.lumiere`, identifiant installé = `APP_ID` appliqué via `--rename-manifest-package`), qui n'autorise que `http://HA_IP:HA_PORT/local/led/`. Recompiler avec `android/build.sh` (clé de debug `~/.android/debug.keystore` : garder la même pour les mises à jour), installer avec `adb install -r android/build/ma-lumiere.apk`. Si l'IP de HA change : modifier `config.local.env`, recompiler et réinstaller. ## Architecture ``` [Page HTML statique] --POST JSON--> [Webhook HA (local_only)] --> [Automatisation] --> light.* / scripts d'effets /config/www/led/ /api/webhook/ servie sur /local/led/ ``` 1. **Scripts d'effets** (`script.led_`) : boucles infinies (`repeat: while true`) de `light.turn_on` avec `transition`, en `mode: restart`. 2. **Automatisation webhook** : point d'entrée unique, qui ne peut agir que sur le ruban et sur une liste fermée de scripts. 3. **Page web** : gros boutons, aucune authentification, à ajouter sur l'écran d'accueil du MP3. ## Contrat du webhook (corps JSON) | action | champs | effet | |--------------|--------------------------|-----------------------------------------------------------------| | `off` | — | arrête tous les effets et éteint le ruban (transition 1 s) | | `couleur` | `teinte` (0–359) | arrête les effets, couleur fixe `hs_color: [teinte, 100]` | | `luminosite` | `valeur` (5–100) | `brightness_pct`, valeur bornée côté HA | | `effet` | `nom` (ex. `arc_en_ciel`) | arrête l'effet en cours et lance `script.led_` s'il figure dans la liste blanche | ## Contraintes et règles - **Sécurité** - Webhook en `local_only: true` et `allowed_methods: [POST]`, avec un ID aléatoire long. - Liste blanche stricte des scripts dans l'automatisation ; ne jamais construire un entity_id arbitraire à partir du JSON. - Toutes les valeurs numériques sont bornées et ont un `default` côté HA. - Aucun jeton HA dans la page. - **Zigbee** : ne pas inonder le réseau. Garder au moins 1 s entre deux commandes dans les scripts (idéalement 2–3 s avec `transition` égale au delay). Les fondus sont lissés par le driver. - **Effets** : lancer un nouvel effet ou une couleur fixe arrête toujours l'effet en cours. - **Pas de retour d'état** : le webhook ne renvoie rien. La page ne connaît pas l'état du ruban et l'UI ne doit pas faire semblant de le connaître (pas de toggle on/off avec un état affiché). - **Page web** - Un seul fichier HTML autonome (CSS et JS inline), sans dépendance externe ni CDN. - JS compatible avec un vieux navigateur Android : ES5 de préférence, ou au minimum sans syntaxe récente (`?.`, `??`, etc.). Utiliser `fetch` s'il est disponible, sinon `XMLHttpRequest`. - Pensée pour un petit écran tactile en portrait : grandes cibles tactiles, peu de texte, très visuelle (pastilles de couleur, icônes d'effets), retour visuel immédiat au tap. - Balises `` et `apple-mobile-web-app` / `manifest` minimal pour que le raccourci sur l'écran d'accueil ressemble à une appli. - Interface en français, pour une enfant. ## Effets (en place dans `packages/led_chambre.yaml`) - Calmes (≥ 2 s entre commandes) : `arc_en_ciel` (pas de 30°, 3 s), `respiration` (10 ↔ 100 %, 3 s), `coucher_de_soleil` (5 s), `ocean` (4 s), `veilleuse` (orange 5 %, extinction en fondu après 30 min). - Boum (1 commande/s, le minimum) : `disco` (sauts de couleur), `boum` (flash 100 % puis fondu à 25 %), `tourbillon` (arc-en-ciel rapide). Pas de stroboscope. - Le webhook remet 100 % quand on sort d'un effet qui baisse la luminosité (veilleuse, respiration, boum) ou quand le ruban est éteint. - Piège : dans une palette en `variables`, une teinte `0` arrive vide dans `hs_color` et fait planter le script → utiliser `360` pour le rouge. - Ajouter un effet = script `led_` + entrée dans `effets` et `tous_les_effets` de l'automatisation + tuile dans la page ; déployer avec `./deploy.sh` (copie, `ha core check`, `script.reload` / `automation.reload`, pas de redémarrage). ## Livrables attendus 1. `scripts.yaml` : les scripts d'effets 2. `automations.yaml` : l'automatisation webhook (ou un package `packages/led_chambre.yaml` regroupant les deux) 3. `www/led/index.html` : la page 4. Procédure de test : - `curl -X POST -H "Content-Type: application/json" -d '{"action":"effet","nom":"arc_en_ciel"}' http://:8123/api/webhook/` - tester chaque action avec curl **avant** de toucher à la page 5. APK « Ma lumière » (`android/`) installé via ADB, à autoriser dans l'app lock ## Ordre de travail 1. Scripts d'effets, testés depuis Outils de développement → Actions 2. Automatisation webhook, testée avec curl 3. Page web, testée d'abord sur desktop en vue mobile, puis sur le MP3