NEWS
Script zum auslesen eines C.M.I von TA UVR1611
-
Hallo zusammen,
da mir das Forum schon so viel geholfen hat, möchte ich mich bedanken und auch ein Script beisteuern.
Villeicht kann es ja jemand mit einer UVR Steuerung von TA (Technische Alternative) gebrauchen.
Das Script ruft per JSON API das CMI ab und legt entsprechend die Datenpunkte an.
Im nächsten Durchlauf werden dann die Datenpunkte mit den Werten gefüllt.
Für meine Anwendung speziell wird noch die verfügbare Wasserspeicher Menge berechnet.
Diesen wird dann in noch zu befüllende Kg für den Holzvergaser umgerechnet und per MQTT
an das Display(ESP Arduino OLED) meines HVS25 gesendet.
Viel Spaß damit.
Edit da hat der Fehlerteufel zugeschlagen, deshalb jetzt Version 0.2
! ```
`/*******************************************************************************
** Script zum auslesen von 2 UVR1611 über das CMI Interface mit JSON V3 API **
** Die Abfragen erfolgen zeitgesteuert versetzt, das gleichzeitiges Abfragen **
** von mehreren Knoten des CMI nicht möglich ist. Die Datenpunkte werden bei **
** Sciptstart angeleget und dann im weiteren Verlauf mit Werten beschieben. **
** zusätzlich erfolgt noch eine Berechnung der Speicherkapazität der Puffer **
** mit einer Angabe der noch zu heizenden maximalen Holzmenge für den HVS25 **
** Version 0.2 **
** Sven **
********************************************************************************/! var request = require("request");
//username & password for CMI
username = "admin",
password = "admin",
auth = "Basic " + new Buffer(username + ":" + password).toString("base64");
! //URL to CMI Interface, only change IP
var url1 = 'http://192.168.10.201/INCLUDE/api.cgi?jsonnode=1&jsonparam=I,O,Na,Nd';
var url2 = 'http://192.168.10.201/INCLUDE/api.cgi?jsonnode=2&jsonparam=I,O,Na,Nd';
! // JSON with Unit from CMI_JSON_API_V3 https://www.ta.co.at/downloads/datei/17511763-cmi-json-api/
var unitJson = {"0":"","1":"°C","2":"W/m²","3":"l/h","4":"Sek","5":"Min","6":"l/Imp","7":"K","8":"%","10":"kW","11":"kWh","12":"MWh",
"13":"V","14":"mA","15":"Std","16":"Tage","17":"Imp","18":"KΩ","19":"l","20":"km/h","21":"Hz","22":"l/min","23":"bar",
"24":"","25":"km","26":"m","27":"mm","28":"m³","35":"l/d","36":"m/s","37":"m³/min","38":"m³/h","39":"m³/d","40":"mm/min",
"41":"mm/h","42":"mm/d","43":"Aus/Ein","44":"Nein/Ja","46":"°C","50":"€","51":"$","53":"","54":"°","56":"°","57":"Sek",
"58":"","59":"%","60":"Uhr","63":"A","65":"mbar","66":"Pa","67":"ppm"};
! // Hilfsvariablen
var stateanlegen = true;
var state1anlegen = false;
var state2anlegen = false;
var llog = true; // loging ein/aus (true/false)
! // zeitlich die Abfrage wiederhohlen
//jede x minute
schedule("0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58 * * * *", function () {
readurl1();
gewicht();
});
//jede y minute
schedule("1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59 * * * *", function () {
readurl2();});
! function readurl1() {
readJson(url1, function(err,json) {
if(!err) {
if (json['Status_code'] ===0){
// console.log('ReadStatus_Knoten 1 '+json['Status']);
setDataObjectsKnoten1(json);} } else { log("Fehler beim Auslesen des Knoten 1 JSON. Keine Daten erhalten.","warn"); log("Errorcode "+json['Status_code'],"warn"); } });
}
! function readurl2() {
readJson(url2, function(err,json) {
if(!err) {
if (json['Status_code'] ===0){
// console.log('ReadStatus_Knoten 2 '+json['Status']);
setDataObjectsKnoten2(json);
}
} else {
log("Fehler beim Auslesen des Konten 2 JSON. Keine Daten erhalten.","warn");
log("Errorcode "+json['Status_code'],"warn");
}
});
}
! function gewicht() {
if ((state1anlegen ===true) && (state2anlegen === true)){
stateanlegen = false;
}
if (stateanlegen === false){
//getState("ID auswählen").val;
//Maximales Gewicht in Kg für das Brennholz. Speicherkapazität berechnen. 3x800L Puffer Q=mcdT 8004.182xK
var tank_1=((8004.182)(90-((getState("javascript.0.UVR1611_CMI_Knoten_1.Input_Number12").val/Input_Number12/+getState("javascript.0.UVR1611_CMI_Knoten_1.Input_Number13").val/Input_Number13/+getState("javascript.0.UVR1611_CMI_Knoten_2.Input_Number09").val/Input_Number09/+getState("javascript.0.UVR1611_CMI_Knoten_2.Input_Number10"/Input_Number10/).val)/4))/3600);
var tank_2=((8004.182)(90-((getState("javascript.0.UVR1611_CMI_Knoten_2.Input_Number11").val/Input_Number11/+getState("javascript.0.UVR1611_CMI_Knoten_2.Input_Number12").val/Input_Number12/+getState("javascript.0.UVR1611_CMI_Knoten_2.Input_Number13").val/Input_Number13/+getState("javascript.0.UVR1611_CMI_Knoten_1.Network_Analog_Number01"/Network_Analog_Number01/).val)/4))/3600);
var tank_3=((8004.182)(90-((getState("javascript.0.UVR1611_CMI_Knoten_2.Input_Number14").val/Input_Number14/+getState("javascript.0.UVR1611_CMI_Knoten_2.Input_Number16").val/Input_Number16/+getState("javascript.0.UVR1611_CMI_Knoten_1.Input_Number15").val/Input_Number15/)/3))/3600);
var tank=(((tank_1+tank_2+tank_3)/5)*1.15);
// Daten per MQTT zum HVS25 Display schicken
setState("mqtt.0.HVS25E.HVS25E_Holz"/HVS25E_Holz/,tank.toFixed(2),true);
setState("mqtt.0.HVS25E.HVS25E_Time"/HVS25E/HVS25E_Time/, formatDate(new Date(), "hh:mm"), true);
}
}
! function readJson(url, callback) {
request({
url : url,
headers : {
"Authorization" : auth
}
},
function (error, response, body) {if (body) { result = body.replace(/ /g, '_'); //alle Leerzeichen durch Unterstrich ersetzten var jdata = JSON.parse(result); //Json Array erzeugen callback(null, jdata); } else { log(error, "warn"); callback(error, null); } });
}
! function setDataObjectsKnoten1(jsondata){
// console.log(jsondata['Data']['Inputs']['0']['Value']['Value']);
// console.log(jsondata['Data']['Inputs']['0']['Value']['Unit']);if (stateanlegen === true){ // User Variablen anlegen Achtung keine Punkte im Namen verwenden. createState('javascript.0.UVR1611_CMI_Knoten_1.Header.Version', { name: 'Version', type: 'number', unit: '', write: false, read: true }); createState('javascript.0.UVR1611_CMI_Knoten_1.Header.Device', { name: 'Device', type: 'string', unit: '', write: false, read: true }); createState('javascript.0.UVR1611_CMI_Knoten_1.Header.Timestamp', { name: 'Timestamp', type: 'number', unit: '', write: false, read: true }); var i=0; for (i=0; i<=15;i++){ var inputsUnit = unitJson[jsondata['Data']['Inputs'][i]['Value']['Unit']]; var networkAnalogUnit = unitJson[jsondata['Data']['Network_Analog'][i]['Value']['Unit']]; var networkDigitalUnit = unitJson[jsondata['Data']['Network_Digital'][i]['Value']['Unit']]; if (i<9){ createState('javascript.0.UVR1611_CMI_Knoten_1.Input_Number0'+jsondata['Data']['Inputs'][i]['Number'],'', { name: 'Input_Number0'+jsondata['Data']['Inputs'][i]['Number']+'_'+jsondata['Data']['Inputs'][i]['AD'], type: 'number', unit: ''+inputsUnit, write: false, read: true }); createState('javascript.0.UVR1611_CMI_Knoten_1.Network_Analog_Number0'+jsondata['Data']['Network_Analog'][i]['Number'],'', { name: 'Network_Analog_Number0'+jsondata['Data']['Network_Analog'][i]['Number']+'_'+jsondata['Data']['Network_Analog'][i]['AD'], type: 'number', unit: ''+networkAnalogUnit, write: false, read: true }); createState('javascript.0.UVR1611_CMI_Knoten_1.Network_Digital_Number0'+jsondata['Data']['Network_Digital'][i]['Number'],'', { name: 'Network_Digital_Number0'+jsondata['Data']['Network_Digital'][i]['Number']+'_'+jsondata['Data']['Network_Digital'][i]['AD'], type: 'number', unit: ''+networkDigitalUnit, write: false, read: true }); } else{ createState('javascript.0.UVR1611_CMI_Knoten_1.Input_Number'+jsondata['Data']['Inputs'][i]['Number'],'', { name: 'Input_Number'+jsondata['Data']['Inputs'][i]['Number']+'_'+jsondata['Data']['Inputs'][i]['AD'], type: 'number', unit: ''+inputsUnit, write: false, read: true }); createState('javascript.0.UVR1611_CMI_Knoten_1.Network_Analog_Number'+jsondata['Data']['Network_Analog'][i]['Number'],'', { name: 'Network_Analog_Number0'+jsondata['Data']['Network_Analog'][i]['Number']+'_'+jsondata['Data']['Network_Analog'][i]['AD'], type: 'number', unit: ''+networkAnalogUnit, write: false, read: true }); createState('javascript.0.UVR1611_CMI_Knoten_1.Network_Digital_Number'+jsondata['Data']['Network_Digital'][i]['Number'],'', { name: 'Network_Digital_Number0'+jsondata['Data']['Network_Digital'][i]['Number']+'_'+jsondata['Data']['Network_Digital'][i]['AD'], type: 'number', unit: ''+networkDigitalUnit, write: false, read: true }); } } i=0; for (i=0; i<=12;i++){ var outputsUnit = unitJson[jsondata['Data']['Outputs'][i]['Value']['Unit']]; if (i<9){ createState('javascript.0.UVR1611_CMI_Knoten_1.Output_Number0'+jsondata['Data']['Outputs'][i]['Number'],'', { name: 'Output_Number'+jsondata['Data']['Outputs'][i]['Number']+'_'+jsondata['Data']['Outputs'][i]['AD'], type: 'number', unit: ''+outputsUnit, write: false, read: true }); if (jsondata['Data']['Outputs'][i]['AD']==='A'){ createState('javascript.0.UVR1611_CMI_Knoten_1.Output_Number_State0'+jsondata['Data']['Outputs'][i]['Number'],'', { name: 'Output_Number_State'+jsondata['Data']['Outputs'][i]['Number']+'_'+jsondata['Data']['Outputs'][i]['AD'], type: 'number', unit: ''+outputsUnit, write: false, read: true }); } } else{ // set +jsondata['Data']['Outputs'][i]['Value']['Value'], createState('javascript.0.UVR1611_CMI_Knoten_1.Output_Number'+jsondata['Data']['Outputs'][i]['Number'],'', { name: 'Output_Number'+jsondata['Data']['Outputs'][i]['Number']+'_'+jsondata['Data']['Outputs'][i]['AD'], type: 'number', unit: ''+outputsUnit, write: false, read: true }); if (jsondata['Data']['Outputs'][i]['AD']==='A'){ // set +jsondata['Data']['Outputs'][i]['Value']['Value'], createState('javascript.0.UVR1611_CMI_Knoten_1.Output_Number_State'+jsondata['Data']['Outputs'][i]['Number'],'', { name: 'Output_Number_State'+jsondata['Data']['Outputs'][i]['Number']+'_'+jsondata['Data']['Outputs'][i]['AD'], type: 'number', unit: ''+outputsUnit, write: false, read: true }); } } } console.log("Variablen Knoten 1 angelegt"); state1anlegen = true; } else{ //Variablen setstate setState('javascript.0.UVR1611_CMI_Knoten_1.Header.Version',jsondata['Header']['Version']); setState('javascript.0.UVR1611_CMI_Knoten_1.Header.Device',jsondata['Header']['Device']); setState('javascript.0.UVR1611_CMI_Knoten_1.Header.Timestamp',jsondata['Header']['Timestamp']); i=0; for (i=0; i<=15;i++){ if (i<9){ //set jsondata['Data']['Inputs'][i]['Value'],['Value'] setState('javascript.0.UVR1611_CMI_Knoten_1.Input_Number0'+jsondata['Data']['Inputs'][i]['Number'],jsondata['Data']['Inputs'][i]['Value']['Value']); setState('javascript.0.UVR1611_CMI_Knoten_1.Network_Analog_Number0'+jsondata['Data']['Network_Analog'][i]['Number'],jsondata['Data']['Network_Analog'][i]['Value']['Value']); setState('javascript.0.UVR1611_CMI_Knoten_1.Network_Digital_Number0'+jsondata['Data']['Network_Digital'][i]['Number'],jsondata['Data']['Network_Digital'][i]['Value']['Value']); } else{ setState('javascript.0.UVR1611_CMI_Knoten_1.Input_Number'+jsondata['Data']['Inputs'][i]['Number'],jsondata['Data']['Inputs'][i]['Value']['Value']); setState('javascript.0.UVR1611_CMI_Knoten_1.Network_Analog_Number'+jsondata['Data']['Network_Analog'][i]['Number'],jsondata['Data']['Network_Analog'][i]['Value']['Value']); setState('javascript.0.UVR1611_CMI_Knoten_1.Network_Digital_Number'+jsondata['Data']['Network_Digital'][i]['Number'],jsondata['Data']['Network_Digital'][i]['Value']['Value']); } } i=0; for (i=0; i<=12;i++){ if (i<9){ setState('javascript.0.UVR1611_CMI_Knoten_1.Output_Number0'+jsondata['Data']['Outputs'][i]['Number'],jsondata['Data']['Outputs'][i]['Value']['Value']); if (jsondata['Data']['Outputs'][i]['AD']==='A'){ setState('javascript.0.UVR1611_CMI_Knoten_1.Output_Number_State0'+jsondata['Data']['Outputs'][i]['Number'],jsondata['Data']['Outputs'][i]['Value']['State']); } } else{ setState('javascript.0.UVR1611_CMI_Knoten_1.Output_Number'+jsondata['Data']['Outputs'][i]['Number'],jsondata['Data']['Outputs'][i]['Value']['Value']); if (jsondata['Data']['Outputs'][i]['AD']==='A'){ setState('javascript.0.UVR1611_CMI_Knoten_1.Output_Number_State'+jsondata['Data']['Outputs'][i]['Number'],jsondata['Data']['Outputs'][i]['Value']['State']); } //setState('javascript.0.PoolController.ADC'+[i-1], parseFloat(Number(wert).toFixed(2))); } } }
}
! function setDataObjectsKnoten2(jsondata){
if (stateanlegen === true){
// User Variablen anlegen Achtung keine Punkte im Namen verwenden.
createState('javascript.0.UVR1611_CMI_Knoten_2.Header.Version', {
name: 'Version',
type: 'number',
unit: '',
write: false,
read: true
});
createState('javascript.0.UVR1611_CMI_Knoten_2.Header.Device', {
name: 'Device',
type: 'string',
unit: '',
write: false,
read: true
});
createState('javascript.0.UVR1611_CMI_Knoten_2.Header.Timestamp', {
name: 'Timestamp',
type: 'number',
unit: '',
write: false,
read: true
});var i=0; for (i=0; i<=15;i++){ var inputsUnit = unitJson[jsondata['Data']['Inputs'][i]['Value']['Unit']]; var networkAnalogUnit = unitJson[jsondata['Data']['Network_Analog'][i]['Value']['Unit']]; var networkDigitalUnit = unitJson[jsondata['Data']['Network_Digital'][i]['Value']['Unit']]; if (i<9){ //set jsondata['Data']['Inputs'][i]['Value'],['Value'] createState('javascript.0.UVR1611_CMI_Knoten_2.Input_Number0'+jsondata['Data']['Inputs'][i]['Number'],'', { name: 'Input_Number0'+jsondata['Data']['Inputs'][i]['Number']+'_'+jsondata['Data']['Inputs'][i]['AD'], type: 'number', unit: ''+inputsUnit, write: false, read: true }); // set jsondata['Data']['Network_Analog'][i]['Value']['Value'] createState('javascript.0.UVR1611_CMI_Knoten_2.Network_Analog_Number0'+jsondata['Data']['Network_Analog'][i]['Number'],'', { name: 'Network_Analog_Number0'+jsondata['Data']['Network_Analog'][i]['Number']+'_'+jsondata['Data']['Network_Analog'][i]['AD'], type: 'number', unit: ''+networkAnalogUnit, write: false, read: true }); //set +jsondata['Data']['Network_Digital'][i]['Value']['Value'] createState('javascript.0.UVR1611_CMI_Knoten_2.Network_Digital_Number0'+jsondata['Data']['Network_Digital'][i]['Number'],'', { name: 'Network_Digital_Number0'+jsondata['Data']['Network_Digital'][i]['Number']+'_'+jsondata['Data']['Network_Digital'][i]['AD'], type: 'number', unit: ''+networkDigitalUnit, write: false, read: true }); } else{ //set jsondata['Data']['Inputs'][i]['Value'],['Value'] createState('javascript.0.UVR1611_CMI_Knoten_2.Input_Number'+jsondata['Data']['Inputs'][i]['Number'],'', { name: 'Input_Number'+jsondata['Data']['Inputs'][i]['Number']+'_'+jsondata['Data']['Inputs'][i]['AD'], type: 'number', unit: ''+inputsUnit, write: false, read: true }); // set jsondata['Data']['Network_Analog'][i]['Value']['Value'] createState('javascript.0.UVR1611_CMI_Knoten_2.Network_Analog_Number'+jsondata['Data']['Network_Analog'][i]['Number'],'', { name: 'Network_Analog_Number0'+jsondata['Data']['Network_Analog'][i]['Number']+'_'+jsondata['Data']['Network_Analog'][i]['AD'], type: 'number', unit: ''+networkAnalogUnit, write: false, read: true }); //set +jsondata['Data']['Network_Digital'][i]['Value']['Value'] createState('javascript.0.UVR1611_CMI_Knoten_2.Network_Digital_Number'+jsondata['Data']['Network_Digital'][i]['Number'],'', { name: 'Network_Digital_Number0'+jsondata['Data']['Network_Digital'][i]['Number']+'_'+jsondata['Data']['Network_Digital'][i]['AD'], type: 'number', unit: ''+networkDigitalUnit, write: false, read: true }); } } i=0; for (i=0; i<=12;i++){ var outputsUnit = unitJson[jsondata['Data']['Outputs'][i]['Value']['Unit']]; if (i<9){ createState('javascript.0.UVR1611_CMI_Knoten_2.Output_Number0'+jsondata['Data']['Outputs'][i]['Number'],'', { name: 'Output_Number'+jsondata['Data']['Outputs'][i]['Number']+'_'+jsondata['Data']['Outputs'][i]['AD'], type: 'number', unit: ''+outputsUnit, write: false, read: true }); if (jsondata['Data']['Outputs'][i]['AD']==='A'){ createState('javascript.0.UVR1611_CMI_Knoten_2.Output_Number_State0'+jsondata['Data']['Outputs'][i]['Number'],'', { name: 'Output_Number_State'+jsondata['Data']['Outputs'][i]['Number']+'_'+jsondata['Data']['Outputs'][i]['AD'], type: 'number', unit: ''+outputsUnit, write: false, read: true }); } } else{ createState('javascript.0.UVR1611_CMI_Knoten_2.Output_Number'+jsondata['Data']['Outputs'][i]['Number'],'', { name: 'Output_Number'+jsondata['Data']['Outputs'][i]['Number']+'_'+jsondata['Data']['Outputs'][i]['AD'], type: 'number', unit: ''+outputsUnit, write: false, read: true }); if (jsondata['Data']['Outputs'][i]['AD']==='A'){ createState('javascript.0.UVR1611_CMI_Knoten_2.Output_Number_State'+jsondata['Data']['Outputs'][i]['Number'],'', { name: 'Output_Number_State'+jsondata['Data']['Outputs'][i]['Number']+'_'+jsondata['Data']['Outputs'][i]['AD'], type: 'number', unit: ''+outputsUnit, write: false, read: true }); } } } console.log("Variablen Knoten 2 angelegt"); state2anlegen = true;
}
else{
//Variablen setstate
setState('javascript.0.UVR1611_CMI_Knoten_2.Header.Version',jsondata['Header']['Version']);
setState('javascript.0.UVR1611_CMI_Knoten_2.Header.Device',jsondata['Header']['Device']);
setState('javascript.0.UVR1611_CMI_Knoten_2.Header.Timestamp',jsondata['Header']['Timestamp']);
i=0;
for (i=0; i<=15;i++){
if (i<9){
setState('javascript.0.UVR1611_CMI_Knoten_2.Input_Number0'+jsondata['Data']['Inputs'][i]['Number'],jsondata['Data']['Inputs'][i]['Value']['Value']);
setState('javascript.0.UVR1611_CMI_Knoten_2.Network_Analog_Number0'+jsondata['Data']['Network_Analog'][i]['Number'],jsondata['Data']['Network_Analog'][i]['Value']['Value']);
setState('javascript.0.UVR1611_CMI_Knoten_2.Network_Digital_Number0'+jsondata['Data']['Network_Digital'][i]['Number'],jsondata['Data']['Network_Digital'][i]['Value']['Value']);
}
else{
setState('javascript.0.UVR1611_CMI_Knoten_2.Input_Number'+jsondata['Data']['Inputs'][i]['Number'],jsondata['Data']['Inputs'][i]['Value']['Value']);
setState('javascript.0.UVR1611_CMI_Knoten_2.Network_Analog_Number'+jsondata['Data']['Network_Analog'][i]['Number'],jsondata['Data']['Network_Analog'][i]['Value']['Value']);
setState('javascript.0.UVR1611_CMI_Knoten_2.Network_Digital_Number'+jsondata['Data']['Network_Digital'][i]['Number'],jsondata['Data']['Network_Digital'][i]['Value']['Value']);}
}
i=0;
for (i=0; i<=12;i++){
if (i<9){
setState('javascript.0.UVR1611_CMI_Knoten_2.Output_Number0'+jsondata['Data']['Outputs'][i]['Number'],jsondata['Data']['Outputs'][i]['Value']['Value']);
if (jsondata['Data']['Outputs'][i]['AD']==='A'){
setState('javascript.0.UVR1611_CMI_Knoten_2.Output_Number_State0'+jsondata['Data']['Outputs'][i]['Number'],jsondata['Data']['Outputs'][i]['Value']['State']);
}
}
else{
setState('javascript.0.UVR1611_CMI_Knoten_2.Output_Number'+jsondata['Data']['Outputs'][i]['Number'],jsondata['Data']['Outputs'][i]['Value']['Value']);
if (jsondata['Data']['Outputs'][i]['AD']==='A'){
setState('javascript.0.UVR1611_CMI_Knoten_2.Output_Number_State'+jsondata['Data']['Outputs'][i]['Number'],jsondata['Data']['Outputs'][i]['Value']['State']);
}
//setState('javascript.0.PoolController.ADC'+[i-1], parseFloat(Number(wert).toFixed(2)));
}}
}
}`
4689_objekte_knoten1_2.png
4689_objekte_knoten2_2.png
4689_objekte_knoten2_1.png
4689_objekte_knoten1_1.png [/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i] -
Hallo!
Mir geht es so wie auch Sven12. Das Forum hat mir durch Nachlesen der vielseitigen Themen immer wieder weitergeholfen.
Ich habe auch lange veruscht die Daten meiner CMI bzw. der beiden UVR1611 und RSM610 auszulesen. Bin dann auch auf den http Request mit Json Antwort gestoßen.
Nachdem ich im Skripte schreiben nicht so der Profi bin, und im ioBroker mehr mit Blockly bastle, darf ich das hier auch zur Verfügung stellen.
Also für die nicht so bewanderten Programmierer eventuell leichter zu verstehen.
Macht im Endeffekt auch nichts anderes, lest aber nicht alle Daten aus, nur bestimmte, die Datenpunkte im ioBroker müssen vorher manuell angelegt werden.
Zur Abfrage wird in diesem Fall folgende http verwednet: http://admin:password@192.168.1.100/inc … sonparam=I
In diesem Fall werden die Eingänge (jsonparam=I) des Knoten 1 (jsonnode=1) im CAN-Bus Netzwerk ausgelesen. Je nach Eingabe der Knotenummer (jsonnode) und der Zusätze (jsonparam) in der http requestadresse kann dies abgewandelt werden. Über die i`s im Blocky wird die Auslesung des i.ten wertes im Json definiert.
Hier noch der Link zur Beschreibung der http Requests und Antwort der CMI: https://www.google.at/url?sa=t&rct=j&q= … A869gWoXZG
Das Blockly dazu schaut folgendermaßen aus:
6302_blockly_-_abfrage_cmi_knoten_1.png -
Ich benutze hier den ModBus Adapter zum Auslesen des CMI. Hat den Charme, dass das CMI aktiv neue Werte in Richtung ioBroker pusht und man kann auch Werte im CMI / UVR setzen.
-
Ich benutze hier den ModBus Adapter zum Auslesen des CMI. n. `
Hast Du auch eine Beschreibung wie genau das abläuft?
Dafür wird doch sicher noch ein Adapter benötigt oder?
Gruß
Sven
-
Weil es ein kleines bisschen Umdenken erfordert, mache ich es an einem Beispiel für einen Sensor-Eingang an der UVR (z.B. Temperaturfühler)
1. Sensor Eingang in der UVR auf einen CAN Ausgang mappen
~~![](</s><URL url=)https://i.imgur.com/XXXqul5.png" />
2. CAN Eingang in das CMI
Die UVR stellt ihren Wert nun über den CAN Bus zur Verfügung. Also brauchen wir einen CAN Bus Eingang an der CMI:
~~![](</s><URL url=)https://imgur.com/vFdPa2F.png" />
3. Ausgang vom CMI
Den Wert den wir uns von der UVR per CMI Eingang geholt haben, geben wir jetzt über den ModBus (over TCP) Ausgang des CMI wieder aus:
~~![](</s><URL url=)https://i.imgur.com/Vk4kbdX.png" />
-
IP: Die der ioBroker Instanz
-
Gerät: Irgendeine FREIE CAN Bus Nummer (UVR typischerweise 1 und CMI 56)
-
Adresse: Frei gewählte CAN Bus Adresse unseres Gerätes (siehe obiger Punkt). Brauchen wir dann in ioBroker
-
Funktion: 06
-
Datentyp und Byte Order: 16 bit big-endian
4. ModBus Adapter Settings
~~![](</s><URL url=)https://i.imgur.com/CvxTllm.png" />
-
TCP/Serial: TCP
-
Partner IP: IP des CMI
-
Port: 502
-
Gerät: Unsere Geräte ID aus #3
-
Typ: Slave (Das CMI agiert immer als Master und sendet die Werte zum Slave)
5. Holding Register
Die Werte welche wir einlesen wollen sind Holding Register. Die Werte wie Adresse etc. sind analog der oben getroffenen Einstellungen
~~![](</s><URL url=)https://i.imgur.com/GJ0Oreh.png" />
Sollen Werte aus ioBroker in die UVR übertragen werden ist grundsätzlich umgekehrt zu verfahren:
-
Statt Holding Register werden Eingangsregister verwendet
-
Was im obigen Beispiel ein Eingang ist wird zum Ausgang und umgekehrt
-
Eingangswerte werden mit der CAN Funktion 4 eingelesen~~~~~~~~~~
-
-
Hallo Sineos,
erstmal vielen Dank für deinen tollen Beitrag zur Übertragung der UVR-Daten mittel Can- und Modbus.
Derzeit habe ich damit nur ein Problem:
Wenn ich Werte von iobroker zur UVR übertrage werden nur Integerzahlen zum Modbuseingang der UVR weitergeben.
Das Objekt in Iobroker (erstellt im Modbusadapter dort : input Registers ) zeigt eine Real-Zahl an.
Ich habe schon einige Einstellungen versucht, leider ohne Erfolg.
Derzeitige Einstellung: Signed 16Bit Big Endian im Modbusein- und ausgang .
In der UVR : Modbuseingang: Funktion 04
Vielleicht kannst du einen Tip geben?
-
Wenn ich Werte von iobroker zur UVR übertrage werden nur Integerzahlen zum Modbuseingang der UVR weitergeben.
Das Objekt in Iobroker (erstellt im Modbusadapter dort : input Registers ) zeigt eine Real-Zahl an. `
Das liegt an der eigenwilligen Art der UVR mit Größen und Einheiten umzugehen. Über den Bus und, nach meinem Eindruck, auch intern arbeitet die UVR nur mit Integer Zahlen und erst in Kombination mit einer Einheit wird das ganze zu einer Float.
So hat z.B. die Einheit Temperatur 1 Dezimalstelle, Leistung (kW) 2 Dezimalstellen usw. Ich hab mal für ein JS-Script die Anzahl Stellen rausgesucht:
var MeasurementMapping = { '0': { Name: 'None', Unit: 'None', Decimals: 0 }, '1': { Name: 'Temperature', Unit: '°C', Decimals: 1 }, '2': { Name: 'Global Radiation', Unit: 'W/m²', Decimals: 0 }, '3': { Name: 'FlowRate', Unit: 'l/h', Decimals: 0 }, '4': { Name: 'Time', Unit: 's', Decimals: 0 }, '5': { Name: 'Time', Unit: 'min', Decimals: 0 }, '8': { Name: 'Percent', Unit: '%', Decimals: 1 }, '10': { Name: 'Power', Unit: 'kW', Decimals: 2 }, '11': { Name: 'Power Consumption', Unit: 'kWh', Decimals: 1 }, '12': { Name: 'Power Consumption', Unit: 'MWh', Decimals: 0 }, '13': { Name: 'Voltage', Unit: 'V', Decimals: 2 }, '14': { Name: 'Current', Unit: 'mA', Decimals: 1 }, '15': { Name: 'Time', Unit: 'h', Decimals: 0 }, '16': { Name: 'Time', Unit: 'd', Decimals: 0 }, '17': { Name: 'Pulse', Unit: 'None', Decimals: 0 }, '18': { Name: 'Resistance', Unit: 'kOhm', Decimals: 2 }, '19': { Name: 'Volume', Unit: 'l', Decimals: 0 }, '20': { Name: 'Speed', Unit: 'km/h', Decimals: 0 }, '22': { Name: 'FlowRate', Unit: 'l/min', Decimals: 0 }, '23': { Name: 'Pressure', Unit: 'bar', Decimals: 2 }, '24': { Name: 'Performance Factor', Unit: 'None', Decimals: 2 }, '28': { Name: 'Volume', Unit: 'm3', Decimals: 0 }, '35': { Name: 'FlowRate', Unit: 'l/d', Decimals: 0 }, '36': { Name: 'Speed', Unit: 'm/s', Decimals: 0 }, '37': { Name: 'FlowRate', Unit: 'm3/min', Decimals: 0 }, '38': { Name: 'FlowRate', Unit: 'm3/h', Decimals: 0 }, '39': { Name: 'FlowRate', Unit: 'm3/d', Decimals: 0 }, '50': { Name: 'Currency', Unit: 'Euro', Decimals: 2 }, '51': { Name: 'Currency', Unit: 'USD', Decimals: 2 }, '52': { Name: 'Absolute Humidity', Unit: 'g/m3', Decimals: 1 }, '53': { Name: 'None', Unit: 'None', Decimals: 5 }, '54': { Name: 'Angle', Unit: 'Degree', Decimals: 2 }, '58': { Name: 'None', Unit: 'None', Decimals: 1 }, '63': { Name: 'Current', Unit: 'A', Decimals: 1 }, '65': { Name: 'Pressure', Unit: 'mbar', Decimals: 1 }, '66': { Name: 'Pressure', Unit: 'Pa', Decimals: 0 }, '-1': { Name: 'Undefinded', Unit: 'None', Decimals: 0 } };
Ist aber ein älterer Firmware Stand, ich glaube die haben was geändert.
Heisst also übersetzt, du musst in der UVR und im CMI die richtige Messgröße einstellen und eine entsprechend skalierte Integerzahl über den Bus schicken. So wird dann aus 227 und der Einheit Temperatur die gewünschten 22,7 °C.
Im ioBroker Modbus Adapter kann man bei den Registern das Verhalten über den Faktor steuern. So würde hier ein Temperaturwert einen Faktor 10 bekommen. Sprich ein anderer ioBroker Adapter sendet 22,7 °C, der Modbus Adpater skaliert mit 10 (=227) und die UVR macht dann über die eingestellte Einheit wieder 22,7 draus.
Braucht man eine höhere Genauigkeit, gibt es auch eine dimensionslose Einheit mit 5 Dezimalstellen. Hier wäre entsprechend mit 100.000 zu skalieren.
-
Vielen Dank für die tolle Erklärung.
Das mit den Messgrößen habe ich damit super hinbekommen.
Allerdings sieht es derzeit so aus, als würde die CMI das Register des Modbus-Adapters nicht triggern.
Nur wenn ich den Modbus-Adapter neu starte, bekomme ich neue Werte.
Meine CMI Einstellung:
siehe Bild
6962_download__1_.png -
Allerdings sieht es derzeit so aus, als würde die CMI das Register des Modbus-Adapters nicht triggern.
Nur wenn ich den Modbus-Adapter neu starte, bekomme ich neue Werte. `
Die Anzeige in den CMI Einstellungen aktualisiert sich nicht freiwillig (zumindest bei mir). Wenn ein neuer Wert gesendet wurde (Intervallzeiten beachten) und man drückt, wie in deinem Screenshot dargestellt, nochmals auf "Speichern" aktualisiert sich der Wert.In der UVR sollten die Werte ankommen, also am besten dort testen oder über ein Online-Schema in der CMI.
-
Hallo,
das sich die Anzeige im CMI nur nach dem Speichern erneut aktualisiert ist klar.
Leider aktualisiert sich der Wert in der UVR sowie im Onlineschema erst nach Neustart des Modbus-Adapters.
-
Sorry für die späte Antwort, ich war geschäftlich unterwegs.
Kann mir keinen direkten Reim drauf machen, warum es bei dir nicht funktioniert. Läuft bei mir anstandslos mit mehreren Werten. Ich hab mal ein Beispiel von mir angehängt:
Kann es vielleicht sein, dass du eine hohe "Sendebedingung bei Änderung" hast?
-
Hallo Sineos:
vielen Dank für deine Mühe.
Genauso wie in deinen Beispiel habe ich die Einstellungen auch.
Trotzdem werden ohne periodischen Modbus_Neustart keine Werte in Richtung Modbus (iobroker) und Modbus (UVR1611) aktualisiert.
Ich habe Werte in sämtlichen Registern getestet – gleiches Ergebnis.
Ich wollte einen Heizkreis der UVR mittels Raumthermostat der Homematic steurern (Vorlaufsoll).
Ich muss mir was anderes einfallen lassen.
Nochmal vielen Dank für die Mühe.
-
Vielleicht noch ein paar Ideen:
-
Ich benutze node-red für die Übertragung an den Modbus Adapter. Siehe Screenshot
-
Screenshot meines Eingangsregisters
-
In der CMI Firmware gab es ein paar Bugfixes den Modbus betreffend. Neueste CMI Firmware ist gerade 1.30.2
-
Ggf. mal den Modbus Adpater auf Debug setzen und schauen ob er auch tatsächlich periodisch neue Werte bekommt
-
Den Modbus Adpater über die Konsole (nicht in der WebUI) neu installieren und schauen ob diese fehlerfrei durchläuft
-
-
Habe alles durchprobiert.
Neuste Firmware auf dem CMI, Modbus Adpater auf Debug gesetzt, Adapter neu installiert über Konsole.
Immer das gleiche Ergebnis: in Richtung Iobroker läuft der Modbus; in Richtung CMI leider nicht.
Scheint am CMI zu liegen.
Nochmal vielen Dank für deine Mühe.
Wenn ich dazu komme teste ich es mal über node-red.
Grüsse
-
Wenn dein CMI einmalig die Daten nach einem Neustart des Modbus Adapter bekommt, dann glaube ich nicht, dass es am CMI liegt. Auch ist das CMI der Master und sitzt deshalb eigentlich nur faul rum und wartet bis ein Slave sich meldet. Heißt, der Modbus Adapter baut für jeden Wert eine neue Verbindung zum Master auf. Ich denke, das Problem liegt irgendwo in deiner ioBroker Instanz.
Du kannst den Modbus auch mit Tools wie z.B. http://www.tuomio.fi/ananas/index.htm testen:
-
Hallo Sineos,
vielen Dank für den Tipp mit dem Tool Ananas.
An ihm konnte ich erkennen, dass es nicht am CMI liegt.
In Ananas wird der Modbus Wert des iobrokers auch nicht aktualisiert.
Dies bezieht sich aber nur auf das Input-Register.
Die Holdings und Coils werden aktualisiert!
Ich kann es mir nicht erklären.
Die Werte in den Objekten des Iobroker werden brav aktualisiert und angezeigt.
Ich weiss nicht weiter.
-
Mir fällt jetzt leider auch nichts mehr ein.
Einzig vielleicht auf https://github.com/ioBroker/ioBroker.modbus ein Issue aufmachen mit Referenz zu diesem Thread. Vielleicht können die Entwickler zusätzliche Debug-Ausgaben hinzufügen, um zu sehen wo was falsch läuft.
-
Und momentan maximal den Modbus-Adapter in Version 1.1.2 verwenden, da die Slave-Option in 2.x broken ist.
-
Lässt sich leider bei mir nicht mehr downgraden..
-
Öhm, doch geht. Brauchst Du aber nicht mehr, weil jetzt eine neuere Variante von 2.0.6 auf Github steht. Die neuste Version (immer noch 2.0.6, aber von Bluefox nachgebessert) tut jetzt bei "Slave" was sie soll.
Lösung: Die Partner-ID auf 0.0.0.0 stellen oder die IP des ioBroker Servers angeben. Das funktioniert bei mir. Den Rest wie bei 1.1.2 lassen.
Nutzt du auch eine UVR? Edit: Dumme Frage