Appareils Xiaomi dans Home Assistant sans cloud Xiaomi
Connecter ses capteurs et appareils Xiaomi à Home Assistant pour les piloter via l'agent IA.
⚠️ Archivé — Ce tuto documente OpenClaw, framework remplacé par Hermes Agent (Nous Research, MIT License) depuis mai 2026. Contenu conservé à titre de référence historique. Voir 20-hermes/architecture pour l’écosystème actuel.
Temps estimé : 60 min
Résultat final : Capteurs et interrupteurs Xiaomi appairés dans Home Assistant, contrôlables via commandes Telegram → OpenClaw → HA, sur un réseau IoT isolé sans cloud Xiaomi.
Prérequis :
- TUTO-04 complété — Home Assistant installé et accessible
- TUTO-05 complété — OpenClaw connecté à HA via Tailscale
- TUTO-06 complété — Agent Telegram opérationnel
- Matériel : gateway Xiaomi (voir étape 1) + au moins un capteur/interrupteur Zigbee Xiaomi
Objectif
Intégrer les équipements Xiaomi dans Home Assistant en mode 100% local :
- Pas de cloud Xiaomi (Mi Home désactivé)
- Zigbee local via ZHA ou Zigbee2MQTT selon le gateway
- Réseau IoT isolé (VLAN ou réseau WiFi dédié)
- Contrôle vocal via Telegram → OpenClaw → HA
Étape 1 : Identifier le matériel Xiaomi
La différence gateway Zigbee vs WiFi est critique pour l’intégration locale.
| Gateway | Protocole | Intégration HA | Mode local |
|---|---|---|---|
| Xiaomi Gateway 3 (ZNDMWG03LM) | Zigbee + WiFi | ZHA ou Z2M | ✅ possible (telnet requis) |
| Aqara Hub M2 | Zigbee | ZHA ou Z2M | ✅ natif |
| Xiaomi Gateway 2 (DGNWG02LM) | WiFi uniquement | Plugin dédié | ⚠️ limité |
| Capteurs Aqara/Mi (température, mouvement, interrupteur) | Zigbee | Via gateway | ✅ |
| Appareils WiFi (prises, ampoules Mi) | WiFi (Miio) | Integration Miio | ⚠️ cloud par défaut |
# Sur le VPS/RPi — identifier les appareils Zigbee déjà visibles si un coordinateur est connecté
ls /dev/serial/by-id/ | grep -i "zigbee\|cc2531\|conbee\|sonoff"
# Si vide : le coordinateur Zigbee n'est pas encore connecté
les appareils Xiaomi WiFi (protocole Miio) communiquent par défaut avec les serveurs cloud Xiaomi (CN). L’intégration locale Miio fonctionne mais requiert d’extraire le token de l’appareil — procédure à faire avant la première connexion au cloud. Une fois synchronisé avec le cloud, le token change et l’extraction est plus complexe.
Checklist étape 1 :
- Type de gateway identifié (Zigbee vs WiFi)
- Protocole confirmé (Zigbee → ZHA ou Z2M, WiFi → Miio)
- Liste des capteurs/interrupteurs à intégrer établie
Étape 2 : Intégration dans Home Assistant — ZHA ou Zigbee2MQTT
Option A — ZHA (recommandé, intégré dans HA)
ZHA est l’intégration Zigbee native de Home Assistant. Aucun service supplémentaire requis.
- HA → Paramètres → Appareils et services → + Ajouter une intégration
- Rechercher Zigbee Home Automation (ZHA)
- Sélectionner le port série du coordinateur Zigbee :
/dev/ttyUSB0 (clé USB Zigbee : ConBee II, Sonoff Zigbee 3.0 USB) /dev/ttyAMA0 (GPIO sur RPi) - Laisser la configuration automatique
# Sur le RPi/N54L — vérifier le port série du coordinateur
ls -la /dev/ttyUSB* /dev/ttyACM* 2>/dev/null
# Identifier le device correspondant au coordinateur Zigbee
ne jamais utiliser le gateway Xiaomi natif comme coordinateur ZHA sans avoir désactivé sa connexion cloud au préalable (étape 5). Un gateway connecté au cloud Xiaomi transmet l’état de tes appareils vers des serveurs CN.
Option B — Zigbee2MQTT (pour setups avancés avec MQTT broker)
set -euo pipefail
# Sur le VPS/RPi — installer Mosquitto MQTT broker
sudo apt-get install -y mosquitto mosquitto-clients
# Vérifier que Mosquitto tourne
sudo systemctl status mosquitto
# Créer la config Zigbee2MQTT minimale
mkdir -p /opt/zigbee2mqtt
cat > /opt/zigbee2mqtt/configuration.yaml << 'EOF'
homeassistant: true
permit_join: false
mqtt:
base_topic: zigbee2mqtt
server: "mqtt://localhost"
serial:
port: /dev/ttyUSB0
advanced:
network_key: GENERATE
log_level: warn
EOF
permit_join: false par défaut — ne l’activer que pendant l’appairage
(étape 3), puis le remettre à false immédiatement après.
Un réseau Zigbee en mode permit_join: true accepte n’importe quel appareil à portée.
Checklist étape 2 :
- Coordinateur Zigbee identifié sur
/dev/ttyUSB0ou équivalent - ZHA configuré dans HA (option A) OU Zigbee2MQTT installé (option B)
-
permit_join: falsevérifié en config initiale
Étape 3 : Capteurs et interrupteurs — appairage + test
Procédure d’appairage (ZHA)
- HA → Paramètres → Appareils et services → ZHA → Configurer
- Cliquer Ajouter des appareils (active
permit_joinpour 60s uniquement) - Sur le capteur/interrupteur Xiaomi : maintenir le bouton reset ~5s jusqu’au clignotement LED
- HA détecte l’appareil automatiquement
# Vérifier que l'appareil est bien appairé dans HA
curl -s -H "Authorization: Bearer ${HA_TOKEN}" \
http://homeassistant.local:8123/api/states \
| jq '[.[] | select(.entity_id | startswith("sensor.")) | {id: .entity_id, state: .state}]' \
| head -20
après appairage, désactiver permit_join dans ZHA immédiatement.
HA affiche un avertissement si permit_join reste actif plus de 60s — ne pas l’ignorer.
Test d’un capteur de température
# Remplacer sensor.xiaomi_temperature par l'entity_id réel
curl -s -H "Authorization: Bearer ${HA_TOKEN}" \
http://homeassistant.local:8123/api/states/sensor.xiaomi_temperature \
| jq '{state: .state, unit: .attributes.unit_of_measurement, last_updated: .last_updated}'
Test d’un interrupteur
# Allumer une lumière via l'API HA (remplacer light.salon par l'entity_id réel)
curl -s -X POST \
-H "Authorization: Bearer ${HA_TOKEN}" \
-H "Content-Type: application/json" \
http://homeassistant.local:8123/api/services/light/turn_on \
-d '{"entity_id": "light.salon"}' \
| jq '.[] | {entity_id, state}'
le token HA_TOKEN dans ces commandes est un Long-Lived Access Token HA.
Ne jamais l’écrire en dur — toujours via ${HA_TOKEN} depuis ~/.openclaw.env.
Rotation : HA → Profil → Tokens d’accès longue durée → Supprimer + Recréer.
Checklist étape 3 :
- Appairage ZHA réussi pour chaque appareil
-
permit_joindésactivé après appairage - État capteur température visible via API HA
- Interrupteur lumière :
turn_on/turn_offfonctionnels via API
Étape 4 : Automatisations IA via OpenClaw → HA
Configurer ha-agent pour les devices Xiaomi
Dans openclaw.json, ha-agent doit déclarer explicitement les entities autorisées :
{
"agents": {
"ha-agent": {
"homeAssistant": {
"url": "http://homeassistant.local:8123",
"token": "${HA_TOKEN}",
"allowedEntities": [
"light.salon",
"light.chambre",
"switch.prise_bureau",
"sensor.temperature_salon",
"sensor.mouvement_entree",
"binary_sensor.porte_garage"
],
"forbiddenDomains": ["automation", "script", "shell_command"]
}
}
}
}
allowedEntities est une liste blanche stricte.
Si une entity n’est pas dans cette liste, ha-agent ne peut pas y accéder.
forbiddenDomains bloque l’exécution de scripts/automations HA arbitraires depuis l’agent —
cela évite qu’une injection de prompt déclenche shell_command dans HA.
Flux Telegram → OpenClaw → HA
Telegram : "Allume la lumière du salon"
↓
telegram-agent : interprète + demande confirmation
↓
Confirmation "oui" reçue
↓
ha-agent : ha.services.call light.turn_on light.salon
↓
HA : exécute l'action
↓
Telegram : "✅ Lumière salon allumée"
# Tester le flux complet depuis Telegram
# Envoyer : "quelle est la température du salon ?"
# Attendu : l'agent interroge HA et retourne la valeur en temps réel
# (pas de validation humaine requise pour une lecture)
# Tester une action avec validation
# Envoyer : "éteins toutes les lumières"
# Attendu : "Action prévue : light.turn_off all. Confirmer ? (oui/non)"
# Répondre "oui" → toutes les lumières s'éteignent
Checklist étape 4 :
-
allowedEntitiesconfiguré dansha-agent(liste blanche) -
forbiddenDomainsinclutautomation,script,shell_command - Lecture état sensor via Telegram : fonctionnel (sans validation)
- Action lumière via Telegram : fonctionnel (avec validation humaine)
Étape 5 : Sécurité — isoler le réseau Xiaomi
Principe
Les appareils IoT Xiaomi ne doivent pas pouvoir communiquer avec ton VPS, ton réseau perso, ni l’internet (cloud Xiaomi désactivé).
Réseau principal (192.168.1.0/24)
├── VPS Tailscale
├── RPi Home Assistant
└── [Accès vers IoT VLAN autorisé uniquement pour HA]
Réseau IoT VLAN (192.168.10.0/24)
├── Gateway Zigbee (local seulement)
├── Capteurs Xiaomi WiFi
└── [Pas d'accès internet, pas d'accès réseau principal]
Configuration VLAN sur le routeur (exemple OpenWrt)
set -euo pipefail
# Sur OpenWrt — créer le VLAN IoT
# (adapter selon ton routeur — Freebox, Livebox, etc.)
uci set network.iot=interface
uci set network.iot.proto='static'
uci set network.iot.ipaddr='192.168.10.1'
uci set network.iot.netmask='255.255.255.0'
uci commit network
service network restart
# Règle firewall : IoT → pas d'internet, pas d'accès réseau principal
# Seule exception : HA peut requêter les appareils IoT (sens HA → IoT uniquement)
uci add firewall rule
uci set firewall.@rule[-1].src='iot'
uci set firewall.@rule[-1].dest='wan'
uci set firewall.@rule[-1].target='REJECT'
uci set firewall.@rule[-1].name='block_iot_wan'
uci commit firewall
service firewall restart
sans isolation réseau, un appareil Xiaomi compromis peut scanner ton réseau local, atteindre ton VPS ou exfiltrer des données vers le cloud CN. Le VLAN IoT est la contre-mesure principale — non négociable en production.
Désactiver le cloud Xiaomi
# Pour les appareils WiFi Xiaomi (Miio) — désactiver la connexion cloud
# Bloquer les domaines Xiaomi au niveau DNS/firewall
# Domaines à bloquer : *.iot.mi.com, api.io.mi.com
# Sur Pi-hole ou AdGuard Home (si installé) :
echo "0.0.0.0 iot.mi.com" >> /etc/pihole/custom.list
echo "0.0.0.0 api.io.mi.com" >> /etc/pihole/custom.list
pihole restartdns
vérifier que les appareils Xiaomi ne communiquent plus avec les serveurs CN
après le blocage DNS :
tcpdump -i br-iot 'host 110.43.0.0/8 or host 120.92.0.0/14' -c 10
Si des paquets apparaissent encore, le blocage DNS n’est pas suffisant — ajouter une règle
firewall de sortie explicite (REJECT dst_ip range CN).
Validation isolation réseau
# Depuis un appareil sur le VLAN IoT — vérifier qu'il ne peut pas atteindre internet
# (à effectuer depuis le routeur ou un appareil de test sur le VLAN)
ping -c 3 8.8.8.8 -I br-iot
# Attendu : 100% packet loss
# Vérifier que HA peut toujours atteindre les appareils IoT
curl -s -H "Authorization: Bearer ${HA_TOKEN}" \
http://homeassistant.local:8123/api/states/sensor.temperature_salon \
| jq '.state'
# Attendu : valeur de température actuelle (pas d'erreur d'accès)
Checklist étape 5 :
- VLAN IoT créé et séparé du réseau principal
- Règle firewall : IoT → WAN = REJECT
- Domaines Xiaomi cloud bloqués (DNS + firewall)
- Test isolation : ping 8.8.8.8 depuis IoT VLAN = 0% réponse
- Test HA → IoT : lecture capteur toujours fonctionnelle
-
tcpdump: aucun paquet vers IP CN
Checklist finale TUTO-07
Matériel et intégration
- Type de gateway identifié et protocole confirmé
- ZHA ou Zigbee2MQTT opérationnel dans HA
- Tous les capteurs/interrupteurs appairés et visibles dans HA
Sécurité agent
-
allowedEntitiesdansha-agent= liste blanche stricte (devices Xiaomi uniquement) -
forbiddenDomains=automation,script,shell_command -
exec=nonepourha-agent
Réseau
- VLAN IoT isolé du réseau principal
- Cloud Xiaomi bloqué (DNS + firewall)
- HA → IoT : accès maintenu
- IoT → WAN : bloqué
Tests validés
- Lecture capteur via Telegram : fonctionnel
- Action domotique via Telegram + validation humaine : fonctionnel
- Isolation réseau vérifiée par tcpdump
Dépannage
Appareil Zigbee non détecté lors de l’appairage
# Vérifier que le coordinateur est bien reconnu
ls -la /dev/ttyUSB* /dev/ttyACM*
# Vérifier les logs ZHA dans HA : Paramètres → Journal → filtrer "zha"
Si l’appareil ne se met pas en mode appairage : maintenir le bouton reset 10s (reset complet), puis réessayer.
permit_join reste actif après appairage
# Désactiver manuellement via l'API HA
curl -s -X POST \
-H "Authorization: Bearer ${HA_TOKEN}" \
-H "Content-Type: application/json" \
http://homeassistant.local:8123/api/services/zha/permit \
-d '{"duration": 0}'
Capteur WiFi Xiaomi ne répond pas en mode local
# Extraire le token Miio (à faire avant connexion cloud)
pip3 install python-miio
miiocli device --ip 192.168.10.X --token XXXXXXXX info
VLAN IoT : HA ne peut plus accéder aux appareils
Vérifier la règle firewall inter-VLAN : le sens HA (réseau principal) → IoT VLAN doit être autorisé. Seul le sens IoT → réseau principal est bloqué.
Références
- ZHA (Zigbee Home Automation) : https://www.home-assistant.io/integrations/zha/
- Zigbee2MQTT : https://www.zigbee2mqtt.io/
- Python-Miio (token extraction) : https://python-miio.readthedocs.io/
- OpenWrt VLAN config : https://openwrt.org/docs/guide-user/network/vlan/switch_configuration
- TUTO-05 — OpenClaw ↔ Home Assistant : TUTO-05