Home Assistant, Zigbee & Legrand

On m'a demandé récemment d'intégrer des appareils Legrand dans Home Assistant, je l'avais déjà fait pour certains et j'en avais parlé dans cet article. Aujourd'hui il s'agit d'intégrer des commandes sans fil vue come des télécommandes dans HA. Vous allez me demander quel est l'intérêt quand un simple bouton Ikea (E1743) à moins de 10 fait le job pour mes volets roulants. C'est purement esthétique, quand on a un logement équipé en Legrand Céliane ou Mosaic, on veut parfois que les commandes des volets soient dans la même collection.

Soit, Legrand propose des commandes en Zigbee, il n'y a plus qu'à !

Dans la pratique on va voir que ce n'est pas si simple, en tous cas bien moins simple qu'avec mon bouton Ikea à 10 € ! Je précise le prix car les commandes Legrand sont plutôt à 80 €. Mais quand on aime on ne compte pas.

Il existe plusieurs type d'équipements Zigbee chez Legrand

  • Ceux qui sont filaires, j'en ai parlé ici (micro modules, contacteur DIN, prise connectée, etc...)
  • La gamme des commandes sans fil à pile
  • La gamme des commandes sans fil sans piles (gamme Self-e). J'y reviendrait certainement, mais d'après mes infos cette gamme supporte tous les canaux et serait mieux intégrée ZHA/Z2M.

Je me suis donc penché sur la gamme avec pile.

Première observation, ces devices sont généralement livrés avec un firmware de niveau 42 qui ne permet que l'utilisation du canal Zigbee 11. Don impossible à faire fonctionner sur mon ZHA qui est en 15. Je l'ai donc appairé sur mon Z2M en 11 et ça fonctionne. Et là je me suis dit que j'allais pouvoir mettre à jour ce firmware en OTA. Mais non, ça ne fonctionne pas et on se retrouve dans la problématique des équipements franco Français qui n'intéressent pas grand monde au niveau international (on pense par exemple à tout ce qui est lié à l'intégration Overkiz...).

Après moultes lectures des forums de diverses plateformes domotique, la conclusion est que la mise à jour du firmware ne peut se faire qu'au travers d'une passerelle officielle Legrand ! J’ai donc acheté le kit qui comprend :

  • La prise Control qui sert de passerelle
  • Un inter sans fil
  • Une ampoule

Il faut bien sur installer l’appli Legrand et ensuite tenter d’associer la prise au WIFI. Facile ? Non, ça m’a pris de plombes car vu que leur process est trop long, le mobile qui se connecte à la prise pour la configurer repasse sur le WIFI normal ou il retrouve Internet, et perd la config en cours. Solution faire ça avec un vieux mobile… Bref, un premier amateurisme car on fait facilement ce genre d'association avec la majorité des objets mobile en WIFI !

Bon, la logique de l’appli est orientée électricien très grand public, avec une logique d'électricien qui n’est pas nécessairement la notre. C'est un choix, il faut s'y faire, mais n'oublions pas que nous sommes ici uniquement pour faire un mise à jour...

Ensuite il faut ajouter les inter. Sauf que la il faut comprendre qu’on ne peut pas ajouter un inter seul. Dans la logique Legrand si tu ajoute un inter, en fin de dialogue ça te demande ce que tu veux commander, sans quoi ça bloque et il n’y a plus qu’à forcer le redémarrage de l’appli et recommencer... Je n’avais pas de prise Legrand sous la main, mais au bout d’un moment j’ai fini par penser à appairer l’ampoule. Et la je vois enfin l’inter livré et mon inter de volet roulant qui ne peut rien commander, c’est le même mais avec un firmware différent.

Mais souvenons nous que nous somme là à jouer avec ce bazar dans le seul but de mettre à jour le firmware de ces putains d’inter qui au delà de couter un rein ne fonctionnent (mal) que sur le canal 11. Hélas il n’y arien pour faire cette mise à jour, mon inter de VR apparait en 42 dans l’appli et en 002a dans z2m, donc identique l’un étant en hexa. D’après ce que j’ai pu lire, la mise à jour se fera, un jour, mais on ne peut pas la forcer. Il faut juste laisser branché, en espérant que mon inter qui n’est pas connecté à un appareil se mette à jour tout seul…

Donc je laisse branché, la suite pour bientôt…

EDIT un peu plus tard :

  • L’inter (0 677 73N) est passé de 50 à 70
  • L’inter VR (0 777 48LA) n’a pas bougé…
  • Je testerais si on peut l’appairer hors du canal 11 mais je commence à douter…

EDIT le lendemain :

  • L’inter s’appaire bien sur un autre canal après sa mise à jour. Testé en ZHA sur 15, mais ZHA ne le supporte pas et rien ne bouge, aucun event.
  • L’inter VR ne s’est toujours pas mis à jour. Un peu comme s’il lui fallait une charge...

EDIT le lendemain soir :

  • L’inter VR est bien passé de 42 à 70, mon ZHA qui est sur le canal 15 le voit mais n’en fait rien. Quand à Z2M il n’en veut plus ! Pire ça me fait planter Z2M…

EDIT le sur lendemain midi :

  • L’inter VR qui ne veut toujours pas de ZHA ou Z2M s’est appairé correctement sur deconz en canal 15, il retourne dans les event les valeurs suivantes :

Montée : 1002 / Montée puis relâché : 1002/3002
Descente : 2002 / Descente puis relâché : 2002/3003
Stop (Les deux en même temps) : 3003

Ce comportement est identique à ce qu’il était sous Z2M et contrairement à d'autres télécommandes (le on/off Ikea (E1743 par exemple) il manque le fait qu’un second appui bref provoque un stop. Il faut donc bien appuyer au milieu pour faire un « stop » et ce n’est pas toujours pris en compte (problème physique).

Qu’il ne soit pas supporté sur ZHA est un fait, il faudrait développer un quirk et ça me dépasse. Je ne sais pas pourquoi il ne veut plus s’appairer sur Z2M, mais c’est peut être lié à mon installation, ma clé, que sais-je...

Il y a des chances que l’aventure Legrand va prendre fin et je que je retourne fissa ce Kit à Amazon !

Homekit

A signaler toutefois que cette passerelle est Homekit. Ce qui veut dire que ses équipements remontent dans Home Assistant. Mais ne rêvez pas trop, si l’ampoule remonte bien, et certainement tous les actionneurs connectés (prises, modules DIN), pas les inter En fait si, il faut juste attendre un peu. Néanmoins tout ne semble pas remonter, uniquement une action par bouton ! Mais j’avais déjà remarqué ça avec les télécommandes Tuya qui ne remontent pas via une passerelle Tuya Homekit. Il y a une forme de logique, Homekit sert à commander un équipement, comme une télécommande, hors on ne commande pas une télécommande…

Par contre ça veut dire que les équipements reconnus par Legrand vont remonter dans Homekit, ce qui peut être une solution de contrôle facile pour des produit pas reconnus par HA (Profalux, Bubendorf, Aldes, etc…).

La suite

Je vous propose de poursuivre ici et que chacun y apporte ses retours.

Sources

  • https://developer.legrand.com/production-firmware-download/

Home Assistant & Mi Boxer

J'avais acheté cette télécommande Mi Boxer il y a quelques mois afin de gérer les éclairages de mon séjour, en me disant que les curseurs seraient plus pratiques que mon Opple avec ses 6 boutons actuelle. Hélas elle n'était reconnue nulle part et avait terminé sa course dans le tiroir aux oubliettes du Zigbee...

C'était sans compter sur la ténacité de quelques amateurs de reverse engineering sur lesquels je suis tombé il y a quelques semaines et qui on fait un travail formidable qui a aboutit à une extension pour Zigbee2MQTT, ce qui rend cette télécommande enfin utilisable, tout au moins partiellement pour l'instant. Mais l'essentiel est là !

Ce qui fonctionne :

  • 7 boutons avec ON et OFF (deux actions et non un toggle). Celui du bas à droite n'est pas actif et je vous déconseille de l'utiliser...
  • 1 bouton avec ON et OFF (en haut)
  • 1 bouton W (si on veut bricoler...)
  • La barre de réglage de la luminosité
  • La remontée de l'état de la batterie

Ce qui ne fonctionne pas (pour l'instant) :

  • La barre de réglage des couleurs
  • La barre de réglage de la température du blanc
  • Les touches RGB
  • Les touches de temporisation (en bas à droite)

Une fois la télécommande reconnue sous Z2M on peut commencer à créer des actions. On remarque tout de suite que l'affaire va manquer de sensor: et que certains ne fonctionnent pas. Pas de panique, il y a une solution comme je vais vous le démonter avec l'automation: qui suit. 

J'ai fait un mélange de choose: / conditions: / trigger.id . C'est un peu long, mais je la colle en entier ce qui vous évitera une fastidieuse saisie. Il faudra tout de même y coller vous id: et entity: ! Ah j'allais oublier, il faut aussi ajouter un petit input_select: ... Voir plus bas EDIT du 11/01/2024 !

J'ai tenté de faire ça avec ControllerX que j'adore et qui me sert pour toutes mes télécommandes, mais pour l'instant c'est un échec !

alias: GUI - Mi Boxer
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.mi_boxeur_brightness
    id: bright
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_1_on
    discovery_id: 0x003c84fffec29c71_zone_1_button_on
    id: 1on
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_1_off
    discovery_id: 0x003c84fffec29c71_zone_1_button_off
    id: 1off
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_2_on
    discovery_id: 0x003c84fffec29c71_zone_2_button_on
    id: 2on
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_2_off
    discovery_id: 0x003c84fffec29c71_zone_2_button_off
    id: 2off
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_3_on
    discovery_id: 0x003c84fffec29c71_zone_3_button_on
    id: 3on
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_3_off
    discovery_id: 0x003c84fffec29c71_zone_3_button_off
    id: 3off
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_4_on
    discovery_id: 0x003c84fffec29c71_zone_4_button_on
    id: 4on
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_4_off
    discovery_id: 0x003c84fffec29c71_zone_4_button_off
    id: 4off
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_5_on
    discovery_id: 0x003c84fffec29c71_zone_5_button_on
    id: 5on
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_5_off
    discovery_id: 0x003c84fffec29c71_zone_5_button_off
    id: 5off
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_6_on
    discovery_id: 0x003c84fffec29c71_zone_6_button_on
    id: 6on
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_6_off
    discovery_id: 0x003c84fffec29c71_zone_6_button_off
    id: 6off
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_7_on
    discovery_id: 0x003c84fffec29c71_zone_7_button_on
    id: 7on
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_7_off
    discovery_id: 0x003c84fffec29c71_zone_7_button_off
    id: 7off
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_8_on
    discovery_id: 0x003c84fffec29c71_zone_8_button_on
    id: 8on
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: button_short_press
    subtype: button_group_8_off
    discovery_id: 0x003c84fffec29c71_zone_8_button_off
    id: 8off
    
condition: []
action:
  - choose:
      - conditions: "{{ trigger.id in ['1on'] }}"
        sequence:
          - service: light.turn_on
            data: {}
            target:
              entity_id: light.shellydimmer_f3d426
          - service: input_select.select_option
            data:
              option: "1"
            target:
              entity_id: input_select.mi_boxer_select
      - conditions: "{{ trigger.id in ['1off'] }}"
        sequence:
          - service: light.turn_off
            data: {}
            target:
              entity_id: light.shellydimmer_f3d426

      - conditions: "{{ trigger.id in ['2on'] }}"
        sequence:
          - service: light.turn_on
            data: {}
            target:
              entity_id: light.shellydimmer_d3e57c
          - service: input_select.select_option
            data:
              option: "2"
            target:
              entity_id: input_select.mi_boxer_select
      - conditions: "{{ trigger.id in ['2off'] }}"
        sequence:
          - service: light.turn_off
            data: {}
            target:
              entity_id: light.shellydimmer_d3e57c

      - conditions: "{{ trigger.id in ['3on'] }}"
        sequence:
          - service: light.turn_on
            data: {}
            target:
              entity_id: light.ikea_e27_tv
          - service: input_select.select_option
            data:
              option: "3"
            target:
              entity_id: input_select.mi_boxer_select
      - conditions: "{{ trigger.id in ['3off'] }}"
        sequence:
          - service: light.turn_off
            data: {}
            target:
              entity_id: light.ikea_e27_tv

      - conditions: "{{ trigger.id in ['4on'] }}"
        sequence:
          - service: light.turn_on
            data: {}
            target:
              entity_id: light.lidl_led_stand
          - service: input_select.select_option
            data:
              option: "4"
            target:
              entity_id: input_select.mi_boxer_select
      - conditions: "{{ trigger.id in ['4off'] }}"
        sequence:
          - service: light.turn_off
            data: {}
            target:
              entity_id: light.lidl_led_stand

      - conditions: "{{ trigger.id in ['5on'] }}"
        sequence:
          - service: light.turn_on
            data: {}
            target:
              entity_id: light.dimmable_sm309
          - service: input_select.select_option
            data:
              option: "5"
            target:
              entity_id: input_select.mi_boxer_select
      - conditions: "{{ trigger.id in ['5off'] }}"
        sequence:
          - service: light.turn_off
            data: {}
            target:
              entity_id: light.dimmable_sm309

      - conditions: "{{ trigger.id in ['6on'] }}"
        sequence:
          - service: light.turn_on
            data: {}
            target:
              entity_id: light.shelly_bulb_1
          - service: input_select.select_option
            data:
              option: "6"
            target:
              entity_id: input_select.mi_boxer_select
      - conditions: "{{ trigger.id in ['6off'] }}"
        sequence:
          - service: light.turn_off
            data: {}
            target:
              entity_id: light.shelly_bulb_1

      - conditions: "{{ trigger.id in ['7on'] }}"
        sequence:
          - service: light.turn_on
            data: {}
            target:
              entity_id: light.led_strip_1
          - service: input_select.select_option
            data:
              option: "7"
            target:
              entity_id: input_select.mi_boxer_select
      - conditions: "{{ trigger.id in ['7off'] }}"
        sequence:
          - service: light.turn_off
            data: {}
            target:
              entity_id: light.led_strip_1

      - conditions: "{{ trigger.id in ['8on'] }}"
        sequence:
          - service: light.turn_on
            data: {}
            target:
              entity_id: 
                - light.shellydimmer_f3d426
                - light.shellydimmer_d3e57c
                - light.ikea_e27_tv
                - light.dimmable_sm309
                - light.shelly_bulb_1
                - light.lidl_led_stand
                - light.plug_tz_10_switch
                - light.led_strip_1
          - service: input_select.select_option
            data:
              option: "8"
            target:
              entity_id: input_select.mi_boxer_select
      - conditions: "{{ trigger.id in ['8off'] }}"
        sequence:
          - service: light.turn_off
            data: {}
            target:
              entity_id: 
                - light.shellydimmer_f3d426
                - light.shellydimmer_d3e57c
                - light.ikea_e27_tv
                - light.dimmable_sm309
                - light.shelly_bulb_1
                - light.lidl_led_stand
                - light.plug_tz_10_switch
                - light.led_strip_1
              
      - conditions: >-
          {{ is_state('input_select.mi_boxer_select', '1') and trigger.id in ['bright'] }}
        sequence:
          - service: light.turn_on
            data:
              brightness_pct: "{{ trigger.to_state.state }}"
              transition: 0.2
            target:
              entity_id: light.shellydimmer_f3d426
            enabled: true

      - conditions: >-
          {{ is_state('input_select.mi_boxer_select', '2') and trigger.id in ['bright'] }}
        sequence:
          - service: light.turn_on
            data:
              brightness_pct: "{{ trigger.to_state.state }}"
              transition: 0.2
            target:
              device_id: 1ff4112785e14b8b8cba18d45fec3b11
            enabled: true

      - conditions: >-
          {{ is_state('input_select.mi_boxer_select', '3') and trigger.id in ['bright'] }}
        sequence:
          - service: light.turn_on
            data:
              brightness_pct: "{{ trigger.to_state.state }}"
              transition: 0.2
            target:
              entity_id: light.ikea_e27_tv
            enabled: true

      - conditions: >-
          {{ is_state('input_select.mi_boxer_select', '4') and trigger.id in ['bright'] }}
        sequence:
          - service: light.turn_on
            data:
              brightness_pct: "{{ trigger.to_state.state }}"
              transition: 0.2
            target:
              entity_id: light.lidl_led_stand
            enabled: true

      - conditions: >-
          {{ is_state('input_select.mi_boxer_select', '5') and trigger.id in ['bright'] }}
        sequence:
          - service: light.turn_on
            data:
              brightness_pct: "{{ trigger.to_state.state }}"
              transition: 0.2
            target:
              entity_id: light.dimmable_sm309
            enabled: true

      - conditions: >-
          {{ is_state('input_select.mi_boxer_select', '6') and trigger.id in ['bright'] }}
        sequence:
          - service: light.turn_on
            data:
              brightness_pct: "{{ trigger.to_state.state }}"
              transition: 0.2
            target:
              entity_id: light.shelly_bulb_1
            enabled: true

      - conditions: >-
          {{ is_state('input_select.mi_boxer_select', '7') and trigger.id in ['bright'] }}
        sequence:
          - service: light.turn_on
            data:
              brightness_pct: "{{ trigger.to_state.state }}"
              transition: 0.2
            target:
              entity_id: light.led_strip_1
            enabled: true
mode: restart

EDIT 11/01/2024

Avec la dernière mise à jour Zigbee2MQTT (1.35.1-1) il n’y a plus besoin de l’extension. Par contre ce que j’avais fait sur la base de ce qui est proposé ici ne fonctionne plus (bien que toujours dans la doc).

J’ai donc biaisé en faisant du mqtt direct :

Pour la détection (trigger:) des boutons (à dupliquer) :

- platform: mqtt
    topic: zigbee2mqtt/Mi Boxer
    payload: ('on', 101)
    value_template: "{{ value_json.action , value_json.action_group }}"
    id: 1on
  - platform: mqtt
    topic: zigbee2mqtt/Mi Boxer
    payload: ('off', 101)
    value_template: "{{ value_json.action , value_json.action_group }}"
    id: 1off

Et pour la luminosité (il me reste à trouver comment ne prendre en compte que la charge action_level) :

- platform: mqtt
    topic: zigbee2mqtt/Mi Boxer
    id: bright

Ensuite on modifie dans le chose: coté action (à dupliquer bien entendu :

      - conditions:
          - condition: template
            value_template: >-
              {{ is_state('input_select.mi_boxer_select', '2') and trigger.id in ['bright'] }}
        sequence:
          - service: light.turn_on
            data_template:
              entity_id: light.shellydimmer_d3e57c
              brightness_pct: "{{ trigger.payload_json.action_level }}"

EDIT 11/01/2024

Le problème avec la solution de mon EDIT précédent est que le trigger sur la charge MQTT globale génère trop de bruit. On va donc faire deux sensor: basés sur MQTT afin d'isoler la valeur de la luminosité (merci Mathieu) ainsi que le groupe (bouton) correspondant à la light: active, ce qui va nous permettre d'éliminer l'input_select: dans le filtrage à venir :

mqtt:
  sensor:
    - name: "Mi Boxer Bright"
      unique_id: "mi_boxer_bright"
      state_topic: "zigbee2mqtt/Mi Boxer"
      value_template: "{{ value_json.action_level |int }}"

    - name: "Mi Boxxer Group"
      unique_id: "mi_boxer_group"
      state_topic: "zigbee2mqtt/Mi Boxer"
      value_template: "{{ value_json.action_group |int }}"

En trigger: on utilisera l'action : action_brightness_move_to_level qui remonte dans HA :

trigger:
  - platform: device
    domain: mqtt
    device_id: 86c1403c24491ce021ac3ee081a86308
    type: action
    subtype: brightness_move_to_level
    discovery_id: 0x003c84fffec29c71 action_brightness_move_to_level
    id: bright

Et on complète notre action déclenchée par l'id: bright et filtrée sur le sensor: correspondant au bon bouton, et j'ai ajouté le light: actif afin de ne pas risquer une fausse manœuvre :

      - conditions:
          - condition: template
            value_template: >-
              {{ is_state('sensor.mi_boxer_group', '101') and trigger.id in ['bright'] and is_state('light.shellydimmer_f3d426', 'on') }}
        sequence:
          - service: light.turn_on
            data_template:
              entity_id: light.shellydimmer_f3d426
              brightness_pct: "{{ states('sensor.mi_boxer_bright') | int}}"

Il ne reste plus qu'à attendre que Z2M remonte les informations liées à la température du blanc et la roue chromatique et on pourra les traiter avec la même méthode.

 
 

 

 

Home Assistant, Zigbee, encore...

Alors, comment dire, dans la série jamais content, le Zigbee... Aujourd'hui ce protocole dispose d'une multitude d'approches plus ou moins simples à mette en œuvre, on résume :

  • Deconz / Phoscon : l'ancêtre toujours vaillant avec les clés Combee I et II ou le module RPI. Ca fonctionne, mais le développement est lent les nouveaux appareils tardent à êtres intégrés. De plus ça nécessite un addon et une intégration, le tout étant moyennement bien intégré. C'est ce qui assure la grande majorité de mes objets Zigbee depuis le début, d'abbord Sous Jeedom et ensuite sous Home Assistant.
  • ZHA (Zigbee Home Automation) : Totalement intégré à Home Assistant c'est la voie la plus simple qui supporte la majorité des clés du marché. Rien à redire, presque trop simple...
  • Zigbee2MQTT : La voie royale de geeks en tout genre, MQTT est à la mode, ce protocole est certes génial, mais franchement si vous débutez en domotique il est tout à fait possible de s'en passer en passant par ZHA.
  • Les passerelles des marques (Xiaomi, Ikea, Hue, etc...) : ça peut faire le job, mais ça restera lié aux équipement de la marque.
  • Les passerelles sous Tasmota, comme la Sonoof : pas testé, donc par essence ça me parait complexe et vaut mieux avoir un pote barbu habile du fer à souder. Idem pour la fameuse SLS dont certains ont du entendre parler.

Si la première des solutions (Deconz) fonctionne exclusivement avec la clé de la marque, ZHA et Zigbee2MQTT savent fonctionner avec toutes les clés disponibles. A commencer par la peu couteuse mais pas très performante cc2531. C'est pas cher et c'est une bonne option pour se faire la main, mais on se rendra rapidement compte que ça manque parfois de réactivité, une faiblesse qui ne sera pas gênante sur des sondes de température, mais qui le deviendra sur des interrupteurs, ou pire des variateurs. On va donc chercher à gagner du temps en explorant d'autres options.

Je vais explorer deux options en utilisant Zigbee2MQTT, mais j'aurais pu faire la même chose avec ZHA si j'avais voulut faire simple.

Clé USB à base de cc2652P

Si on commence à en trouver sur le net, il se trouve que j'ai un pote habile de ses mains qui sait souder et cherche à gagner sa vie en intégrant cette clé. Je lui ai donc acheté une des premières productions il il y a quelques semaines et je l'ai faite fonctionner sous Zigbee2MQTT en replacement de la cc2532.

J'ai un peu galéré sur la config à changer (pan_id) et surtout on passe en Zigbee 3.0 et le ré appairage des équipements est obligatoire, au final surtout fastidieux.

  serial:
  port: /dev/serial/by-id/usb-1a86_USB_Serial-if00-port0
advanced:
  rtscts: false
  log_level: info
  pan_id: 231  ## Attention à ce point...

La réactivité est bien meilleure et dans l'absolu le nombre d'équipements supportés simultanément bien plus important

La passerelle Xiaomi V3

Là vous vous demandez ce que vient faire cette passerelle que je dénigras plus haut. En fait elle est là car je vais l'utiliser non pas en mode natif avec une liste de devices limitée, mais en remplacement de la clé USB avec Zigbee2MQTT (ou ZHA). La liaison se fait en WIFI, et je peux donc placer la passerelle ou je veut dans la maison. Et cerise sur le gâteau les devices BLE reconnus remontent nativement dans Home Assistant...

La mise en place est un peu plus compliquée car il y a plusieurs façon d'utiliser ça, mais je vais essayer de vous mâcher un peu le travail. D'abord il vous faut une Gateway Xiaomi v3 (ZNDMWG03LM (CN) ou ZNDMWG02LM (EU) et rien d'autre), on en trouve chez AliExpress (27 €) ou Amazon (35/40€), de plus ces temps ci il y en a pas mal en reconditionnées état neuf chez Amazon à 25 €, donc plus simple que d'attendre 3/4 semaines avec le risque que le tanker se mette en travers du canal de Suez...

Une fois que vous avez en main votre nouveau jouet, vous l'ajoutez à Mi Home sans faire les mise à jour proposées (serveur Chine, j'ai pas essayé en serveur Europe mais ça devrait fonctionner également, retour welcome). A partir de là il faut récupérer le token (Mi Home, ou ici par exemple.) et lui assigner une réservation DHCP pour ne pas la perdre.

Ensuite sous Home Assistant :

  • On installe cette intégration via HACS (si vous n'avez pas HACS ou ne savez pas ce dont il s'agit, repassez dans quelques semaines...).
  • On ajoute l'intégration Xiaomi Gateway 3 dans Home Assistant (choisir Host & Token) en renseignant le HOST et le TOKEN et sans toucher aux options Telnet. Si ça ne fonctionne pas c'est surement lié à la version du firmware, firmware qu'il est possible de downgrader via Telnet (et pour une fois sans rien à souder).

Je vous ai perdu ? Pas de panique, tout est expliqué dans le GitHub de l'intégration et Google Translate est notre ami !

Modes de fonctionnement

  1. Natif Mi Home : On remonte dans Home Assistant les devices associables à Mi Home en ZigBee ou BLE (modules Xiaomi, Aqara et quelques ampoules Ikea).
  2. ZHA : La passerelle devient le coordinateur de ZHA et on profite de tous les devices supportés par ZHA. Cette option n'est pour l'instant pas la plus stable.
  3. Zigbee2MQTT : La passerelle devient le coordinateur de Zigbee2MQTT et on profite de tous les devices supportés par cette option. C'est la voie que j'ai explorée.

En choisissant l'option 3 et en considérant que Zigbee2MQTT est bien installé avec son broker, il suffit de modifier la configuration de l'addon en remplaçant la clé USB par un port TCP :

serial:
  port: 'tcp://192.168.210.119:8888'
  adapter: ezsp

Et bien sur de refaire les associations... Et constater une excellente réactivité. Meilleure qu'avec la clé à base de cc2652P, il me semble mais ça reste vraiment très subjectif. En tous cas sans commune mesure comparé à une clé cc2531.

On fait ainsi d'une pierre deux coups avec du Zigbee déporté qui intéressera ceux qui font tourner Home Assistant dans une VM installée au fond du garage, mais aussi la remontée des capteurs BLE, ce qui permettra de faire le ménage dans les intégrations dédiées BLE, et dans mon cas me séparer de mon Home Assistant remote qui supportait les clés USB

Et si on fait l'impasse sur le BLE, je pense qu'une fois la passerelle configurée pour Zigbee2MQTT on peut même désinstaller l'intégration...

Cette solution basée sur du reverse engineering sera pérenne pour peu que vous ne fassiez pas les mises à jour depuis Mi Home, et pour ça il existe dans l'intégration une possibilité de blocage.

EDIT 21/05/2021 : J'observe quelque plantages qui nécessitent le redémarrage de Zigbee2MQTT. Le problème semble venir du driver EZSP et non de la passerelle. Et curieusement ces plantages sont différents selon le type d'équipements. J'ai constaté une certaine allergies aux télécommandes IKEA par exemple... Par contre parfait pour remonter des sondes en BLE. A suivre.

EDIT 01/07/2021 : En l'état pas d'amélioration et inutilisable avec ZHA ou Zigbee2MQTT. Par contre 100% fiable en mode natif Xiaomi Mi Home. Donc parfait pour déporter des devices reconnus dans Mi Home

 

Home Assistant, RC & Lights

Me voici bien installé sous Home Assistant, j'ai choisi au départ Zigbee pour les capteurs de température et d'ouverture, puis au hasard des pubs sur Ali Express et de mes passages chez Ikea j'ai acheté diverses télécommandes en me disant que j'en ferait bien quelque chose... L'usage principal étant de piloter des éclairages ou des scènes, du son, ou encore une action du genre "chauffe la salle de bain" et dis à Alexa de me prévenir quand la température sera idéale". Bien sur on peut remplacer les télécommandes par Alexa ou GH, mais ça me fait toujours bizarre de parler à ces objets, surtout quand je ne suis pas seul...

Bref, pour piloter un éclairage depuis une télécommande Zigbee il existe plusieurs approches plus ou moins facile à mettre en œuvre. On part du principe que Zigbee s'appuie sur ZHA, Zigbee2Mqtt, Deconz ou directement en MQTT.

Phoscon

Il s'agit ici de l'interface de Deconz qui est la solution la plus répandue et à mon gout la plus performante. Cette passerelle va plus loin que les autres en ce sens qu'elle intègre une interface qui permet facilement d'associer les touches d'une télécommande à des ampoules ou des prises. En fait au départ Phoscon est juste fait pour remplacer les passerelles propriétaires (Hue, Ikea, etc.) sans pour autant disposer de Home Assistant et il est même possible de créer des scènes et de disposer des fonctionnalités des passerelles émulées.

C'est donc la solution idéale quand on ne dispose que d'ampoules ou prises Zigbee, d'autant plus que ces éléments seront toujours disponibles sous HA pour d'autres actions et que cette passerelle est compatible Alexa. Personnellement je recommande l'installer sur un vieux RPI à part et ainsi la placer au centre du logement.

Automations

Mais, ça va se compliquer quand on va vouloir associer une télécommande Zigbee à un équipement non Zigbee. J'ai par exemple quelques variateurs Shelly et je voulais y associer une télécommande Opple afin de plus bouger mon cul du canapé, bien que dans la vraie vie je passe tout de même plus de temps dans mon fauteuil de bureau.

La solution consiste donc à écrire des automations en se basant sur les devices et les codes retournées par ces télécommandes. C'est long, fastidieux et encombrant quand on sait qu'il faut 4 automations pour gérer les fonctions de base d'une ampoule variable , et je ne parle pas de la gestion des couleurs. C'est lourd, mais ça fonctionne à coup de copié / collé, et le faire sous NodeRed sera tout aussi fastidieux.

ControllerX

Alors j'ai longtemps laissé ces télécommandes en déshérence, puis un soir je me suis mis à explorer la communauté HA (celle en anglais) à la recherche d'une alternative, et je suis tombé sur ControllerX. Au départ je n'ai pas aimé car ça s'appuie sur AppDaemon qu'il me fallait installer, ce qui alourdit mon serveur HA. Et puis en lisant je me suis dit que ça valait le coup de creuser la chose.

Je vous laisse installer AppDaemon 4, c'est un AddOn qui s'installe comme les autres depuis le superviseur sur Hassio. On peu aussi l'installer en Docker pour ceux qui aiment se compliquer la vie. Il faut juste créer un fichier de config basic qui sera suffisant pour ce que l'on va en faire dans :

secrets: /config/secrets.yaml
appdaemon:
  latitude: 52.379189
  longitude: 4.899431
  elevation: 2
  time_zone: Europe/Paris
  plugins:
    HASS:
      type: hass
http:
  url: http://127.0.0.1:5050
hadashboard:
admin:
api:

/config/appdaemon/appdaemon.yaml

Ensuite on va installer ControllerX depuis HACS et une fois fait créer le fichier de config, non pas de ControllerX mais des apps AppDaemon :

sejour_halogène: 
  module: controllerx
  class: WXCJKG13LMLightController
  controller: aqara_opple
  integration: deconz
  automatic_steps: 30
  mapping:
    3001: hold_brightness_toggle
    3002: toggle
    3003: release
    3004: toggle_full_brightness
    3005: toggle_min_brightness
  light: light.shelly_shdm_1_f3758  

/config/appdaemon/apps/apps.yaml

Et la lumière fut ! Ces quelques lignes assurent les 5 fonctions d'une touche de ma télécommande qui en comporte 6. Et encore ici j'ai choisit un mapping personnalisé car je souhaite que chaque touche ne commande qu'un seul point lumineux en me servant du multiclic, mais ça serait encore plus simple si je voulais juste reproduire les fonction d'une télécommande Ikea ou Hue avec l'ampoule ivrée avec.

Explications lignes par lignes :

  1. un nom d'app que vous choisissez.
  2. le nom du module AppDaemon, ici ControllerX.
  3. le code de la télécommande utilisée : ici le controleur Opple avec 6 boutons (ici la liste des contrôleurs supportés).
  4. l'ID du device fournit par la passerelle (controller_id ou adresse IEEE (voir ici comment récupérer cette information).
  5. L'intégration utilisée (deconz, mqtt, zha, state) (plus d'informations ici).
  6. Des options (multiple_click_delay: 500, delay: 50, automatic_steps: 30, manual_steps: 10 (je vous laisse cherche run peu car il y en d'autres).
  7. Les mapping, ce qui qui va consister à associer les codes envoyés par la télécommande aux fonctions possibles.
  8. Enfin, on pointe sur l'éclairage déclaré dans Home Assistant, ici un Dimmer Shelly.

Je n'ai parlé ici que de ce que j'ai utilisé. Mais ControllerX va beaucoup plus loin. Il est bien sur possible de piloter des scènes, des automation ou encore des lecteurs multimédia, et par exemple d'associer le bouton rotatif Ikea à votre lecteurs Sonos. Je vous conseille la lecteur du sujet dédié et bien sur de la doc sur GitHub, même si ce développeur est bien dans le codage de ses url qu'il faudra souvent reconstituer...

Bonus

Il existe deux intégration intéressantes à associer à ces problématiques, d'abord Light Switch qui va permettre de créer une entité de type lampe à partir d'un switch, et ensuite Light Group qui va permettre de grouper plusieurs lampes pour en faire une seule...

Edit

Alors depuis que j'ai écrit cet article il y une nouveauté dans Home Assistant : Blue Print. Cela va permettre de télécharger des automations (partagées ici par exemple, et bientôt sur HACF) qui vont permettre de gérer des télécommandes en quelques clics et sans rentre dans le code. Le catalogue s'étoffe de jours en jours, donc n'hésitez pas à y retourner.

Il n'en reste pas moins qu'il y a une chose que je n'ai pas trouvé en Blue Print. Je voulais avec une télécommande Ikea 5 boutons, pouvoir passer d'une ampoule à une autre avec les touches directionnelles.  Et ça je n'ai réussit à le faire qu'avec ControllerX, en créant un input_select: et en me servant des options de contrainte, voilà un exemple pour deux lampes :

select_light_app:
  module: controllerx
  class: CallServiceController
  controller: ikea_tradfri_rc
  integration: deconz
  mapping:
    4002:
      service: input_select.select_previous
      data:
        entity_id: input_select.rc_ikea_1
    5002:
      service: input_select.select_next
      data:
        entity_id: input_select.rc_ikea_1

light_app_1:
  module: controllerx
  class: E1810Controller
  controller: ikea_tradfri_rc
  integration: deconz
  light: light.shelly_shdm_1_f3d426
  constrain_input_select: input_select.rc_ikea_1,light_1
  excluded_actions: [4002, 5002]

light_app_2:
  module: controllerx
  class: E1810Controller
  controller: ikea_tradfri_rc
  integration: deconz
  light: light.shelly_shdm_1_f3a100
  constrain_input_select: input_select.rc_ikea_1,light_2
  excluded_actions: [4002, 5002]

Home Assistant & ZigBee

ZigBee est un protocole de haut niveau permettant la communication d'équipements personnels ou domestiques équipés de petits émetteurs radios à faible consommation ; il est basé sur la norme IEEE 802.15.4 pour les réseaux à dimension personnelle (Wireless Personal Area Networks : WPAN). Wikipédia et Google vous raconteront le reste... Mais sous Home Assistant il y (principalement) trois façons d'approcher Zigbee :

Deconz / Phoscon

La clé Combee II dépend ici de l’environnement logiciel de son éditeur, qu'il soit installé de façon indépendante ou plus ou moins mergé à Home Assistant (ou une autre solution). C'est donc une une solution qui peut s'utiliser de façon autonome, ce qui était leur but de départ, remplacer simplement quelques passerelles propriétaires (Hue, Ikea, etc..). ils fournisse d'ailleurs des images RPI pour se passer de leur boitier et c'’est d'ailleurs ainsi que je l'avait monté sur un RPI2 auquel j'accédait depuis Jeedom, et auquel j'accède maintenant avec Home Assistant.

Le fait que ce soit autonome permet de réaliser des opérations sans passer par une plateforme domotique, tout en disposant des équipements sur une ou plusieurs solutions domotique. Par exemple, pour associer un interrupteur avec une ampoule, il est plus simple de le faire sous Phoscon, sachant que de toutes façons l'état de l'ampoule remontera dans Home Assistant et que je pourrais toujours l'éteindre avec une automation...

Enfin, les équipements sont également accessibles en parallèle depuis Alexa...

C’est donc la solution la plus proche d'une passerelle propriétaire, de ses avantages, de sa façon de fonctionner et d'évoluer. C’est celle que je conseillerais pour installer un HA chez un tiers, la plus grand public qui s'appuie sur des équipements l'ont peut facilement acquérir dans le commerce.

ZHA

Zigbee Home Automation est la solution la plus intégrée à Home Assistant. Elle s'appuie sur à peu près toutes les clés Zigbee du marché et fonctionne plutôt bien. Par contre ici on est sur une intégration fermée dans et pour HA. Elle supporte (à titre expérimental) même la Zigate dont j'avais fini par me débarrasser sous Jeedom...

Rien à ajouter de plus, pour faire simple et rester dans HA c’est la solution à adopter et l'on retrouvera les menus de configurations dans la configuration HA

zigbee2mqtt

C'est la solution à la mode, parce que MQTT est à la mode. Mais au delà de l'effet de mode, MQTT est le protocole qui fait son chemin et risque de devenir un standard bien au delà de nos petits bricolages domotique. Ici on passe par une passerelle que l'on va monter ou on le souhaite (RPI Zero indépendant, HA remote, etc...), qui va transmettre ses infos à un brooker qui lui aussi peut être n'importe ou (LAN/WAN) et notre HA ne sera qu'un client de ce brooker. L'étape suivante étant bien sur que les équipements intègrent ce protocole, ça arrive, notamment sur du DIY avec le firmware Tasmota et on peut imaginer que le marché adopte MQTT, c’est d'ailleurs le cas des équipements Shelly en WI-FI qui proposent (timidement) ce protocole de façon native, ou d'autres passerelles comme ble2mqtt...

Pour revenir à zigbee2mqtt le projet est très actif, plutot stable et c'est par exemple le seul qui propose les mises à jours bios de certains équipements. Pour ce test je l'ai monté sur un HA remote et j'ai utilisé une intégration sous forme d'addon. En fait simplement parce que j'avais ce HA remote sous la main, mais pour le coup la com ne se fait pas en remote mais en MQTT. C'est une solution ultra paramétrable, chaque équipement est ajustable à la source et les infos remonteront vers les clients, je dis bien les clients car on peut tout à fait imaginer qu'in équipement soit utilisable avec plusieurs solutions, un capteur de température vu par HA mais aussi par une solution externe, etc...

A noter que contrairement aux deux précédentes solution j'ai bien la remontée de l'état des piles sur les révisions récentes (fin 2019) des capteurs Aqara, ce n'est toujours pas les cas des deux solutions concurrentes, preuve de plus que le projet est très actif.

Enfin zigbee2mqtt s'appuie sur une clé DIY, ce qui veut dire qu'il faudra bricoler un peu et acheter quelques accessoires. Mais ça reste easy !

EDIT 22/01/2021 : Pensez à mettre à jour le firmware de vos clés, ça fonctionnera mieux avec les dernières versions...

Alternatives...

D'autres continuent à utiliser l'intégration Xiaomi avec la passerelle de première génération. Ça fonctionne, mais pour moi ce n'est pas une solution Zigbee, mais une solution Xiaomi qui repose sur l'utilisation d'un serveur Chinois, dépendant de la volonté de Xiaomi d'en laisser l'usage détourné possible, voire de la Chine de laisser passer ou non les flux. Si le fonctionnement se fait en local, c’est également un potentiel cheval de Troie, mais ça c'est un autre débat. Vous aurez compris que je ne suis pas fan.

EDIT 22/01/2021 : SLS, vous risquez d'en entendre parler cette année...

Conclusion

Conclusion il faut choisir. Choisir n'est jamais simple, et en l'espèce ce n'est pas moi qui vais vous dire quoi choisir ! Il faut tout de même savoir que si les produits les plus courants sont supportés par toutes les solutions, d'autres plus confidentiels ne le seront que par l'une ou l'autre.

Sources