NEWS
Zwei Werte Subtahieren mit Node-Red
-
Hallo,
ich bin absoluter Neuling was Node-Red angeht und möchte eigentlich nur zwei Werte subtrahieren.
Mir fehlt hier leider der Ansatz. Kann ich mit zwei Variablen auf einen Eingang eines Function-Nodes gehen?
Wie verarbeite ich dann diese Werte?
Ich wäre euch sehr dankbar für ein kleines Beispiel!
Gruß
Andy
-
ich bin absoluter Neuling was Node-Red angeht und möchte eigentlich nur zwei Werte subtrahieren. `
Dies kannst Du über das function-Node und einem kleinen Javascript machen.> Kann ich mit zwei Variablen auf einen Eingang eines Function-Nodes gehen?
Ja.> Wie verarbeite ich dann diese Werte?
Indem Du ein Javascript schreibst.Vielleicht beschreibst Du erst einmal woher die beiden Werte kommen und was Du mit dem berechneten Wert vor hast.
Hier noch ein Minibeispiel, da der msg,topic Wert als String gesendet wird musste dieser erst noch mit parseFloat in eine Fließkommzahl umgewandelt werden.
-
Ich möchte eigentlich den Datenverbrauch meiner Fritzbox visualisieren.
Ich lese über den Fritz-Box Node " NewTotalBytesReceived " aus. Ich löse um 00:00 Uhr einen Reconnect der Internetverbindung aus und speichere diesen Wert dann über IO-Broker Output. Wäre dieser Wert nach einem Reconnect immer 0 wäre es kein Problem.
Ich würde jetzt gerne diesen Wert von " NewTotalBytesReceived " abziehen um eine Richtige Anzeige meines Datenvolumens zu bekommen.
-
Ich habe mir deinen Beitrag jetzt dreimal durchgelesen, aber ich verstehe im Kern nicht was Du wovon abziehen möchtest. Ein simples Beispiel habe ich meinem ersten Antwortpost beigefügt. Da kannst Du sehen wie einfach es geht. Und wenn ich dann noch verstehe was Du wovon abziehen möchtest, dann kann ich dir bei weiteren Fragen auch noch weiterhelfen.
-
In dem Bild sieht man was ich möchte. In dem Function Node byte2GB rechne ich von Byte in Gigabyte um.
Die Werte für "NewTotalBytesReceived" hole ich mir alle 10 Sekunden neu. Leider ist der Wert nach einem Reconnect schon ein paar Gigabyte groß, somit stimmt natürlich meine Anzeige nicht.
Ich möchte jetzt einfach nur "Download Helfer" von "NewTotalBytesReceived" abziehen und in GB umrechnen.
Dein Beispiel hilft mir auch fast weiter.
Nur habe ich ja jetzt 2 x msg.payload statt 1 x msg.payload und 1 x msg.topic
Wie verarbeite ich jetzt diese zwei Werte?
Irgendwie muss ich im Function Node sagen dass var a = msg.payload "Download Helfer" und var b = msg.payload "NewTotalBytesReceived" ist.
Ich habe nur keine Ahnung wie???
-
Ich habe nur keine Ahnung wie??? `
O.K. neue Strategie. Nachdem ich nun anhand von deinem Flow verstanden habe was Du machen möchtest (wäre schneller gegangen, wenn Du diesen direkt gepostet hättest) benutzen wir einfach zwei globale Variablen.Hier ein wenig Lesestoff zu dem Thema:
viewtopic.php?f=32&t=12558#p133250
https://nodered.org/docs/writing-functi … al-context
Und hier die konkrete Hilfe:
Du solltest dir noch folgende Node installieren:
Nach der Installation hast Du einen Contextbrowser in dem dir die Globalen Variablen angezeigt werden. Die Aktivierung de Contextbrowsers erfolgt über die Menüleiste:
Die Werte und Werteaktualisierungen werden erst nach dem Klick auf das Auffrischensymbol (im Kreis gezeichnete Pfeile) angezeigt! Sieht dann so aus:
Um in meinem Beispielflow zu bleiben:
Hier der Flow:
! ````
[{"id":"ec30fc16.ae51d8","type":"function","z":"fb411b0a.dca158","name":"globale Variable Wert1","func":"global.set("wert1",msg.payload);\nmsg.payload = (global.get("wert1") - global.get("wert2"));\nreturn msg;","outputs":1,"noerr":0,"x":620,"y":620,"wires":[["b50e8abc.2bf48"]]},{"id":"96ea10aa.dc6fd","type":"inject","z":"fb411b0a.dca158","name":"","topic":"","payload":"45","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":619,"wires":[["ec30fc16.ae51d8"]]},{"id":"b50e8abc.2bf48","type":"debug","z":"fb411b0a.dca158","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":870,"y":620,"wires":[]},{"id":"cb7fba74.ee0e4","type":"inject","z":"fb411b0a.dca158","name":"","topic":"","payload":"30","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":680,"wires":[["7b44fb35.070904"]]},{"id":"7b44fb35.070904","type":"function","z":"fb411b0a.dca158","name":"globale Variable Wert2","func":"global.set("wert2",msg.payload);\nreturn msg\n","outputs":1,"noerr":0,"x":380,"y":680,"wires":[[]]}]Und so sieht das Ergebnis aus: ![3639_screen4.jpg](/assets/uploads/files/3639_screen4.jpg) Jetzt musst Du mal schauen, ob dir diese Möglichkeit weiterhilft.
-
Vielen vielen Dank für deine ausführliche Hilfe und die Geduld!
Es funktioniert jetzt genau so wie ich es wollte.
Du hast mir nicht nur geholfen, sondern auch noch was beigebracht.
Habe mir die Links intensiv durchgelesen und blicke jetzt etwas besser durch!
Vielen Dank!
Gruß
Andy
-
Es funktioniert jetzt genau so wie ich es wollte. `
Schön zu lesen.> Du hast mir nicht nur geholfen, sondern auch noch was beigebracht.
Und auch ich habe wieder etwas dazu gelernt. Ein Problem dieser Art hatte ich bisher auch noch nicht gehabt. Mein erster Lösungsansatz msg.payload umbenennen zu wollen klappte nicht so einfach wie gedacht. Dann kam mir in den Sinn doch globale Variable zu verwenden.Diese Art der Variablen sind Segen und Fluch zugleich. Die von mir verwendete Variablennamen Wert1 und Wert2 würde ich nicht gerade als gelungen bezeichnen. Es wäre besser die Variablen als globalWert1und globalWert2 zu definieren. Für die Funktion spielt die Benamung der Variablen natürlich keine Rolle. Verwendte man aber die einfachen Variablennamen wie z.B. Wert1 und Wert2 noch einmal rein zufällig in anderen Flows, dann wird es schnell zu erst einal unerklärlichen Fehlern kommen. :shock:
-
Für die Funktion spielt die Benamung der Variablen natürlich keine Rolle. Verwendte man aber die einfachen Variablennamen wie z.B. Wert1 und Wert2 noch einmal rein zufällig in anderen Flows, dann wird es schnell zu erst einal unerklärlichen Fehlern kommen. :shock:
Deshalb sollte mann globale Variablen auch nur dort einsetzen, wo sie wirklich global sein müssen.
Ich mach es immer so:
Normale Contextvariable (context.set(), context.get()) wenn die Variable nur für das entsprechende Funktionsnode Werte speichern soll.
FlowContextvariable (flow.set(), flow.get()) wenn die Variable für allen (Teil)Flows des Tabs gespeichert werden sollen.
Oder halt global.set(), global.get(), dann sind die Variablen auch von Flow (anderen Tabs) erreichbar.
-
Deshalb sollte mann globale Variablen auch nur dort einsetzen, wo sie wirklich global sein müssen. ` Dem ist nichts mehr hinzuzufügen. Danke für deine Hinweise.
Ich habe meine Auflistung noch einmal überarbeitet:
<u><size size="150">Insgesamt gibt es folgende Variablentypen:</size></u>
Die einfachste Form
var x = 1;
Diese Variablen behalten ihren Wert nur innerhalb des Function Node und werden bei jedem inject wieder mit ihrem Eingangswert, hier mit dem Wert 1, versehen. Dieser Variablentyp ist als Zähler nicht geeignet.
Die context Variable
context.set("x",y); context.get("x")
Um einen Variablenwert dauerhaft im function-Node festzuschreiben muss dieser Variablentyp gewählt werden. Der Variablenwert kann nur in dem definierten Node verwendet werden. Andere Nodes wie das switch-Node, inject-Node und change-Node können nicht auf die Variable zugreifen.
Die definierten context-Variablen werden im contextbrowser unter Node angezeigt.
Die flow Variable
flow.set("x",y), flow.get("x")
Die Werte aus diesem Variablentyp können im gesamten Flow (außer in Subflows) und somit in allen auf der Seite befindlichen Nodes ausgelesen werden.
Der Variablenwert kann im gesamten Flow verwendet werden. Andere Nodes wie das switch-Node, inject-Node und change-Node können ebenfalls lesend und schreibend auf die Variable zugreifen.
Die definierten context-Variablen werden im contextbrowser unter Flow angezeigt.
Die globale Variable
global.set("x",y), global.get("x")
Die Werte aus diesem Variablentyp können über alle Flows von Node-Red in den Nodes ausgelesen werden. Andere Nodes wie das switch-Node, inject-Node und change-Node können ebenfalls lesend und schreibend auf die Variable zugreifen.
Die definierten globalen-Variablen werden im contextbrowser unter Global angezeigt.
x = Variablenname , y = Variablenwert
<u>Beispiel:</u>
global.set("Mustermann",100); // globale Variablen setzen
msg.payload = global.get("Mustermann") // globale Variable in msg.payload einlesen
<u>Informationsquellen:</u>
https://nodered.org/docs/writing-functi … al-context
https://www.youtube.com/watch?v=kNfP1vw2Img Youtubevideo
https://www.youtube.com/watch?v=NAgM-Ty9Zxs Youtubevideo für get und set Variable
<size size="150"><u>Anwendungsempfehlung:</u></size>
********* Definiere normale Contextvariable wenn die Variable nur für das function-Node Werte speichern soll.
********* Definiere FlowContextvariable wenn die Variable für alle (Teil)Flows des Tabs gespeichert werden soll.
********* Definiere Globalvariable wenn die Variable von allen Flows, in allen Tabs erreichbar sein soll.
-
@Graf: Perfekte Auflistung! Kannst du direkt in irgendein deutschsprachiges NR WIKI einstellen
> Die Werte aus diesem Variablentyp können im gesamten Flow (außer in Subflows)
Ja, das hatte ich vergessen zu erwähnen. Hat mich schon mal stundenlanges Debugger gekostet. Ist besonders hinterhältig, wenn man bestehende, getestete Teil-Flows in Subflows umwandelt.