- Python 90.8%
- Dockerfile 7.2%
- Shell 2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
deploy / deploy (push) Successful in 15s
Depuis HA 2026.8, `http:` dans configuration.yaml est déprécié et sera ignoré en 2027.2.0 : HA l'importe une fois dans `.storage/http` (`yaml_migration_done: true`) puis la conf vit dans Paramètres > Système > Réseau. Le repair « La configuration YAML HTTP est obsolète » est apparu juste après la montée en 2026.9.1. Le bloc `http:` a été retiré de configuration.yaml sur le serveur (fichier hors repo, `config/` est exclu du rsync ; backup en configuration.yaml.bak.20260911-220645). L'étape de patch n'avait donc plus aucune prise : elle serait tombée à chaque déploiement dans sa branche « Pas de section http:, skip (à configurer manuellement) », message que personne n'aurait lu. Conséquence assumée, documentée dans le README : `trusted_proxies` n'est plus provisionnable par la CI. `.storage/` est de l'état runtime HA, hors IaC. Sur un host reconstruit à neuf c'est désormais une étape UI manuelle — et si on l'oublie, nginx renvoie 400 sans message explicite. |
||
| .forgejo/workflows | ||
| docs | ||
| stacks | ||
| .gitignore | ||
| CLAUDE.md | ||
| README.md | ||
homeassistant-timothy
Home Assistant + écosystème (Zigbee2MQTT, Mosquitto, ha-bridge, Whisper, Piper) pour le ThinkCentre maison A, plus edge Zigbee (Mosquitto + Z2M) à Lescuretie maison C. Archi hub-and-spoke : un seul HA central à A, deux meshes Zigbee séparés (un par site), bridge MQTT bidirectionnel via tailnet pour que le HA voie tous les devices.
Périmètre
Maison A (Argenteuil, ThinkCentre)
| Service | Type | Réseau | Notes |
|---|---|---|---|
| Home Assistant | Docker compose | host |
mDNS, découverte, websocket. Central pour toute la topologie multi-sites |
| Mosquitto MQTT | Docker compose | web |
broker partagé HA + Z2M local + reçoit le bridge de Lescuretie sur 100.64.0.7:1883 |
| Zigbee2MQTT | Docker compose | web |
dépend du coordinateur USB (Sonoff V2 CC2652P), base topic zigbee2mqtt |
| ha-bridge | Docker compose | web |
build local (Dockerfile dans le repo), expose 127.0.0.1:8765 derrière nginx infra |
| Whisper | Docker compose | host port 127.0.0.1:10300 |
STT local (faster-whisper, FR, base-int8) |
| Piper | Docker compose | host port 127.0.0.1:10200 |
TTS local (voix fr_FR-siwis-medium) |
Maison C (Lescuretie, Pi 4B)
| Service | Type | Réseau | Notes |
|---|---|---|---|
| Mosquitto MQTT | Docker compose | web |
broker local + bridge bidirectionnel vers Argenteuil (100.64.0.7:1883 via tailnet) |
| Zigbee2MQTT | Docker compose | web |
dongle Sonoff CC2674P10 (nouveau chip 2024), base topic zigbee2mqtt_lescuretie, frontend :8080 en LAN/tailnet only |
Pas de HA à Lescuretie — l'archi hub-and-spoke exige la connectivité tailnet pour piloter les devices distants depuis HA central (accepté comme tradeoff, cf. project_homeassistant.md en mémoire session Claude).
Hors périmètre (vivent dans le repo Infra) : OS bootstrap, nginx + certbot, WireGuard, ntfy, mariepro, chessia, runner Forgejo.
Le réseau Docker web est créé par le repo infra/, ce repo s'y attache (external: true).
Layout
homeassistant/
├── stacks/
│ ├── homeassistant/
│ │ ├── docker-compose.yml
│ │ └── config/
│ │ ├── configuration.yaml # importé du RPi au D-day
│ │ ├── packages/
│ │ │ └── voice_assistant.yaml # intents tempo / PC / Claude remote
│ │ ├── custom_sentences/fr/
│ │ │ └── voice_assistant.yaml # phrases FR → intents
│ │ ├── prompts/
│ │ │ └── claude_system.md # template prompt Anthropic Conversation
│ │ └── ... # automations.yaml, scripts.yaml, etc.
│ ├── mosquitto/
│ │ ├── docker-compose.yml
│ │ └── config/mosquitto.conf
│ ├── zigbee2mqtt/
│ │ ├── docker-compose.yml
│ │ └── data/ # importé du RPi au D-day (network_key, coordinator_backup, database, state)
│ ├── ha-bridge/
│ │ ├── docker-compose.yml
│ │ ├── Dockerfile
│ │ └── server.py
│ ├── whisper/
│ │ └── docker-compose.yml
│ └── piper/
│ └── docker-compose.yml
├── .forgejo/workflows/
│ └── deploy.yml
└── docs/
└── ARCHITECTURE.md
Workflow
Push main → Forgejo Actions (runner unique sur ThinkCentre) déclenche selon les paths :
deploy.yml(aucun path filter, se lance à chaque push) → converge Argenteuil :docker compose -f stacks/{homeassistant,mosquitto,zigbee2mqtt,ha-bridge,whisper,piper}/docker-compose.yml up -d.deploy-lescuretie.yml(path filterstacks/lescuretie/**) → converge Lescuretie via SSH sur tailnet : rsyncstacks/lescuretie/vers le Pi +docker compose up -ddistant.
Les repos infra/ et homeassistant/ se déploient indépendamment. Pré-requis : le réseau Docker web doit déjà exister (créé par infra/) sur les deux hosts (Argenteuil ET Lescuretie).
Migration depuis le RPi (D-day)
Voir infra/docs/migration.md — ce repo contribue les data à rsync :
/opt/stacks/hass/hass-config/→stacks/homeassistant/config/~/dockercompose/zigbee2mqtt/data/→stacks/zigbee2mqtt/data/(⚠️ contientnetwork_key,coordinator_backup.json— sans ça : re-pairing complet des devices Zigbee)~/dockercompose/mosquitto/→stacks/mosquitto/
Whisper et Piper téléchargent leurs modèles au premier démarrage : rien à rsync.
Pipeline vocale (HA Voice PE → Whisper → Claude → Piper)
Architecture : le HA Voice PE détecte le wake word on-device (XMOS), envoie l'audio à HA, qui :
- STT via Whisper local (
127.0.0.1:10300) - Tente le matching local (intents définis dans
packages/voice_assistant.yaml, phrases danscustom_sentences/fr/voice_assistant.yaml) - Si pas de match : délègue à Claude (intégration Anthropic Conversation, prompt système dans
prompts/claude_system.md) - TTS via Piper local (
127.0.0.1:10200)
Étapes UI à faire après le D-day
Le code du repo couvre les composants déployables. Le câblage final passe par l'UI (config_entries en .storage/, non versionnable).
-
configuration.yaml— ajouter (en haut du fichier) :homeassistant: packages: !include_dir_named packagesSans cette ligne,
packages/voice_assistant.yamln'est pas chargé. -
Ajouter le service Whisper : Paramètres → Appareils & services → Ajouter une intégration → Wyoming Protocol. Hôte
127.0.0.1, port10300. -
Ajouter le service Piper : idem, port
10200. -
Ajouter Anthropic Conversation : Paramètres → Appareils & services → Ajouter → Anthropic. Coller la clé API, choisir le modèle (Claude Sonnet 4.6 par défaut), coller le prompt système depuis
config/prompts/claude_system.md. -
Configurer la pipeline Assist : Paramètres → Voice assistants → créer une pipeline « Maison » avec :
- Conversation agent : Anthropic Conversation
- Option « Prefer handling commands locally » : ON (pour que les intents locaux passent en premier)
- STT : Whisper
- TTS : Piper (voix
fr_FR-siwis-medium)
-
Serveur HTTP / reverse proxy : Paramètres → Système → Réseau → section Serveur HTTP.
- Trust X-Forwarded-For : ON
- Trusted proxies :
172.16.0.0/12(bridges Docker, pour nginx),127.0.0.1/32,::1/128
Sans ça, nginx se présente avec une IP de bridge Docker, HA rejette ses en-têtes
X-Forwarded-Foret le reverse proxy renvoie 400 Bad Request, sans message explicite. C'était auparavant patché automatiquement pardeploy.ymldans le blochttp:deconfiguration.yaml; depuis HA 2026.8 cette conf YAML est dépréciée (ignorée en 2027.2.0) et vit dans.storage/, qui n'est pas versionnable — d'où cette étape manuelle. Si les champs n'apparaissent pas dans l'UI, recharger la page en Ctrl+F5. -
Associer le HA Voice PE à la pipeline : Paramètres → Appareils & services → HA Voice PE → choisir la pipeline « Maison ».
Secrets / Variables
Forgejo Actions, repo-level (cf. .forgejo/workflows/deploy.yml).
Variables (non-secrets, visibles non-redactées dans les logs CI) :
| Variable | Usage |
|---|---|
MONPC_MAC |
ha-bridge — adresse MAC du PC pour le WoL (08:bf:b8:82:e0:dc) |
MONPC_HOST |
ha-bridge — IP LAN du PC pour net rpc shutdown (192.168.112.41) |
Secrets :
| Secret | Usage |
|---|---|
MONPC_USER |
ha-bridge — compte Microsoft du PC pour net rpc shutdown |
MONPC_PASS |
ha-bridge — mdp du compte Microsoft |
HABRIDGE_CLAUDE_CREDENTIALS_JSON |
ha-bridge — OAuth Claude Code (abonnement Max) |
À ajouter quand on en aura besoin :
MQTT_PASSWORD— Mosquitto auth (TODO, actuellement anonyme)
La clé API Anthropic n'est pas un secret Forgejo : elle vit dans .storage/core.config_entries côté HA, saisie via l'UI à l'étape 4 ci-dessus.