Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Comfort to MQTT
#11
I managed to get comfort talking to Mqtt and node-red via ucm/232 and a usb/serial convertor. Works great both to and from.

It\'s on Windows though so I needed to completely re-write the perl driver to work. I\'ll share it here when I\'ve got it refined.
Reply
#12
[user=5265]meep[/user] wrote:
Quote:I managed to get comfort talking to Mqtt and node-red via ucm/232 and a usb/serial convertor. Works great both to and from.

It\'s on Windows though so I needed to completely re-write the perl driver to work. I\'ll share it here when I\'ve got it refined.
Thanks v.much
Reply
#13
Well, I managed to get this working on windows with Win32::SerialPort in Perl. (just couldn\'t hack the above code to work so started afresh).

It\'s a long way from cab123\'s original driver in terms of code but owes a lot to his concept, structure and techniques. It\'s also got a LOT less error checking implemented so is really just a proof of concept at this stage and would require a few more additions to make it more robust.

While this does send and receive between comfort and MQTT, and you can check these messages in Node-Red, I added a Trace function to allow key messages be printed to the console - really helps with debugging.

Code:
!/usr/bin/perl

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

#hello
print STDERR \"\
\".localtime().\"\
Opening Comfort Communications... \
\";

#Set up & open  port
my $port = Win32::SerialPort->new(\"COM5\") or die \"Failed to open port: $!\
\";
print STDERR \"Port established: $port \
\";

$port->baudrate(9600);
$port->databits(8);
$port->parity(\"none\");
$port->stopbits(1);
$port->handshake(\"xoff\");
$port->write_settings;


#set up mqtt & polling for inbound messages
my $mqtt_hostname = \'192.168.1.199\';
my $mqtt_to_comfort = \"comfort/to\";
my $mqtt_from_comfort = \"comfort/from\";

my $mqtt = Net::MQTT::Simple->new($mqtt_hostname);
$mqtt->subscribe($mqtt_to_comfort,&callback);

#additional control vars
my $serial_stream = \"\"; #container for serial input from comfort
my $ts = time(); #current time
my $defaultreadspeed = 1; #port read interval
my $trace = 1; #enable debug output to console

#setup complete
print STDERR \"Starting to listen...\
\";

while (1) { #main loop

if ( time() - $ts >  $defaultreadspeed ) { #use $defaultreadspeed to throttle

$ts = time(); #set target time for next loop
$serial_stream = $port->read(200);  #read up to 200 bytes from Comfort

if ($serial_stream) { #check if there\'s data read

doTrace (\"received from Comfort: $serial_stream\");
#split the data into an array based on STX or EOL
#remove those extraneous characters from the resulting array elements
my @reports = split /(?:\\x03|\\x0D|\\x0A)/, $serial_stream;

for my $rep (@reports) { #loop through each of the returned strings
if (length($rep)){ #only process non-empty strings
doTrace (\"sending report to MQTT: $rep\");
$mqtt->publish($mqtt_from_comfort => $rep); #send to MQTT
}else{
doTrace(\"empty string, not sending to MQTT\");
}
}

$port->lookclear; #needed to prevent blocking (?)
} #end check if data read

$mqtt->tick(1); #force query MQTT input with 1 second timeout

} #time check
}#while loop



################
##SUBROUTINES##
##############

sub callback { #process inputs from MQTT and send to Comfort
my ($topic, $message) = @_;
doTrace (\"got message from MQTT:  $message\");

$port->lookclear; #needed to prevent blocking (?)
my $str = chr(0x03).$message.\"\\
\"; #prepend STX char and add CR
$port->write($str); #send to Comfort

doTrace (\"sent to Comfort: $str\");
}

sub doTrace { #write trace logs to console
my ($traceString) = @_;

if ($trace){ #only implement if enabled
my $timestamp = getLoggingTime(); #get timestamp
print STDERR \"$timestamp $traceString \
\"; #print to console
}
}

sub getLoggingTime { #compose a decent looking timestamp

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
my $nice_timestamp = sprintf ( \"%04d%02d%02d %02d:%02d:%02d\",
$year+1900,$mon+1,$mday,$hour,$min,$sec);
return $nice_timestamp;
}

This can be tested with something like the command below at the command line. Obviously change your own Mosquito server and port details. (note, you must first issue the login (LI) command to Comfort, with a user code, or it will keep returning \'NA\' as the response);

Code:
mosquito_pub -h 192.168.1.199 -p 1883 -t comfort/to -m \"z?\"

Attached is an example of this running. You can see the initial receipt of the \"z?\" query from MQTT and the response from comfort sent back. Then you can see Comfort reporting activity Input 05 (that\'s the result of me opening and closing a window with a contact sensor).

NB: For some reason, the forum is stripping backslashes from the code segments above. I\'ve tried to add them back in but if you\'re trying to run this and it\'s failing, it mey be due to a missing \'\\\' somewhere.




Attached Files Thumbnail(s)
   
Reply
#14
Hey! I\'m very happy to see you are having fun with this!

I don\'t have much more javascript examples, aside from what i already shared, it\'s pretty basic stuff.

i would recommend you to switch to a linux box for these server-side protocols - they will run forever, will never complain, and be readily available to serve you anytime :-)
A small raspberry Pi is cheap to buy/run and has enough horsepower to do this and much more.
Reply
#15
Cheers, it\'s more getting to grips with node-red and regex to be honest, getting there slowly.

I run all my stuff on a single unraid server through a combination of dockers and vms.

I went with a Windows vm as I needed to pass through the usb/serial adapter and as I\'ll likely need to run comfigurator for a while, thought I\'d go with Windows as I wouldn\'t need to keep swapping connections etc.

Might switch back to a Linux vm as I get more comfortable with it all.

Thanks for the inspiration on this and taking the time to document it here, really helped me realise what I needed to do was possible.
Reply
#16
@cab123

If you\'re still working on this any plans to implement an MQTT broker on the UCM/Pi module?

Obviously one could use the UCM/Eth03 and then link to a standard external Raspberry Pi but would seem to make sense to do the Comfort side of this using the dedicated Pi module.
Reply
#17
The alphaWerk components uses MQTT as their backend & Mosquitto is installed on the CM3. It is locked to localhost only by default but can be opened up to external devices easily.

There is also nothing stopping you from installing different software, hardware notes are available to use your own tools to talk to comfort and manage the watchdog timer.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)