Comme un boomerang, du vieux matériel est revenu à la maison. Parmi les appareils récupérés, deux dispositifs demeurent utiles: une télécommande sans fil PalmPad X10 et un émetteur-récepteur radio X10 avec connexion USB, soit le CM19A. Ces appareils étaient au coeur du système domotique à ses débuts. On pourrait difficilement mieux les assortir qu'avec un Raspeberry Pi B de la première génération pour en faire un système de contrôle supplémentaire de luminaires semblable aux boutons Zigbee ajoutés dernièrement et au contrôle vocal via Alexa en place depuis quelques années. Malgré son âge et sa technologie dépassée, la télécommande PalmPad offre des avantages. Elle est utilisable par tous, u'importe le niveau de connaissance technique. En d'autres mots, des invités peuvent allumer ou éteindre plusieurs luminaires au rez-de-chaussée avec le PalmPad sans aucune aide. D'ailleurs, j'estime qu'il est plus pratique d'utiliser la télécommande pour contrôler l'intensité lumineuse du plafonnier dans l'entrée que de passer par Alexa.
Table des matières
- Le matériel
- Configuration du Raspberry Pi
- Installation de
mochad
- Prise en charge de
mochad
par Domoticz - Commutateurs virtuels pour
Mochad
- Script Python pour se connecter à
Mochad
- Fixer le niveau d'intensité lumineuse dans Domoticz
- Obtenir le niveau d'intensité lumineuse dans Domoticz
- Analyse syntaxique des messages de
mochad
- Addiciel à la paserelle Mochad de Domoticz
- Jouer dans la cour des grands
- Version 0.5 de
mochas
Le matériel
L'ordinateur monocarte est un Raspberry Pi modèle B (Rev 2.0) (c) 2011.12. Cette revision du tout premier modèle grand public faisait passer la mémoire à 512 Mo. Les autres caractéristiques, deux ports USB 2.0, un port Ethernet 10/100Mb, 1 port CSI, 1 port DSI et un connecteur d'entrée/sortie avec 28 broches ne changeaient pas. La puce système est un BCM2835 de Broadcom qui renferme un processeur ARM1176JZF-S (monocœur, 32 bits) cadencé à 700 Mhz. Ce Pi vieux de 12 ans n'est plus en vente, mais fonctionnellement il ressemble au Raspberry Pi Zero qui est toujours en production. Les deux sont basés sur la puce BCM2825, bien qu'elle soit cadencée à 1 000 MHz sur le modèle plus récent. Le Pi Zero n'a qu'un seul port USB, mais en revanche il possède le même connecteur d'entrée/sortie de 40 broches adopté dès la seconde génération des Pi. La version Pi Zero W ajoute une connexion Wi-Fi et serait donc facilement substituée au vieux modèle B.
Le CM19A de X10 (l'entreprise) est une passerelle entre un ordinateur, auquel il est relié avec une connexion USB, et des modules qui transmettent ou reçoivent des commandes radio X10 (le protocole). Les transmetteurs sont des télécommandes sans fil, des capteurs de mouvements, des capteurs de porte de sécurité et ainsi de suite. Seule la capacité du CM19A à retransmettre les paquets radio X10 reçus d'une télécommande vers une connexion sérielle est utile puisque je ne possède aucun module X10 récepteur contrôlé par radio. On peut utiliser l'interface CM15A ActiveHome Pro beaucoup plus gros et bien plus dispendieux que le CM19A. En plus de gérer les commandes sans fil comme le CM19A, le CM15A prend en charge la transmission et réception des signaux numériques superposés sur le courant secteur alternatif du système X10 initial.
La télécommande X10 radio utilisée est le PalmPad (HR12A ou PHR03) avec huit couples de boutons ON | OFF
et deux boutons pour intensifier ou diminuer l'intensité lumineuse du dernier dispositif allumé ayant cette capacité. On peut voir sur la photographie, l'étiquette avec les noms des luminaires contrôlés ce qui explique pourquoi j'estime que cette télécommande est si facile d'utilisation même pour les non initiés. X10 produisait d'autres télécommandes radio qui pourraient être utilisées aussi bien que le PalmPad. En voici que j'ai pu identifier: Keychain Remote Control (KR19A ou PHR04), CreditCard Thin Remote Control (KR22A), Slimline Switch Decorator White (SS13A ou PHW04D). La télécommande prend aussi en charge le capteur de mouvement sans fil ActiveEye (MS16A ou PMS03).
Le petit ordinateur doit être connecté au réseau local ce qui pourrait être fait aisément avec un câble Ethernet. Ce n'est malheureusement pas pratique là où se trouve le Pi, alors j'ai rajouté une clé USB-Wifi pour une connexion sans fil. Auparavant, j'ai utilisé des clés contenant des puces Realtek dont les numéros d'identité étaient 0bda:8179
, 0bda:0179
et 0bda:8176
. Aucune ne fonctionne correctement maintenant. Je ne vais pas reprendre cette discussion ici. Heureusement, j'ai trouvé dans ma collection deux adaptateurs qui sont adéquats.
Évidemment, ce problème n'existe pas chez les Raspberry Pi avec radio Wi-Fi intégré, soit les modèles 3 et plus récents et les modèles Zero W.
Enfin il faut une carte mémoire de type SD (ou micro-SD avec adaptateur SD). Une carte de 8 Go peut facilement contenir le système d'exploitation et tous les programmes et données qu'on y rajoutera. Il est avantageux de choisir une carte de bonne qualité et préférablement rapide.
En principe, il ne faut pas plus de matériel, car l'installation peut se réaliser en mode étêté signifiant qu'on peut se passer d'un clavier et d'un moniteur reliés au Pi. Cependant, qu'on ajoute une clé Wi-Fi ou non, il est fortement recommandé de connecter le Raspberry Pi au réseau avec un câble Ethernet pour l'installation du système d'exploitation. Les téléchargements des mises à jour sont volumineux et demandent beaucoup de temps au petit modèle B. En plus, il est facile de faire une erreur lorsqu'on définit les paramètres du réseau Wi-Fi et alors la seule façon de se connecter à l'appareil étêté sera par session SSH via l'interface Ethernet ou directement par la console via un clavier et moniteur.
Configuration du Raspberry Pi
Une des raisons que tant d'enthousiastes demeurent fidèles envers l'écosystème du Raspberry Pi est le support indéfectible envers les premiers Pi vendus. Ainsi la plus récente version de Raspberry Pi OS fonctionne sur le modèle B vieux de douze ans est la plus récente version fonctionnant sur le modèle B. Parmi les nombreuses versions du système d'exploitation, j'ai choisi Raspberry Pi OS Lite (32-bit) Bookworm
(2023-12-11-raspios-bookworm-armhf-lite.img
).
Le téléversement du système d'exploitation sur la carte SD est très facile avec Raspberry Pi Imager qu'on obtient en cliquant sur le lien. Il y a tellement de tutoriels sur ce dernier qu'il est inutile de reprendre ce sujet ici. Notons toutefois que lors du téléversement avec Imager
, j'ai activé le serveur SSH, modifié le nom d'utilisateur à vpi
et changer le nom d'hôte du Raspberry Pi à vieuxpi
. Il est aussi possible de saisir les coordonnées d'un réseau Wi-Fi, mais on peut également attendre à plus tard si c'est possible d'établir une connexion filaire au réseau local avec accès à l'Internet.
il a été possible d'ouvrir une session SSH avec le Raspberry Pi après son premier démarrage. Il faut être patient, car le Raspberry Pi doit faire des opérations, dont l'expansion du système de fichier, qui prennent beaucoup de temps pendant ce premier démarrage.
Identifions exactement le système d'exploitation.
il faut mettre à jour le système d'exploitation auquel de nombreuses modifications ont été apportées depuis sa sortie. C'est une opération qui peut être lente, surtout avec un Pi monocoeur. Après le lancement de la commande multiple ci-dessous, on aura le temps de se préparer un café ou un léger repas.
Ce fut déconcertant d'aboutir à ce dernier avertissement après une mise à niveau de 46 minutes. J'ai décidé de répéter les étapes.
Apparamment, il n'y avait rien de plus à faire, et j'ai supposé que la mise à niveau de Raspian 6.1.63 à 6.1.73 avait fonctionné correctement. La vérification de l'état de systemd
semble le confirmer.
Si l'on veut que le Raspberry Pi accède au réseau local avec le Wi-Fi et si l'on n'a pas défini les paramètres avec Imager
avant le téléversement du système d'exploitation, il faut activé le Wi-Fi maintenant. Avant, du temps de Raspbian
on utilisait l'utilitaire raspi-config
pour configurer les paramètres réseau, mais maintenant dans Rasberry Pi OS
c'est avec l'utilitaire nmtui
(NetManager
) qu'on procède.
Il faut doter le Raspberry Pi d'une adresse IP statique, car plusieurs logiciels ne prennent pas en charge les noms d'hôte du domaine .local
. La meilleure façon de le faire est d'attribuer une adresse fixe au Pi d'après son adresse MAC dans le routeur. Comme ça, il n'y a rien à changer sur le Raspberry Pi et si le sous-réseau devait changer le Raspberry Pi pourrait obtenir une adresse valide. On peut aussi fixé l'adresse IP d'une interface réseau sur le PI avec NetManager
. Il faut s'assurer que l'adresse choisie n'est pas dans la plage des adresses dynamique du routeur. Mon approche est de donner une adresse fixe à l'interface Wi-Fi et de continuer avec une adresse dynamique pour l'interface Ethernet qui n'est pas utilisée normalement. Si quelque chose change avec le réseau Wi-Fi, il sera possible de brancher le Pi sur le réseau câblé et le retrouver comme lors du premier démarrage.
Installation de mochad
Selon la documentation au sujet de mochad
ce nom est un sigle provenant de Multiple Online Controllers for Home Automation Daemon. La description du programme est plus éloquente: mochad
is a Linux TCP gateway daemon for the X10 CM15A RF (radio frequency) and PL (power line) controller and the CM19A RF controller. Comme traduction libre je propose: mochad
est un service Linux agissant comme passerelle entre les contrôleurs CM15A ou CM19A de X10 et les connexions TCP. Ce service doit être en place avant d'intégrer le matériel X10 dans Domoticz.
J'ai suivi mes propres instructions pour installer mochad
depuis la version qu'on retrouve dans mon référentiel sur GitHub. Les explications dans ce dépot sont en anglais, mais les instructions d'installation en français sont dans un ancien billet sur ce site. Je ne vais pas répéter tous ces détails ici.
Après l'installation de mochad
, le service devrait démarrer lorsqu'un émetteur-récepteur CM15A ou CM19A est branché à un port USB du Raspberry Pi. On peut alors vérifier le fonctionnement en se connectant à mochad
avec netcat
.
Ces messages provenaient de mochad
alors que j'appuyais sur des touches du PalmPad dont la molette de réglage du code maison était sur « J ».
Il est très important de vérifier que l'on a accès au service depuis tout autre ordinateur sur le réseau local dont nécessairement celui sur lequel roule Domoticz. Ci-dessous je teste avec mon ordinateur bureau.
Prise en charge de mochad
par Domoticz
Domoticz communique avec le service mochad
directement avec une passerelle nommée Mochad CM15Pro/CM19A bridge with LAN interface
(Mochad
pour faire court) qu'il faut activer.
Les étapes pour réaliser cette activation devraient être évidentes quand on examine la figure ci-dessus. Notons qu'il faut choisir le type de matériel (étape 3) avant de voir tous les champs à compléter. On peut donner le nom qu'on veut à l'étape 5 et il faut ajuster l'adresse distante qui est l'adresse IP du Raspberry Pi sur lequel mochad
est installé. Malheureusement, l'adresse distante ne peut pas être un nom d'hôte local comme vieuxpi.local
. C'est pour cela qu'il fallait donner une adresse IP statique à l'interface réseau du Raspberry Pi. Le port pour la connexion TCP est par défaut 1099. La valeur serait différente seulement si SERVER_PORT
dans mochad.c
avait été modifié avant la compilation de la source.
Il ne faut pas oublier d'activer la passerelle (étape 4) et, surtout, de cliquer sur
(dernière étape 7) quand les champs sont correctement définis. Si l'on fait une erreur ou si quelque chose change plus tard, on peut toujours modifier les paramètres de la passerelle en la sélectionnant (en cliquant sur celle-ci) puis en cliquant sur . Après l'activation et l'ajout de la passerelle, on peut vérifier que la passerelle communique avec le service mochad
sur le Raspberry Pi en examinant le journal de Domoticz (Configuration/Log).
On devrait y voir que Mochad
a réussi à se connecter à mochad
; c'est l'enregistrement Mochad: connected to: xxx.xxx.xxx.xxx
. On peut alors essayer de vérifier que la télécommande PalmPad fonctionne. La seule façon de le faire ici, c'est d'activer un des boutons ▲ ▼ ce qui entraîne l'affichage d'un message d'erreur de décodage de la part de Mochad
qu'on peut voir ci-dessus. Rien n'apparaît dans le journal lorsqu'un quelconque bouton blanc de la télécommande est activé. Clairement, Mochad
comprend des messages de type 02/19 20:39:17 Rx RF HouseUnit: J6 Func: Off
provenant de mochad
, mais pas ceux qui ne contiennent pas d'adresse d'unité comme 02/20 15:53:30 Rx RF House: J Func: Dim
. Au moins cela constitue une confirmation que mochad
est correctement installé sur le vieux Raspberry Pi et que la passerelle Mochad
reçoit bien les messages. Cela explique aussi pourquoi il nous faudra prendre en charge les messages Bright
et Dim
directement.
Commutateurs virtuels pour Mochad
puisqu'il y a 8 paires de boutons marche/arrêt sur le PalmPad et que celui-ci sera placé dans la salle de séjour, j'ai dressé une liste de sept luminaires au rez-de-chaussée qu'on pourra contrôler avec l'appareil. Il y a un groupe, au début de cette liste, activer ensemble trois appareils de la salle de séjour (Torchère, Bibliothèque et Lampe) .
dispositif | Idx | type | |
---|---|---|---|
1 | Salon | 1 | groupe |
2 | Torchère | 1 | lampe |
3 | Bibliothèque | 3 | lampe |
4 | Lampe | 4 | lampe |
5 | Balcons | 140 | lampe |
6 | Entrée | 113 | lampe (gradateur) |
7 | Lustre | 89 | lampe (gradateur) |
8 | Cuisine | 90 | lampe (gradateur) |
La colonne Idx
contient le numéro d'identité unique affecté à chaque dispositif virtuel dans Domoticz qui contrôle déjà le luminaire. Aucun changement ne sera apporté à ce fonctionnement. L'astuce, déjà expliqué en 2017 dans la section 4 de Contrôleur sans fil X10 avec l'interface CM19A dans Domoticz, est l'ajout d'un second commutateur virtuel sur la passerelle Mochad
pour transmettre les commandes du PalmPad au commutateur contrôlant déjà le luminaire. Si l'on décide de se défaire du matériel X10, on pourra éliminer ces commutateurs secondaires sans conséquences pour le bon fonctionnement des commutateurs principaux dans Domoticz.
À titre d'exemple, examinons l'ajout d'un commutateur virtuel sur Mochad
pour contrôler indirectement le plafonnier de l'entrée avec le PalmPad. En principe, il y a plus d'une façon d'ajouter un nouveau dispositif virtuel dans Domoticz. Voici celle qui me semble la plus facile à mettre en oeuvre avec le matériel X10 utilisé.
Dans l'onglet
, cliquer sur le bouton . Le message suivant est affiché pendant quelques secondes.Pendant l'affichage de ce message, on active un bouton de la télécommande. Dans mon cas j'ai appuyé sur le sixième bouton On et la boîte de dialogue suivante apparaît.
Il faut saisir le nom du dispositif virtuel qu'on veut créer, puis cliquer sur le Add Device. Pour m'y retrouver plus tard, j'annexe « _mochad
» au nom du nouveau dispositif virtuel qui sera contrôlé par la télécommande. Comme tout nouveau dispositif, il sera affiché après les autres dans l'onglet .
Cliquer sur son bouton
. Les caractéristiques du dispositif sont alors affichées dans l'onglet. Les requêtes HTML suivantes sont saisies dans les champs Action
On
et Off
.
Action On:
http://192.168.1.22:8080/json.htm?type=command¶m=switchlight&idx=113&switchcmd=On
Action Off:
http://192.168.1.22:8080/json.htm?type=command¶m=switchlight&idx=113&switchcmd=Off
Évidemment, il faudra ajusté l'URL de Domoticz et le numéro d'identité du dispositif virtuel (l'idx
) qui contrôle le luminaire.
Maintenant, il faut utiliser la télécommande pour vérifier qu'elle contrôle effectivement le plafonnier de l'entrée. Si tout fonctionne bien, on peut éliminer ce nouveau dispositif de l'onglet en changeant son nom à $entree_mochad
. Encore une fois, il y a plus d'une façon de renommer un dispositif virtuel, mais ici le plus simple est de cliquer sur son bouton de nouveau. On pourra toujours retrouver ce dispositif « invisible » dans la liste des dispositifs: Configuration/Dispositifs.
J'ai refait toutes ces démarches pour les six autres luminaires en ajustant le nom de chaque nouvel interrupteur virtuel et le numéro d'identité du dispositif contrôlant le luminaire visé dans ses requêtes HTTP.
Le premier couple de boutons marche/arrêt de la télécommande ne contrôle pas un luminaire, mais plutôt un groupe et, conséquemment, il faut modifier la requête HTTP. Plus précisément, il faut ajuster la valeur associée à la clé param
.
Action On:
http://192.168.1.22:8080/json.htm?type=command¶m=switchscene&idx=1&switchcmd=On
Action Off:
http://192.168.1.22:8080/json.htm?type=command¶m=switchscene&idx=1&switchcmd=Off
Si les seules actions possibles pour tous les appareils contrôlés avec la télécommande PalmPad sont la mise en marche et l'arrêt, alors il n'y a plus rien à ajouter et ce billet n'est qu'une mise à jour de celui de 2017. En revanche si certains des appareils sont des lampes avec gradateur alors aussi bien trouver une façon de tenir compte des messages des boutons ▲ ▼ de la télécommande.
Le wiki de Domoticz contient une longue page consacré à l'API du service domoticz
: Domoticz API/JSON URL's. La section Turn a light/switch on/off contient l'explication suivante pour les requêtes faites ci-dessus:
When error:
On ne peut pas dire qu'il s'agit d'une documentation prolixe, mais pour une action aussi simple c'est suffisant. En revanche on verra ci-dessous que l'information peut être insuffisante quand il s'agit de l'intensité lumineuse et que j'ai dû expérimenter pour arriver à mes fins.
Script Python pour se connecter à mochad
Voici un petit script en Python 3 qui établie une connexion avec mochad
et imprime les messages de ce service dans une boucle sans fin.
J'ai pensé qu'il serait préférable de prendre en charge certaines exceptions pour obtenir des messages un peu plus descriptifs.
J'ai compris plus tard que cette prise en charge des exceptions n'était pas au point. Il est approprié de répéter ici que je n'ai qu'une connaissance élémentaire de Python et que le code que je crée est fait avec l'aide d'un outil de recherche sur le web. Peut-être obtiendrai-je l'aide d'une intelligence artificielle à l'avenir, mais en attendant je serai reconnaissant pour toutes les suggestions susceptibles d'améliorer le code.
Jusqu'ici nous n'avons créé qu'une pâle imitation d'une petite partie de ce que netcat
peut faire.
Fixer le niveau d'intensité lumineuse dans Domoticz
L'interface de programmation d'application (ou API pour application programming interface) de Domoticz ne contient pas de méthode pour accroître ou diminuer l'intensité lumineuse d'un gradateur virtuel. Tout ce que l'on trouve sur le sujet est une méthode pour fixer l'intensité à un niveau quelconque : Set a dimmable light/selector to a certain level. Voici la syntaxe de la requête HTTP à formuler.
Il faut, bien sur, remplacer {domoticz} par l'adresse IP et le port du serveur Domoticz, {idx} par l'index du dispositif virtuel et {value} par l'intensité lumineuse désirée. Dans le cas des gradateurs installés dans la maison, cette intensité est une valeur entre 0 et 100, mais il existe des appareils avec des échelles d'intensité différentes. Le petit script Python suivant permet de tester l'API de domoticz
.
Le script ne fonctionne que si l'hôte de Domoticz et l'ordinateur depuis lequel ce script est exécuté sont membres du même réseau de confiance paramétré dans la section Sécurité
de Domoticz. Il me faudrait revenir sur la sécurité des connexions plus tard, mais ce ne sera qu'à la fin de ce billet.
Le script est instructif. L'API de Domoticz est très stricte quant à la syntaxe des requêtes tout en tolérant des valeurs peu sensées.
Aucune exception n'a été engendrée et le code HTTP en réponse à chaque requête est toujours 200 (rq.ok
est l'équivalent de rq.status_code == 200
). Le journal de Domoticz ne signale rien d'anormal sauf pour les indices de dispositif non valides.
L'interface Web de Domoticz n'affiche pas les valeurs négatives. En fait une intensité inférieure ou égale à zéro est interprétée comme une directive d'éteindre le luminaire, qu'importe si le dispositif virtuel est un commutateur ou un gradateur. Quand un gradateur est éteint, l'intensité lumineuse n'est pas modifiée. Ainsi quand le gradateur est réallumé, il reviendra à son niveau de luminosité antérieur. De même, fixer l'intensité lumineuse à une valeur positive allume la lampe contrôlée, qu'importe qu'elle soit à intensité variable ou non. Cela me semble tout à fait acceptable, mais en revanche le traitement des intensités supérieures à 100 % est surprenant. L'image ci-dessous est éloquente à ce sujet.
Toute intensité supérieure à 100 % est affichée, qu'importe le type de dispositif virtuel, mais on ne peut dépasser 100 % d'intensité lumineuse et Domoticz fixe le niveau de luminosité à 100 dans ces situations de dépassement.
Si l'adresse IP de Domoticz est incorrect alors une avalanche d'exception est déclenchée.
Si une erreur HTTP se produit, en utilisant /json.html
plutôt que /json.htm
par exemple, rien ne fonctionne, mais aucune exception n'est soulevée et rien n'est affiché dans le journal de Domoticz.
On peut faire mieux dans la gestion des exceptions et erreurs HTTP. Voici une nouvelle version de la fonction set_level
.
Encore une fois, la gestion des exceptions sera améliorée dans le script final. Malheureusement, si la requête est mal formée alors rien n'est modifié au niveau des dispositifs virtuels et réels, le journal contiendra un message d'erreur ou d'avertissement, mais la fonction set_level
agira comme si rien n'était.
Le message suivant est affiché dans le journal si la requête envoyée contient une coquille comme type=comand
:
Le niveau du message (status = 2
) n'est pas une indication qu'il s'agit d'une erreur, même si la requête est ignorée. De même, si on se trompe avec switchlight
, la commande est ignorée et le journal contient le massage suivant au niveau 1 comme si c'était normal.
Pire du point de vue d'identification des erreurs, quand le commandement final est St%20Level&level=
plutôt que Set%20Level&level=
il n'y a aucune exception et rien n'apparaît dans le journal.
Il faut spécifier l'heure locale depuis laquelle on veut les messages et le niveau des messages à afficher. L'heure doit être le nombre de secondes écoulée depuis le début de l'époche Linux. Vu l'incohérence des niveaux des message, il faut récupérer tous les messages depuis l'envoi de la requête pour fixer l'intensité lumineuse. Donc il faudra éplucher la réponse au format JSON pour retrouver les messages pertinents et soulever une exception le cas échéant. Ce serait beaucoup d'efforts pour atteindre une solution incomplète comme le dernier test à démontré.
La leçon est claire: il faut examiner les luminaires pour s'assurer que le script fonctionne bien. Si ce n'est pas le cas, un examen des dispositifs virtuels et du journal pendant l'exécution du script et les exceptions soulevées par ce dernier pourrait révéler l'erreur, mais rien n'est garanti à ce niveau.
Obtenir le niveau d'intensité lumineuse dans Domoticz
Puisqu'il y a une requête pour fixer le niveau d'intensité lumineuse, on penserait qu'il y aurait une pour obtenir l'intensité. Or la symétrie get/set
qu'on retrouve dans les définitions d'objets n'est pas respectée dans Domoticz. Pour lire une propriété d'un dispositif virtuel, il faut obtenir l'état entier du dispositif et rétrouver la propriété désirée dans cette information assez touffue.
Toute cette information est obtenue en responsa à une requête API Retrieve status of Domoticz instance. Pour autant que je sache, c'est toujours la même structure qu'importe la nature du dispositif et conséquemment il y a des enregistrements qui ne correspondent à rien. Il y a six clés rattachées à la variabilité de la luminosité, dont trois avec valeur numérique et trois avec une chaîne comme valeur décrivant la nature du dispositif.
Clé | Valeur | |
---|---|---|
Gradateur | Commutateur | |
"DimmerType" | "abs" | "none" |
"HaveDimmer" | true | true |
"Level" | 49 | 90 |
"IntLevel" | 49 | 90 |
"MaxDimLevel" | 100 | 100 |
"SwitchType" | "dimmer" | "On/Off" |
Une vérification de "SwitchType"
distingue les gradateurs des commutateurs ci-dessous alors que la valeur de "HaveDimmer"
ne fonctionnerait pas. Quelle est la différence entre "Level"
et "IntLevel"
? J'ai choisi d'utiliser le dernier en supposant que la valeur du premier pourrait être une chaîne selon le type de gradateur. Les clés "DimmerType"
et "MaxDimLevel"
ne sont pas utilisées ici parce que l'intensité est fixée de façon absolue sur une échelle de 0 à 100 sur tous les gradateurs de la maison. Voici une fonction qui peut extraire la valeur de "LevelInt"
si elle existe.
La requête HTTP auprès de Domoticz est faite de la même façon qu'auparavant dans set_level
. La réponse du serveur domotique au format JSON est convertie en dictionnaire et d'où l'on obtient l'information désirée. Si le numéro idx ne correspond pas à un dispositif, même quand il est négatif, Domoticz retourne un code 200 et une réponse au format JSON qui contient le préambule, soit les lignes 1 à 14 seulement. Dans ce cas, une exception de type KeyError
est créée quand on demande la valeur associée à la clé "result"
. Cette exception sera soulevée si les clés "SwitchType
et "LevelInt"
ne sont pas trouvées.
Analyse syntaxique des messages de mochad
Le service mochad
peut transmettre plusieurs types de messages, mais seulement deux sont pertinents. Comparons ces deux types de messages qui sont composés de huit éléments.
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
mois/jour | heure | Dir | Tech. | Type | Adr. | Cmd | Action |
02/20 | 18:53:40 | Rx | RF | HouseUnit: | J3 | Func: | (On|Off) |
02/20 | 19:02:08 | Rx | RF | House: | J | Func: | (Bright|Dim) |
On sait que la passerelle Mochad
de Domoticz ne peut pas décoder le second type de message. Parce que ce type de message contient une adresse incomplète, il faut décoder le premier type de message aussi pour conserver la dernière adresse X10 complète et pour l'utiliser pour modifier l'intensité du bon appareil.
À la première étape de l'analyse, le message obtenu de mochad
est divisé en éléments avec l'espace comme séparateur. On vérifie qu'il y a huit éléments, car il arrive souvent que mochad
transmet des messages incomplets. Après on s'assure que les éléments fixes (Rx
, RF et
Func:
) sont présents. On coupe court à l'analyse si le message est à propos d'une unité avec un code maison autre que celui spécifié dans la constante HOUSE
. Ce code correspond à la lettre choisie avec la roulette au bas du PalmPad. Rendu ici, il suffit d'examiner les éléments 4 et 7 pour sauvegarder le nom de la dernière unité allumée ou éteinte dans la variable Unit
ou pour ajuster l'intensité de cette dernière unité. La constante DELTA
spécifie de combien il faut augmenter ou diminuer l'illumination. Évidemment, la fonction update_level
n'est qu'une ébauche ci-dessus.
Addiciel à la paserelle Mochad de Domoticz
En combinant les fonctions présentées ci-dessus, on aboutit à une première ébauche de l'addiciel à la passerelle Mochad.
La seule nouveauté c'est la fonction update_level(unit, delta)
. En premier elle obtient le numéro d'identité du dispositif virtuel contrôlé avec l'unité X10 unit
. S'il y a erreur et unit
n'est pas une clé dans DEVICES
, la fonction ne fait rien. Autrement, la fonction obtient le niveau de luminosité actuel selon Domoticz. Si ce n'est pas possible, alors l'exécution de la fonction est terminée. Si tout est bien, la fonction ajoute delta
pour obtenir la nouvelle intensité. S'assurant que cette valeur est entre 0 et 100, elle fixe l'intensité en utilisant la fonction set_level
. La démarche est en fait un plus complexe, car Domoticz refuse de fixer le niveau à 0. Il éteint plutôt le luminaire et l'on a déjà vu qu'il ne met pas l'intensité à 0 dans ce cas. Donc, quand le niveau est ramené à 0 avec le bouton Dim, je triche un peu en disant à Domoticz de régler l'intensité sur 1, puis en lui disant d'éteindre la lumière. Selon Domoticz l'intensité lumineuse est de 1 et le luminaire est éteint. Quand Domoticz retourne un niveau de luminosité de 1, ce chiffre est ramené à 0 avant d'ajouter delta
. Donc les luminosités au bas de l'échelle sont 0 et 15 (=DELTA), mais on peut aboutir à 10 diminuant l'intensité depuis 100 avec le PalmPad.
J'ai testé avec succès ce script sur mon ordinateur bureau et il a fonctionné continuellement sur le Raspberry Pi depuis plus de deux semaines. Cependant, il n'est pas pratique de lancer manuellement ce programme, alors je l'ai sauvegardé sous le nom mochadad.py
dans le dossier /home/pi/.local/bin
. Puis j'ai vérifié que Python3 est là où la première ligne du script indique qu'il se trouve. Ensuite, j'ai marqué le script comme un fichier exécutable.
Il restait une problème un peu épineux que j'ai bâclé avec une tâche cron
qui s'exécute 5 minutes après chaque démarrage de tarte
. Voici la tâche.
On ajoute cette ligne dans un fichier système avec la commande suivante
Le &
terminal indique que mochadad.py
doit fonctionner en arrière-plan alors que nohup
est pour supprimer les messages du programme vers la console. Pourquoi 5 minutes d'attente avant de lancer mochadad.py
? C'est pour s'assurer que mochad
est activé, car autrement, une exception arrête l'exécution de mochadad.py
. Je pourrais changer le script et mettre la dernière partie après la ligne #-----
dans une boucle perpétuelle qui s'exécute toutes les 60 secondes. Comme ça mochad
ou Domoticz arrêtent de fonctionner pendant un certain temps puis reviennent en ligne, mochadad.py
pourra se reconnecter. J'ai procédé autrement.
Jouer dans la cour des grands
Comme complément de formation pour autodidacte, j'ai décidé d'essayer de transformer ce script en service géré par systemd
. Je ne vais pas présenter en détail le coude source du script sensiblement modifié. On le trouvera dans le référentiel mochas sur GitHub avec deux autres fichiers qu'on verra ci-dessous. Pour faire comme les autres services ajoutés au système d'exploitation, j'ai décidé d'installer le script dans le même répertoire que mochad
. Du coup, j'ai changé son nom pour la symétrie qu'on peut voir ci-dessous.
Comme pour mochad
seul root
a les permissions pour écrire, lire et exécuter le script nommé mochas
.
Il fallait aussi modifier le script pour expédié ses messages vers le journal du système puisque tout se fait en arrière plan. J'ai aussi voulu rendre l'utilisation du script plus facile pour les deux ou trois autres personnes qui pourraient se servir de mochas
pour intégré un PalmPad dans Domoticz. Pour cela j'ai rajouté un fichier de configuration, mochas.json
stocké dans le dossier /etc/mochas
.
Je pense qu'il n'est pas nécessaire d'expliquer la structure et le contenu de ce fichier. Le seul ajout par rapport au paramètres constants dans mochadad.py
est LOGLEVEL
qui peut prendre une de trois valeurs: error
, info
ou debug
avec error
comme choix typique en temps normal et info
si l'on rencontre des problème ou debug
pour obtenir encore plus d'information.
Enfin, il fallait créer un fichier de service qui est enregistré dans le dossier /etc/systemd/system
.
Le type de service est fixé sur exec
puisque c'est ce qui est recommandé dans la documentation de systemd. J'ai rajouté l'enregistrement StandardError=null
dans la section [Service]
. C'est quelque chose qu'on voit rarement dans les exemples présentés dans les tutoriels. La raison est que les messages envoyés au journal apparaissaient deux fois. Je pense qu'il serait possible de stopper ce comportement avec le module logger
plutôt que syslog
, mais ce sera quelque chose à voir éventuellement.
L'enregistrement ExecStart=/usr/local/bin/mochas &
est essentiel, mais on comprend facilement ce qu'il fait. Dans une session j'ai lancé l'affichage du journal en temps réel, puis dans une autre session j'ai démarré le service mochas
.
On peut donc suivre le démarrage de mochas
et le voir à l'oeuvre alors que j'ajustais l'intensité d'un gradateur.
Notons que mochas
n'a rencontré aucun problème puisque mochad
était déjà en marche. Quand le Raspberry Pi redémarre, ce n'est pas aussi simple. Voici les enregistrements du journal du système au sujet de mochad
et mochas
lors d'un démarrage du Raspberry Pi.
Le logiciel d'initialisation systemd
essaye de démarrer tous les services en parallèle pour accéléré le lancement du système d'exploitation. En même temps, on peut ordonner le démarrage des services avec des options dans le fichier de service. C'est le but des enregistrements WantedBy=multi-user.target
, Requires=mochad
et After=multi-user.target mochad.service
. Effectivement, mochas
n'est démarré qu'après l'activation du service mochad
. Toutefois, mochas
est arrêté à 12:10:25 et 12:10:38. Je suppose que la raison est que mochad
n'est pas encore connecté au CM19A et qu'il est conséquemment impossible de se connecter à son port TCP. Or parmi les paramètres du fichier de service de mochas
on retrouve les enregistrements RestartSec=5
et Restart=always
. Les conséquences sont que le service sera automatiquement redémarré toutes les 5 secondes s'il est arrêté. Après deux tentatives, mochas
est enfin connecté à mochad
. Voilà pourquoi il n'a pas été nécessaire de créer la boucle pour repartir le service dans le script que j'avais mentionnée auparavant.
Vérification faite, il semble que mochad
et mochas
sont en mesure de fonctionner correctement après la déconnexion du CM19A puis son rebranchement sur le Raspberry Pi. En d'autres mots, cette configuration des services est robuste. Ceci étant dit, je suis certain que ce premier exercice à écrire un fichier de service systemd
pour un script Python3 laisse à désiré. Toutes suggestions pour améliorer le code sont bienvenues.
Version 0.5 de mochas
Par défaut, mochas
suppose que les paramètres de sécurité du serveur domotique sont fixés au niveau le plus faible possible. Aucun nom d'utilisateur ni mot de passe n'est fourni lors de l'utilisation de l'API de Domoticz et il n'y aucun chiffrement des requêtes HTTP qui sont donc en texte brut. Nous avons déjà vu que pour que cela fonctionne, Domoticz et mochas
doivent être sur le même sous-réseau qui, à son tour, doit être inclus dans les réseaux de confiance
dans les paramètres de sécurité (Configuration / Paramètres / Sécurité) de Domoticz.
Avec la version 0.5 de mochas
(disponible sur le référentiel), l'addiciel n'a plus besoin d'être sur un réseau de confiance. Dans ce cas, les requêtes HTTP ou HTTPS envoyées à Domoticz doivent contenir le nom et le mot de passe d'un utilisateur de Domoticz disposant des droits d'administrateur. Les informations d'identification doivent être combiné en une seule chaine: "nom_d'utilisateur:mot_de_passe"
. Cette chaîne (sans les guillemets) doit être codée en base64 et ajouté dans l'entête de la requête. Si cette chaîne codée est spécifiée dans le fichier de configuration de mochas
, elle sera automatiquement utilisée. Cependant, les requêtes HTTP non sécurisées ne provenant pas d'un réseau de confiance seront ignorées par Domoticz par défaut. Pour modifier ce comportement il faut cocher
[ ] autoriser l'authentification Basic-Auth sur du pur HTTP (API seulement)
dans la section Protection API:
des paramètres de sécurité de Domoticz directement au dessus des réseaux de confiance
dans Configuration / Paramètres / Sécurité).
En aucun cas, l’encodage base64 ne doit être considéré comme sécurisé. On vérifie facilement qu'un chaîne codée comme cG9uZG1pc3Q6c2VhYnJlYXpl
correspond à la chaîne pondmist:seabreaze
. Par conséquent, si cette option est utilisée avec des requêtes HTTP, cela revient à envoyer les informations d'identification sous forme de texte brut dans un en-tête HTTP.
Heureusement, à partir de la version 0.5, les requêtes HTTP sécurisées peuvent être activées dans mochas
. Il suffit de définir la valeur d'un nouveau paramètre dans le fichier de configuration mochas.json
. Toutefois, il y a une complication. Le certificat numérique fourni avec Domoticz étant autosigné, la vérification échouera à moins que le certificat autosigné soit remplacé par un certificat d'une autorité reconnue ou que la vérification de l'autorité de certification soit désactivée. Encore une fois, un nouveau paramètre dans le fichier de configuration contrôle ce comportement.
Voici le modèle du fichier de configuration pour la version 0.5 de mochas
qui devra être adapté à la situation locale.
Comme on peut voir il contient trois nouveaux paramètres qui sont toutefois facultatifs.
Type | Clé | Valeur |
---|---|---|
o | LOGLEVEL | niveau des messages affichés dans le journal, l'un des suivants : "erreur", "info" ou "debug". |
o | HOST | l'adresse IP de mochad . |
o | PORT | le port TCP de mochad . Cette valeur est codée en dur dans la source mochad donc peu susceptible de changer. |
o | HOUSE | Code maison X10 surveillé, une lettre de « A » à « P ». |
o | DELTA | Valeur absolue du changement du niveau de lumière à appliquer lors de la réception d'un paquet Dim ou Bright. Le niveau de lumière est un entier compris entre 0 et 100, la valeur delta doit donc être considérablement inférieure à 50 et bien sûr supérieure à 0. |
f | CREDS64 | Informations d'identification "utilisateur: mot de passe" encodées en base64 d'un utilisateur Domoticz avec des droits d'administrateur. Valeur par défaut : "" (aucun). |
f | TLS | Si true alors le protocole sécurisé HTTPS avec données chiffrées est utilisé, si false le protocole HTTP avec données en texte brut est utilisé. Le port TCP spécifié dans la valeur de DOMOTICZ doit être correct. Valeur par défaut: false . |
f | VERIFY | Lorsque cela est vrai, le certificat numérique renvoyé par Domoticz sera vérifié. Cette valeur devra être explicitement définie sur false si le certificat autosigné fourni avec Domoticz n'a pas été remplacé par un certificat d'une autorité de certification reconnue. Cette valeur est ignorée si TLS est false . Valeur par défaut: true . |
o | DOMOTICZ | Adresse IP et port TCP de Domoticz. Il n'y a pas de valeur par défaut pour le port et il doit correspondre au protocole HTTP non sécurisé ou au protocole HTTPS sécurisé selon la valeur du paramètre TLS . |
o | DEVICES | Carte des paires clé:valeur où la clé est une chaîne représentant un numéro d'unité X10 (de "1" à "16") et sa valeur est le numéro d'identité (idx ) du dispositif Domoticz contrôlant un gradateur. |
La colonne Type indique si une entrée est obligatoire (o) ou facultative (f). La valeur par défaut sera utilisée si la valeur facultative n'est pas présente. La présence des clés obligatoires est vérifiée au chargement du fichier de configuration. Aucun contrôle de validité des valeurs est faite à ce moment-là.
Pour résumer,
- Si le fichier de configuration ne contient pas les enregistrements
CREDS64
,TLS
etVERIFY
, alors la version 0.5 demochas
se comporte exactement comme la version 0.4. Il faudra quemochas
soit membre d'un réseau de confiance de Domoticz. Dès lors, tout autre appareil sur le réseau de confiance peut accéder à l'API de Domoticz. - Si l'API de Domoticz ne doit être accessible qu'avec un nom d'utilisateur et mot de passe, il ne faut pas spécifier de réseau de confiance et il faut ajouter la clé
"CRED64": "nom_d'utilisateur:mot_de_passe"
où la chaîne valeur, encodé - Le protocole sécurisé HTTPS est utilisé si l'enregistrement
"TLS" : true
est contenu dans le fichier de configuration.- Si
"VERIFY": true
alorsmochas
vérifie que le certificat digital provenant de Domoticz provient d'une autorité reconnue et si ce n'est pas le cas, aucune requête ne sera acheminée vers le serveur. Or Domoticz est installé avec un certificat autosigné quemochas
n'accepte pas. - Si
"VERIFY": false
alorsmochas
ne vérifie pas le certificat provenant de Domoticz et lui achemine les requêtes HTTPS sans problème.
- Si
Sans aucun doute, il y a eu une grande amélioration de la sécurité dans Domoticz depuis la version 2023.1. Inévitablement, cette plus grande sécurité s'achète au prix de complications dont je n'ai pas encore saisi l'étendue complète.