NEWS
Daten aus einer Website mit Javascript
-
Hi
nun sind bei mir auch die Fehler scheinbar weg. Danke!
Eine Frage noch:
Die Werte D_Y_4_xx haben einen "Namen" von "Prozentsatz Regeneration 1vor aktueller". Abgesehen von dem Fehlenden Leerzeichen zwischen der Zahl und dem Wort "vor" bekomme ich hier als Werte allerdings Stunden / Minuten angezeigt ??!?!?!?! `
Ja, da ist noch ein Fehler enthalten.
D_Y_4_xx ist die Zeit von Regeneration zu Regeneration und D_A_3_2_xx sollte die Prozentangabe der Regeneration sein.
Du kanns entweder den Text ändern oder das Script anpassen.
-
Erst mal danke an alle für das Script und die Anleitung.
Habe auch als Laie, was Java Script angeht, alles soweit hinbekommen.
Weiss jemand wie man eine manuelle Regeneration über IO Brocker auslösen kann ?
-
Für alle die was kopieren wollen habe mein View Gruenbeck eingefügt
10332_21_gruenbeck.txt
10332_gr_nbeck.png -
Ich hatte heute etwas Zeit um mich mit dem Thema zu beschäftigen.
Ich habe die Enthärtungsanlage softliQ:SC18 und bei mir erhalte ich
bei folgenden Abfragen keine vernüftige Rückmeldungen:
D_C_5_2 Datum (kein Wert)
D_C_5_3 Sommer/Winterzeit (kein Wert)
D_Y_13 wird bei mir Wert 0 angezeigt was nach der Austauscher gestört bedeutet, obwohl keine Störung vorliegt.
D_A_3_2_1-14 wird bei allen Werten nur der Prozentsatz der letzten Regeneration angezeigt und nicht der letzten 14 Regenerationen
D-A-3_1 sollte nach der Schnittstellenbeschreibung ein String sein (TT.MM.JJJ HH:MM) ist aber die Zeit der letzten Regeneration in h
Meine Frage ist, ob das bei allen so ist, oder jemand mit der SC18 da was Sinnvolles angezeigt bekommt ?
-
D_C_5_2 Datum (kein Wert)
=> Anfrage liefert keinen Wert => Wert ist aber eigentlich auch uninteressant => wurde entfernt
D_C_5_3 Sommer/Winterzeit (kein Wert)
=> Anfrage liefert keinen Wert => Wert ist aber eigentlich auch uninteressant => wurde entfernt
D_Y_13 wird bei mir Wert 0 angezeigt was nach der Austauscher gestört bedeutet, obwohl keine Störung vorliegt.
=> Da hast du eigentlich recht. Ist bei meiner Anlage auch so. Nicht gestört oder in Regeneration und 0 :shock:
D_A_3_2_1-14
=> Auch hier hast du recht. Ist bei meiner Anlage auch so. :shock:
D_A_3_1
=> Auch hier hast du recht. Ist bei meiner Anlage auch so. :shock:
Ich habe das Script nochmals überarbeitet.
siehe Seite 1
6543_gruenbeck_webserver_dokumentation.pdf -
Ich muss nochmals meine Frage zum Wasserverbrauch aufgreifen.
Da die meisten mit einem Verschnitt arbeiten (wer will schon eine Härte von 0), muss der Wasserverbrauch doch berechnet werden, da ein Teil des Wassers ja an der Anlage vorbei geht, oder sehe ich das hier komplett falsch?
-
Die Anzeige des momentanen Verbrauchs bezieht sich auf das 0°dH Wasser welches durch die Anlage selber geht . Um den realen Durchfluss zuhaben, müsstest du den prozentualen Verschnitt über das Verschneide Ventil mit dazu rechnen.
-
Vielleicht noch ein paar hinweiße zur Erklärung der Kapazitätszahl (Anlagenkapazität), die ich im Haustechnik Dialog Forum, gefunden habe.
Die Kapazitätszahl errechnet sich durch den Durchschnittsverbrauch 0 °dH Wasser der drei letzten Tage, ohne Verschnittwasser
mal je nach Modus Eco 1,3 und Power 1,8 mal Grundhärte.
Berechnung der automatischen Einstellung der Anlagenkapazität
= Wasser Durchschnittverbrauch x (1,3 Eco, oder 1,8 Power) x Grundhärte
Kleines Beispiel:
Verbrauch vor 1 Tag 323 l, vor 2 Tagen 292 l, vor 3 Tagen 282 l, Einstellung Power Modus, Grundwasserhärte 21 °dH
323+292+282 = 897 l /3 = 299 l Wasser Durchnittsverbrauch
299 l x 1,8 (Power Modus) = 538,2 l x 21 °dH = 11,30 qm x °dH
Hier noch ein paar Berechnungen, die interessant sind:
- Berechnung Restkapazität (max)
= Anlagenkapazität / Grundhärte
- Berechnung max. Verschnittwassermenge (Grundhärtewasser und SC18-Wasser)
= Anlagenkapazität / (Grundhärte - Schnitthärte)
-
hiasii12 kannst du das Script noch etwas optimieren ??
In der Schnittstellenbeschreibung steht "Um die Schnittstelle zuverlässig betreiben zu können, sollte der Abstand zweier Anfragen eine Zeit
von 15 Sekunden zueinander nicht unterschreiten."
Das konnte ich bereits auch feststellen, da ich bei weniger als 15 sek. keine Einstellungen mehr mit der Grünbeck APP verändern konnte.
Ich würde gerne alle Werte in ein Paket packen und alle 15 sek. abfragen, nicht wie jetzt über drei Abfragen verteilt.
Die Werte für Wasserverbrauch D_Y_2_xx und Zeit letzte Regeneration D_Y_4_xx würden einmal am Tag ausreichen, da sich ja nichts ändert.
(z.B. immer um 1:00 Uhr in der Nacht)
Würde es ja selber machen, aber bei der Aufgabe, Werte nur einmal am Tag abfragen, scheitere ich mit meinen Scriptkenntnissen. :?
So sieht mein View jetzt aus
Ach ja, wenn jetzt noch jemand weiss wie mann eine manuelle Regeneration über Vis auslösen kann, währe ich happy :mrgreen:
-
Hallo,
vielleicht kann mir jemand helfen. Ich habe das Problem, dass das Logger-Script nicht läuft.
Die Datenpunkte wurden durch das erste Script erstellt.
Wenn ich das Logger-Script starte kommt die Fehlermeldung:javascript.0 2019-02-11 16:40:47.957 error Error in callback: Error: INVALID_STATE_ERR: send flag is true
und
error javascript.0 at Object.Interval (script.js.gruenbeck_logger:28:9)
Hat er ein Problem mit der function Interval?
Hier noch mein komplettes Script:
// Logger // Wichtige Daten hier anpassen // V1.0: Erstellung // V1.1: Header mit Konstanten hinzu; // Verbindungsüberwachung hinzu; // V1.2: Datum auslesen entfernt // Sommer/Winterzeit auslesen entfernt // Hier IP Adresse der Anlage eintragen var constIP = "192.168.10.31" // Hier Namen der State Variable eintragen wenn Verbindung über Ping Adapter geprüft werden soll // Wenn kein Ping Adapter verwendet werden soll dan True eintragen var statePingAdapter = 'ping.0.iobroker.192_168_10_31' // Hier Abfragezyklus in Sekunden eintragen var constTick = 5 var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; var parser = require('xmldom').DOMParser; var xhr = new XMLHttpRequest(); var requestNumber = 1 ; xhr.onload = function () { }; xhr.onerror = function () { }; var varInterval = setInterval(Interval, constTick * 1000 ); function Interval() { var connection = getState(statePingAdapter) // console.log(connection.val); if (connection.val) { xhr.open("POST","http://" + constIP + "/mux_http"); xhr.setRequestHeader("Content-type", "application/json"); xhr.responseType = "document"; switch(requestNumber) { case 1: //console.log('Request ' + requestNumber + ' ausgeführt'); xhr.send("id=8871&show=D_Y_2_1|D_Y_2_2|D_Y_2_3|D_Y_2_4|D_Y_2_5|D_Y_2_6|D_Y_2_7|D_Y_2_8|D_Y_2_9|D_Y_2_10|D_Y_2_11|D_Y_2_12|D_Y_2_13|D_Y_2_14~"); xhr.onreadystatechange = function() { if (xhr.readyState==4) { if (xhr.status == 200) { if (xhr.responseText) { var str = xhr.responseText; const regex = /<data>`([^\<]+)<\/code><d_y_2_1>([^\<]+)<\/D_Y_2_1><d_y_2_2>([^\<]+)<\/D_Y_2_2><d_y_2_3>([^\<]+)<\/D_Y_2_3><d_y_2_4>([^\<]+)<\/D_Y_2_4><d_y_2_5>([^\<]+)<\/D_Y_2_5><d_y_2_6>([^\<]+)<\/D_Y_2_6><d_y_2_7>([^\<]+)<\/D_Y_2_7><d_y_2_8>([^\<]+)<\/D_Y_2_8><d_y_2_9>([^\<]+)<\/D_Y_2_9><d_y_2_10>([^\<]+)<\/D_Y_2_10><d_y_2_11>([^\<]+)<\/D_Y_2_11><d_y_2_12>([^\<]+)<\/D_Y_2_12><d_y_2_13>([^\<]+)<\/D_Y_2_13><d_y_2_14>([^\<]+)<\/D_Y_2_14><\/data>/; const subst = regex.exec(str); if (subst) { for ( i = 1; i < 15; i++ ) { i1 = i + 1; if (i < 10) setState("Messwerte.0.SC18.Wasserverbrauch.D_Y_2_0" + i , parseInt(subst[i1]) ); else setState("Messwerte.0.SC18.Wasserverbrauch.D_Y_2_" + i , parseInt(subst[i1]) ); } } requestNumber = 2; } } } }; break; case 2: //console.log('Request ' + requestNumber + ' ausgeführt'); xhr.send("id=8871&show=D_C_4_1|D_C_4_2|D_C_4_3|D_C_5_1|D_C_7_1~"); xhr.onreadystatechange = function() { if (xhr.readyState==4) { if (xhr.status == 200) { if (xhr.responseText) { var str = xhr.responseText; const regex = /<data>`([^\<]+)<\/code><d_c_4_1>([^\<]+)<\/D_C_4_1><d_c_4_2>([^\<]+)<\/D_C_4_2><d_c_4_3>([^\<]+)<\/D_C_4_3><d_c_5_1>([^\<]+)<\/D_C_5_1><d_c_7_1>([^\<]+)<\/D_C_7_1><\/data>/; const subst = regex.exec(str); if (subst) { setState("Messwerte.0.SC18.Allgemein.D_C_4_1" , parseInt(subst[2]) ); setState("Messwerte.0.SC18.Allgemein.D_C_4_2" , subst[3] ); setState("Messwerte.0.SC18.Allgemein.D_C_4_3" , subst[4] ); setState("Messwerte.0.SC18.Allgemein.D_C_5_1" , parseInt(subst[5]) ); setState("Messwerte.0.SC18.Allgemein.D_C_7_1" , parseInt(subst[6]) ); } requestNumber = 3; } } } }; break; case 3: //console.log('Request ' + requestNumber + ' ausgeführt'); xhr.send("id=8871&show=D_Y_4_1|D_Y_4_2|D_Y_4_3|D_Y_4_4|D_Y_4_5|D_Y_4_6|D_Y_4_7|D_Y_4_8|D_Y_4_9|D_Y_4_10|D_Y_4_11|D_Y_4_12|D_Y_4_13|D_Y_4_14~"); xhr.onreadystatechange = function() { if (xhr.readyState==4) { if (xhr.status == 200) { if (xhr.responseText) { var str = xhr.responseText; const regex = /<data>`([^\<]+)<\/code><d_y_4_1>([^\<]+)<\/D_Y_4_1><d_y_4_2>([^\<]+)<\/D_Y_4_2><d_y_4_3>([^\<]+)<\/D_Y_4_3><d_y_4_4>([^\<]+)<\/D_Y_4_4><d_y_4_5>([^\<]+)<\/D_Y_4_5><d_y_4_6>([^\<]+)<\/D_Y_4_6><d_y_4_7>([^\<]+)<\/D_Y_4_7><d_y_4_8>([^\<]+)<\/D_Y_4_8><d_y_4_9>([^\<]+)<\/D_Y_4_9><d_y_4_10>([^\<]+)<\/D_Y_4_10><d_y_4_11>([^\<]+)<\/D_Y_4_11><d_y_4_12>([^\<]+)<\/D_Y_4_12><d_y_4_13>([^\<]+)<\/D_Y_4_13><d_y_4_14>([^\<]+)<\/D_Y_4_14><\/data>/; const subst = regex.exec(str); if (subst) { for ( i = 1; i < 15; i++ ) { i1 = i + 1; if (i < 10) setState("Messwerte.0.SC18.Regenerationen.D_Y_4_0" + i , subst[i1] ); else setState("Messwerte.0.SC18.Regenerationen.D_Y_4_" + i , subst[i1] ); } requestNumber = 4; } } } } }; break; case 4: //console.log('Request ' + requestNumber + ' ausgeführt'); xhr.send("id=8871&show=D_Y_5|D_Y_7|D_Y_8_11|D_Y_10_1|D_Y_13|D_Y_14|D_B_1|D_C_5_1~"); xhr.onreadystatechange = function() { if (xhr.readyState==4) { if (xhr.status == 200) { if (xhr.responseText) { var str = xhr.responseText; const regex = /<data>`([^\<]+)<\/code><d_y_5>([^\<]+)<\/D_Y_5><d_y_7>([^\<]+)<\/D_Y_7><d_y_8_11>([^\<]+)<\/D_Y_8_11><d_y_10_1>([^\<]+)<\/D_Y_10_1><d_y_13>([^\<]+)<\/D_Y_13><d_y_14>([^\<]+)<\/D_Y_14><d_b_1>([^\<]+)<\/D_B_1><d_c_5_1>([^\<]+)<\/D_C_5_1><\/data>/; const subst = regex.exec(str); if (subst) { setState("Messwerte.0.SC18.Allgemein.D_Y_5" , parseInt(subst[2]) ); setState("Messwerte.0.SC18.Allgemein.D_Y_7" , subst[3] ); setState("Messwerte.0.SC18.Allgemein.D_Y_8_11" , parseInt(subst[4]) ); setState("Messwerte.0.SC18.Allgemein.D_Y_10_1" , parseInt(subst[5]) ); setState("Messwerte.0.SC18.Allgemein.D_Y_13" , parseInt(subst[6]) ); setState("Messwerte.0.SC18.Allgemein.D_Y_14" , subst[7] ); setState("Messwerte.0.SC18.Allgemein.D_B_1" , parseInt(subst[8]) ); setState("Messwerte.0.SC18.Allgemein.D_C_5_1" , parseInt(subst[9]) ); } requestNumber = 5; } } } }; break; case 5: //console.log('Request ' + requestNumber + ' ausgeführt'); xhr.send("id=8871&show=D_A_1_1|D_A_1_2|D_A_1_3|D_A_2_1|D_A_3_1|D_A_3_2~"); xhr.onreadystatechange = function() { if (xhr.readyState==4) { if (xhr.status == 200) { if (xhr.responseText) { var str = xhr.responseText; const regex = /<data>`([^\<]+)<\/code><d_a_1_1>([^\<]+)<\/D_A_1_1><d_a_1_2>([^\<]+)<\/D_A_1_2><d_a_1_3>([^\<]+)<\/D_A_1_3><d_a_2_1>([^\<]+)<\/D_A_2_1><d_a_3_1>([^\<]+)<\/D_A_3_1><d_a_3_2>([^\<]+)<\/D_A_3_2><\/data>/; const subst = regex.exec(str); if (subst) { setState("Messwerte.0.SC18.Aktualwerte.D_A_1_1" , parseFloat(subst[2]) ); setState("Messwerte.0.SC18.Aktualwerte.D_A_1_2" , parseFloat(subst[3]) ); setState("Messwerte.0.SC18.Aktualwerte.D_A_1_3" , parseFloat(subst[4]) ); setState("Messwerte.0.SC18.Aktualwerte.D_A_2_1" , parseInt(subst[5]) ); setState("Messwerte.0.SC18.Aktualwerte.D_A_3_1" , subst[6] ); setState("Messwerte.0.SC18.Aktualwerte.D_A_3_2" , parseInt(subst[7]) ); } requestNumber = 1; } } } }; } } }
Auch ist mir die folgende Zeile im Original-Script nicht ganz klar:
var statePingAdapter = 'ping.0.matthias-SS15HT.192_168_0_132'/192 168 0 132/
gehört das /192 168 0 132/ mit dazu oder ist das ein Kommentar?
Wenn ich das mit reinschreibe, gibt es ein compile error.Gruß
Marc -
So, der Fehler ist, warum auch immer, verschwunden?!
Allerdings werden keine Daten in die Objekte geschrieben.
Ich habe mit console.Log das Script im Betrieb mal überprüft:- console.Log(xhr.responseText) enthält die Daten, die mit xhr.send angefragt wurden
- console.Log(subst) hat aber den Inhalt null. Es scheint so, dass das regex nicht richtig funktioniert oder sehe ich das falsch?
Wenn ich es auf der Seite regex101.com wie folgt teste, gibt es keine Übereinstimmung:
REGULAR EXPRESSION
<data>`([^\<]+)<\/code><d_c_4_1>([^\<]+)<\/D_C_4_1><d_c_4_2>([^\<]+)<\/D_C_4_2><d_c_4_3>([^\<]+)<\/D_C_4_3><d_c_5_1>([^\<]+)<\/D_C_5_1><d_c_7_1>([^\<]+)<\/D_C_7_1><\/data>
TEST STRING
<data><code>ok</code><D_C_4_1>1</D_C_4_1><D_C_4_2>13:10</D_C_4_2><D_C_4_3>02:00</D_C_4_3><D_C_5_1>0</D_C_5_1><D_C_7_1>365</D_C_7_1></data>
Könnte hier jemand sein Logger-Script einstellen, was bei ihm funktioniert?
Ich habe es von hier kopiert, aber durch den Seitenumzug ist ja, wie man ganz oben sieht, alles zerschossen und ich bin mir nicht sicher ob mein Script soweit i.O. ist bzw. ob ich es richtig kopiert habe.Gruß
Marc -
So, Problem gefunden.
Durch die Forenumstellung sind die 2 Skripte oben unbrauchbar.Hier die 2, die bei mir jetzt einwandfrei laufen:
statemachine// StateMaschine var i // Wasserverbrauch var path = 'Messwerte.0.SC18.Wasserverbrauch.'; for ( i = 1; i < 15; i++ ) { if (i<10)var id = path + 'D_Y_2_0' + i; else var id = path + 'D_Y_2_' + i ; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Wasserverbrauch vor ' + i + ' Tagen' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = 'Wasserverbrauch vor ' + i + ' Tagen'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = 'Liter'; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); } // Regenerationen var path = 'Messwerte.0.SC18.Regenerationen.'; for ( i = 1; i < 15; i++ ) { if (i<10)var id = path + 'D_Y_4_0' + i; else var id = path + 'D_Y_4_' + i ; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Zeitpunkt Regenereation ' + i + ' vor aktueller'; obj.common.type = 'string'; obj.common.role = 'string'; obj.common.desc = 'Zeitpunkt Regenereation ' + i + ' vor aktueller'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = ''; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); } // Allgemeine Felder var path = 'Messwerte.0.SC18.Allgemein.'; var id = path + 'D_C_4_2'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Uhrzeit' ; obj.common.type = 'string'; obj.common.role = 'string'; obj.common.desc = 'Uhrzeit'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = 'Uhr'; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); var id = path + 'D_C_5_1'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Ansprechverhalten' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = 'Ansprechverhalten'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = ''; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); var id = path + 'D_C_4_1'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Regenerationszeitpunkt' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = 'Regenerationszeitpunkt 0= Auto 1= Fest'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = ''; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); var id = path + 'D_C_4_3'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Startzeit Regeneration' ; obj.common.type = 'string'; obj.common.role = 'string'; obj.common.desc = 'Startzeit Regeneration'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = 'Uhr'; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); var id = path + 'D_C_7_1'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Soll Service Intervalldauer' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = 'Soll Service Intervalldauer'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = 'Tage'; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); var id = path + 'D_A_2_2'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Tage bis zur nächsten Wartung' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = 'Tage bis zur nächsten Wartung'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = 'Tage'; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); var id = path + 'D_Y_5'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Aktueller Regenerationsschritt 0= keine Regeneration 1= Soletank füllen 2= Besalzen 3= Verdrängen 4= Rückspülen 5= Erstfiltrat' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = 'Aktueller Regenerationsschritt 0= keine Regeneration 1= Soletank füllen 2= Besalzen 3= Verdrängen 4= Rückspülen 5= Erstfiltrat'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = ''; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); var id = path + 'D_Y_7'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Inbetriebnahme-Datum' ; obj.common.type = 'string'; obj.common.role = 'string'; obj.common.desc = 'Inbetriebnahme-Datum'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = ''; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); var id = path + 'D_Y_8_11'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Ergebnis letzter E-Mail Versand 0=keine Mail versandt 1=Mail erfolgreich versandt 2=Benutzerdaten fehlerhaft 3= kein Internetzugang/Server nicht bereit' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = 'Ergebnis letzter E-Mail Versand 0=keine Mail versandt 1=Mail erfolgreich versandt 2=Benutzerdaten fehlerhaft 3= kein Internetzugang/Server nicht bereit'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = ''; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); var id = path + 'D_Y_10_1'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Aktuelle Restkapazität Austauscher' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = 'Aktuelle Restkapazität Austauscher'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = '%'; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); var id = path + 'D_Y_13'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = '0= Austauscher gestört/in Regeneration 1= Austauscher in Betrieb' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = '0= Austauscher gestört/in Regeneration 1= Austauscher in Betrieb'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = ''; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); var id = path + 'D_Y_14'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Voraussichtliche nächste Regeneration' ; obj.common.type = 'string'; obj.common.role = 'string'; obj.common.desc = 'Voraussichtliche nächste Regeneration'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = ''; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); //region D_B_1 Regeneration var id = path + 'D_B_1'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Regeneration aktiv' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = 'Regeneration aktiv'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = ''; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); // Aktualwerte var path = 'Messwerte.0.SC18.Aktualwerte.'; //region D_A_1_1 var id = path + 'D_A_1_1'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Aktueller Durchfluss' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = 'Aktueller Durchfluss'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = 'm³/h'; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); //endregion D_A_1_1 //region D_A_1_2 var id = path + 'D_A_1_2'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Restkapazität' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = 'Restkapazität'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = 'm³*°dH'; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); //endregion //region D_A_1_3 var id = path + 'D_A_1_3'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Kapazitätszahl' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = 'Kapazitätszahl'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = 'm³*°dH'; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); //endregion //region D_A_2_1 var id = path + 'D_A_2_1'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Restzeit/-menge Reg.Schritt' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = 'Restzeit/-menge Reg.Schritt'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = 'l oder min'; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); //endregion //region D_A_3_1 var id = path + 'D_A_3_1'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Letzte Regeneration' ; obj.common.type = 'string'; obj.common.role = 'string'; obj.common.desc = 'Letzte Regeneration vor x h'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = 'h'; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); //endregion //region D_A_3_2 var id = path + 'D_A_3_2'; var obj = {}; obj.type = 'state'; obj.common = {}; obj.common.name = 'Letzte Regeneration Über' ; obj.common.type = 'number'; obj.common.role = 'number'; obj.common.desc = 'Letzte Regeneration Über'; obj.common.read = true; obj.common.write = true; obj.common.def = 0; obj.common.min = 0; obj.common.unit = '%'; setObject(id, obj, function(err) { if(err) log('Cannot write object: ' + err); else setState(id, obj.common.def); }); //endregion
logger
// Logger // Wichtige Daten hier anpassen // V1.0: Erstellung // V1.1: Header mit Konstanten hinzu; // Verbindungsüberwachung hinzu; // V1.2: Datum auslesen entfernt // Sommer/Winterzeit auslesen entfernt // Hier IP Adresse der Anlage eintragen var constIP = "192.168.10.31" // Hier Namen der State Variable eintragen wenn Verbindung über Ping Adapter geprüft werden soll // Wenn kein Ping Adapter verwendet werden soll dan True eintragen var statePingAdapter = 'ping.0.iobroker.192_168_10_31' // Hier Abfragezyklus in Sekunden eintragen var constTick = 15 var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; var parser = require('xmldom').DOMParser; var xhr = new XMLHttpRequest(); var requestNumber = 1 ; xhr.onload = function () { }; xhr.onerror = function () { }; var varInterval = setInterval(Interval, constTick * 1000 ); function Interval() { var connection = getState(statePingAdapter); // console.log(connection.val); if (connection.val) { xhr.open("POST","http://" + constIP + "/mux_http"); xhr.setRequestHeader("Content-type", "application/json"); xhr.responseType = "document"; switch(requestNumber) { case 1: console.log('Grünbeck: Request ' + requestNumber + ' ausgeführt'); xhr.send("id=8871&show=D_Y_2_1|D_Y_2_2|D_Y_2_3|D_Y_2_4|D_Y_2_5|D_Y_2_6|D_Y_2_7|D_Y_2_8|D_Y_2_9|D_Y_2_10|D_Y_2_11|D_Y_2_12|D_Y_2_13|D_Y_2_14~"); xhr.onreadystatechange = function() { if (xhr.readyState==4) { if (xhr.status == 200) { if (xhr.responseText) { var str = xhr.responseText; const regex = /<data><code>([^\<]+)<\/code><D_Y_2_1>([^\<]+)<\/D_Y_2_1><D_Y_2_2>([^\<]+)<\/D_Y_2_2><D_Y_2_3>([^\<]+)<\/D_Y_2_3><D_Y_2_4>([^\<]+)<\/D_Y_2_4><D_Y_2_5>([^\<]+)<\/D_Y_2_5><D_Y_2_6>([^\<]+)<\/D_Y_2_6><D_Y_2_7>([^\<]+)<\/D_Y_2_7><D_Y_2_8>([^\<]+)<\/D_Y_2_8><D_Y_2_9>([^\<]+)<\/D_Y_2_9><D_Y_2_10>([^\<]+)<\/D_Y_2_10><D_Y_2_11>([^\<]+)<\/D_Y_2_11><D_Y_2_12>([^\<]+)<\/D_Y_2_12><D_Y_2_13>([^\<]+)<\/D_Y_2_13><D_Y_2_14>([^\<]+)<\/D_Y_2_14><\/data>/; const subst = regex.exec(str); if (subst) { for ( i = 1; i < 15; i++ ) { i1 = i + 1; if (i < 10) setState("Messwerte.0.SC18.Wasserverbrauch.D_Y_2_0" + i , parseInt(subst[i1]) ); else setState("Messwerte.0.SC18.Wasserverbrauch.D_Y_2_" + i , parseInt(subst[i1]) ); } } requestNumber = 2; } } } }; break; case 2: console.log('Grünbeck: Request ' + requestNumber + ' ausgeführt'); xhr.send("id=8871&show=D_C_4_1|D_C_4_2|D_C_4_3|D_C_5_1|D_C_7_1~"); xhr.onreadystatechange = function() { if (xhr.readyState==4) { if (xhr.status == 200) { if (xhr.responseText) { var str = xhr.responseText; const regex = /<data><code>([^\<]+)<\/code><D_C_4_1>([^\<]+)<\/D_C_4_1><D_C_4_2>([^\<]+)<\/D_C_4_2><D_C_4_3>([^\<]+)<\/D_C_4_3><D_C_5_1>([^\<]+)<\/D_C_5_1><D_C_7_1>([^\<]+)<\/D_C_7_1><\/data>/; const subst = regex.exec(str); if (subst) { setState("Messwerte.0.SC18.Allgemein.D_C_4_1" , parseInt(subst[2]) ); setState("Messwerte.0.SC18.Allgemein.D_C_4_2" , subst[3] ); setState("Messwerte.0.SC18.Allgemein.D_C_4_3" , subst[4] ); setState("Messwerte.0.SC18.Allgemein.D_C_5_1" , parseInt(subst[5]) ); setState("Messwerte.0.SC18.Allgemein.D_C_7_1" , parseInt(subst[6]) ); } requestNumber = 3; } } } }; break; case 3: console.log('Grünbeck: Request ' + requestNumber + ' ausgeführt'); xhr.send("id=8871&show=D_Y_4_1|D_Y_4_2|D_Y_4_3|D_Y_4_4|D_Y_4_5|D_Y_4_6|D_Y_4_7|D_Y_4_8|D_Y_4_9|D_Y_4_10|D_Y_4_11|D_Y_4_12|D_Y_4_13|D_Y_4_14~"); xhr.onreadystatechange = function() { if (xhr.readyState==4) { if (xhr.status == 200) { if (xhr.responseText) { var str = xhr.responseText; const regex = /<data><code>([^\<]+)<\/code><D_Y_4_1>([^\<]+)<\/D_Y_4_1><D_Y_4_2>([^\<]+)<\/D_Y_4_2><D_Y_4_3>([^\<]+)<\/D_Y_4_3><D_Y_4_4>([^\<]+)<\/D_Y_4_4><D_Y_4_5>([^\<]+)<\/D_Y_4_5><D_Y_4_6>([^\<]+)<\/D_Y_4_6><D_Y_4_7>([^\<]+)<\/D_Y_4_7><D_Y_4_8>([^\<]+)<\/D_Y_4_8><D_Y_4_9>([^\<]+)<\/D_Y_4_9><D_Y_4_10>([^\<]+)<\/D_Y_4_10><D_Y_4_11>([^\<]+)<\/D_Y_4_11><D_Y_4_12>([^\<]+)<\/D_Y_4_12><D_Y_4_13>([^\<]+)<\/D_Y_4_13><D_Y_4_14>([^\<]+)<\/D_Y_4_14><\/data>/; const subst = regex.exec(str); if (subst) { for ( i = 1; i < 15; i++ ) { i1 = i + 1; if (i < 10) setState("Messwerte.0.SC18.Regenerationen.D_Y_4_0" + i , subst[i1] ); else setState("Messwerte.0.SC18.Regenerationen.D_Y_4_" + i , subst[i1] ); } requestNumber = 4; } } } } }; break; case 4: console.log('Grünbeck: Request ' + requestNumber + ' ausgeführt'); xhr.send("id=8871&show=D_Y_5|D_Y_7|D_Y_8_11|D_Y_10_1|D_Y_13|D_Y_14|D_B_1|D_C_5_1~"); xhr.onreadystatechange = function() { if (xhr.readyState==4) { if (xhr.status == 200) { if (xhr.responseText) { var str = xhr.responseText; const regex = /<data><code>([^\<]+)<\/code><D_Y_5>([^\<]+)<\/D_Y_5><D_Y_7>([^\<]+)<\/D_Y_7><D_Y_8_11>([^\<]+)<\/D_Y_8_11><D_Y_10_1>([^\<]+)<\/D_Y_10_1><D_Y_13>([^\<]+)<\/D_Y_13><D_Y_14>([^\<]+)<\/D_Y_14><D_B_1>([^\<]+)<\/D_B_1><D_C_5_1>([^\<]+)<\/D_C_5_1><\/data>/; const subst = regex.exec(str); if (subst) { setState("Messwerte.0.SC18.Allgemein.D_Y_5" , parseInt(subst[2]) ); setState("Messwerte.0.SC18.Allgemein.D_Y_7" , subst[3] ); setState("Messwerte.0.SC18.Allgemein.D_Y_8_11" , parseInt(subst[4]) ); setState("Messwerte.0.SC18.Allgemein.D_Y_10_1" , parseInt(subst[5]) ); setState("Messwerte.0.SC18.Allgemein.D_Y_13" , parseInt(subst[6]) ); setState("Messwerte.0.SC18.Allgemein.D_Y_14" , subst[7] ); setState("Messwerte.0.SC18.Allgemein.D_B_1" , parseInt(subst[8]) ); setState("Messwerte.0.SC18.Allgemein.D_C_5_1" , parseInt(subst[9]) ); } requestNumber = 5; } } } }; break; case 5: console.log('Grünbeck: Request ' + requestNumber + ' ausgeführt'); xhr.send("id=8871&show=D_A_1_1|D_A_1_2|D_A_1_3|D_A_2_1|D_A_3_1|D_A_3_2~"); xhr.onreadystatechange = function() { if (xhr.readyState==4) { if (xhr.status == 200) { if (xhr.responseText) { var str = xhr.responseText; const regex = /<data><code>([^\<]+)<\/code><D_A_1_1>([^\<]+)<\/D_A_1_1><D_A_1_2>([^\<]+)<\/D_A_1_2><D_A_1_3>([^\<]+)<\/D_A_1_3><D_A_2_1>([^\<]+)<\/D_A_2_1><D_A_3_1>([^\<]+)<\/D_A_3_1><D_A_3_2>([^\<]+)<\/D_A_3_2><\/data>/; const subst = regex.exec(str); if (subst) { setState("Messwerte.0.SC18.Aktualwerte.D_A_1_1" , parseFloat(subst[2]) ); setState("Messwerte.0.SC18.Aktualwerte.D_A_1_2" , parseFloat(subst[3]) ); setState("Messwerte.0.SC18.Aktualwerte.D_A_1_3" , parseFloat(subst[4]) ); setState("Messwerte.0.SC18.Aktualwerte.D_A_2_1" , parseInt(subst[5]) ); setState("Messwerte.0.SC18.Aktualwerte.D_A_3_1" , subst[6] ); setState("Messwerte.0.SC18.Aktualwerte.D_A_3_2" , parseInt(subst[7]) ); } requestNumber = 1; } } } }; } } }
Gruß
Marc -
danke fürs wieder einstellen.
Ob das Script auch bei der nächst groesseren anlage funktioniert? Weis das jemand die SC23. -
Hm, leider wohl etwas zu früh gefreut.
Manchmal (eigentlich "recht oft") kommt bei der Aktualisierung, egal ob Request 1, 2, 3, 4 oder 5 die folgende Fehlermeldung:javascript.0 2019-02-13 15:31:53.460 error at Timer.listOnTimeout (timers.js:290:5) javascript.0 2019-02-13 15:31:53.460 error at tryOnTimeout (timers.js:323:5) javascript.0 2019-02-13 15:31:53.460 error at ontimeout (timers.js:511:34) javascript.0 2019-02-13 15:31:53.460 error at Timeout._onTimeout (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1815:34) javascript.0 2019-02-13 15:31:53.459 error at Object.Interval (script.js.gruenbeck_logger:28:9) javascript.0 2019-02-13 15:31:53.459 error at exports.XMLHttpRequest.setRequestHeader (/opt/iobroker/node_modules/iobroker.javascript/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:201:13) javascript.0 2019-02-13 15:31:53.459 error Error in callback: Error: INVALID_STATE_ERR: send flag is true javascript.0 2019-02-13 15:31:48.456 info script.js.gruenbeck_logger: Grünbeck: Request 1 ausgeführt
Er versucht dann den Request so oft, bis er den abarbeiten konnte und den Request-Zähler intern erhöht. Dann macht er weiter.
Scheint ja irgendein Timout Problem zu sein.
Gibt es eine Möglichkeit, irgendwo ein Timeout einzustellen? Oder liegt das Problem wo anders?
Alternativ: Gibt es eine Möglichkeit für dieses Script die Log-Ausgabe von error zu unterbinden? Das macht das Log völlig unübersichtlich.Gruß
Marc -
Das Problem liegt so wie ich das sehe, dass versucht wird, die XMLHttpRequest-Instanz während eines laufenden Sendevorgangs zu modifizieren.
Ich hätte einen anderen Vorschlag: Nutze statt XMLHttpRequest eine etwas komfortablere Library wie das bereits im JS-Adapter integrierte https://github.com/request/request
Die macht das ganze Status-Handling deutlich einfacher.
-
Müsste ich mir näher anschauen. Kennst Du dich mit request etwas aus?
Habe mal versucht, Daten von der Grünbeck zu empfangen, was aber leider wohl so nicht funktioniert?!const request = require('request'); request.post({ headers: {'Content-Type': 'application/json'}, url: 'http://192.168.10.31/mux_http', body: 'id=8871&show=D_Y_2_1~' }, function (err, res, body) { console.log('err:' + err); console.log('res:' + res); console.log('body:' + body); });
Als Ausgabe kommt nur:
info javascript.0 script.js.test: registered 0 subscriptions and 0 schedules info javascript.0 script.js.test: err:null info javascript.0 script.js.test: res:[object Object] info javascript.0 script.js.test: body:<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"xml:lang="en" lang="en"> <head> <title>Error</title> </head> <body> <b>400 Bad Request: No Host Header</b> <br/> /mux_http <br/> </body> </html>
Gruß
Marc -
@Marc_P sagte in Daten aus einer Website mit Javascript:
400 Bad Request: No Host Header
Das hab ich selbst noch nicht erlebt, aber versuche mal
host: "192.168.10.31"
manuell zu den Headern hinzuzufügen. -
Ne, funktioniert leider auch nicht. Gleiche Meldung.
Ich habe auch schon gefühlt halb google nach einer Lösung durchsucht.Bin jetzt aber auch nicht wirklich so der Programmierer.
-
Noch mal abschließend:
Die Nutzung von request lege ich zur Seite, denn das Script mit xmlhhtprequest läuft jetzt ohne Fehler.
Meine Vermutung:
Während das Script vorgestern ja erst lief, habe ich parallel andere Abfragen gemacht. Die Webseite der Grünbeck war im Forefox offen, dann noch ein Test mit dem Firefox-Plugin HTTP Request Maker und die Android App war auch noch auf. Scheinbar war das das Problem. Zumindest seit gestern Nachmittag läuft das Script mit alleiniger Nutzung ohne Fehler durch. Den Abfrageintervall habe ich auf 15 Sekunden gestellt. -
@Marc_P Ok gut zu wissen, habe mir den gruenbeck nämlich schon bestellt.