Sunday, 9 October 2016

MQTT bi-directional communications in PERL

In attempting to interface openHab with my Comfort system, I needed to adapt an existing Perl linux driver for Comfort to work in Windows. The idea is that a small Perl program manages serial communications with the Comfort system and uses the IoT protocol MQTT to pass messages back and forth with openHab.

In doing so, I found that there was a very limited amount of information on integrating MQTT with Perl. There is a minimal MQTT interface for Perl that does the trick but the sample code was not obvious to me and there's very little else out there.

I've written a vey basic Perl <-> MQTT program to show how basic input and output is achieved.

It's my reference for future  use and maybe it will be helpful to someone else sometime;


use Net::MQTT::Simple;
use strict;
use warnings;

#Set Up MQTT server and channel details
my $mqtt_hostname = '';
my $mqtt_input = "test/to";
my $mqtt_output = "test/from";

#instantiate the MQTT connection
my $mqtt = Net::MQTT::Simple->new($mqtt_hostname);

#subscribe to the input channel
#direct incoming messages to the callback function

while(1) { #main loop
    #$mqtt->tick(1); #check MQTT with a 1 second timeout

sub callback {#function to handle incoming MQTT messages
  my ($topic, $message) = @_; #take the incoming message data
  my $res = "got message: $message"; #store the message in a result string
  print STDERR $res."\n"; #print to console for debugging
  $mqtt->publish($mqtt_output => $res); #send the result string back to MQTT

The key element here is inclusion of the #$mqtt->tick(1); call in the main loop. This is what polls MQTT and is missing from the MQTT interface sample code.

You can test running the above in Perl and then entering the following in another terminal window (or on a different machine). Obviously, change the IP and Port of your Mosquitto server;

mosquito_pub -h -p 1883 -t test/to -m “Hello World”

You should see the 'Hello World' message appear on the console running the above program and have the message returned to the specified output MQTT channel. I used node-red to monitor the MQTT channels I was testing;

No comments: