Publishing RFXmeter power sensor data to MQTT

More hunting around for helpful modules led me to believe that the easiest way to get data from my RFXmeter sensors into MQTT/mosquitto so it can be read by emoncms was to stick with Perl and use the Device::RFXCOM and Net::MQTT::Simple modules from CPAN. Had there been suitable Python modules available for handling RFXmeter devices I might have gone that way, but at the moment I’m not really of a mind to fix the broken one I found.

It didn’t take much coding effort to come up with this:

!/usr/bin/perl

use warnings;
use strict;
use Device::RFXCOM::RX;
use Net::MQTT::Simple;

my $DEVICE             = '/dev/ttyUSB0';
my $MQTT_HOST          = '<ip-address>';
my $MQTT_PORT          = 1883;
my $MQTT_USER          = 'power';
my $MQTT_PASS          = '<password>';
my $SENSORS_PER_METER  = 3;

# Allow unencrypted connection with credentials
$ENV{MQTT_SIMPLE_ALLOW_INSECURE_LOGIN} = 1;

my $mqtt;

sub
cleanUp
{
  $mqtt->disconnect();
  die "Quitting... $!";
}

my $rx = Device::RFXCOM::RX->new ( device => $DEVICE );

$mqtt = Net::MQTT::Simple->new ( "$MQTT_HOST:$MQTT_PORT" );
$SIG{INT} = \&cleanUp;
$SIG{TERM} = \&cleanUp;

$mqtt->login ( $MQTT_USER, $MQTT_PASS );

while (1) {
  my $data = $rx->read() or next;
  if ( !$data->duplicate ) {
    if ( $data->type eq 'rfxmeter' ) {

      # I'm expecting something like:
      #
      # 'messages' => [
      #   bless( {
      #     'measurement' => 'count',
      #     'device' => 'rfxmeter.02f2',
      #     'value' => 448770
      #   }, 'Device::RFXCOM::Response::Sensor' )
      # ],

      foreach my $msg ( @{$data->messages} ) {
        if ( $msg->{measurement} eq 'count' ) {
          if ( $msg->{device} =~ /rfxmeter.([0-9a-f]{2})[0-9a-f]{2}/ ) {
            # this works for me because my sensors appear to be numbered
            # 00f0, 01f1, 02f2, 03f3 and 04f4, the first three being on the
            # first RFXmeter and the last two being on the second.
            my $sensorNum = hex ( $1 );
            my $meterNum = int ( $sensorNum / $SENSORS_PER_METER ) + 1;
            $sensorNum %= $SENSORS_PER_METER;
            my $sensorName = "rfxmeter$meterNum-$sensorNum";
            $mqtt->publish ( "sensors/$sensorName/count", $msg->{value} );
          } else {
            print "failed match\n";
          }
        }
      }
    }
  }
}

If I connect to mosquitto in another window, using:

mosquitto_sub -h <ip-address> -v -t sensors/#

and run the above script, I get output of the form:

sensors/rfxmeter1-0/count 784628
sensors/rfxmeter1-1/count 373203
sensors/rfxmeter1-2/count 451528
sensors/rfxmeter1-0/count 784648
sensors/rfxmeter1-1/count 373213
sensors/rfxmeter1-2/count 451536
sensors/rfxmeter2-0/count 0
sensors/rfxmeter2-1/count 43623

which looks good to me.

Now I need to go back to emoncms and see if I can confirm that it is picking up the same data, but first I shall rename the sensors as I suggested towards the end of my previous post on this topic.

This entry was posted in Computing and tagged , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *