View single post by cab123
 Posted: Monday Feb 8th, 2016 08:13 pm
 PM  Quote  Reply  Full Topic 
cab123

 

Joined: Saturday Oct 3rd, 2009
Location: Coimbra, Portugal
Posts: 25
Status: 
Offline

  back to top

Hi, i would like to share with the community my simple driver implementation of comfort to MQTT.

I have this running for a couple of months and never registered any failure with the communication. MQTT is amazingly light and mature. And my driver seems to be stable enough for the job, had some issues with strange USB resets, but now it gracefully handles every USB quirks i found, including reconnecting the UCM.

This approach provides a simple and flexible way to interact with comfort from/to multiple sources. Personally i have comfort ULTRA, individual power monitoring, solar inverter statistics all feeding data to a MQTT broker. Then I process some of that data in NodeRED and present/control everything in OpenHAB. It works really well.

I do not use the alarm section of comfort, only home automation with push buttons, relays, infrared and some KNX stuff.


Used hardware:
- UCM USB
- A x86 server with Debian Jessie installed (could be a raspberry Pi)



(1)
Connect the UCM/USB to the server and make the USB connection deterministic:

(1.1)
Find the Device / ID / Serial Number of the device:

root@debian:/# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

root@debian:/# lsusb -d 0403:6001 -v | grep iSerial
  iSerial                 3 A7007iyv
 
 

(1.2)
From the output above we get:
- idVendor: 0403
- idProduct: 6001
- Serial Number: A7007iyv

Your data will probabily be the same, except for the unique serial number of your UCM.
Next create a file like the one below and add the right info:

nano /etc/udev/rules.d/99-usb-serial.rules

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A7007iyv", SYMLINK+="comfort"


Now everytime the USB UCM is connected th the server it will be uniquely available at /dev/comfort, regardless of other USB peripherals in the system.

(2)
Install MQTT broker and clients


http://mosquitto.org/2013/01/mosquitto-debian-repository/

for the clients:
sudo apt-get install mosquitto-clients

anoher good reference with some testing:
https://pallavichaurasia94.wordpress.com/2014/10/14/mosquitto-in-debian/



(3)
the script to establish a bridge between Comfort and MQTT:

(3.1)
First install the folloing perl modules:

cpan Net::MQTT::Simple
cpan IO::Select
cpan Time::HiRes


(3.2)
Find a appropriate directory, for example /opt and copy the contents of the script to a new file, for example:

nano simple_mqtt_serial_select.pl

#!/usr/bin/perl

use Net::MQTT::Simple;
use IO::Select;
use Time::HiRes qw(time);
use strict;

#############################################################
###                                                by:APR ###
###                                                       ###
### Perform the following system commands:                ###
### lsusb                                                 ###
### lsusb -d 0403:6001 -v | grep iSerial                  ###
### nano /etc/udev/rules.d/99-usb-serial.rules            ###
### SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A7007iyv", SYMLINK+="comfort"
###                                                       ###
### Change the following lines to suit your configuration ###
###                                                       ###
#############################################################

my $comfort_port = '/dev/comfort';
my $mqtt_hostname = 'localhost';
my $mqtt_to_comfort = "comfort/to";
my $mqtt_from_comfort = "comfort/from";

#############################################################

my $serial_location = "off";
my $serie =  IO::Select->new();

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

my $ts = time();

while(1) {

  if ( time() - $ts > 10 ) { # every 10 secs
    $ts = time();
    my $SL = `ls -al /dev/comfort 2>&1`;
    if( $SL =~ /(comfort -> .+)/ ) { # isconnected
      $SL = $1;
      if ( $serial_location eq "off" ) { # was plugged
        print localtime(time) . " $SL\n";
        $serial_location = $SL;
        open(SERIAL,  "+<$comfort_port") or die "Can't open serial port: $!\n";
        $serie->add(\*SERIAL);
      }
      elsif ( $SL ne $serial_location) { # was restarted
        print localtime(time) . " $SL\n";
        $serial_location = $SL;
        $serie->remove(\*SERIAL);
        close(SERIAL);

        open(SERIAL,  "+<$comfort_port") or die "Can't open serial port: $!\n";
        $serie->add(\*SERIAL);
      }
    }
    else {  # is disconnected
      if($serial_location ne "off") { # was removed
        print localtime(time) . "UCM disconnected\n";
        $serial_location = "off";
        $serie->remove(\*SERIAL);
        close(SERIAL);
      }
    }
  }
  $mqtt->tick(0.1);
  if($serial_location ne "off") {
    if ($serie->can_read(.01)) {
      my $recv = <SERIAL>;
      $recv =~ tr/\x03\x0D\x0A//d;
      $mqtt->publish($mqtt_from_comfort => $recv);
    }
  }
}

sub callback {
  my ($topic, $message) = @_;
  if($serial_location  ne "off") { print SERIAL chr(0x03) . "$message\r\n"; }
  else { $mqtt->publish($mqtt_from_comfort => "OFFLINE"); }
}


To test:
WINDOW_1: run the script

root@debian:/# perl simple_mqtt_serial_select.pl



WINDOW_2: listen for MQTT events

root@debian:/# mosquitto_sub -v -t comfort/#


WINDOW_3: post something to comfort topic MQTT

root@debian:/# mosquitto_pub -t comfort/to -m 'LI1234'


On the WINDOW_2 you should see something like:

comfort/to LI1234
comfort/from LU01


That´s it! Now you can subscribe (listen) or post commands to the MQTT broker and interact with comfort.

Make the script boot at startup by editing the file just before "exit 0"

root@debian:/# nano /etc/rc.local
/usr/bin/perl /opt/simple_mqtt_serial_select.pl &


And now comfort can easily be integrated with other bits of amazing software, like openHAB, NodeRED, etc.


If there is any interest in this i can share some of my NodeRED and OpenHAB integration configuration.


Have fun!

 Close Window