Commandes RF pour Domoticz via rtl_433
Cet article est une variante de la méthode exposée dans l’article Commandez vos lumières avec des interrupteurs RF sous Domoticz qui utilise une clé RTL-SDR au lieu d’un récepteur RFLink.
Matériel
Dans cet article, le récepteur sera un récepteur RTL-SDR, c’est-à-dire un récepteur radio à décodage logiciel (SDR: Software Defined Radio) basé sur le chipset RTL2832U (exemple ici sur AliExpress), pour environ entre 10 et 50 euros selon la qualité. L’avantage de ce matériel est qu’il n’est pas spécialisé à la réception 433MHz et peut être utilisé sur plein d’autres projets (comme dans cet article pour analyser le signal d’une télécommande mais également pour recevoir la radio, la TNT, et même les signaux des avions.
Le modèle d’interrupteur reste le même (interrupteur RF mural 433, ou également des télécommandes RF “universelles”)
Vous pourrez ensuite paramétrer n’importe quelle action dans Domoticz. Dans mon cas cela commandera des bandeaux LED, mais ça pourrait être n’importe quoi d’autre.
Paramétrage de rtl_433
Installation et premier essai
Pour décoder les signaux de la télécommande nous allons utiliser l’excellent rtl_433. Il est disponible dans de nombreuses distributions, (sudo apt install rtl-433
sous Debian/Ubuntu) mais comme il est régulièrement mis à jour avec de nouveaux appareils, cela peut être intéressant de l’installer manuellement (voir docs/BUILDING.md pour les quelques étapes à suivre pour compiler avec cmake)
Par défaut, si on lance simplement rtl_433
et qu’on appuie sur un bouton de l’interrupteur, rtl_433 va bien reconnaitre un signal, mais va l’interpréter comme un signal d’un détecteur de fumée (Smoke GS558):
time : 2023-05-01 15:39:52
model : Smoke-GS558 id : 32369
unit : 11 learn : 0 Raw Code : 4fce2b
Décoder le protocole EV1527
Dans l’absolu pour simplement détecter le signal ça pourrait être suffisant, mais pour l’intégration classique de rtl_433 dans Domoticz, il va être nécessaire d’avoir la définition d’un interrupteur (Generic Remote). Après quelques tentatives infructueuses, j’ai enfin repéré que la description de certains interrupteurs muraux ou télécommandes universelles mentionnaient l’utilisation de EV1527. Il s’agit d’une puce qui se charge du décodage/encodage de signaux 433 Mhz, avec un protocole qui lui est propre. La bonne nouvelle est que rtl_433 comporte déjà des définitions permettant de décoder EV1527.
On va donc simplement désactiver la reconnaissance du protocole du détecteur de fumée pour voir s’il devient reconnu comme télécommande : rtl_433 -R-86
(-R
est l’option de sélection de protocoles, -86
pour désactiver le protocole 86 qui correspond au détecteur de fumée, trouvé dans la liste que l’on obtient avec rtl_433 -R
). Malheureusement, pour une raison qui m’échappe, le protocole générique ne semble pas reconnaître l’interrupteur.
Il existe cependant d’autres solutions dans rtl_433, dont notamment le fichier EV1527-4Button-Universal-Remote.conf dont le nom est très prometteur. Il s’agit de la configuration d’un récepteur très générique flex et qui peut être paramétré dans le fichier de configuration de rtl_433, ou en ligne de commande via l’argument -X
(en agrégeant toutes les lignes de l’intérieur des accolades sur une seule)
$ rtl_433 -R-86 -X 'n=EV1527-Remote,m=OOK_PWM,s=369,l=1072,g=1400,r=12840,bits>=24,repeats>=3,invert,get=@0:{20}:code:[123456:REMOTE-A 987654:REMOTE-B],get=@20:{4}:button:[1:A 2:B 3:AB 4:C 5:AC 6:BC 7:ABC 8:D 9:AD 10:BD 11:ABD 12:CD 13:ACD 14:BCD 15:ALL],unique' -F json
...
{"time" : "2023-05-01 15:43:32", "model" : "EV1527-Remote", "count" : 6, "num_rows" : 7, "len" : 25, "data" : "d473f10", "code" : 870207, "button" : "A"}
Adapter la sortie pour Domoticz
Notre interrupteur est maintenant correctement reconnu par rtl_433, mais nous ne sommes pas au bouts de nos efforts car l’intégration Domoticz nécessite la présence de champs particuliers que nous pouvons voir dans le fichier du hardware Domoticz Rtl433.cpp :
- il faut un champ
id
pour identifier l’interrupteur - si on veut que chaque bouton corresponde à un interrupteur distinct dans Domoticz, il faut également un champ
channel
- et l’appui doit correspondre à un champ
command=On
Par chance, le décodeur flex
utilisé est très configurable et va nous permettre d’ajouter ces fonctionnalités ; la lecture du code de flex.c permet de comprendre la syntaxe utilisée, dont je n’ai pas trouvé la documentation ailleurs ; ainsi dans l’extrait ci-dessus get=@20:{4}:button:[1:A 2:B 3:AB 4:C 5:AC 6:BC 7:ABC 8:D 9:AD 10:BD 11:ABD 12:CD 13:ACD 14:BCD 15:ALL]
correspond à une commande get
dont les paramètres, séparés par :
(l’ordre n’est pas important)
@20
indique la sélection des bits à partir du 20ème bit{4}
indique qu’une longueur de 4 bits sera sélectionnéebutton
indique que le paramètre de sortie sera nommé button[1:A 2:B 3:AB 4:C 5:AC 6:BC 7:ABC 8:D 9:AD 10:BD 11:ABD 12:CD 13:ACD 14:BCD 15:ALL]
indique un mapping optionnel entre la valeur lue et celle qui sera dans le message de sortie (liste<valeur lue>:<valeur de sortie>
séparée par des espaces et entre crochets)
Ainsi pour satisfaire aux exigences de Domoticz, nous allons modifier le paramétrage du décodeur flex comme suit:
code
est à renommer enid
button
est à renommer enchannel
- nous allons ajouter
param=On
en utilisant les fonctionnalités de mapping deget
sur n’importe quel bit dont les valeurs 0 et 1 seront mappées sur On :get:@0:{1}:command:[0=On 1=On]
Encore une petite contrainte Domoticz, la méthode de protection contre les attaques via arguments de ligne de commande est un peu brutale et va remplacer notamment '
et /
; cela ne nous permet donc ni de passer notre décodeur directement dans le paramétrage de rtl_433 du hardware, ni d’indiquer un chemin vers un fichier de configuration spécifique. Nous allons donc ajouter notre décodeur dans un des emplacements de configuration par défaut, dans /etc/rtl_433/rtl_433.conf
pour ma part :
decoder {
n=EV1527-Remote,
m=OOK_PWM,
s=369,
l=1072,
g=1400,
r=12840,
bits>=24,
repeats>=3,
invert,
get=@0:{20}:id,
get=@20:{4}:channel,
unique,
get=command:@0:{1}:[0:On 1:On]
}
C’est fini coté rtl_433, il reste un peu de boulot dans Domoticz.
Paramétrage de Domoticz
Installation du matériel Domoticz rtl_433
Dans l’onglet Hardware, ajouter un équipement de type “Rtl433” et ajouter dans les paramètres la désactivation du protocole Smoke-GS558 -R-86
(sauf si vous l’avez également inclus dans le fichier de configuration).
Ajout des interrupteurs
Appuyez sur chacun des boutons que vous voulez ajouter. Puis dans l’écran “Device” de Domoticz, vous allez voir les nouvelles entrées détectées :
Cliquez sur la flèche verte sur la droite pour ajouter le bouton. Le bouton va être ajouté dans l’onglet “Interrupteurs” et prendre par défaut l’apparence d’une ampoule allumée.
Cependant l’interrupteur ne peut pas encore fonctionner pour l’instant à cause d’une petite subtilité avec l’interface de rtl_433 qui ne permet pas d’envoyer une commande qui correspond déjà au statut de l’appareil. Or les interrupteurs que j’ai choisi sont des boutons poussoirs qui vont toujours envoyer une commande ‘On’. Le fautif est le code Rtl433.cpp utilise la fonction SendSwitch qui vérifie l’état avant de lancer la commande ; il faudrait remplacer par la fonction SendSwitchUnchecked qui ne réalise pas cette vérification.
Palliatif pour forcer le changement de statut
Pour pallier ce fonctionnement actuel, on va créer deux scripts qui vont forcer le retour à l’état ‘Off’ des interrupteurs :
- un premier va régulièrement forcer tous les interrupteurs RF à Off
- un second va immédiatement forcer l’interrupteur à actionner à Off
On pourrait se contenter du premier, mais cela ne permettrait pas des appels multiples rapprochés, par exemple pour sélectionner un type d’éclairage par appui successifs. Ou également se contenter du second, en forçant tous les interrupteurs Off à chaque fois, mais on a besoin au moins une première fois du premier pour réinitialiser le statut.
Pour fonctionner avec ces scripts, tous les switchs RF doivent être nommés avec le préfixe “RFSwitch” (par exemple “RFSwitch Salon bouton Gauche”)
Dans le menu Configuration / Plus d’options / Evènements, créeé un script dzVents “RFSwitch Reset All” :
return {
on = { timer = { 'every minutes' } },
execute = function(domoticz, triggeredItem, info)
domoticz.devices().forEach(function(device)
if (device.name:match("RF ?Switch.*")) then
if device.state ~= "Off" then
domoticz.log('Reset ' .. device.name)
device.updateQuiet('Off')
end
end
end)
end
}
Ce script va tourner toutes les minutes et forcer la réinitialisation à ‘Off’ des interrupteurs ayant le préfixe “RFSwitch” (ou “RF Switch”). Une fois réinitialisés, lorsque vous appuierez sur un interrupteur lvous verrez passer l’évènement dans Domoticz et l’ampoule passer au jaune (temporairement).
Le deuxième script force la réinitialisation immédiate après le passage à ‘On’ ; vous ne verrez donc plus l’ampoule jaune, mais l’évènement sera bien utilisable dans Domoticz. Dans le menu Configuration / Plus d’options / Evènements, créeé un script dzVents “RFSwitch Reset” :
return {
on = {devices = {'RFSwitch*' },},
execute = function(domoticz, triggeredItem, info)
if triggeredItem.state ~= "Off" then
triggeredItem.updateQuiet('Off')
end
end
}
Script pour réaliser les actions souhaitées pour chaque bouton
Maintenant que nous avons dans Domoticz l’évènement correspondant à l’appui sur l’interrupteur RF, nous pouvons lui faire faire n’importe quoi, en Blockly, ou via script. Voici un exemple en dzVents, correspondant à la commande d’un bandeau LED : un premier appui va allumer ou éteindre, et un appui successif va changer la luminosité:
return {
on = { devices = { 'RFSwitch Salon'},},
logging = {level = domoticz.LOG_INFO, marker = "RFSalon" },
execute = function(domoticz, triggeredItem, info)
local led = domoticz.devices('LED Salon')
local cycleTimeSeconds = 5
if ((led.lastUpdate.secondsAgo > cycleTimeSeconds) or (not led.active)) then
led.toggleSwitch()
else
if (led.level == 100) then
led.dimTo(75)
elseif (led.level == 75) then
led.dimTo(50)
elseif (led.level == 50) then
led.dimTo(25)
else
led.dimTo(100)
end
end
end
}