OTmonitor and Domoticz parallel access to OTGW

For OpenTherm-gateway related questions in Domoticz
jake
Posts: 185
Joined: Saturday 30 May 2015 22:40
Target OS: Raspberry Pi
Domoticz version: beta
Contact:

OTmonitor and Domoticz parallel access to OTGW

Postby jake » Saturday 25 June 2016 17:50

After spending half a day by gathering bits and pieces from all over the place, I have OTmonitor and Domoticz running together on a RPI, both having access to the OTGW. I decided to put all information here, also for my own memory in the future :D

I started today by connecting the OTGW-USB to my Windows 10 Machine. Problem 1: USB to serial driver not compatible. I found the solution here http://www.ifamilysoftware.com/news37.html by following all steps.

Since I could read all information from the OpenTherm connection, I was sure that the hardware was OK. Time to move on to the RPI.

I shutdown the RPI, connected the OTGW-USB and started the RPI again.
To install/run the OTmonitor software, I followed the steps of Newwolf in this topic: https://www.domoticz.com/forum/viewtopic.php?f=26&t=211&start=240#p34738
In my case I had to change ttyUSB0 to ttyUSB1

Code: Select all

### Download OTGW
mkdir /home/pi/otgw/
wget -N http://otgw.tclcode.com/download/otmonitor-ahf -P /home/pi/otgw/
chmod +x /home/pi/otgw/otmonitor-ahf

### Make config file

nano /home/pi/otgw/otmonitor.conf

web {
 enable true
 port 8081
 nopass true
}
connection {
 device /dev/ttyUSB0
 type serial
 enable true
}
server {
 enable true
 port 7686
 relay true
}


### Run it
/home/pi/otgw/otmonitor-ahf --daemon -f "/home/pi/otgw/otmonitor.conf" &

### Kill it (if needed)
killall -9 otmonitor-ahf


Connect Domoticz or OTGW-monitor to it's IP-address and port 7686

In any browser the webUI could by started now by this address http:\\RPIaddress\8081
From the Windows 10 machine, with OTmonitor.exe I had to change the connection to TCP connection with as Remote host the RPIaddress and port 7686

In order to restart OTmonitor automatically when the RPI reboots, I didn't follow Newwolf after all, since his suggestion did not auto-start OTmonitor.
I used Supervisor to set it up:

Code: Select all

sudo apt-get install supervisor
### create a config file, I needed sudo to do that
sudo nano /etc/supervisor/conf.d/otmonitor.conf

### paste the following text in there and save/exit with CTRL-X
[program:otmonitor]
command = /home/pi/otgw/otmonitor-ahf --daemon -f "/home/pi/otgw/otmonitor.conf"
directory = /home/pi/otgw/
autostart = true
autorestart = true
stderr_logfile = NONE
stdout_logfile = NONE

###I than did a stop/start of supervisor
sudo service supervisor stop
sudo service supervisor start

###Check if supervisor correctly started otmonitor
sudo supervisorctl status

In Domoticz I turned on "allow new hardware" (first for 5 minutes, but when I had issues, no new devices were created. I therefore enabled new hardware 'permanently'
In Hardware I added the OTGW-LAN device with as address: 127.0.0.1 and port 7686
In the device tab you can find and add your switches, setpoints etc.

2 open issues for me:
- After hours fiddling, I discovered that otmonitor doesn't show any status or summary when the command PS=1 is issued, only when PS=0 is everything showing fine. Domoticz however sets the PS=1 with every action it does. No clue why this happens
- I have the Remeha Gateway in my system to connect the solar boiler to the heating system. I therefore have in the OpenTherm variables also the line: 1D 29 Read Solar storage temperature --- 53.00 I would like to read this in Domoticz very much, but it doesn't show.

User avatar
sincze
Posts: 627
Joined: Monday 02 June 2014 22:46
Target OS: Linux
Domoticz version: 3.6833
Location: Netherlands
Contact:

Re: OTmonitor and Domoticz parallel access to OTGW

Postby sincze » Sunday 26 June 2016 13:48

A yes, I used this solution to monitor my OTGW indeed and push data to domoticz as well.
Runs okay.
PS=1/0 is an issue indeed. In the end I stopped using it as the OTGW was running okay with Domoticz anyway :D
Running Domoticz since 2013 with Cubietruck
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave
WIFI: Mi-light Wifi-Bridge, Sonoff, ESP8266
Sensors: You name it I probably got 1.

Bororo
Posts: 8
Joined: Thursday 09 June 2016 21:06
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: OTmonitor and Domoticz parallel access to OTGW

Postby Bororo » Tuesday 13 September 2016 15:38

Hello,
I have Domoticz running with OTGW LAN device on RaspberryPi3.
My otmonitor-ahf is configured to run as a daemon during startup.
I'm using otmonitor-ahf mainly for sending data to ThingSpeak channel.
I found that if Domoticz is running, my otmonitor-ahf is sending same values to Thingspeak (data are not changing), even in Domoticz I can see changing data e.g. Room Temperature is rising.
Is this bug in Domoticz?
Is there any way how to set-up otmonitor-ahf and Domoticz co-existence?
Many thanks in advance.

jake
Posts: 185
Joined: Saturday 30 May 2015 22:40
Target OS: Raspberry Pi
Domoticz version: beta
Contact:

Re: OTmonitor and Domoticz parallel access to OTGW

Postby jake » Friday 07 October 2016 22:10

It is all about the PS=1 or PS=0. OTMonitor can only work when PS=0 and Domoticz obviously needs PS=1. PS stands for Print Summary. In the state '1' it will print a predefined amount of variables. It seems logical that Domoticz need that and doesn't want to find all the updates in between a lot of unwanted data. Details about the PS info can be found here at the source: http://otgw.tclcode.com/firmware.html#configuration

At the moment I turn on the OTGW in Domoticz, the log stream in OTMonitor stops, but changes to a stream that is updated every 30 seconds by a command PS=1, initiated by Domoticz. The report is long string of those predefined variables. Something that Domoticz cuts into values for the different devices within Domoticz.
Example: 22:15:26.186498 01000000/00000000,6.00,00000001/00000001,100.00,0/0,16.00,0.00,0.00,20.63,23.00,0.00,21.70,22.00,75/20,45/0,47.00,0.00,23210,0,0,11760,29070,4421,1045,4470

ernorv
Posts: 17
Joined: Sunday 13 November 2016 11:42
Target OS: -
Domoticz version:
Contact:

Re: OTmonitor and Domoticz parallel access to OTGW

Postby ernorv » Sunday 13 November 2016 12:02

I actually wanted 2 things to happen while Domoticz is connected:
- otmonitor fully functional (PS=1 and PS=0 dilemma)
- use TC (permanent setting) instead of TT (temporary setting) of the controlled temperature.

Hence I decided to make a small node.js program (you can install node.js on your raspberry if it wasn't already installed).

(code updated, port for otmonitor is now the default otmonitor port, domoticz should be configured to use 7689, also some better suppressions for all the opentherm messages implemented)

-edit 2- code updated after it was running to do even Jake's special change stuff, lots of cleanups in between, and does try to reconnect instead of throwing errors all the time.

Code: Select all

#!/usr/bin/node
/*
Make a small listener that Domoticz can connect to as if it was the real otmonitor application.
Then relay the messages between OTGW and Domoticz such that otmonitor is still fully functional.

author: ernorv

v2.0
   - rewrote the OpenTherm parts to be splitted into separate function
   - added check whether port are actually opened, if no connection to OTGW, wait ten seconds and retry
      this can happen if starting both this script and OTGW, where OTGW needs some time
   - added check if we could open a port for Domoticz, now nicely goes out of the function without throwing an error
   - added specific author section for debugging purposes
   - fieldnumberInPsOutputToReplace was actually off with 1, so now if you set it to 11, it will be 11 according to the list below
   - for older node versions, plug in the repeat function for string.
*/

var portNumberForDomoticzToUse     = 7689;   // The new port that Domoticz needs to use. In Domoticz, set this number as the port under the OTGW hardware
var portNumberOfOtMonitor          = 7686;   // The network port OTGW provides, as can be set under the Configuration parts
const replaceTTwithTC              = true;   // If true: use TC instead of TT (if false, just standard Domoticz TT usage)

// -------------- Normally no further settings required below this line
var resetOTGW_PS_state             = true; // default true: sets the PS state back to 0 after Domoticz has its data, is what allows otmonitor to keep making nice graphs as if Domoticz was not there

// -------------- just if you really know what you do, set these
var replaceAnIdInDomoticzOutput    = false; // default: false! set this to true for replacement of the DHW Setpoing with Solar Temperature
var idToUseForReplacement          = 29;   // (Decimal) ID of the Opentherm message to use. 29 refers to the Solar Boiler Temperature
var fieldnumberInPsOutputToReplace = 11;   // which field to replace in PS output to replace, see numbers below

/*
   The PS1 output has 25 field: see http://otgw.tclcode.com/firmware.html#dataids
   
   The OTGW outputs the following fields (normally that is). I have given them below. Set the 'fieldnumberInPsOutputToReplace' to the
   fieldnumber in accordance with what you like to be replace, given these fields (default is 16):
   
   1)  Status (MsgID=0) - Printed as two 8-bit bitfields
   2)  Control setpoint (MsgID=1) - Printed as a floating point value
   3)  Remote parameter flags (MsgID= 6) - Printed as two 8-bit bitfields
   4)  Maximum relative modulation level (MsgID=14) - Printed as a floating point value
   5)  Boiler capacity and modulation limits (MsgID=15) - Printed as two bytes
   6)  Room Setpoint (MsgID=16) - Printed as a floating point value
   7)  Relative modulation level (MsgID=17) - Printed as a floating point value
   8)  CH water pressure (MsgID=18) - Printed as a floating point value
   9)  Room temperature (MsgID=24) - Printed as a floating point value
   10) Boiler water temperature (MsgID=25) - Printed as a floating point value
   11) DHW temperature (MsgID=26) - Printed as a floating point value
   12) Outside temperature (MsgID=27) - Printed as a floating point value
   13) Return water temperature (MsgID=28) - Printed as a floating point value
   14) DHW setpoint boundaries (MsgID=48) - Printed as two bytes
   15) Max CH setpoint boundaries (MsgID=49) - Printed as two bytes
   16) DHW setpoint (MsgID=56) - Printed as a floating point value
   17) Max CH water setpoint (MsgID=57) - Printed as a floating point value
   18) Burner starts (MsgID=116) - Printed as a decimal value
   19) CH pump starts (MsgID=117) - Printed as a decimal value
   20) DHW pump/valve starts (MsgID=118) - Printed as a decimal value
   21) DHW burner starts (MsgID=119) - Printed as a decimal value
   22)   Burner operation hours (MsgID=120) - Printed as a decimal value
   23)   CH pump operation hours (MsgID=121) - Printed as a decimal value
   24) DHW pump/valve operation hours (MsgID=122) - Printed as a decimal value
   25) DHW burner operation hours (MsgID=123) - Printed as a decimal value
   
*/

// ------------- do not use, specific for author ---------------
var   extraDebug      = false;
const authorOverrides = false; // for anybody out there, keep this to false !!!

if (authorOverrides) {
   portNumberForDomoticzToUse     = 17689;   // for test, do not interrupt normal running process, so throw it somewhere else
   portNumberOfOtMonitor          = 7686;
   resetOTGW_PS_state             = false;   // not to interfere with the actual program already runing
    replaceAnIdInDomoticzOutput    = true;    // default: false! set this to true for replacement of the DHW Setpoing with Solar Temperature
   idToUseForReplacement          = 25;      // (Decimal) ID of the Opentherm message to use. I use 25 for test purposes
   fieldnumberInPsOutputToReplace = 11;      // which field to replace in PS output to replace, see list above
   extraDebug = true;
}


// ----------------------------------------------------------

var net = require('net');
var server
var otgwSocket
var domSocketsArray = [];

// -------------- DEFINE SERVER LISTENING FOR CONNECTIONS FROM DOM ---------------
server = net.createServer(function (socket) {
   console.log('Incoming Domoticz Connection...');
   domSocketsArray.push(socket);
   
   socket.on('data', function (data) {
      data = data.toString(); // data may come in as Buffer
      console.log('DOM: ' + data.replace(/[\r\n]*$/, "").replace(/\r\n/g, ','));
      if (! otgwSocket.destroyed) {
         if (replaceTTwithTC) {
            otgwSocket.write(data.replace("TT=", "TC="));
         } else {
            otgwSocket.write(data);
         };
      }
   });

   socket.on('end', function() {
      console.log('end');
      domSocketsArray.splice(domSocketsArray.indexOf(socket), 1);
   });
   
   socket.on('error', function () {
      console.log('DOM: detected error on socket: probably otgwSocket died');   
      domSocketsArray.splice(domSocketsArray.indexOf(socket), 1);
   });
   
   socket.on('close', function () {
      console.log('DOM: socket closed');
      domSocketsArray.splice(domSocketsArray.indexOf(socket), 1);
   });
});

server.on('error', function(err) {
   console.log('Could not open the port ' + portNumberForDomoticzToUse + ' for Domoticz to connect to.');
   console.log('Please check whether the port is actually free to use, and adapt the "portNumberForDomoticzToUse" in the script.');
   console.log('A common source for this is that one uses the port number of the OTGW instead of a free one.')
   process.exit(1);
});


// ---------------- CONNECT TO OTGW ----------------
function relayToClients(data) {
   for (var i =0 ; i < domSocketsArray.length; i++) {
      if (! domSocketsArray[i].destroyed) {
         domSocketsArray[i].write(data);
      }
   }
}

var resetPS1 = false;
var currentReplacementValue = 0; // init this with 0

function connectToOTGW() {
   
   otgwSocket = net.createConnection({port: portNumberOfOtMonitor}, function() {
     console.log('Connected to OTGW server at port number ' + portNumberOfOtMonitor + '!');
   });

   otgwSocket.on('data', function(data) {
      data = data.toString(); // data comes in as Buffer, we want to use it as string
      
      if (data.match(/[BTARE][0-9ABCDEF,]{8}/)) {
         // this data is not for Domoticz, it is what makes the normal otmonitor app work
         // console.log('<not relayed> OTGW: ' + data.toString().replace("\r", '').replace('\n', ''));
         
         // this data can contain a possible value for replacement purposes, inspect it.
         if (replaceAnIdInDomoticzOutput || extraDebug) {
            var otObj = parseMessage(data);
            if (replaceAnIdInDomoticzOutput && (otObj.readAck || otObj.writeAck) && (otObj.otMsgId == idToUseForReplacement)) {
               currentReplacementValue = (otObj.recognized) ? otObj.valstr : otObj.asFloat.toFixed(2);
               console.log("New replacement value found: (msgid " + otObj.otMsgId + ": '" + otObj.name + "') : " + currentReplacementValue);
            }
         }         
      } else {
         
         console.log('OTGW : ' + data.replace(/[\r\n]*$/, "").replace(/\r\n/g, ','));
         // sometimes there is a PR:,I=00 on the line which ends up in Domoticz status log. It looks like
         // malfomed data coming from the OTGW itself. Let's do some cleaning up, keeping the status log clean
         data = data.replace(/PR:[ ]*,/g, "PR: ");
         data = data.replace(/PR, /g, "PR: ");
         // a difficult one: this happens every so often, a comma missing in the output of the OTGW PS=0 output, let's repair this
         data = data.replace(/([01]{8}\/[01]{8},[0-9\.]{4,6},[01]{8}\/[01]{8})([0-9\.]{4,6}.*)/, "$1,$2");
         
         /* Now we can replace a field in the output to Domoticz with another one, as long as the one to read has also a
          * floating point definition (bit technical, but if you like, google for the specification of the Opentherm itself).
          * This implies that we can only put it into a Domoticz field that also understand this floating point definition.
          * Most temperatures are by the way. Also the (Opentherm ID) needs to be filled in. These are both done above in the
          * const definition section of the script.
          */
         
         if (replaceAnIdInDomoticzOutput) {
            tmp = data.split(',')
            if (tmp.length == 25) { // for the PS1 output we expect 25 fields: see http://otgw.tclcode.com/firmware.html#dataids
               tmp[fieldnumberInPsOutputToReplace-1] = currentReplacementValue;
               data = tmp.join(",");
               console.log("RPLC : " + data.replace(/[\r\n]*$/, ""));
            }
         }
         relayToClients(data);
      }
      
      if (data.indexOf('PS: 1') !== -1 ) {
         // Domoticz is issueing a PS1 command, reset it if indicated by the settings above
         resetPS1 = resetOTGW_PS_state;
      };
      if (resetPS1 && (data.match(/[01]{7,9}\/[01]{7,9},.*/))) {
         // ok the data requested by domoticz has been produced, now go back to normal otmonitor operation
         otgwSocket.write('PS=0\r\n'); // no need to test for destroyed here, data just arrived from it
         resetPS1 = false;
      };
   });

   otgwSocket.on('end', function() {
      console.log('OTGW disconnected from server, reconnecting in 1 second.');
      setTimeout(function() { connectToOTGW(); }, 1000)
   });
   
   otgwSocket.on('error', function(err) {
      console.log('==> Could not connect to the OTGW at port ' + portNumberOfOtMonitor);
      console.log('==> Make sure the OTGW is running and set to provide the port as given above.');
      console.log('==> Will try to reconnect in 10 seconds, maybe OTGW is just starting up here.');
      setTimeout(function() { connectToOTGW(); }, 10000);
   });
   
   otgwSocket.on('close', function() {
      console.log('otgwSocket Close part');
   });
}

//-------------------------- function for extra debug --------------------

// apparently the String.repeat does not always exists, depending on Node version, define one if needed
if (typeof(String.prototype.repeat) == 'undefined') {
    console.log('String.repeat does not exist, adding a prototype definition (normal for older NodeJS versions).');
   String.prototype.repeat = function(n) {
      var tmpstr = "";
      for (var i=0; i < n; i++) tmpstr += this ;
      return tmpstr
   }
}


// the following is a list of already known IDs and how to convert them
// otdef[OTMSGIDasDecimal] = {'readable name', '[asFlags|asFloat|asUInt|asSInt|asFlags]'
var otdef  = {};
otdef[0]   = {name:"Master and slave status flags", val:"asFlags"}; // read ack: slave, read-data: master
otdef[5]   = {name:"Application Specific Flags", val: "asFlags"};
otdef[9]   = {name:"Remote Override Room Setpoint", val: "asFloat"};
otdef[14]  = {name:"Maximum Relative Modulation Level", val: "asFloat"};
otdef[16]  = {name:"Room Setpoint", val: "asFloat"};
otdef[17]  = {name:"Relative Modulation Level", val: "asFloat"};
otdef[18]  = {name:"Water Pressure", val: "asFloat"};
otdef[24]  = {name:"Room Temperature", val: "asFloat"};
otdef[25]  = {name:"Boiler Water Temperature", val: "asFloat"};
otdef[26]  = {name:"DHW Temperature", val: "asFloat"};
otdef[27]  = {name:"Outside Temperature", val: "asFloat"};
otdef[28]  = {name:"Return Water Temperature", val: "asFloat"};
otdef[29]  = {name:"Solar Boiler Temperature", val: "asFloat"};
otdef[56]  = {name:"DHW Setpoint", val: "asFloat"};
otdef[57]  = {name:"Max CH water Setpoint", val: "asFloat"};
otdef[100] = {name:"Remote Override Function", val: "asROF"};
otdef[120] = {name:"Burner Operation Hours", val: "asUInt"};
otdef[121] = {name:"CH Pump Operation Hours", val: "asUInt"};
otdef[122] = {name:"DHW Pump/Valve Operation Hours", val: "asUInt"};

function parseMessage(data) {
   /*
    * this function parses those B12345678 like messages and returns the information
    * in case it is either a read-ack or a write-ack, such to simplify the msgs as
    * from the OTGW side. The instruction before are not so interesting, as we would
    * like to see the actual information in the datastreams.
    */
   
   // byte 2 is data-id, byte 3 and 4 contain the data value
   // byte 1: parity bit, 3 bits msg type and 4 bits spare, hence mind the parity
   
   data = data.substr(0,9);  // remove extra newline stuff
   data = data[0] + (parseInt(data[1], 16)&0x7) + data.substr(2); // remove that parity bit for more consistent reading
   
   var otObject = {recognized: false,
               readData  : parseInt(data.substr(1,1), 16) == 0,
               writeData : parseInt(data.substr(1,1), 16) == 1,
               readAck   : parseInt(data.substr(1,1), 16) == 4,
               writeAck  : parseInt(data.substr(1,1), 16) == 5,
               otMsgId   : parseInt(data.substr(3,2), 16),
               asFloat   : ((parseInt(data.substr(5,2))&0x80)>0?-1:1) *
                        ((parseInt(data.substr(5,2), 16)&0x7F) + (parseInt(data.substr(7,2), 16))/256.0 ),
               asUInt    : parseInt(data.substr(5,4), 16),
               asSInt    : ((parseInt(data.substr(5,4), 16) + 0x8000) & 0xFFFF)-0x8000,
               asStatus  : "",
               data      : data};      
      
   var valstr
   var value
   
   if (otdef[otObject.otMsgId]) {
      otObject.recognized = true;
      switch (otdef[otObject.otMsgId].val) {
         case "asFloat" :
            valstr = otObject[otdef[otObject.otMsgId].val].toFixed(2);
            value  = otObject[otdef[otObject.otMsgId].val];
            break;
            
         case "asFlags":
            var tmpstr = (otObject.asUInt >>> 8).toString(2);
            valstr = ("0").repeat(8-tmpstr.length) + tmpstr + "/" ;
            tmpstr = ((otObject.asUInt >>> 0)&0xFF).toString(2);
            valstr += ("0").repeat(8-tmpstr.length) + tmpstr;
            value  = otObject["asUInt"];
            break;
            
         case "asROF": // remote override function: the TT/TC, special treatment here
            var tmpstr = (otObject.asUInt >>> 8).toString(2);
            valstr = ("0").repeat(8-tmpstr.length) + tmpstr + "/" ;
            tmpstr = ((otObject.asUInt >>> 0)&0xFF).toString(2);
            valstr += ("0").repeat(8-tmpstr.length) + tmpstr;
            otObject.asStatus = ((otObject.asUInt & 0x0300) ? (((otObject["asUInt"] & 0x0100) ? "TC" : "TT")) : "") ;
            value = valstr;
            break;
            
         default :
            valstr = otObject[otdef[otObject.otMsgId].val] + "";
            value  = otObject[otdef[otObject.otMsgId].val];
      }
      
      otObject.name = otdef[otObject.otMsgId].name;
      otObject.valstr = valstr;
      otObject.value  = value;
   } else {
      // unknown id used here, do not know how to convert
   }
   
   if ((otObject.otMsgId != 1) & (otObject.otMsgId != 1) &
       (otObject.readAck | otObject.writeAck) & extraDebug) { // 0 is the standard status report, bit boring
      if (otObject.recognized) {
         console.log(otObject.data.replace(/[\n\l\r]/g, "") +" ("+otObject.otMsgId+")" + " " + otObject.name + " : " + otObject.valstr);
      } else {
         console.log(otObject.data.replace(/[\n\l\r]/g, "") + " : " + JSON.stringify(otObject));
      }
   }
   
   return otObject
} // parseMessage

// instruct this program to connect to the otmonitor application
connectToOTGW();

// ---------------------- start the server for active listening ----------------
server.listen(portNumberForDomoticzToUse, function() {
   console.log('Server for Domoticz is now listening, point Domoticz OTGW Hardware to port '+ portNumberForDomoticzToUse + '.');
});

console.log('Application started.');



If you run this ('node <filename.js>'), it will automatically switch PS state back once the data that Domoticz likes to see is send, hence the otmonitor application is still fed with its normal data.
Tip: use something like 'supervisor' to start this automatically, like you would like for otmonitor itself.

ernorv
Last edited by ernorv on Wednesday 28 December 2016 20:37, edited 3 times in total.

User avatar
sincze
Posts: 627
Joined: Monday 02 June 2014 22:46
Target OS: Linux
Domoticz version: 3.6833
Location: Netherlands
Contact:

Re: OTmonitor and Domoticz parallel access to OTGW

Postby sincze » Sunday 13 November 2016 12:07

Nice work around .

Sent from my SM-G925F using Tapatalk
Running Domoticz since 2013 with Cubietruck
LAN: RFLink, P1, OTGW, MySensors
USB: RFXCom, ZWave
WIFI: Mi-light Wifi-Bridge, Sonoff, ESP8266
Sensors: You name it I probably got 1.

Heelderpeel
Posts: 8
Joined: Sunday 26 April 2015 21:56
Target OS: Raspberry Pi
Domoticz version: V3.5877
Location: Nederland
Contact:

Re: OTmonitor and Domoticz parallel access to OTGW

Postby Heelderpeel » Wednesday 21 December 2016 12:52

I tried the script from ernorv on my RPI but I have some errors that I do not get solved.

Can someone explain to me what I do wrong
should I set anything else on RPI or domoticz. (preferably as sreenshot)

I am a beginner sorry if I ask a stupid question.
Attachments
Knipsel1.PNG
Knipsel1.PNG (11.93 KiB) Viewed 1052 times

ernorv
Posts: 17
Joined: Sunday 13 November 2016 11:42
Target OS: -
Domoticz version:
Contact:

Re: OTmonitor and Domoticz parallel access to OTGW

Postby ernorv » Wednesday 21 December 2016 21:01

@heelderpeel have a look at the updated code, should be a lot user friendlier without that kind of errors.

Heelderpeel wrote:I tried the script from ernorv on my RPI but I have some errors that I do not get solved..


Looking at the error, node can not open the TCP port, probably because somebody else is already using it: otmonitor itself.
Did you set all the port correctly?, i.e. at the top of the script we have:


Code: Select all

const portNumberForDomoticzToUse = 7686;  // if otmonitor is already using this one, choose another!
const portNumberOfOtMonitor      = 7685;  // most of the times 7686 would be used for this one
const replaceTTwithTC            = true;  // set to false in case you would like to use TT,


the 'portNumberOfOtMonitor' must be aligned with your 'otmonitor' setup. you could try looking in the otmonitor webpage if you have this one, under the configure tab (web page looks something like: http://raspberrypi:8081/configure.html where you replace raspberrypi with the IP adress). There you see on the left side a tab called Remote Access. Make sure the 'Relay Server' is checked, and make a mental note of the port number directly below. You can also find this in the otmonitor configuration file directly on your PI, e.g. /home/pi/otgw/otmonitor.conf , note that actual path depends off course on your installation.

Use this port for portNumberOfOtMonitor. Now the application is able to connect to the otmonitor application itself.
Probably you now have twice the same port number, so we need to tell domoticz to use a different one. First change the portNumberForDomoticzToUse to a free number, e.g. 7689. Now try to run the js file. If this works, go to your domoticz and change the port number for the OTGW under the Hardware tab (make sure to update the device ;) )

Hope this helps
ernorv

PS: code above is updated, it now points to the default otmonitor port, lot easier for everybody I think .... port to which domoticz should now point is 7689. Also better suppression of some strange opentherm messages that sometimes came into the Domoticz logs (and I like them clean)
Last edited by ernorv on Tuesday 27 December 2016 16:21, edited 1 time in total.

jake
Posts: 185
Joined: Saturday 30 May 2015 22:40
Target OS: Raspberry Pi
Domoticz version: beta
Contact:

Re: OTmonitor and Domoticz parallel access to OTGW

Postby jake » Wednesday 21 December 2016 23:11

Are you able with the code in your file to exchange some values towards domoticz? I have a solar system connected and would like very much to let Domoticz read the solar boiler temperature. However, with the standard setup, the set of parameters for PS=1 can't be changed. The owner of the otgw code advised me to compile my own version, but that is way beyond my skills. I hope your work around can be the perfect solution for my problem!

ernorv
Posts: 17
Joined: Sunday 13 November 2016 11:42
Target OS: -
Domoticz version:
Contact:

Re: OTmonitor and Domoticz parallel access to OTGW

Postby ernorv » Thursday 22 December 2016 7:27

I think you would be able to do that with some programming, but ... some points that cross my mind here:
  • The output of PS1 is also parsed by Domoticz, so creating a specific version of PS1 at the otmonitor out side also requires a specific parsing at Domoticz
  • How is that type of data visible if you would only look at the otmonitor application in the first place? A script as above basically sits on the communication line between Domoticz and otmonitor, and then filters this data for different users. surely you can filter out specific parts when required if you know what to look like to obtain the info in the first place
  • Once you have obtained this information, you could use other ways to get the data to Domoticz: one obvious one is to set a custom IDX via the JSON API (e.g. https://www.domoticz.com/wiki/Domoticz_API/JSON_URL's ). It is possible in nodejs to request an url with the correct strings.

[edit]
It just crossed my mind, if you also have a mosquitto server setup somewhere in your system, you can configure otmonitor to post everything overthere. So maybe it is easier to move towards a setup with MQTT based interfaces and NodeRed based parsing/actions etc. Actually I have completely moved away from LUA/blockly in Domoticz, as this keeps crashing every so many days, this setup allows me to completely disable the event system of Domoticz.
Once you have otmonitor publish to MQTT (as given by mosquitto) you would see all the changes flowing in via the 'events/#' topic. Very nice as otmonitor publishes directly 'on change'. Now you could relay the information towards Domoticz via NodeRed, using the domoticz/in (do some googling on the mqtt interface)
[/edit]

jake
Posts: 185
Joined: Saturday 30 May 2015 22:40
Target OS: Raspberry Pi
Domoticz version: beta
Contact:

Re: OTmonitor and Domoticz parallel access to OTGW

Postby jake » Thursday 22 December 2016 20:54

ernorv wrote:I think you would be able to do that with some programming, but ... some points that cross my mind here:
  • The output of PS1 is also parsed by Domoticz, so creating a specific version of PS1 at the otmonitor out side also requires a specific parsing at Domoticz
  • How is that type of data visible if you would only look at the otmonitor application in the first place? A script as above basically sits on the communication line between Domoticz and otmonitor, and then filters this data for different users. surely you can filter out specific parts when required if you know what to look like to obtain the info in the first place
The PS=1 exports 2 temperatures to Domoticz that I don't use, because the Remeha boiler doesn't support it / doesn't have it connected:
6: MsgID 27: Outside temperature
13: MsgID 56: DHW Setpoint
I would like to replace one of those lines (and simply rename the device in Domoticz) with :
MsgID 29: Solar storage temperature
  • Once you have obtained this information, you could use other ways to get the data to Domoticz: one obvious one is to set a custom IDX via the JSON API (e.g. https://www.domoticz.com/wiki/Domoticz_API/JSON_URL's ). It is possible in nodejs to request an url with the correct strings.

  • [edit]
    It just crossed my mind, if you also have a mosquitto server setup somewhere in your system, you can configure otmonitor to post everything overthere. So maybe it is easier to move towards a setup with MQTT based interfaces and NodeRed based parsing/actions etc. Actually I have completely moved away from LUA/blockly in Domoticz, as this keeps crashing every so many days, this setup allows me to completely disable the event system of Domoticz.
    Once you have otmonitor publish to MQTT (as given by mosquitto) you would see all the changes flowing in via the 'events/#' topic. Very nice as otmonitor publishes directly 'on change'. Now you could relay the information towards Domoticz via NodeRed, using the domoticz/in (do some googling on the mqtt interface)
    [/edit]

    This might be beyond my skills as mechanical engineer :lol:

    ernorv
    Posts: 17
    Joined: Sunday 13 November 2016 11:42
    Target OS: -
    Domoticz version:
    Contact:

    Re: OTmonitor and Domoticz parallel access to OTGW

    Postby ernorv » Thursday 22 December 2016 21:19

    @jake Do you have an example of how the Solar boiler is reported in the messages of otmonitor?

    jake
    Posts: 185
    Joined: Saturday 30 May 2015 22:40
    Target OS: Raspberry Pi
    Domoticz version: beta
    Contact:

    Re: OTmonitor and Domoticz parallel access to OTGW

    Postby jake » Thursday 22 December 2016 21:31

    ernorv wrote:@jake Do you have an example of how the Solar boiler is reported in the messages of otmonitor?

    Yes:
    20:25:36.008115 T001D0000 Read-Data Solar storage temperature: 0.00
    20:25:36.188145 BC01D0F00 Read-Ack Solar storage temperature: 15.00

    This is the one I can't use in Domoticz, probably because the boiler doesn't have it's own hot water reservoir:
    20:24:55.987709 T801A0000 Read-Data DHW temperature: 0.00
    20:24:56.170039 BE01A0000 Data-Inv DHW temperature: 0.00

    ernorv
    Posts: 17
    Joined: Sunday 13 November 2016 11:42
    Target OS: -
    Domoticz version:
    Contact:

    Re: OTmonitor and Domoticz parallel access to OTGW

    Postby ernorv » Thursday 22 December 2016 23:05

    @jake It took a bit more fiddling around than I thought, but I do think the following should work... At least I now have read parts of the Opentherm Interface Specifications :ugeek:

    keep in mind to set 'replaceID56WithSolar' to true in the script below. (kept it at false to prevent others to accidentally use a wrong script)

    Code: Select all

    #!/usr/bin/node
    /*
    Make a small listener that Domoticz can connect to as if it was the real otmonitor application.
    Then relay the messages between OTGW and Domoticz such that otmonitor is still fully functional.

    author: ernorv

    v1.0 - Special

    */

    const portNumberForDomoticzToUse = 7689;  // if otmonitor is already using this one, choose another!
    const portNumberOfOtMonitor      = 7686;  // most of the times 7686 would be used for this one
    const replaceTTwithTC            = true;  // set to false in case you would like to use TT,

    // Normally no further settings required below this line

    // -------------- some very specific settings, do not normally use
    const replaceID56WithSolar = false; // set this to true for replacement of the DHW Setpoing with Solar Temperature
    // ----------------------------------------------------------


    var net = require('net');
    var server
    var otgwSocket
    var domSocketsArray = [];

    // -------------- DEFINE SERVER LISTENING FOR CONNECTIONS FROM DOM ---------------
    server = net.createServer((socket) => {
       console.log('Incoming Domoticz Connection...');
       domSocketsArray.push(socket);
       
       socket.on('data', (data) => {
          data = data.toString(); // data may come in as Buffer
          console.log('DOM: ' + data.replace(/[\r\n]*$/, "").replace(/\r\n/g, ','));
          if (! otgwSocket.destroyed) {
             if (replaceTTwithTC) {
                otgwSocket.write(data.replace("TT=", "TC="));
             } else {
                otgwSocket.write(data);
             };
          }
       });

       socket.on('end', () => {
          console.log('end');
          domSocketsArray.splice(domSocketsArray.indexOf(socket), 1);
       });
       
       socket.on('error', () => {
          console.log('DOM: detected error on socket: probably otgwSocket died');   
          domSocketsArray.splice(domSocketsArray.indexOf(socket), 1);
       });
       
       socket.on('close', () => {
          console.log('DOM: socket closed');
          domSocketsArray.splice(domSocketsArray.indexOf(socket), 1);
       });
    });

    server.on('error', (err) => {
      throw err;
    });


    // ---------------- CONNECT TO OTGW ----------------
    function relayToClients(data) {
       for (var i =0 ; i < domSocketsArray.length; i++) {
          if (! domSocketsArray[i].destroyed) {
             domSocketsArray[i].write(data);
          }
       }
    }

    var resetPS1 = false;
    var currentSolarTemperature = 0

    function connectToOTGW() {
       otgwSocket = net.createConnection({port: portNumberOfOtMonitor}, () => {
         console.log('Connected to OTGW server at port number ' + portNumberOfOtMonitor + '!');
       });

       otgwSocket.on('data', (data) => {
          data = data.toString(); // data comes in as Buffer, we want to use it as string
          //console.log(data.replace(/\n/, ""))
          if (data.match(/[BTAR][0-9ABCDEF,]{8}/)) {
             // this data is not for Domoticz, it is what makes the normal otmonitor app work
             // console.log('<not relayed> OTGW: ' + data.toString().replace("\r", '').replace('\n', ''));
          
             // for solar temperature we are looking for the following: B C01D 0F00
             // solar temp: id 29 R - Solar storage temperature f8.8 -40..127 Solar storage temperature (°C)

             // for test purposes, lets look at B40192B00 : 49.00 degrees of boiler water temperature
             // 25 R - Boiler water temp. f8.8 -40..127 Flow water temperature from boiler (°C)
             // note: sign bit!
             // byte 2 is data-id, byte 3 and 4 contain the data value
             // byte 1: parity bit, 3 bits msg type and 4 bits spare, hence mind the parity
             if (replaceID56WithSolar && (data[0] == 'B')) {
                if ((parseInt(data.substr(1,2), 16)&0x70) == 0x40){ // test whether this is a read-ack
                   //console.log('that was a read-ack')
                   if ((parseInt(data.substr(3,2), 16)) == 29){ // for test purposes I used 25 -> Boiler water temp, use for Solar
                      var f1, f2, s
                      s  = parseInt(data.substr(5,2))&0x80;
                      f1 = parseInt(data.substr(5,2), 16)&0x7F;
                      f2 = parseInt(data.substr(7,2), 16);
                      
                      currentSolarTemperature = f1 + f2/256.0;
                      if (s >0) currentSolarTemperature *= -1;
                      console.log(data.replace(/[\n\l\r]/g, "") + ': Solar Water Temperature with temp ' + currentSolarTemperature.toFixed(2))
                   }
                }
             }
          } else {
             
             console.log('OTGW: ' + data.replace(/[\r\n]*$/, "").replace(/\r\n/g, ','));
             // sometimes there is a PR:,I=00 on the line which ends up in Domoticz status log. It looks like
             // malfomed data coming from the OTGW itself. Let's do some cleaning up, keeping the status log clean
             data = data.replace(/PR:[ ]*,/g, "PR: ");
             data = data.replace(/PR, /g, "PR: ");
             // a difficult one: this happens every so often, a comma missing in the output of the OTGW PS=0 output, let's repair this
             data = data.replace(/([01]{8}\/[01]{8},[0-9\.]{4,6},[01]{8}\/[01]{8})([0-9\.]{4,6}.*)/, "$1,$2");
             if (replaceID56WithSolar) {
                // 00000000/00000000,10.00,00000011/00000011,0.00,28/43,20.00,0.00,1.70,20.31,40.00,33.00,4.90,40.00,70/40,90/20,Deze moet vervangen worden (58.00) ,65.00,0,0,0,0,10317,26222,5097,0
                //console.log('------')
                //console.log(data)
                //console.log(data.replace(/(([^,]*,){15})([^,]*),(.*)/, "$1"+"DEZE"+",$4"))
                //console.log(data.replace(/(([^,]*,){15})([^,]*),(.*)/, "$1"+currentSolarTemperature.toFixed(2)+",$4"))
                data = data.replace(/(([^,]*,){15})([^,]*),(.*)/, "$1"+currentSolarTemperature.toFixed(2)+",$4")
             }
             relayToClients(data);
          }
          
          if (data.indexOf('PS: 1') !== -1 ) {
             // see if we can set it back to PS=0
             resetPS1 = true;
          };
          if (resetPS1 && (data.match(/[01]{7,9}\/[01]{7,9},.*/))) {
             // ok the data requested by domoticz has been produced, now go back to normal otmonitor operation
             otgwSocket.write('PS=0\r\n'); // no need to test for destroyed here, data just arrived from it
             resetPS1 = false;
          };
       });

       otgwSocket.on('end', () => {
          console.log('OTGW disconnected from server, reconnecting in 1 second.');
          setTimeout(() => { connectToOTGW(); }, 1000)
       });
    }
    connectToOTGW();

    // ---------------------- start the server for active listening ----------------
    server.listen(portNumberForDomoticzToUse, () => {
       console.log('Server for Domoticz is now listening, point Domoticz OTGW Hardware to port '+ portNumberForDomoticzToUse + '.');
    });

    console.log('Application started.');

    jake
    Posts: 185
    Joined: Saturday 30 May 2015 22:40
    Target OS: Raspberry Pi
    Domoticz version: beta
    Contact:

    Re: OTmonitor and Domoticz parallel access to OTGW

    Postby jake » Thursday 22 December 2016 23:51

    @ernorv
    Thanks a lot for your help there. However, I will need to start from 'scratch' by installing node.js on my RPI 1b (Arm6). I found the following installation advice:

    Code: Select all

    wget https://nodejs.org/dist/v4.2.4/node-v4.2.4-linux-armv6l.tar.gz
    sudo mv node-v4.2.4-linux-armv6l.tar.gz /opt
    cd /opt
    sudo tar -xzf node-v4.2.4-linux-armv6l.tar.gz
    sudo mv node-v4.2.4-linux-armv6l nodejs
    sudo rm node-v4.2.4-linux-armv6l.tar.gz
    sudo ln -s /opt/nodejs/bin/node /usr/bin/node
    sudo ln -s /opt/nodejs/bin/npm /usr/bin/npm
    Does this sound OK with you?
    I am unfortunately from the cut and paste generation, since this is not my daily job. Anyway, I figured it out as well to get OTmonitor running at every boot, I will probably succeed with this as well.

    Will this node.js add a lot of load to the RPI, or make a lot of writes on the SD-card? I am a bit careful not to overstress things there.

    Should I install the 4.2.4 version on my RPI1? On the https://nodejs.org/dist/ I find versions up to 7.3.0 that all have the xxx-armv6l.tar.gz file

    jake
    Posts: 185
    Joined: Saturday 30 May 2015 22:40
    Target OS: Raspberry Pi
    Domoticz version: beta
    Contact:

    Re: OTmonitor and Domoticz parallel access to OTGW

    Postby jake » Sunday 25 December 2016 17:42

    Without installing anything, I realized that Node.js is already installed on my system. However, the code doesn't want to run properly:

    Code: Select all

    [email protected] ~/node_modules $ node --version
    v0.12.1
    [email protected] ~/node_modules $ node otgwmod.js
    /home/pi/node_modules/otgwmod.js:29
    server = net.createServer((socket) => {
                                       ^^
    SyntaxError: Unexpected token =>
        at exports.runInThisContext (vm.js:73:16)
        at Module._compile (module.js:443:25)
        at Object.Module._extensions..js (module.js:478:10)
        at Module.load (module.js:355:32)
        at Function.Module._load (module.js:310:12)
        at Function.Module.runMain (module.js:501:10)
        at startup (node.js:129:16)
        at node.js:814:3
    [email protected] ~/node_modules $

    ernorv
    Posts: 17
    Joined: Sunday 13 November 2016 11:42
    Target OS: -
    Domoticz version:
    Contact:

    Re: OTmonitor and Domoticz parallel access to OTGW

    Postby ernorv » Monday 26 December 2016 10:02

    @jake Probably has to do with the version of NodeJS. However I have replaced them with more common definitions below.

    Still keep in mind to set the replaceID56WithSolar to true instead of the default false :D

    Code: Select all

    #!/usr/bin/node
    /*
    Make a small listener that Domoticz can connect to as if it was the real otmonitor application.
    Then relay the messages between OTGW and Domoticz such that otmonitor is still fully functional.

    author: ernorv

    v1.0 - Special
    v1.0 - Special with => replaced for better compatibility

    */

    const portNumberForDomoticzToUse = 7689;  // The new port that Domoticz needs to use. In Domoticz, set this number as the port under the OTGW hardware
    const portNumberOfOtMonitor      = 7686;   // The network port OTGW provides, as can be set under the Configuration parts

    const replaceTTwithTC            = true;   // If true: use TC instead of TT (if false, just standard Domoticz TT usage)

    // Normally no further settings required below this line
    // -------------- some very specific settings, do not normally use
    const resetOTGW_PS_state   = true; // default true: sets the PS state back to 0 after Domoticz has its data, is what allows otmonitor to keep making nice graphs as if Domoticz was not there

    // just if you really know what you do, set these
    const replaceID56WithSolar  = false; // default: false! set this to true for replacement of the DHW Setpoing with Solar Temperature
    const idToUseForReplacement = 29;    // 29 refers to the Solar, I use 25 for test purposes

    // ----------------------------------------------------------

    var net = require('net');
    var server
    var otgwSocket
    var domSocketsArray = [];

    // -------------- DEFINE SERVER LISTENING FOR CONNECTIONS FROM DOM ---------------
    server = net.createServer(function (socket) {
       console.log('Incoming Domoticz Connection...');
       domSocketsArray.push(socket);
       
       socket.on('data', function (data) {
          data = data.toString(); // data may come in as Buffer
          console.log('DOM: ' + data.replace(/[\r\n]*$/, "").replace(/\r\n/g, ','));
          if (! otgwSocket.destroyed) {
             if (replaceTTwithTC) {
                otgwSocket.write(data.replace("TT=", "TC="));
             } else {
                otgwSocket.write(data);
             };
          }
       });

       socket.on('end', function() {
          console.log('end');
          domSocketsArray.splice(domSocketsArray.indexOf(socket), 1);
       });
       
       socket.on('error', function () {
          console.log('DOM: detected error on socket: probably otgwSocket died');   
          domSocketsArray.splice(domSocketsArray.indexOf(socket), 1);
       });
       
       socket.on('close', function () {
          console.log('DOM: socket closed');
          domSocketsArray.splice(domSocketsArray.indexOf(socket), 1);
       });
    });

    server.on('error', function(err) {
      throw err;
    });


    // ---------------- CONNECT TO OTGW ----------------
    function relayToClients(data) {
       for (var i =0 ; i < domSocketsArray.length; i++) {
          if (! domSocketsArray[i].destroyed) {
             domSocketsArray[i].write(data);
          }
       }
    }

    var resetPS1 = false;
    var currentSolarTemperature = 0

    function connectToOTGW() {
       otgwSocket = net.createConnection({port: portNumberOfOtMonitor}, function() {
         console.log('Connected to OTGW server at port number ' + portNumberOfOtMonitor + '!');
       });

       otgwSocket.on('data', function(data) {
          data = data.toString(); // data comes in as Buffer, we want to use it as string
          //console.log(data.replace(/\n/, ""))
          if (data.match(/[BTAR][0-9ABCDEF,]{8}/)) {
             // this data is not for Domoticz, it is what makes the normal otmonitor app work
             // console.log('<not relayed> OTGW: ' + data.toString().replace("\r", '').replace('\n', ''));
          
             // for solar temperature we are looking for the following: B C01D 0F00
             // solar temp: id 29 R - Solar storage temperature f8.8 -40..127 Solar storage temperature (°C)

             // for test purposes, lets look at B40192B00 : 49.00 degrees of boiler water temperature
             // 25 R - Boiler water temp. f8.8 -40..127 Flow water temperature from boiler (°C)
             // note: sign bit!
             // byte 2 is data-id, byte 3 and 4 contain the data value
             // byte 1: parity bit, 3 bits msg type and 4 bits spare, hence mind the parity
             if (replaceID56WithSolar && (data[0] == 'B')) {
                if ((parseInt(data.substr(1,2), 16)&0x70) == 0x40){ // test whether this is a read-ack
                   //console.log('that was a read-ack')
                   if ((parseInt(data.substr(3,2), 16)) == idToUseForReplacement){ // new data to use
                      var f1, f2, s
                      s  = parseInt(data.substr(5,2))&0x80;
                      f1 = parseInt(data.substr(5,2), 16)&0x7F;
                      f2 = parseInt(data.substr(7,2), 16);
                      
                      currentSolarTemperature = f1 + f2/256.0;
                      if (s >0) currentSolarTemperature *= -1;
                      console.log(data.replace(/[\n\l\r]/g, "") + ': New replacement Temperature with temp ' + currentSolarTemperature.toFixed(2))
                   }
                }
             }
          } else {
             
             console.log('OTGW: ' + data.replace(/[\r\n]*$/, "").replace(/\r\n/g, ','));
             // sometimes there is a PR:,I=00 on the line which ends up in Domoticz status log. It looks like
             // malfomed data coming from the OTGW itself. Let's do some cleaning up, keeping the status log clean
             data = data.replace(/PR:[ ]*,/g, "PR: ");
             data = data.replace(/PR, /g, "PR: ");
             // a difficult one: this happens every so often, a comma missing in the output of the OTGW PS=0 output, let's repair this
             data = data.replace(/([01]{8}\/[01]{8},[0-9\.]{4,6},[01]{8}\/[01]{8})([0-9\.]{4,6}.*)/, "$1,$2");
             if (replaceID56WithSolar) {
                // 00000000/00000000,10.00,00000011/00000011,0.00,28/43,20.00,0.00,1.70,20.31,40.00,33.00,4.90,40.00,70/40,90/20,Deze moet vervangen worden (58.00) ,65.00,0,0,0,0,10317,26222,5097,0
                // replace field 25
                tmp = data.split(',')
                if (tmp.length == 25) { // for the PS1 output we expect 25 field: see http://otgw.tclcode.com/firmware.html#dataids
                   tmp[15] = currentSolarTemperature.toFixed(2);
                   data = tmp.join(",");
                   console.log("RPLC: " + data);
                }
             }
             relayToClients(data);
          }
          
          if (data.indexOf('PS: 1') !== -1 ) {
             // Domoticz is issueing a PS1 command, reset it if indicated by the settings above
             resetPS1 = resetOTGW_PS_state;
          };
          if (resetPS1 && (data.match(/[01]{7,9}\/[01]{7,9},.*/))) {
             // ok the data requested by domoticz has been produced, now go back to normal otmonitor operation
             otgwSocket.write('PS=0\r\n'); // no need to test for destroyed here, data just arrived from it
             resetPS1 = false;
          };
       });

       otgwSocket.on('end', function() {
          console.log('OTGW disconnected from server, reconnecting in 1 second.');
          setTimeout(function() { connectToOTGW(); }, 1000)
       });
    }
    connectToOTGW();

    // ---------------------- start the server for active listening ----------------
    server.listen(portNumberForDomoticzToUse, function() {
       console.log('Server for Domoticz is now listening, point Domoticz OTGW Hardware to port '+ portNumberForDomoticzToUse + '.');
    });

    console.log('Application started.');

    jake
    Posts: 185
    Joined: Saturday 30 May 2015 22:40
    Target OS: Raspberry Pi
    Domoticz version: beta
    Contact:

    Re: OTmonitor and Domoticz parallel access to OTGW

    Postby jake » Monday 26 December 2016 13:37

    @ernorv

    Excellent, the program now runs fine and the solar boiler data shows up in Domoticz under the DHW temperature parameter.

    @gizmocuz
    I wonder if this nice piece of software improvement should be added to the Wiki to support Remeha boiler owners with a Remeha Gateway + solar boiler!

    ernorv
    Posts: 17
    Joined: Sunday 13 November 2016 11:42
    Target OS: -
    Domoticz version:
    Contact:

    Re: OTmonitor and Domoticz parallel access to OTGW

    Postby ernorv » Monday 26 December 2016 13:39

    :D :D :D

    jake
    Posts: 185
    Joined: Saturday 30 May 2015 22:40
    Target OS: Raspberry Pi
    Domoticz version: beta
    Contact:

    Re: OTmonitor and Domoticz parallel access to OTGW

    Postby jake » Monday 26 December 2016 16:30

    ernorv wrote::D :D :D

    Hmm, I :D a little too early. In my previous posts I must have mixed some things up :oops: . The mentioned script works as requested (putting the solar storage temperature in a 'not used parameter', however, I asked for the wrong parameter change:

    Instead of putting the 'solar storage temperature' (MsgID29) in the 'DHW temperature' (MsgID 26), I asked for putting it in the DHW setpoint (MsgID 56) instead.
    I also provided a piece of the log about DHW temperature, that part was correct:
    14:38:47.170914 T801A0000 Read-Data DHW temperature: 0.00
    14:38:47.350798 BE01A0000 Data-Inv DHW temperature: 0.00
    14:50:07.693095 T801A0000 Read-Data DHW temperature: 0.00
    14:50:07.872856 BE01A0000 Data-Inv DHW temperature: 0.00
    15:01:28.300745 T801A0000 Read-Data DHW temperature: 0.00
    15:01:28.482246 BE01A0000 Data-Inv DHW temperature: 0.00

    as can be seen, the DHW temperature only passes once per 1600-2000 log lines. The same for the solar storage temperature:

    14:50:47.744408 T001D0000 Read-Data Solar storage temperature: 0.00
    14:50:47.929358 B401D1A00 Read-Ack Solar storage temperature: 26.00
    15:02:11.340563 T001D0000 Read-Data Solar storage temperature: 0.00
    15:02:11.537065 B401D1A00 Read-Ack Solar storage temperature: 26.00

    I wonder if it is possible to exchange the solar value one more time :oops:
    Is it possible that the code become one more bit simplified by adding in the first lines the possibility to specify which parameters to exchanges? (in my case it would be MsgID 26= MsgID29)

    To solve it myself, I looked into your code to see if I could fix my mistake myself, but that was a bit over the top for me.

    I saw in your code 1 line of Dutch comments, must be a slip of the tongue ;)


    Return to “OpenTherm gateway”

    Who is online

    Users browsing this forum: No registered users and 2 guests