NEWS
Node-Red Javascript Node - Berechnung ungewünscht doppelt
-
Moin Moin Allerseits,
ich versuche hier gerade Schritt für Schritt in Javascript reinzukommen und habe aktuell ein kleines Problem/Frage:
Der Funktionsnode "Taupunkt" erhält im Eingang seine beiden Werte Temperatur und Lufteuchtigkeit und berechnet dann im Ausgang den aktuellen Taupunkt. Die Werte Temperatur und Luftfeuchtigkeit kommen ca. alle 60 Sekunden rein und werden vorher erstmal weiterverarbeitet - z.B. String nach Zahl und Fahrenheit nach °C.
Dadurch scheint der Node Taupunkt die Werte zeitversetzt zu erhalten und triggert die Berechnung zwei mal. Im schlimmsten Falle auch mit der Ausgabe "not a number"...
Wie kann ich das abfangen?
JS Taupunkt Funktionsnode:
Anbei ansonsten auch nochmal der komplette Wetterstation Node-Red Flow:
Wäre da über jeden Tip dankbar...
-
@lemuba Ohne jetzt durch deinen kompletten Flow zu steigen. Der "Taupunkt" wird ja auch 2 mal getriggert. Einmal vom Subflow3(temperatur) und einmal vom Subflow6(feuchte).
Statt dessen solltest du an den Taupunkt ein Objekt übergeben, welches sowohl die termeratur als auch die feuchte beinhaltet.
Das könntest du leicht, wenn du den Input von "Taupunkt" direkt vom Output "Listen to GW1000 in Ecowitt Mode" abgreifst und Temp/Hum in "Taupunkt" extrahierst. -
Mit Leicht ist noch nicht als Anfänger...
habe noch keine Ahnung wie ich das Alles in eine Function reinbekomme und gleichzeitig berechne...
Aber der Ansatz ist natürlich sicherlich gut und sinnvoll...Lieber wäre mir aber, auch um es für Anfänger wie mich bei einer möglichen Erweiterung um weitere Sensoren einfacher zu halten: Lieber mehr Einzelnodes mit einfachen Funktionen in Reihe, wie einen Großen...
-
Ja Dein Problem wurde letztlich von @rewenode richtig beschrieben. Du triggerst Deine Funktion immer mehrfach mit jedem Input. Du führst beide Werte über den Funktionsnode zusammen, indem Du es über den Context speicherst. Den Taupunkt speicherst Du in einer Flow-Variablen - was unnötig ist.
aber Du musst eigentlich in Deiner Funktion gar nicht soviel ändern:
Speichere den Taupunkt doch einfach auch in einer Kontextvariable (eine FlowVariable erschliesst sich mir hier nicht) und sende nur, wenn sich was ändert bzw. der Wert valide ist.
Ich habe Deinen Code mal ergänzt, so müsste es einigermaßen funktionieren:
var tempf = context.get('tempf')|| 0; var humidity = context.get('humidity')|| 0; var oldTp = context.get('contexttp') || 0; var tp = 0; if (msg.topic === "tempf") { tempf= msg.payload; context.set('tempf',msg.payload); } else if (msg.topic === "humidity") { humidity= msg.payload; context.set('humidity',msg.payload); } // Quelle: https://www.chemie-schule.de/KnowHow/Taupunkt // Gültigkeitsbereich Taupunkt: -30°C <= tmp <= 70°C if (tempf >0 && humidity > 0 ) { tp = ((241.2 * Math.log(humidity/100)) + ((4222.03716 * tempf) / (241.2 + tempf))) / (17.5043 - Math.log(humidity/100) - ((17.5043*tempf)/(241.2+tempf))); tp = Math.round( tp * 100 ) / 100; context.set("contexttp",tp); } if (oldTp !== tp) { msg.payload = tp; msg.topic = "Taupunkt"; return msg } else { return null; }
Somit wird nur gesendet, wenn sich Taupunkt verändert hat - bzw. gültig ist. Ggf. halt noch NaN abfangen und die Funktion mit "return null" verlassen!
Wenn die Bedingung nicht zutrifft - sendet Dein Funktionsnode einfach nichts und die eingehenden Nachrichten befüllen nur die internen Variablen, bis ein Ergebnis da ist.
-
Ich hab den Code nochmal leicht editiert!
-
Vielen Dank erstmal - das muss noch ein kleiner Fehler im Script sein...?
13.5.2020, 15:48:05node: Taupunktfunction : (error)
"ReferenceError: oldTP is not defined (line 22, col 1)"Line 22:
if (oldTP !== tp) {
-
@lemuba Ja ich habe nochmal geändert. War ein großes P anstelle eines kleinen und aussßerdem darfst die Variablen nur mit richtigem Topic setzen. Kopier nochmal alles aus der Box.
-
Top - funktioniert!:
13.5.2020, 16:01:28node: 81594f23.375458
Taupunkt : msg.payload : number
6.09Das kann ich nun sicherlich als Grundlage nehmen um auch weitere Berechnungen durchzuführen/zu optimieren, wie z.B. Windchill:
-
Noch eine Frage - bedeutet das jetzt aber, daß der Taupunkt nur bei Temperaturen über 0 Grad berechnet wird?
if (tempf >0 && humidity > 0 ) {
tp = ((241.2 * Math.log(humidity/100)) + ((4222.03716 * tempf) / (241.2 + tempf))) / (17.5043 - Math.log(humidity/100) - ((17.5043*tempf)/(241.2+tempf)));
tp = Math.round( tp * 100 ) / 100;
context.set("contexttp",tp);
} -
@lemuba Ja da hast Du Recht - letztlich diente die Bedingung nur dazu, zu überprüfen ob alles initialisiert ist. Entweder Du fängst das ab mit != NaN oder Du nimmst einfach einen anderen Wert.
Du kannst ja die Temperatur mit -100 initialisieren und dann in der Abfrage > -100 arbeiten. -
Ok, bin aber gerade am schauen ob eine Taupunktberechnung unter Null Grad überhaupt relevant ist - ein anderes, dann metrolgisches Thema...
-
if (!(isNaN(tempf) || isNaN(humidity))) { ...
müsste eigentlich auch funktionieren als Bedingung
-
@mickym sagte in Node-Red Javascript Node - Berechnung ungewünscht doppelt:
!(isNaN(tempf) || isNaN(humidity))
Ich habe nun die -100 Variante eingebaut, weil die habe ich glaube ich verstanden... und funktioniert so weit:
Mir war nicht ganz klar wo das reingehört hätte:
!(isNaN(tempf) || isNaN(humidity))
-
var tempf = context.get('tempf')|| 0; var humidity = context.get('humidity')|| 0; var oldTp = context.get('contexttp') || 0; var tp = 0; if (msg.topic === "tempf") { tempf= msg.payload; context.set('tempf',msg.payload); } else if (msg.topic === "humidity") { humidity= msg.payload; context.set('humidity',msg.payload); } // Quelle: https://www.chemie-schule.de/KnowHow/Taupunkt // Gültigkeitsbereich Taupunkt: -30°C <= tmp <= 70°C if (!(isNaN(tempf) || isNaN(humidity))) { tp = ((241.2 * Math.log(humidity/100)) + ((4222.03716 * tempf) / (241.2 + tempf))) / (17.5043 - Math.log(humidity/100) - ((17.5043*tempf)/(241.2+tempf))); tp = Math.round( tp * 100 ) / 100; context.set("contexttp",tp); } if (oldTp !== tp) { msg.payload = tp; msg.topic = "Taupunkt"; return msg } else { return null; }
-
@mickym sagte in Node-Red Javascript Node - Berechnung ungewünscht doppelt:
var tempf = context.get('tempf')|| 0;
var humidity = context.get('humidity')|| 0;
var oldTp = context.get('contexttp') || 0;
var tp = 0;if (msg.topic === "tempf") {
tempf= msg.payload;
context.set('tempf',msg.payload);} else if (msg.topic === "humidity") {
humidity= msg.payload;
context.set('humidity',msg.payload);
}// Quelle: https://www.chemie-schule.de/KnowHow/Taupunkt
// Gültigkeitsbereich Taupunkt: -30°C <= tmp <= 70°C
if (!(isNaN(tempf) || isNaN(humidity))) {
tp = ((241.2 * Math.log(humidity/100)) + ((4222.03716 * tempf) / (241.2 + tempf))) / (17.5043 - Math.log(humidity/100) - ((17.5043*tempf)/(241.2+tempf)));
tp = Math.round( tp * 100 ) / 100;
context.set("contexttp",tp);
}if (oldTp !== tp) {
msg.payload = tp;
msg.topic = "Taupunkt";
return msg }
else {
return null;
}Funktioniert auch... nun habe ich estmal was zum weiterspielen/testen... Vielen Dank erstmal!
Den Link/Quelle zu diesem Beitrag werde ich gleich mal im Script notieren....