Xiaomi / Aqara & Zigbee...

Partager
Xiaomi / Aqara & Zigbee...
Photo by Jakub Żerdzicki / Unsplash

J'ai, j'avais une passerelle Zigbee deconz/Phoscon qui tournait sur un Raspberry 2 depuis l'époque Jeedom avec une clé Combee. Peut être pas 10 ans, mais pas loin.

Sur cette passerelle j'avais environ 50 objets de l'époque, des capteurs d'ouverture, des sondes de température et des détecteurs de présence (Aqara et Xiaomi) ainsi que prises et boutons Ikea. La chose tournait comme une horloge suisse, made in Germany ! Je l'avais naturellement raccroché à Home Assistant.

Et puis j'ai ajouté une autre clé pour ZHA, puis une autre pour Z2M et mes réseaux on grossit, peut (surement) être trop. Il me restait toutefois cette passerelle deconz avec quelques objets Aqara / Xiaomi. Dans un soucis de rationalisation, mais aussi afin de limiter les canaux qui se chevauchaient, j'ai voulu me débarrasser de deconz. J'ai donc commencé à migrer ses objets vers ZHA et / ou Z2M. Et c'est là que l'ensemble devient instable et que certains objets se déconnectent. Le problème est connu et on sait que certains objets Xiaomi / Aqara (et d'autres) ne respectent pas tout à fait la norme Zigbee 3.0

C'est pernicieux, car le problème ne se pose pas pour tous les objets (même identiques), en fait tout dépend des routeurs qu'ils croisent.

Il y a un contournement possible qui consiste à ramener tout ça dans l'écosystème du constructeur. En fait j'ai testé des passerelle Xiaomi et également le hub Aqara M3 que j'avais acheté pour Matter, au début. Aujourd'hui Matter est très fiable directement dans Home Assistant, par contre M3 reconnait tous les objets Xiaomi / Aqara et ils remontent parfaitement et localement dans HA, en local, via Matter (objets enfants du hub M3, ou même dans HomeKit). De plus ce hub étant POE c'est très stable et pas tributaire du WI-FI. Ils remontent localement, mais pour intégrer les objets il faut l'application Aqara, au moins une fois. Ca fonctionne également très bien avec les passerelles supportées par l'intégration Xiaomi Gateway 3 en mode Mi Home avec remontée locale (ces passerelles peuvent également servir de clés distantes pour ZHA ou Z2M mais ça reste du bricolage).

Outre la fiabilité, l'avantage de cette solution, qui complexifie tout de même un peu l'installation, est que ça laisse respirer mes réseaux ZHA et Z2M (plus de place en migrant à terme une trentaine de devices, et bien sur moins de retry).

Attention toutefois, quand un device est appairé sur le M3 il remonte dans Matter via Matter Server. Sur l'intégration Matter il faut les renommer au fur et à mesure sans quoi on ne saura pas qui est qui. Et si d'aventure vous avez un autre Home Assistant associé au hub M3 ils remonteront également et il faudra également les renommer. La seule façon de les repérer reste leur numéro de série.

Incident Matter

Problème solutionné ? Pas si sur ! J'ai un capteur de porte Zigbee (Aqara MCCGQ11LM) qui passe parfois unavailable 1 heure. Il est donc connecté au hub M3 Aqara, il remonte dans Home Assistant via Matter. Ce même capteur remonte également via HomeKit (le M3 étant également compatible HomeKit. Et sous HomeKit il ne passe en unavailable.

Remontée via Matter avec une indisponibilité
Remontée via HomeKit sans indisponibilité

On peut donc penser être face à un problème de signalisation entre le Hub M3 et la couche Matter de Home Assistant, ce que confirme le log interne du M3 qui ne signale pas cette indisponibilité.

Sans vous relater toutes les hypothèses proposées par les IA, je pense simplement que la couche HomeKit est plus éprouvée que Matter qui est un protocole encore jeune. Même si j'aime bien les Mac, je ne suis pas fan de l'écosystème Apple, de fait j'ai parfois tendance à minimiser les capacités et la fiabilité de HomeKit. A tort.

Face à ce genre d'incidents je me suis intéressé à cette intégration qui permet de surveiller la disponibilité des entités sensibles (installée sur un HA des test mais un peu lourd). On peut également utiliser des templates comme expliqué ici ou . Ou utiliser Alert2 (évolution de l'intégration core Alert) pour être prévenu :

alert2:
  skip_internal_errors: true
  defaults:
    reminder_frequency_mins: [ 1, 1, 5, 10, 20, 60, 120 ]
    notifier: 
      - Free_Mobile
      - notify.telegram_bot_canaletto
    annotate_messages: true

  alerts:
    - domain: test_domain
      name: anomalies_ouverture
      friendly_name: "Ouvertures"
      delay_on_secs: 300
      # 1. La condition de surveillance
      condition: >-
        {{ states.binary_sensor 
           | selectattr('entity_id', 'in', [
              'binary_sensor.porte_garage', 'binary_sensor.porte_entree', 
              'binary_sensor.fenetre_cuisine', 'binary_sensor.fenetre_sejour', 
              'binary_sensor.fenetre_lionel', 'binary_sensor.fenetre_marie', 
              'binary_sensor.fenetre_antoine', 'binary_sensor.lk_zb_door_01'
             ]) 
           | selectattr('state', 'in', ['unavailable', 'unknown']) 
           | list | count > 0 }}
      # 2. Le message d'alerte initial complet
      message: >-
        {% set noms_naturels = {
          "binary_sensor.porte_garage": "Porte du garage",
          "binary_sensor.porte_entree": "Porte d'entrée (01)",
          "binary_sensor.fenetre_cuisine": "Fenêtre de la cuisine",
          "binary_sensor.fenetre_sejour": "Fenêtre du séjour (02)",
          "binary_sensor.fenetre_lionel": "Fenêtre de Lionel (03)",
          "binary_sensor.fenetre_marie": "Fenêtre de Marie (05)",
          "binary_sensor.fenetre_antoine": "Fenêtre d'Antoine (04)",
          "binary_sensor.lk_zb_door_01": "Baie du séjour"
        } %}
        {% set trad_etats = {
          'unavailable': 'Indisponible (Hors-ligne)',
          'unknown': 'État inconnu (Non initialisé)'
        } %}
        {% set pannes = states.binary_sensor | selectattr('entity_id', 'in', noms_naturels.keys()) | selectattr('state', 'in', ['unavailable', 'unknown']) | list %}
        ⚠️ Alerte : Anomalie détectée :
        {% for capteur in pannes %}
          - {{ noms_naturels[capteur.entity_id] }} : {{ trad_etats[capteur.state] }}
        {% endfor %}
      # 3. Le message de rappel simple, validé et efficace
      reminder_message: "⏰ Rappel : Anomalie persistante."
      # 4. Le message de fin simple et efficace
      done_message: "✅ OK : Retour à la normale."

Aqara natif

Face à Matter et HomeKit il existe également en local le protocole natif Aqara, LanLink. Pas ou peu documenté, pourtant un développeur s'y est risqué, ça semble intéressant pour remonter des devices inaccessibles autrement car verrouillés sur une passerelle Aqara (certaines caméras par exemple, climatiseurs distribués en Chine). Ca remonte près de 400 modèles Aqara, mais l'intégration est encore trop jeune à mon gout, en test sur mon HA de test.

Contournement

Une possibilité pour éviter les pannes consiste à créer un groupe, mais pas un simple groupe. Quand la pile est totalement vide, le capteur s'éteint sans envoyer de dernier message. Il finit par passer unavailable après l'expiration du délai de présence (timeout). Idem pour la liaison (notre problème),

Si le capteur passe unavailable, un groupe de binary_sensor standard va mal réagir selon sa configuration :

Comportement d'un groupe standard

  • all: false - mode OU : Si le capteur défaillant est unavailable et que l'autre est off, le groupe reste off (fermé). Mais si le capteur reste bloqué sur unavailable pendant que la porte s'ouvre, l'autre capteur passe à on et le groupe passe à on. La détection d'ouverture fonctionne encore grâce au capteur survivant. En revanche, si la panne survient alors que le capteur s'est éteint en position on, le groupe restera bloqué sur on indéfiniment.
  • all: true - mode ET : Dès qu'un capteur passe unavailable, le groupe devient inutilisable ou passe off.

La solution (ou l'exercice de style) : Filtrer les états via un template:. Ainsi les 4 capteurs sur la même porte se secourent mutuellement. Dans la pratique il n'y en a que 2, Aqara et Visonic, mais les Aqara ont deux sources, HomeKit et Matter. La tolérance aux pannes consiste à ignorer les capteurs hors ligne et ne prendre en compte que ceux qui répondent (on ou off). J'ai poussé le vice jusqu'à associer mes anciens capteurs Visonic que je remonte en RF, pour le sport...

template:
  - trigger:                                                                  # Groupes de contacts
      - trigger: state
        entity_id:
          - binary_sensor.hk_aqara_contact_1              # HomeKit
          - binary_sensor.aqara_contact_1                 # Matter
          - binary_sensor.visonic_z01_porte_entree_zone   # Visonic
          - binary_sensor.visonic_porte_entree            # RF
        to:
          - "on"
          - "off"
      - trigger: event
        event_type: 
          - homeassistant_started
          - event_template_reloaded               
    binary_sensor:
      - name: "Contacts : Porte Entrée"
        unique_id: bf5018c7-21a9-4980-a01a-porte-entree
        device_class: door
        state: >
          {% if trigger.platform == 'state' %}
            {{ trigger.to_state.state }}
          {% else %}
            {% set sensors = [
              'binary_sensor.hk_aqara_contact_1',
              'binary_sensor.aqara_contact_1',
              'binary_sensor.visonic_z01_porte_entree_zone',
              'binary_sensor.visonic_porte_entree'
            ] %}
            {% set valids = sensors | map('states') | select('in', ['on', 'off']) | list %}
            {{ 'on' in valids if valids | length > 0 else 'off' }}
          {% endif %}
        availability: >
          {{ states('binary_sensor.hk_aqara_contact_1') in ['on','off'] or
             states('binary_sensor.aqara_contact_1') in ['on','off'] or
             states('binary_sensor.visonic_z01_porte_entree_zone') in ['on','off'] or
             states('binary_sensor.visonic_porte_entree') in ['on','off'] }}
  • Ouverture instantanée : Dès qu'une des 4 entités passe à on, le template se déclenche et passe le capteur global à on.
  • Fermeture instantanée : Dès qu'une des 4 capteurs passe à off, le template se déclenche aussitôt et passe le capteur global à off.
  • Pannes ignorées : Si un capteur passe unavailable ou unknown, la règle to: ["on", "off"] fait qu'il est ignoré. Le capteur global conserve son dernier état valide jusqu'à ce qu'un autre capteur vivant envoie un on ou un off.
  • Amorçage : En combinant les events homeassistant_started (qui attend que tous tes réseaux Zigbee/Matter/RF Visonic soient prêts) et event_template_reloaded, on couvre 100 % des cas. Si on ne fait pas ça notre binary_sensor: se trouverait dans un état unknown en attente d'un on ou off lors du démarrage de HA ou du rechargement des templates.

Ikea

Ikea n'a rien à voir avec avec Xiaomi / Aqara (quoique...). Reste la question des vieilles télécommandes Ikea on/off (E1743) qui étaient très bien sur deconz. Je les avait d'abord migrées en ZHA, puis en Z2M ou la mise à jour du firmware a été possible, mais malgré ça elles dévorent les piles bien plus rapidement que quand elles étaient accrochées à deconz. Et je ne parle pas des des vieilles prises Ikea (les ovales moches) ou 2/4 n'ont jamais voulu se réappairer, de ce que j'ai pu lire une mémoire non volatile saturée...

Wi-Fi

Vous allez me dire, il vient faire quoi le Wi-Fi ici ? En fait je ne suis pas sur, mais j'avais un AP Unifi U6 LR très instable avec mes objets IoT Wi-Fi. Depuis que le l'ai remplacé par un U6 Pro ça stabilisé mes objets en Wi-Fi, et j'ai l'impression que mes réseaux Zigbee revivent également. J'en déduit que le U6 LR bavait dans tous les sens, ce que confirment de de nombreux posts (voir mon article ici).

Bref...

Une fois de plus on constate que la maintenance d'un Home Assistant ça peut devenir très chronophage, un job à temps complet !. Un réseau Zigbee peut être très stable pendant des mois et puis on supprime un module, la panne d'un objet routeur par exemple, et ça se déstabilise. On ne peut pas forcer un routage particulier, tout au plus ajouter des routeurs...

Reste une solution plus radicale, identifier et remplacer les objets capricieux (j'en ai une caisse). Et contrairement à ce que l'on pourrait penser, ce ne sont pas toujours les plus couteux qui fonctionnent le mieux, parfois les chinoiseries NoName de chez Ali sont plus fiables...

Sources

Aqara for Local-First Smart Homes - Private Home Lab
Browse Aqara guides from Private Home Lab, focused on practical local-first smart home setups, Home Assistant notes, and privacy-aware device behavior.

Une très bonne source sur les produits Aqara