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-perlet 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