NEWS
Zählerstand vorheriger Wert (previous)
-
Hallo zusammen,
ich bekomme von meinem Modbuszähler alle 10 Sekunden einen neuen Float Wert. Mich interessiert aber nicht der Zählerstand, sondern die Differenz zum Vorgängerwert. Daher bin ich auf diesen älteren Beitrag gestoßen, wo mit dem context gearbeitet wird. Ist das der richtige Ansatz ?
Grüße
-
@langewiese82 merk dir den Wert doch bei änderung im anderen Datenpunkt
-
@arteck hatte ich auch dran gedacht, also quasi wie in C in einer variable speichern. Aber in Node Red wüsste ich gerade nicht, wie ich das umsetze ?
-
@langewiese82 ja das ist der richtige Ansatz - entweder über Flow-Variablen oder den Node-Kontext bei function Nodes
-
@mickym momentan habe ich es folgendermaßen umgesetzt, aber da ist noch der Wurm drin .... nach ein paar Durchläufen wiederholen sich die Werte immer wieder. Der Sinn von dem Ganzen soll ja sein, in erster Linie die Wertänderung festzustellen. Diese wird dann später mal auf einen festen abgelesenen Zählerwert des EVUs addiert.
var vorherigerWert = context.get('previous') || 0;
context.set('previous', msg.payload);
msg.previous = vorherigerWert;
msg.payload=msg.payload-msg.previous;
return msg;Info: msg.payload ist der float wert, welcher alle 10 Sekunden vom Buffer parser rüberkommt
-
@langewiese82 Ehrlich gesagt kann ich keinen Fehler entdecken. Zur Interpretation der Zahlen kann ich nichts sagen. Du siehst doch selbst - da Du Dir ja beides ausgeben lässt, ob die Logik stimmt. Gerechnet werden kann ja nur mit den Zahlen, die Du eingibst. - Also an der Logik kann ich auf den ersten Blick nichts entdecken.
-
@mickym Hallo, ich hab jetzt noch ein bisschen recherchiert und diverse Ansätze probiert und am weitesten komme ich mit der function node. Allerdings fällt mir auf, dass die Werte meiner Subtraktion sich wiederholen und das kann ja eigentlich nicht sein ? (siehe jpg.1 und jpg.3). Meine function Node ist folgendermaßen aufgebaut:
var alterWert = flow.get("vorgaenger") || 0;
flow.set("vorgaenger", msg.payload);
msg.vorgaenger = alterWert;
msg.payload = msg.payload - msg.vorgaenger;
return msg;Das ist doch noch irgendwo ein Fehler .... ???
-
@langewiese82 sagte in Zählerstand vorheriger Wert (previous):
var alterWert = flow.get("vorgaenger") || 0;
flow.set("vorgaenger", msg.payload);
msg.vorgaenger = alterWert;
msg.payload = msg.payload - msg.vorgaenger;
return msg;Bei einer function Node kannst Du das auch im context speichern - musst nicht im Flow speichern. Das Ganze kann ich nicht ganz beurteilen, weil ich ja nicht weiß, was die Eingabe ist, ausser Du setzt den value als neue payload. Testen kannst Du Deine Funktion aber doch am Besten selbst.
Warum soll sich das Ganze denn nicht wiederholen können. Wenn Du 2 mal den gleichen Wert eingibst kommt auch immer die 0 raus. Du kannst ja mal eine Warnung direkt die Eingabe mit im debug-Fenster ausgeben:
node.warn(msg.payload); var alterWert = context.get("vorgaenger") || 0; context.set("vorgaenger", msg.payload); msg.vorgaenger = alterWert; msg.payload = msg.payload - msg.vorgaenger; return msg;
und ich nutze einfache Zahlen, um das nachzuvollziehen:
Also 2,5,14. Damit ich sehe was ich gedrückt habe, lasse ich in einer Warnung immer die Eingangspayload ausgeben.
Am Anfang gebe ich also 3 mal die 2 ein:
In der neuen payload gibst du ja die Differenz zur alten payload aus und in vorgaenger den vorherigen Wert.
Beim erstem Mal 2 drücken, kommt also 2 (die neue Differenz zu 0 als vorgaenger raus).
Beim zweiten und dritten Mal 2 drücken kommt immer 0 raus, da die Differenz zum Vorgänger ist ja 2 immer 0 ist.Dann drücke ich eine 5 und die payload ist eine 3 also die Differenz zwischen 5-2 und im vorgänger stand ja die 2 drin. Also ist das doch richtig.
Dann drücke ich die 14 und es kommt richtig die Differenz 9 raus (14-5) und im Vorgänger stand die 5.
Drücke ich dann wieder die 2, kommt -12 raus.
ALSO: Wenn eine Funktion so erst mal korrekt arbeitet, liegt es doch nicht an Deiner Funktion sondern an Deinen Eingabewerten
Ich habe es mal mit dem mittleren Wert auch getestet:
Dabei ist lediglich die 375 am Ende dazugedichtet. Das ist aber ein Problem von Javascript generell, dass die Genauigkeit hier nicht stimmt. Das korrekte Ergebnis beim manuellen Nachrechnen ist:
0.00600433349609
ggf musst Du halt in Integer umwandeln - wobei ich wie gesagt glaube, dass Du ein Problem mit Deiner Eingabe hast, die Werte stimmen, wenn Du msg.specification.value als neue msg.payload einspeist:
Nehme ich Deinen 1. Screenshot:
Nehme ich Deinen 3. Screenshot:
Wenn Du diese Rundungsfehler bei JS vermeiden willst, musst Du halt mit Integern rechnen, aber insgesamt stimmt das alles:
msg.payload *= 100000000000000; node.warn(msg.payload); var alterWert = context.get("vorgaenger") || 0; context.set("vorgaenger", msg.payload); msg.vorgaenger = alterWert; msg.payload = (msg.payload - msg.vorgaenger) / 100000000000000; return msg;
-
Wenn Du von diesen Rundungsfehlern wegkommen willst, wobei ich denke nicht, dass das Dein Problem ist:
Dann kannst Du auch mit BigInt arbeiten:
Das passt lt. Rechner:
msg.payload = BigInt(msg.payload * 100000000000000); node.warn(msg.payload); var alterWert = BigInt(context.get("vorgaenger") || 0); context.set("vorgaenger", msg.payload); msg.vorgaenger = alterWert; msg.payload = Number(msg.payload - msg.vorgaenger) / 100000000000000; return msg;
-
@mickym Wow !!! was eine Antwort, das schaue ich mir mal in Ruhe genau an … Rundungsfehler hatte ich auch schon im Verdacht … Danke für deine Mühe … ich werde berichten