151 lines
7.3 KiB
Markdown
151 lines
7.3 KiB
Markdown
# CONSIGNE — Claude Code — Webapp “HA Entity Scanner & Manager”
|
||
|
||
## Objectif
|
||
Développer une webapp self-hosted (Docker) qui se connecte à Home Assistant (URL : `http://10.0.0.2:8123` et token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhNjI1NzkyYjZhZmE0MTliOTEwMmFiMGQ4YjExNDZjNiIsImlhdCI6MTc3MTY4MTE2NSwiZXhwIjoyMDg3MDQxMTY1fQ.uus2-4HCDFajj2oFPiiW9b3KjhxF-DdhFN0XuZ_n5E8) pour :
|
||
1) **Scanner / récupérer** la liste des entités,
|
||
2) **Afficher** une page web avec **liste + filtres**,
|
||
3) Permettre de **désactiver** une ou plusieurs entités (ou, si la désactivation native n’est pas possible via API HA, fournir une alternative fiable et clairement indiquée à l’utilisateur).
|
||
|
||
## Contraintes et attentes générales
|
||
- Langue UI : **français**.
|
||
- UI : claire, orientée “admin”, table + panneaux, responsive.
|
||
- Architecture standard : **Backend API + Frontend**.
|
||
- Stockage : **SQLite** par défaut (persistant via volume Docker).
|
||
- Auth : au minimum **token HA** côté backend (jamais exposé côté frontend). Idéalement variable d’environnement.
|
||
- Journalisation : logs backend lisibles + page “Journal” simple (dernières actions : scan, désactivation, erreurs).
|
||
- Fournir un **README** (installation, variables d’env, utilisation).
|
||
- Ne jamais bloquer l’UI : scan asynchrone + état d’avancement.
|
||
|
||
## Périmètre fonctionnel (MVP)
|
||
### A. Connexion Home Assistant
|
||
- Paramètres :
|
||
- `HA_BASE_URL = http://10.0.0.2:8123`
|
||
- `HA_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhNjI1NzkyYjZhZmE0MTliOTEwMmFiMGQ4YjExNDZjNiIsImlhdCI6MTc3MTY4MTE2NSwiZXhwIjoyMDg3MDQxMTY1fQ.uus2-4HCDFajj2oFPiiW9b3KjhxF-DdhFN0XuZ_n5E8`
|
||
- Tester la connexion via l’API REST Home Assistant.
|
||
- Si erreur : message UI explicite (HTTP code + cause probable).
|
||
|
||
### B. Récupération des entités
|
||
- Récupérer la liste des entités (au minimum : `entity_id`, `state`, `attributes`, `last_changed`, `last_updated`).
|
||
- Normaliser les champs utiles pour l’affichage :
|
||
- `domain` (ex: light, switch, sensor)
|
||
- `friendly_name`
|
||
- `device_class`, `unit_of_measurement`, `icon`
|
||
- `area_id` / `device_id` / `integration` si accessibles (sinon marquer “non disponible”)
|
||
- booléen `is_hidden` / `is_disabled` / `is_available` si déductible
|
||
- Mettre en cache en base (table `entities_cache`) et timestamp du dernier scan.
|
||
|
||
### C. UI de listing + actions
|
||
- Page principale : tableau (virtualisé si besoin) avec colonnes configurables.
|
||
- Action : sélection multiple (checkbox) + actions en lot :
|
||
- “Désactiver”
|
||
- “Réactiver” (si applicable)
|
||
- “Masquer (UI)” (fallback si désactivation native impossible)
|
||
- Afficher un panneau “Détails” à droite quand on clique une entité :
|
||
- attributs bruts JSON
|
||
- infos clés (domain, nom, device_class, etc.)
|
||
- boutons d’action sur cette entité
|
||
|
||
## “Désactiver une entité” — règles d’implémentation
|
||
Home Assistant n’offre pas toujours une “désactivation” universelle via une simple API REST. Claude Code doit :
|
||
|
||
1) **Rechercher la méthode la plus correcte** selon le type d’entité :
|
||
- Si l’entité est gérable via **registry** (entity_registry / device_registry) via WebSocket API, utiliser la méthode officielle.
|
||
- Sinon, proposer un **fallback** :
|
||
- “Masquer” (côté HA si possible via registry) ou “Ignorer dans l’app” (flag local DB) avec libellé clair.
|
||
- Option “Désactiver en empêchant les services” : non (trop intrusif) sauf si explicitement demandé.
|
||
2) L’UI doit **indiquer clairement** ce que fait l’action (désactivation HA réelle vs masquage/ignore local).
|
||
3) Toute action doit être **journalisée** (quoi, qui, quand, résultat, erreur).
|
||
|
||
## Brainstorming — filtres “judicieux” à implémenter
|
||
Implémenter une barre de filtres combinables + chips actives :
|
||
1) **Recherche texte** (entity_id, friendly_name).
|
||
2) **Domain** (multi-select) : light/switch/sensor/… + compteur par domaine.
|
||
3) **État** :
|
||
- `state` exact (on/off/…)
|
||
- “Indisponible” (`unavailable`, `unknown`)
|
||
4) **Disponibilité** :
|
||
- disponibles vs indisponibles
|
||
5) **Dernier changement** :
|
||
- “modifié dans les 5 min / 1 h / 24 h”
|
||
6) **Attributs** :
|
||
- `device_class` (multi-select)
|
||
- `unit_of_measurement` (multi-select)
|
||
7) **Source / intégration** (si accessible) :
|
||
- ZHA / Zigbee2MQTT / ESPHome / MQTT / Tapo / Reolink / …
|
||
8) **Zone / Pièce** (area) si accessible.
|
||
9) **Entités problématiques** (smart filters) :
|
||
- “spam logbook” : change très souvent (détecter fréquence)
|
||
- “entités orphelines” : pas de device_id / integration inconnue
|
||
- “noms manquants” : pas de friendly_name
|
||
10) **Statut de gestion** (dans l’app) :
|
||
- “Désactivées”
|
||
- “Masquées”
|
||
- “Ignorées localement”
|
||
11) **Favoris** :
|
||
- Marquer favori (flag local) pour accès rapide.
|
||
|
||
## UX attendue
|
||
- En-tête :
|
||
- bouton “Scanner maintenant”
|
||
- indicateur “Dernier scan : …”
|
||
- statut connexion HA (OK/KO)
|
||
- Zone filtres :
|
||
- champ recherche + filtres en dropdown + chips
|
||
- Table :
|
||
- tri colonnes (domain, nom, last_changed, state)
|
||
- pagination ou virtual scroll
|
||
- multi-sélection + actions groupées
|
||
- Panneau latéral détails :
|
||
- affichage propre des attributs JSON
|
||
- actions rapides (désactiver/masquer/ignorer/favori)
|
||
|
||
## Tech recommandée (choix par défaut)
|
||
- Backend : **Python FastAPI**
|
||
- Client HA via REST + WebSocket (si nécessaire pour registry)
|
||
- SQLite via SQLModel ou SQLAlchemy
|
||
- Frontend : **Vue 3 + Vite** (ou React si préféré), UI simple
|
||
- Docker :
|
||
- `docker-compose.yml` avec volumes (db + config)
|
||
- variables d’environnement pour `HA_BASE_URL`, `HA_TOKEN`
|
||
|
||
## Endpoints backend (à produire)
|
||
- `GET /api/health` : état de l’app + état HA
|
||
- `POST /api/scan` : lance un scan (asynchrone)
|
||
- `GET /api/entities` : liste paginée + filtres (query params)
|
||
- `GET /api/entities/{entity_id}` : détails
|
||
- `POST /api/entities/actions` : actions bulk (disable/enable/hide/unhide/ignore/unignore/favorite/unfavorite)
|
||
- `GET /api/audit` : dernières actions
|
||
|
||
## Données (SQLite)
|
||
Tables minimales :
|
||
- `entities_cache` : entity_id (PK), domain, friendly_name, state, attrs_json, last_changed, last_updated, fetched_at
|
||
- `entity_flags` : entity_id (PK), ignored_local (bool), favorite (bool), notes (text)
|
||
- `audit_log` : id, ts, action, entity_ids_json, result, error
|
||
|
||
## Exigences qualité
|
||
- Gestion d’erreurs explicite (HA down, token invalide, timeout).
|
||
- Timeout réseau configurable.
|
||
- Tests minimaux :
|
||
- test de parsing entités
|
||
- test filtre domain/state
|
||
- test “action bulk” (mock HA)
|
||
- Sécurité :
|
||
- le token HA ne doit jamais apparaître dans le HTML/JS.
|
||
- CORS maîtrisé.
|
||
|
||
## Livrables attendus
|
||
- Arborescence projet complète.
|
||
- `docker-compose.yml`
|
||
- Backend FastAPI prêt à lancer.
|
||
- Frontend page unique fonctionnelle.
|
||
- `README.md` clair.
|
||
- Une section “Limitations” expliquant la différence entre :
|
||
- désactivation réelle HA via registry (si implémentée)
|
||
- masquage/ignore local si non possible selon entité.
|
||
|
||
## Ordre de réalisation imposé
|
||
1) Backend : health + scan + entities list (sans disable)
|
||
2) Frontend : page liste + filtres + détails
|
||
3) Ajout flags locaux (ignore/favorite)
|
||
4) Implémenter “désactiver/masquer” via API HA la plus officielle possible
|
||
5) Audit log + finitions UI + README final |