NEWS
Rest API, Value von Gerät auslesen, In Datenpunkt schreiben
-
ich spreche von dem skript das in der beschreibung enthalten ist
var http = require('http'); var xpath = require('xpath'); var dom = require('xmldom').DOMParser; var etaIP = 'http://192.168.XYZ.XYZ:8080/user/var'; // 1. URI // 2. iobroker Object // 3. read // 4. write // 5. name // 6. type // 7. unit // 8. role // 9. CCU variable (optional) var etaVars = [ ["/120/10251/0/0/12242", "eta.puffer.oben", true, false, "Puffer oben", "number", "°C", "value.temperature", "hm-rega.0.1810"] ,["/120/10251/0/0/12244", "eta.puffer.unten", true, false, "Puffer unten", "number", "°C", "value.temperature", "hm-rega.0.1811"] ,["/120/10251/0/0/12207", "eta.puffer.aktion", true, false, "Puffer Aktion", "string", "", "state", "hm-rega.0.1809"] ,["/120/10251/0/0/12533", "eta.puffer.leistung", true, false, "Puffer Leistung", "number", "KW", "state", "hm-rega.0.5038"] ,["/120/10251/0/0/12129", "eta.puffer.zustand", true, false, "Puffer Zustand", "string", "", "state", ""] ,["/120/10101/0/0/12090", "eta.hk.1.zustand", true, false, "Heizkreis Zustand", "string", "", "state", "hm-rega.0.1812"] ,["/120/10101/0/0/12241", "eta.hk.1.vorlauf", true, false, "Heizkreis Vorlauf", "number", "°C", "value.temperature", "hm-rega.0.8047"] ,["/120/10101/0/0/12111", "eta.hk.1.heizkurve", true, false, "Heizkreis Heizkurve", "number", "°C", "value.temperature", "hm-rega.0.8048"] ,["/120/10101/0/11124/0", "eta.hk.1.pumpe", true, false, "Heizkreis Pumpe", "string", "", "state", "hm-rega.0.1813"] ,["/120/10101/0/11124/2001", "eta.hk.1.anforderung", true, false, "Heizkreis Anforderung", "string", "", "state", ""] ,["/40/10021/0/0/12000", "eta.kessel.aktion", true, false, "Kessel", "string", "", "state", "hm-rega.0.1822"] ,["/40/10021/0/0/12153", "eta.kessel.vollast", true, false, "Kessel Vollaststunden", "string", "", "state", "hm-rega.0.1814"] ,["/40/10021/0/0/12016", "eta.kessel.verbrauch", true, false, "Kessel Gesmtverbrauch", "number", "kg", "state", "hm-rega.0.1815"] ,["/40/10021/0/0/12013", "eta.kessel.aschebox", true, false, "Kessel Verbrauch seit Aschebox", "number", "kg", "state", ""] ,["/40/10021/0/0/12180", "eta.kessel.druck", true, false, "Kessel Druck", "number", "bar", "state", "hm-rega.0.1820"] ,["/40/10021/0/0/12001", "eta.kessel.soll", true, false, "Kessel Soll", "number", "°C", "state", "hm-rega.0.5037"] ,["/40/10021/0/0/12161", "eta.kessel.ist", true, false, "Kessel Ist", "number", "°C", "state", "hm-rega.0.3195"] ,["/40/10021/0/0/12162", "eta.kessel.abgasgtemp", true, false, "Kessel Abgastemperatur", "number", "°C", "state", "hm-rega.0.5040"] ,["/40/10021/0/0/12165", "eta.kessel.abgasgeblaese", true, false, "Kessel Abgasgebläse", "number", "U/min", "state", "hm-rega.0.5039"] ,["/40/10021/0/0/12164", "eta.kessel.restsauerstoff", true, false, "Kessel Restsauerstoff", "number", "%", "state", "hm-rega.0.5041"] ,["/40/10021/0/0/12080", "eta.kessel.zustand", true, false, "Kessel Zustand", "string", "", "state", "hm-rega.0.1808"] ,["/40/10201/0/0/12015", "eta.lager.silo", true, false, "Pellets Silo", "number", "kg", "state", "hm-rega.0.1817"] ,["/40/10021/0/0/12011", "eta.lager.tag", true, false, "Pellets Tagesbehälter", "number", "kg", "state", "hm-rega.0.9651"] ,["/40/10241/0/0/12197", "eta.system.aussentemperatur", true, false, "Aussentemperatur", "number", "°C", "state", "hm-rega.0.1821"] ]; etaVars.forEach(function(etaVar){ createState(etaVar[1], 0, { read: etaVar[2], write: etaVar[3], name: etaVar[4], type: etaVar[5], unit: etaVar[6], role: etaVar[7] }); }); schedule("*/5 * * * *", function () { pollETA(); }); pollETA(); function pollETA() { // console.log("** Polling ETA Variables"); etaVars.forEach(function(etaVar){ http.get(etaIP + etaVar[0], function (http_res) { // initialize the container for our data var data = ""; // this event fires many times, each time collecting another piece of the response http_res.on("data", function (chunk) { // append this chunk to our growing `data` var data += chunk; // console.log("** ETA chunk: " + chunk); }); // this event fires *one* time, after all the `data` events/chunks have been gathered http_res.on("end", function () { // console.log("** ETA data: " + data); try { var doc = new dom().parseFromString(data); var select = xpath.useNamespaces({"eta": "http://www.eta.co.at/rest/v1"}); var strValue = (select('//eta:value/@strValue', doc)[0].nodeValue); var text = (select('//eta:value/text()', doc)[0].nodeValue); var scaleFactor = (select('//eta:value/@scaleFactor', doc)[0].nodeValue); var unit = (select('//eta:value/@unit', doc)[0].nodeValue); var value = ""; if (etaVar[5]=="number") { value = text * 1.0 / scaleFactor; } else { value = strValue; } /* console.log("**** ETA " + etaVar[0] + " @strValue: " + strValue); console.log("**** ETA " + etaVar[0] + " @unit: " + unit); console.log("**** ETA " + etaVar[0] + " text() : " + text); console.log("**** ETA " + etaVar[0] + " @scaleFactor: " + scaleFactor); console.log("** ETA [" + etaVar[4] + "]: " + value + " " + unit); */ setState(etaVar[1], value); // Schreibe Variablen zu CCU if(etaVar[8]!="") { setState(etaVar[8], value); } } catch (e) { log("ETA: Cannot set data "+ etaVar[2] +":" + e, 'error'); } }); }); }); var dateFormat = require('dateformat'); var currentdate = new Date(); log(dateFormat(currentdate, "dd. mmm yyyy hh:MM")); // optional last update in CCU3 setState("hm-rega.0.7022", dateFormat(currentdate, "dd. mmm yyyy hh:MM")); }
-
@wusa sagte in Rest API, Value von Gerät auslesen, In Datenpunkt schreiben:
Könnte ich mir Regex weiter kommen?
Ja, einfacher wäre es aber das XML direkt zu parsen. Oder gibt es ggf. einen Parameter, dass man als Antwort gerne JSON statt XML hätte. Was ist das denn für eine Heizung?
-
Ich weiß nicht genau was du meinst. Wie die Daten verarbeietet werden, ist mir eigentlich egal. Mir ist nur der Wert von "strValue" wichtig. Da würde ich gerne dran kommen.
Es handelt sich um eine ETA Heizung.
-
@haus-automatisierung sagte in Rest API, Value von Gerät auslesen, In Datenpunkt schreiben:
Ja, einfacher wäre es aber das XML direkt zu parsen
dazu muss er erst einmal die daten abrufen können. da scheint es noch daran zu haken
@wusa
kopiere das gepostete skript einfach mal im javascript adapter in ein skript.
dann trage in den javasceript adapter einstellungen als zusätzliche npm module nochxpath
xmldomein. dann müsste das skript laufen und verschiedene datenpunkt anlegen
den letzten befehl
setState("hm-rega.0.7022", dateFormat(currentdate, "dd. mmm yyyy hh:MM"));
löschen, der könnte für dich nicht passen -
@oliverio Ah, ich habe nicht alle Beiträge genau gelesen. Dachte es liegt nur noch am XML, weil hier ja zuletzt Lösungen zum Parsen geteilt wurden.
Dann das Script mal auf den Verbose-Mode umschalten und ggf. den Timeout im Blockly-Baustein erhöhen.
-
Hier ist nochmal die ganze Seite. So wird es angezeigt.
Es wird von REST API gesprochen. Es kommt aber XML-Datei in der Meldung.
Ich bin mir hier leider auch nicht ganz sicher, wie ich ans Ziel komme. -
@oliverio
Das könnte funktioniere. Wollte das aber gerne über einen eigenen Adapter oder über das Blockly lösen.
Wenn etwas neues hinzukommt, dann kann man das relative leicht lösen.
Das Skript verstehe ich zb. gar nicht, daher würde ich es gerne umgehen.Dachte jetzt ehrlich gesagt erstmal an Blockly oder dann an den Parse Adapter.
-
@wusa sagte in Rest API, Value von Gerät auslesen, In Datenpunkt schreiben:
Es wird von REST API gesprochen. Es kommt aber XML-Datei in der Meldung.
Ist doch alles richtig, eine REST-API kann auch XML zurück liefern. Bitte erstmal die Tipps von oben umsetzen. Ist ja soweit auf den ersten Blick alles richtig.
-
@wusa
Wie @haus-automatisierung schon schieb: REST sagt erstmal nix über das Format der Antwort.Probier vielleicht zuerst mal, den Timeout höher zu setzen und lass Dir die Antwort einfach per Debug-Block ausgeben.
Dann sehen wir weiter. -
@haus-automatisierung
Zeit habe ich erhöht. Bisher keine Besserung. Aber was meinst du mit Verbose Modus genau?
Meinst du den Schraubenschlüssel und "Ausführliche Protokollausgaben"? -
-
das gerät anwortet ja auch nicht. was soll da ausgegeben werden?
-
@wusa
Ruf das nochmal im Browser auf und schau per F12 auf den Network-Tab.
Dort siehst Du, wie lange es bis zur Antwort dauert. -
@wusa sagte: Mir ist nur der Wert von "strValue" wichtig.
Funktioniert es denn mit "request"? Wenn ja, dann versuche es mal so:
-
Ich merke gerade, dass ich noch ein ganz anderes Problem habe.
Ich bekommen keinen Ping durch zu dem Gerät. Die Antwort kommt im Browser aber trotzdem.Ich kümmere mich jetzt mal um das Ping Problem, vielleicht sieht es dann schon wieder ganz anders aus.
-
@wusa sagte in Rest API, Value von Gerät auslesen, In Datenpunkt schreiben:
Aber was meinst du mit Verbose Modus genau?
Na die "ausführlichen Protokollausgaben" oben rechts im Script.
@wusa sagte in Rest API, Value von Gerät auslesen, In Datenpunkt schreiben:
Ich bekommen keinen Ping durch zu dem Gerät.
Nicht jedes Gerät muss auf einen Ping (ICMP) antworten. Das hat nichts zu sagen. Da würde ich jetzt keine Zeit investieren.
-
das mag sein, das ein gerät nicht darauf antworten muss.
das icmp protokoll (ping ist ein abfallprodukt daraus) ist aber essentiell zur ip steuerung. daher würde es mich wundern, wenn gerade bei einem headless gerät das nicht implementiert wurde, da icmp meist schon bestandteil des eigentlichen netzwerk stacks ist. wenn icmp nicht durchkommt, dann weil firewalls die messages herausfiltern, da man dadurch auch netzwerkinfrastruktur ausforschen kann. -
@oliverio sagte in Rest API, Value von Gerät auslesen, In Datenpunkt schreiben:
das icmp protokoll (ping ist ein abfallprodukt daraus) ist aber essentiell zur ip steuerung.
Ja, und da funktioniert doch erstmal alles (der GET-Request aus dem Browser heraus wird ja beantwortet). Mich würde die Verbose-Ausgabe mehr interessieren. Ich wollte @wusa nur davon abhalten, am falschen Ende zu suchen und Zeit zu verschwenden.
-
ICMP funktioniert grundsätzlich.
Von einem anderen Gerät aus kommt der Ping wunderbar durch. Nur vom iobroker Server kommt der Ping nicht durch. -
ich habe iobroker im docker container laufen
mein ping zum router geht durch.wie schon erwähnt filtern firewalls die icmp nachrichten (aber nicht standardmäßig, wenn dann muss das konfiguriert sein.).
liegt das evtl an deinem wireguard? warst du nicht das mit wireguard im anderen thread?
auch überschreiten icmp nachrichten nicht die grenzen des netzwerksegments. also wenn deine netzmaske bspw bei 255.255.255.0 liegt, dann kannst du bspw nur von 192.168.1.10 nach 192.168.1.20 pingen. also die ersten 3 ziffern der ip adresse muss identisch sein.das mal nur als hinweis für die fehlersuche