Hallo,
ich habe auch eine Hargassner mit Nano-pk-Steuerung, welche ich mit Hilfe von reinen JS-Skripten auslese.
Der iobroker muss dazu per IP und Port 23 (Telnet) auf die Nano-pk zugreifen können.
Zusätzlich sollte einmal auf einer SD-Karte an der Nano-pk ein Log erstellt werden. Auf der SD-Karte sollte sich danach im Verzeichnis "DAQ" die Log-Datei "DAQ00000.DAQ" (oder ähnlich) liegen. Aus dieser Log-Datei kopieren wir den XML-Code "<DAQPRJ><ANALOG><CHAN [...] /></DIGITAL></DAQPRJ>", da wir ihn im folgenden Skript benötigen
Auf dem iobroker führen wir nun das folgende JS-Skript zum Erstellen der States einmal aus:
//get XML-Code from Hargassner heater (use SD card)
var nanopk = `<DAQPRJ><ANALOG>
<CHANNEL id='0' name='ZK' unit=''/>
<CHANNEL id='1' name='O2' unit='%'/>
<CHANNEL id='2' name='O2soll' unit='%'/>
<CHANNEL id='3' name='TK' unit='°C'/>
...
<CHANNEL id='7' bit='21' name='DReg3 P3'/>
<CHANNEL id='7' bit='22' name='DReg3 Mi auf'/>
<CHANNEL id='7' bit='23' name='DReg3 Mi zu'/>
</DIGITAL></DAQPRJ>`;
let DP="javascript.0.Hargassner" // object-id
var xml2js = require('xml2js'); // please activate npm-module
var parser = new xml2js.Parser();
// translate XML data into states
parser.parseString(nanopk, (err, result) => {
if (err) {
console.error(err);
return;
}
// analog channels
const channelsA = result.DAQPRJ.ANALOG[0].CHANNEL;
channelsA.forEach(channel => {
const id = channel.$.id;
const bit = channel.$.bit;
const name = channel.$.name;
const unit = channel.$.unit;
console.log(`Channel ID: ${id}, Bit: ${bit}, Name: ${name}`);
createState(DP+".analog."+("00" + id).slice(-3),"",{name: name, type: "number", role: "state", unit: unit, read: true, write: false});
});
// digital channels
const channelsD = result.DAQPRJ.DIGITAL[0].CHANNEL;
channelsD.forEach(channel => {
const id = channel.$.id;
const bit = channel.$.bit;
const name = channel.$.name;
console.log(`Channel ID: ${id}, Bit: ${bit}, Name: ${name}`);
createState(DP+".digital."+("00" + id).slice(-3)+"."+("0" + bit).slice(-2),"",{name: name, type: "boolean", role: "state", read: true, write: false});
});
});
Den XML-Code habe ich der Übersicht wegen gekürzt. Da es verschiedene Nano-pk-Steuerungen mit wiederum verschiedenen Firmwares gibt, empfehle ich sehr den XML-Code immer selber zu erstellen.
Die Objekt-ID unter welcher die ganzen States erstellt werden, kann im Skript geändert werden.
Das NPM-Modul xml2js
muss in der javascript-Instanz noch aktiviert werden.
Danach das folgende Skript aktivieren:
let DP = "javascript.0.Hargassner"; // object-id
let ip = '192.168.0.99'; // ip of Nano-pk
let port = 23; // port of Nano-pk (Telnet)
var net = require('net'); // please activate npm-module
// run script every 5 sec
schedule("*/5 * * * * *", function () {
// connect to Nano-pk
var client = new net.Socket();
client.connect(port, ip, function() {
console.debug('Connected');
});
// get data
client.on('data', function(data) {
const values = data.subarray(3,-3).toString('utf8').split(" "); // split received values into array
console.debug('Received: ' + values);
client.destroy(); // kill client after server's response
// set analog states
let DPA = `${DP}.analog.`;
const idAna = $(`state[id=${DPA}*]`);
const valAna = values.slice(0, idAna.length);
idAna.each( function( id, i){
const idSub = id.substring(DPA.length);
const ch = Number(idSub.substring(0,3));
setState(id, Number(valAna[ch]), true);
console.debug(id+`: `+ valAna[i]);
});
// set digital states
let DPD = `${DP}.digital.`;
const idDig = $(`state[id=${DPD}*]`);
const valDig = values.slice(idAna.length);
idDig.each( function( id, i){
const idSub = id.substring(DPD.length);
const ch = Number(idSub.substring(0,3));
const bit = Number(idSub.substring(4));
const bits = parseInt(valDig[ch],16);
const bitMask = 1 << bit;
const value = ((bits & bitMask) > 0);
setState(id, value, true);
console.debug(id+`: `+ value);
});
});
// Closed connection
client.on('close', function() {
console.debug('Closed connection');
});
});
Die Objekt-ID sollte hier die gleiche sein, wie im ersten Skript.
Dann noch die IP (und ggf. bei Bedarf den Port) ändern.
Für dieses Skript noch das NPM-Modul net
aktivieren.
Der Scheduler sorgt in diesem Fall dafür, dass der Code alle 5 Sekunden ausgeführt wird und das Skript entsprechend die Werte bei der Nano-pk holt und in die Objekte schreibt.
Und sobald das zweite Skript läuft, sollten die Werte einlaufen: