[V4] Intégration Zigbee2mqtt

En fait je peux pas , y’a pas d’image amd64 ( Je ferai un build demain :sleeping: )

Ah oui, c’est vrai, je n’ai généré que pour arm.
J’ai relancé le build et toutes les images existent maintenant.

Merci @Reno, je test dans la journée

@Reno je viens de lancer le container, on est d’accord qu’on est obligé de passer par tes conteneurs ? Pas moyen pour le moment d’utiliser un serveur mqtt existant ?

Le log: ( je ne sais pas à quoi il a souscris :smiley: )

  vonox  ~  docker logs gladys-zigbee2mqtt

> gladys-server@ start:prod /src/server
> cross-env NODE_ENV=production node index.js

Initialising OpenZWave 1.6.974 binary addon for Node.JS.
        OpenZWave Security API is ENABLED
        ZWave device db    : /etc/openzwave
        User settings path : /src/server/services/zwave/node_modules/openzwave-shared/build/Release/../../
        Option Overrides : --Logging false --ConsoleOutput false --SaveConfiguration true
2020-05-08T12:25:23+0200 <info> index.js:20 (Object.start) Starting Dark Sky service
2020-05-08T12:25:23+0200 <info> index.js:16 (Object.start) Starting zwave service
2020-05-08T12:25:23+0200 <info> index.js:19 (Object.start) Starting telegram service
2020-05-08T12:25:23+0200 <info> index.js:13 (Object.start) Starting usb service
2020-05-08T12:25:23+0200 <info> service.start.js:16 (Service.start) Service darksky is not configured, so it was not started.
2020-05-08T12:25:23+0200 <info> service.start.js:16 (Service.start) Service telegram is not configured, so it was not started.
2020-05-08T12:25:23+0200 <info> service.start.js:16 (Service.start) Service zwave is not configured, so it was not started.
2020-05-08T12:25:23+0200 <info> service.start.js:16 (Service.start) Service zigbee2mqtt is not configured, so it was not started.
2020-05-08T12:25:23+0200 <info> service.start.js:16 (Service.start) Service mqtt is not configured, so it was not started.
2020-05-08T12:25:23+0200 <info> index.js:63 (Server.<anonymous>) Server listening on port 4080
2020-05-08T12:27:06+0200 <info> docker.stopContainer.js:18 (Docker.stopContainer) container zigbee2mqtt stopped
2020-05-08T12:27:07+0200 <info> docker.startContainer.js:18 (Docker.startContainer) container zigbee2mqtt started
2020-05-08T12:31:55+0200 <info> connect.js:23 (Zigbee2mqttManager.connect) Zigbee2mqtt USB dongle attached to /dev/ttyACM0
2020-05-08T12:31:55+0200 <info> subscribe.js:12 (Zigbee2mqttManager.subscribe) Subscribing to MQTT topic zigbee2mqtt/#

Je plussois !

@pierre-gilles où pourrai t on mettre à disposition les fichiers , repo spécifique ou dans le repo de la doc ?

Je ne pense pas qu’on veuille limiter l’accès du container Gladys à la machine.

Je rappelle que l’image Raspbian Gladys doit fonctionner pendant tout le cycle de vie du Raspberry Pi de l’utilisateur.

Imaginons que l’utilisateur installe Gladys en 2020, et qu’il change de Pi en 2030. Pendant 10 ans, si on ajoute des fonctionnalités, que des nouvelles intégrations sont développés dans Gladys, il faut que l’image Raspbian soit évolutive et que tous les dongles que l’on branche soit gérés par Gladys.

Si on doit demander à l’utilisateur de réinstaller Gladys tous les 4 matins, alors nous avons raté notre mission.

Je cite un post que j’avais écris sur un autre sujet:

Pourquoi utilise on Docker?

Dans Gladys 3, je rappelle qu’on exécutait Gladys directement sur la machine, sans Docker, donc Gladys avait accès à toute la machine.

Dans Gladys 4, on utilise Docker pour faciliter le packaging, le déploiement et la mise à jour des instances Gladys. Etant donné qu’on est dans de l’embarqué, qu’on a besoin d’accéder à des périphériques (USB, GPIO, Camera Pi par le Bus caméra par exemple) cela fait tout à fait sens de donner full accès à la machine à Gladys, comme ce serait le cas si jamais on faisait juste tourner le programme en direct sur le Raspberry Pi.

On est pas du tout dans l’usage Docker d’un provider cloud qui souhaiterait isoler l’exécution de code non-trusté, limiter l’accès à la machine physique, et limiter les ressources d’utilisation d’un utilisateur tiers.

Ici, l’utilisateur fait tourner sur sa machine à lui, tout seul, un programme embarqué qui fait l’usage intensif de périphériques externes et du hardware. Au contraire: on veut profiter des supers capacités du Raspberry Pi, et avoir les mêmes fonctionnalités que si on faisait tourner Gladys directement sur l’host comme la plupart des programmes font.

Essayer de limiter l’accès du container au Pi n’a pas de sens sens, et n’ajoute pas de sécurité…

Il faut penser le plus long terme possible, et à l’expérience de l’utilisateur en premier.

Qu’est-ce qui pose problème avec exposer le /dev? Gladys est là pour faire de la domotique, pas pour rester enfermer dans un container ^^

A chaque reboot tu peux avoir un mount different.

On peut juste proposer dans la doc ( avec des rules) et on reste sur dev en standard. Ou on peux l’intégrer dans le build de l’image.

D’un point de vue utilisateur c’est plus simple

L’un n’empêche pas l’autre.

Par contre je reste sur le partage complet de tout les périphériques ( oui y’a 2 sujets)

Je pense que je n’ai rien compris ce que vous voulez faire alors :smiley:

Ah oui ? je ne savais pas. Si tu as une parade à ça, je suis preneur ! La seule contrainte, c’est qu’il faut que ce soit fait de manière générique dans l’image, que ça fonctionne pour tout le monde, et que ça soit pérenne dans le temps.

J’ai éditer , c’est une grosse ânerie que j’ai sortie :sweat_smile: ( pour le nom du stick )

Le mount différent ça m’arrive quasi à chaque fois avec mon stick zwave

Une udev rule te permet de créer par exemple un alias de toute les clé zwave sur /dev/zwave

Comment tu connais à l’avance toutes les clés Z-Wave? C’est ça que je ne comprends pas en fait…

J’ai créé un sujet pour parler de ce débat assez important qu’est la gestion des instances déployées sur long terme =>

Via le vendor ID , il faudra prendre en compte les nouvelles clés , donc c’est à maintenir, mais l’avantage c’est que même s’il n y’a pas de rule pour une clé , elle reste dispo sur /dev/ttyACM*

C’est juste un lien symbolique beaucoup plus parlant

Ok je comprend, mais du coup pour rebondir sur l’autre sujet, c’est à maintenir dans l’image docker, ou c’est à maintenir sur le système? ( ce qu’on ne peut pas trop faire… )

C’est sur le système hôte ( on est en train de pourrir le topic de @Reno :smiley: )

Je penses que ça coute pas grand chose de le faire, c’est un + à disposition

Ça ne me dérange pas car c’est une vraie question que je me pose depuis quelques temps et que je n’ai pas pris le temps de poster.

Je suis d’accord qu’il y a plusieurs sujets.
Aussi, ok pour le fait qu’on laisse /dev en partage mais je ne suis pas trop pour le ‘–privileged’ mais c’est @pierre-gilles qui décide.
Mon exemple perso est que j’utilise d’autre containers Docker, sur RPi ou sur NAS, qui utilisent également des périphériques (carte son USB, cart tuner TNT, …) et j’ai peur que ça génère des conflits si plusieurs containers ont accès aux mêmes devices. J’essaierai de trouver le temps pour tester.

J’ai modifié le service usb de Gladys pour faire remonter le ‘manufacturer’, le ‘VendorID’ et le ‘ProducID’ pour aider l’utilisateur à choisir la bonne interface lorsqu’il a plusieurs dongles USB. Pour Zigbee2mqtt, ça marche bien puisque le dongle est affiché ‘Texas Instrument’. Par contre, je me suis rendu compte que la clé Zwave que je possède fait remonter un VendorID à la place du Manufacturer, ce qui n’est pas très parlant pour l’utilisateur.
Du coup, il serait effectivement intéressant d’afficher le type de dongle dans Gladys (Zwave ou Z2M ou …). Ça nécessite de référencer tous les dongles mais je ne pense pas qu’il y en ait tant que ça. Dans tous les cas, si on laisse afficher le VendorID dans l’interface, dans le cas d’un dongle non géré, on pourra demander aux testeurs de faire remonter cette info pour le prendre en compte.

Pour la règle udev, soit elle sera intégrée dans l’image distrib Gladys, soit il faudra fournir, dans tous les cas, un script de lancement du container, avec les options nécessaires, si l’utilisateur préfère l’image Docker.
Dans ce cas là, on pourrait ajouter une ligne (ou plusieurs) pour la création des règles udev.
Du coup, on pourrait également ajouter une ligne pour la création d’un network Docker pour Gladys, pour l’échange avec les containers de ces services (autre débat que l’on a par ailleurs avec @VonOx et @AlexTrovato) :wink:

1 « J'aime »

Dans l’image raspbian gladys tourne sous docker.

Je vais faire les modifications pour ajouter les règles udev dans l’image raspbian . ( et la mise à disposition dans la doc)
Par contre le network je suis vraiment pas chaud car on se limite au raspberry et à ceux qui l’auront créer manuellement.

Ce qui fait qu’un utilisateur qui utilise un autre network a un service inutilisable car c’est hard coded.

Pour les services qui doivent créér des conteneurs, le mieux est de les créer sur le même network que gladys. C’est ce que tente de faire @AlexTrovato avec le mqtt ( on croise les doigts :crossed_fingers:)
Si ça marche on pourra créer le network sans problème car plus de contraintes

Et je pense que c’est bon pour le partager du network entre Gladys et les containers créés par Gladys. Ne reste qu’à tester :slight_smile: (mais j’ai laissé localhost comme url)

Je ne comprends pas pourquoi tu dis qu’avec le network, on se limite au Rpi.

J’utilise beaucoup Docker (sur Arm et Intel) et je définis toujours des networks entre les services pour mieux maitriser les communications entre containers.
C’est d’ailleurs préconisé par Docker, en production :

Use user-defined bridge networks shows how to create and use your own custom bridge networks, to connect containers running on the same Docker host. This is recommended for standalone containers running in production.

De plus, il est possible de créer plusieurs networks pour un container et il est même possible de créer un network pendant qu’un container tourne pour ensuite l’attacher à ce network, à chaud.

Pour exemple, sur le service Zigbee2mqtt, j’ai créé un network ‹ gladys-net › sur lequel gladys est attaché et j’y connecte également les containers ‹ mqtt › et ‹ zigbee2mqtt ›. Pour suivre ce que j’applique habituellement, j’aurai même du créer un network spécifique entre les containers zigbee2mqtt et mqtt puisque le container zigbee2mqtt n’a pas vocation à communiquer directement avec Gladys.
Chez moi, j’ai également un container InfluxDB pour sauvegarder toutes les données qui passent par le broker MQTT dans une base de données. Pour cela, je définis un réseau supplémentaire spécifique entre mqtt et influxdb.
Cela n’empêche pas de définir également le network host ou de laisser le -p 80:80 pour permettre de s’y connecter depuis une machine distante.

De plus, ce paramétrage n’empêchera pas un utilisateur qui s’y connait de définir un autre network ‹ gladys-external › attaché à Gladys pour y connecter ses propres containers…

Parce qu’on ne fourni qu’une image raspbian, donc faut pas hard-coder dans les services.

Encore une fois je remet pas en cause le bien fondé des networks ( je le fait moi même avec une quinzaine de conteneur) et l’isolation. Je veux juste une solution qui contente tout le monde.

Là dessus encore une fois j’aimerais un peu plus d’explications quand même ! Je ne comprend toujours pas ce que ça apporte

Exemple:

Tu as un dongle zigbee et zwave, zigbee sur /dev/ttyACM0 et zwave sur /dev/ttyACM1

Tu décide de reboot, après celui ci le mount est inversé , tes services côté gladys ne fonctionne plus.

Les règles udev vont faire un alias, le zwave sera toujours dispo sur /dev/zwave et le dongle zigbee sur /dev/zigbee.

ça n’empeche en rien d’utiliser /dev/ttyACM* ( qui peut le plus peut le moins )