Le boîtier RFXCOM, en version LAN (connecté par prise RJ-45 et non par USB), modèle RFXCOM Récepteur LAN RF 433.92 + 310-Mhz, 1 interface COM
que j’avais acheté en 2008 traînait depuis quelques temps dans un placard, n’étant pas compatible avec OpenHAB 1.x. La version 2.0.x a apporté une compatibilité partielle, actuellement cassée en version 2.1.x.
Afin de recabler ces sondes en y passant le moins de temps possible, il a donc été nécessaire de reconfigurer un hub xPL et d’ajouter un script PERL pour convertir les événements xPL en topics MQTT, auxquels OpenHAB sera abonné.
Installation
Construction du container :
- on part d’une base ALPINE embarquant déjà une installation de PERL + CPAN
- on installe et on compile le package
xpl-perl
et ses dépendances - la configuration provient de variables d’environnement (utilisées par le shell et le perl lancés au démarrage), et peuvent se surcharger au lancement du container via
-e
le script de démarrage est chargé de lancer :
- le hub xPL
- le script
xpl-perl-rx
(réceptions d’événements RFXCOM et émission de ces derniers en tant que messages xPL) - un script PERL créé pour l’occasion, chargé de réceptionner ces événements xPL et de les forwarder en MQTT.
Plusieurs alternatives auraient pu être envisagées mais se sont révèlent toutes problématiques :
- intégration directe du RFXCOM en version LAN dans OpenHAB : actuellement impossible (voir : )
- intégration directe du hub xPL dans OpenHAB : le binding xPL n’a jamais été porté en version OpenHAB 2.x
- création d’un script PERL qui lirait les événements RFXCOM et les forwarderait directement vers OpenHAB, sans passer par la couche xPL (la couche xPL n’apporte ici rien du tout !) : serait tout à fait possible, mais me semblait un peu plus de taf niveau écriture (pour la partie lecture des événements xPL / conversion des trames)
Le container se crée à l’aide du Dockerfile suivant :
FROM scottw/alpine-perl
ENV XPL_HOSTNAME "xpl2mqtt"
ENV MQTT_INTERFACE eth0
ENV MQTT_HOSTNAME 192.168.8.4
ENV MQTT_PORT 1883
ENV RFXCOM_HOSTNAME 192.168.8.13
ENV RFXCOM_PORT 10001
ADD start.sh /opt/
ADD xpl-to-mqtt.pl /opt/
CMD /opt/start.sh
RUN apk update && apk add git curl tar bash make perl && \
cd /opt && \
git clone https://github.com/beanz/xpl-perl && \
cd xpl-perl && cpan install YAML::Syck AnyEvent Date::Parse Module::Pluggable Sub::Name AnyEvent::RFXCOM::RX AnyEvent::MQTT && \
perl Makefile.PL && make && make install && \
chmod a+x /opt/*.sh
WORKDIR /opt/
Les commandes xpl
pour 1) démarrer le hub, 2) éventuellement démarrer le logger (debug), 3) démarrer la connexion sur le RFXCOM sont :
xpl-hub -i ${MQTT_INTERFACE} --define broadcast=0.0.0.0 -v &
# xpl-logger -i ${MQTT_INTERFACE} --define broadcast=0.0.0.0 -v &
xpl-rfxcom-rx -i ${MQTT_INTERFACE} --define broadcast=255.255.255.255 -v --rfxcom-rx-verbose --rfxcom-rx-baud 9600 --rfxcom-rx-tty ${RFXCOM_HOSTNAME}:${RFXCOM_PORT}
Le container se lance classiquement via :
docker run -d --restart=always -v $(realpath /etc/localtime):/etc/localtime:ro -v /home/datas/docker-config/openhab2/etc/timezone:/etc/timezone:ro --name xpl-to-mqtt xpl-to-mqtt
Script PERL
Ce script reçoit les événements XPL et les republie vers MQTT.
L’usage de Net::MQTT::Simple
entraînait des disconnect continus côté broker (mosquitto) (peut-être lié à l’absence de keep-alive), même si la reconnexion se faisait proprement, le switch sur AnyEvent::MQTT
semblait dès lors préférable.
#!/usr/bin/perl -w
print("xpl-to-mqtt starting ...\n");
use strict;
use warnings;
use diagnostics;
use Getopt::Long;
use Pod::Usage;
use xPL::Client;
use AnyEvent::MQTT;
my %args = ( vendor_id => 'bnz', device_id => 'listener', );
my %opt = ();
my $verbose;
my $interface;
my $help;
GetOptions('verbose+' => \$verbose, 'interface=s' => \$interface, 'define=s' => \%opt, 'help|?|h' => \$help, ) or pod2usage(2);
$args{'interface'} = $interface if ($interface);
$args{'verbose'} = $verbose if ($verbose);
# Create an xPL Client object
my $mqtt = AnyEvent::MQTT->new("host" => $ENV{'MQTT_HOSTNAME'}, "port" => $ENV{'MQTT_PORT'}); # keep-alive can be customized as an additional parameter, see documentation
my $xpl = xPL::Client->new(%args, %opt) or die "Failed to create xPL::Client\n";
# Add a callback to receive all incoming xPL messages
$xpl->add_xpl_callback(id => "logger", self_skip => 0, targetted => 0, callback => \&log, filter => "@ARGV");
# Run the main loop
$xpl->main_loop();
# The callback to log the incoming messages
sub log {
my %p = @_;
my $msg = $p{message};
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
# Ex. de trame : xpl-stat/sensor.basic: bnz-rfxcomrx.bd5520524470 -> * thgr228n.4d/temp/15.6
my ($ligne) = $msg->summary;
if ($ligne =~ m/hbeat/) {
print "Skipping heartbeat \n";
} else {
print "About to process [$ligne]\n";
$ligne =~ m/.*\> \* (.*)/;
my $id;
my $attribute;
my $value;
my $dummy;
($id, $attribute, $value, $dummy) = split /\//, $1, 4;
# print " id [$id]\n";
# print " att [$attribute]\n";
# print " value [$value]\n";
# if (defined $dummy) {
# print " misc [$dummy]\n";
# }
my $final_id = $id =~ s/\./\//r;
my $topic = "metrics/rfxcom/$final_id/$attribute";
print " => pushing on [$topic], value [$value]\n";
# $mqtt->publish("$topic", "$value");
my $cv = $mqtt->publish(message => $value, topic => $topic, qos => 1);
$cv->recv; # sent
}
}
Troubleshooting
Messages non correctement décodés
Essayer de procéder à un reset de la configuration du RFXLAN : telnet <hostname> 9999
(setup mode).
# telnet 192.168.8.13 9999
Trying 192.168.8.13...
Connected to 192.168.8.13.
Escape character is '^]'.
MAC address 00204A9768C6
Software version V6.5.0.4 (070531)
Press Enter for Setup Mode
*** basic parameters
Hardware: Ethernet TPI
IP addr - 0.0.0.0/DHCP/BOOTP/AutoIP, no gateway set
DHCP device name : not set
*** Security
Telnet Setup is enabled
TFTP Download is enabled
Port 77FEh is enabled
ECHO is disabled
Enhanced Password is disabled
Port 77F0h is enabled
*** Channel 1
Baudrate 4800, I/F Mode 4C, Flow 00
Port 10001
Connect Mode : C0
Send '+++' in Modem Mode enabled
Show IP addr after 'RING' enabled
Auto increment source port disabled
Remote IP Adr: --- none ---, Port 00000
Disconn Mode : 00
Flush Mode : 00
*** Expert
TCP Keepalive : 45s
ARP cache timeout: 600s
Monitor Mode @ bootup : enabled
MTU Size: 1400
Alternate MAC: disabled
Ethernet connection type: auto-negotiate
Change Setup:
0 Server
1 Channel 1
5 Expert
6 Security
7 Defaults
8 Exit without save
9 Save and exit Your choice ?
Liens :
- http://www.connectingstuff.net/blog/decodage-des-protocoles-oregon-scientific-sur-arduino-2/
- https://metacpan.org/pod/Device::RFXCOM::Decoder::Oregon
- http://www.nas-forum.com/forum/topic/23019-lancement-xpl-hub-xpl-rfxcom-rx-xpl-logger/?page=13
- http://xplproject.org.uk/forums/viewtopic.php?f=1&t=1106
- https://github.com/beanz/xpl-perl/blob/master/bin/xpl-sender
- http://vesta.homelinux.free.fr/wiki/pluviometre_x10_rf.html
- http://vesta.homelinux.free.fr/wiki/xpl.html
- https://github.com/beanz/xpl-perl