NEWS
MSG Payload werte auslesen
-
@mickym
Wow, sehr schöne ausführliche Antwort/Beschreibung.
Du hast sicherlich recht damit, das es nicht der Sinn von Node Red ist alles in Funktion Node umzusetzen. Ich nutze sie aber doch reichlich, da mir die Flows sonst teilweise viel zu lang / groß werden. Kompeltt auf Java Scrip umsteigen will ich aber auch nicht, da dafür mein Halbwissen nicht ausreicht. Auch finde ich das der Script Adapter ein Ressourcenfresser ist, als ich noch den PI3 hatte bin ich deswegen auf NodeRed Adapter umgestiegen, weil der lange nicht so viel Speicher verbraucht. Wobei ich zugeben muss das ich eher Blockly als Java Script genutzt habe. Was ich in den Funktion Nodes umsetzte habe ich viel durch probieren und googeln und durch User wie dich gelernt.
Auch habe ich die Change Node nie so richtig verstanden. Durch deinen Flow sehe ich da jetzt allerdings klarer. Mich hat immer dieses "festlegen msg. , bis msg. gestört. Ist dieses "bis" ein Übersetzungsfehler? Sollte das nicht eher heißen ändere msg. "in" msg. -
@frankyboy73 sagte in MSG Payload werte auslesen:
@mickym
...
Auch habe ich die Change Node nie so richtig verstanden. Durch deinen Flow sehe ich da jetzt allerdings klarer. Mich hat immer dieses "festlegen msg. , bis msg. gestört. Ist dieses "bis" ein Übersetzungsfehler? Sollte das nicht eher heißen ändere msg. "in" msg.Ja das ist in meinen Augen eine sehr unglückliche Übersetzung. Im Englischen heißt es "Set" (übersetzt mit Festlegen) "To" (übersetzt mit Bis) - Man hätte hier besser "Auf oder In" verwendet. In ist auch etwas verwirrend - weil Du eigentlich nichts änderst. Mit Festlegen setzt Du einfach eine Variable. Deswegen kannst Du den Change Node auch wunderbar verwenden um Flow Variablen etc. zu setzen. Ich zeige Dir gleich noch ein Beispiel - wie man mit dem Change Node - quasi programmieren kann.
-
Hier mal ein Beispiel was man mit einer Change Node so alles anstellen kann.
Aus dem Screenshot ersieht man dass leider nur der iobroker List Node mit Wildcards arbeiten kann. Das Problem ist allerdings, dass Du nur Objekte und nicht den Wert zurückbekommst. Deswegen habe ich mir wie folgt beholfen:
Um nun die Werte zu extrahieren und einzelne Nachrichten zu generieren bin ich wie folgt (s. Screenshot) vorgegangen:
Du siehst rechts im Debug Fenster wie ich dann die ID und den Wert extrahiert habe. Ich hätte anstelle des Topics auch die _id verwenden können. Das ist egal.
Was Du in dem Change Node siehst
- wie ich über einen regulären Ausdruck aus dem Topic den relevanten String für das Gerät extrahiere. $1 enthält das was in Klammern steht und kann deshalb im nächsten Schritt verwendet werden.
- ein neues Object msg.new als tempräres Objekt generiere und vorbelege
- Die Werte topic aus dem Message Topic und aus payload.val belege
- Das ganze New Object dann als payload ausgebe.
Du siehst der Change Node arbeitet quasi wie ein kleines Programm.
Damit siehst auch was das Bewegen macht - ist auch so eine doofe Übersetung. Es benennt ein Objekt quasi um - so dass das msg.new Objekt nicht mehr existiert sondern zur payload wird.
-
@mickym Ok, das werde ich mir mal abspeichern, ist ja für mich wesentlich übersichtlicher als das mit ner Funktion umzusetzen und einfacher. Danke.
Sehe ich das richtig das du hier den reset von all deinen Shellys ausliest und dir dann ausgibst von welchem Shelly die msg. kommt? Wenn ja, wie kann ich denn über Node Red mit ner Input bzw. Get Node alle Geräte einer Gruppe (bei mir Sonoff) auslesen. Ich überwache z.B. meine Sonoffs auf erreichbarkeit, bis jetzt habe ich ne eigene Input Node für jeden Sonoff, da ich viele habe, kommt da ne ganze Menge zusammen. Wäre schön wenn ich das reduzieren könnte und dann nur noch auswertet, von welchem Sonoff die msg. kommt. -
@mickym Wer lesen kann ist klar im Vorteil. Habe jetzt gesehen das du die List Node verwendest. Gab es die schon immer? Ist mir früher nie aufgefallen. Aber jetzt habe ich was ich gesucht habe. Danke. Damit kann ich erst mal arbeiten.
-
@frankyboy73 sagte in MSG Payload werte auslesen:
@mickym Ok, das werde ich mir mal abspeichern, ist ja für mich wesentlich übersichtlicher als das mit ner Funktion umzusetzen und einfacher. Danke.
Sehe ich das richtig das du hier den reset von all deinen Shellys ausliest und dir dann ausgibst von welchem Shelly die msg. kommt? Wenn ja, wie kann ich denn über Node Red mit ner Input bzw. Get Node alle Geräte einer Gruppe (bei mir Sonoff) auslesen. Ich überwache z.B. meine Sonoffs auf erreichbarkeit, bis jetzt habe ich ne eigene Input Node für jeden Sonoff, da ich viele habe, kommt da ne ganze Menge zusammen. Wäre schön wenn ich das reduzieren könnte und dann nur noch auswertet, von welchem Sonoff die msg. kommt.Ja und wenn Du Dir im Change Node nicht die Funktionen von JSONATA anschaust, kannst Du auch kleine Rechenoperationen und was Du sonst dort an bereits eingebauten Funktionen siehst nutzen. Um z.Bsp eine Zahl (hier 5) zu addieren einfach folgenden Change Node definieren.
Zu Deinem 2. Thema - ja das siehst Du richtig - wobei Node-Red hier von den Adapter-Entwicklern stiefmütterlich behandelt wird. Ich habe das schon vor einigen Monaten hier mal thematisiert:
https://forum.iobroker.net/topic/36470/node-red-und-iobroker-mqtt-watch-dog-funktion/2
Aber leider meldet sich von den Node-Red Adapter Entwicklern niemand. Insofern muss man weiterhin in der Regel eigene Input Nodes definieren, wenn Du auch bei Wertänderungen aktiv benachtichtigt werden willst.
Ansnsten - so wie ich es in dem Flow gemacht habe gibt es nun den List Node - der mit Wildcards arbeiten kann, den musst Du aber immer manuell antriggern.
DEswegen siehst Du in dem Flow auch den "Check" Input Node - der in einem bestimmten Zeitintervall die Werte über den List Node abfrägt.
Nur über den List Node ist es möglich überhaupt Wildcards (*) zur Abfrage zu definieren!
Ansonsten solltest Du mit Node-Red ggf. noch den Umweg über mqtt überlegen. Das habe ich hier mal thematisiert:
https://forum.iobroker.net/topic/40448/blockly-eleganter-machen/2
(Ganz frisch )
Dabei stellt sich raus, dass hier blockly eindeutig im Vorteil ist, da Du hier anscheinend mit Wildcards und getriggert arbeiten kannst.
Zusammen damit (wenn Du mal die einzelnen Nodes zu initialisierung weg lässt - hab ich deshalb mal aus Übersichtsgründen aus dem Screenshot gelöscht ) kannst Du Dir nämlich einen einfachen JSON String bastelst - den Du dann als Gesamtstatus analysierst und mit einer JOIN Node zusammenfasst:
Das Ergebnis dieser JOIN Node sieht dann so aus:
{"shellydimmer-xxxx":true,"shellyplug-s-xxxx":true,"shellyplug-s-xxxx":true,"shellyplug-s-xxxx":true,"shellyplug-s-xxxx":true,"shellyplug-s-xxxx":true,"shellyplug-s-xxxx":true,"shellyplug-s-xxxx":true,"shellyplug-s-xxxx":true,"shellydimmer-xxxx":true,"shellydimmer-xxxx":true,"shelly1-xxxx":true,"shelly1pm-xxxx":true,"shellyswitch25-xxxx":true,"shellyswitch25-xxxx":true,"shellyplug-s-xxxx":true,"shellyswitch25-xxxx":true,"shellyplug-s-xxxx":true}
Diesen String analysiere ich dann mit einer function Node - so dass wenn nur 1 Parameter false ist - eine Alarm Nachricht ausgelöst wird.
Hier mal der Code der Function Node - wenn ich so einen JSON String analysiere:
var x; var obj = msg.payload; var bIsBoolean=true; for (x in obj) { bIsBoolean = bIsBoolean && obj[x]; } msg.payload=bIsBoolean; return msg;
Also bevor Du Deine schönen iobroker- in-Nodes alle wegschmeisst - machs lieber nicht!!!!
-
@frankyboy73 sagte in MSG Payload werte auslesen:
@mickym Wer lesen kann ist klar im Vorteil. Habe jetzt gesehen das du die List Node verwendest. Gab es die schon immer? Ist mir früher nie aufgefallen. Aber jetzt habe ich was ich gesucht habe. Danke. Damit kann ich erst mal arbeiten.
Erst seit der Node-Red Adapter Version 1.17.x
-
@frankyboy73 sagte in MSG Payload werte auslesen:
@mickym Ok, das werde ich mir mal abspeichern, ist ja für mich wesentlich übersichtlicher als das mit ner Funktion umzusetzen und einfacher. Danke.
Sehe ich das richtig das du hier den reset von all deinen Shellys ausliest und dir dann ausgibst von welchem Shelly die msg. kommt? Wenn ja, wie kann ich denn über Node Red mit ner Input bzw. Get Node alle Geräte einer Gruppe (bei mir Sonoff) auslesen. Ich überwache z.B. meine Sonoffs auf erreichbarkeit, bis jetzt habe ich ne eigene Input Node für jeden Sonoff, da ich viele habe, kommt da ne ganze Menge zusammen. Wäre schön wenn ich das reduzieren könnte und dann nur noch auswertet, von welchem Sonoff die msg. kommt.Übrigens in Ergänzung zu den anderen Post - ich habe Sonoff mit Tasmota geflasht und das wird auch analog zu den Shellies über MQTT überwacht:
Hier habe ich übrigens zur Überwachung einfach den Trigger Node zur Überwachung genutzt, ob das Gerät noch lebt. Die Geräte melden sich ja via mqtt - das sollte aber auch mit dem In-Node von iobroker funktionieren, wenn Du immer Nachrichten erzeugst und nicht nur bei Änderung. Sollte sich ein Gerät 6 min nicht gemeldet haben - erzeugt der Trigger Node dann eine "false" Nachricht!
Den Switch brauchst Du aber nur, wenn Du das topic in lesbare Geräte umsetzen willst. So steht ja im Topic immer der komplete Pfad zum Object und Du brauchst nur einen Trigger und eine JOIN Node um das umzusetzen (musst das halt in der Handhabung - statt für alle Nachrichten - auf für jeden Wert unabhängig setzen.
-
@mickym Hi, vielen Dank für die vielen ausführlichen Antworten.
Ich hatte es bis jetzt so gelöst, das ich mit ner Input Node von jedem Sonoff die Time auf Änderung abfrage. Damit auf nen Trigger, wenn dann nach 30 Minuten keine Änderung kam, ne Nachricht mit dem Topic des Sonoffs per Telegramm Sonoff soundso meldet sich nicht.
Jetzt versuche ich es gerade mit der List Node, damit frage ich den alive Status der Sonoffs ab "sonoff.0.*.alive", alle 5 Minuten, dahinter ne RBE damit ich nur Änderungen mitkriege, dann nen Switch, mit Abrage auf false, damit setzte ich nen Trigger 6 Minuten, den ich zurücksetze falls der Sonoff wieder alive true ist, damit ich nur nen längeren Ausfall gemeldet kriege. Danach lasse ich mir per Funktion Node das Topic des ausgefallenen Sonoffs per Telegramm senden. Die Lösung die Time auf Änderung zu überwachen ist wahrscheinlich die sichere, ich weiß ja nicht ob die Adapter Rückmeldung "Alive" so sicher ist. Aber ich brauche jetzt nur noch einen Trigger und eine Listen Node und nicht mehr über 20 Input Nodes wie sonst.
-
@frankyboy73 Also nur mal ein paar Anregungen zur Optimierung,
Als 1. weiß ich nicht ob das ein eigener Node ist - aber ansonsten kann man den normalen Inject Node auch nutzen um zyklische Abfragen zu generieren - dafür braucht es meines erachtens keinen CRON.
2. Eventuell kann man den Rest auch super vereinfachen - da bin ich mir aber nicht ganz sicher.Du konfigurierst den trigger Node wie folgt:
Mit der Handhabung sollte der trigger Node nun ja auf jeden msg.topic die von dem iobroker list node generiert wird unterschiedlich reagieren.
Kommt also von einem speziellen msg.topic 6 Minuten nichts an - sendet der Trigger - "false" und ansonsten einfach gar nichts. Du kannst natürlich für jeden msg.topic zum Beginn auch ein True schicken, um zu überprüfen, dass jedes Gerät auch 1 mal gesendet hat.
-
@frankyboy73 Ohne Garantie hier mal ein Versuch der Vereinfachung:
[ { "id": "413cec0e.1c8994", "type": "inject", "z": "dce8fa20.2e93c8", "name": "Alle 5 Minuten", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "300", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "sonoff.0.dummy.alive", "payload": "true", "payloadType": "bool", "x": 120, "y": 1380, "wires": [ [ "7fab1454.5756bc" ] ] }, { "id": "7fab1454.5756bc", "type": "ioBroker list", "z": "dce8fa20.2e93c8", "name": "Sonoffs alive", "topic": "sonoff.0.*.alive", "objType": "state", "regex": "", "asArray": "false", "onlyIDs": "false", "withValues": "true", "x": 320, "y": 1380, "wires": [ [ "975325ba.b9aa58" ] ] }, { "id": "dbf63722.beef58", "type": "trigger", "z": "dce8fa20.2e93c8", "name": "", "op1": "verbunden", "op2": "nicht verbunden", "op1type": "str", "op2type": "str", "duration": "6", "extend": true, "overrideDelay": false, "units": "min", "reset": "", "bytopic": "topic", "topic": "topic", "outputs": 1, "x": 780, "y": 1380, "wires": [ [ "5fd5c116.79242" ] ] }, { "id": "5fd5c116.79242", "type": "change", "z": "dce8fa20.2e93c8", "name": "Nachricht erstellen", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "topic & \" \" & payload ", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 990, "y": 1380, "wires": [ [ "846bc903.448268" ] ] }, { "id": "846bc903.448268", "type": "debug", "z": "dce8fa20.2e93c8", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 1190, "y": 1380, "wires": [] }, { "id": "975325ba.b9aa58", "type": "switch", "z": "dce8fa20.2e93c8", "name": "msg.payload.val = true", "property": "payload.val", "propertyType": "msg", "rules": [ { "t": "true" } ], "checkall": "true", "repair": false, "outputs": 1, "x": 560, "y": 1380, "wires": [ [ "dbf63722.beef58" ] ] } ]
Ich habe es gerade getestet - das funktioniert tatsächlich für jedes msg.topic. Die Anzahl der Nachrichten die im trigger zurückgehalten werden, werden sogar angezeigt.
Mich begeistert dieses Programm immer wieder. - Die 1 min hier war nur zum Test -damit ich keine 6 Minuten warten musste.
Korrektur: Ich hatte noch einen Denkfehler drin - Du musst doch eine switch - aber mit true zwischenschalten. Den muss man halt ggf. noch anpassen - je nachdem ob das true als Boolean oder als String kommt.
Alternativ kann man auch im trigger node - den Auslöser zurücksetzen. Indem Du msg.payload.val über eine Change Node in msg.payload setzt -
-
@mickym Hi, vielen Dank, habe es mal nachgebaut. Sieht bis jetzt gut aus, auch simulierte Ausfälle werden mir gemeldet. Lasse das jetzt erst mal so laufen.
Bei den Injekt Nodes dachte ich immer ich müsste sie einmal anschubsen damit der Intervall läuft, deshalb habe ich nen Cron verwendet. Habe jetzt festgestellt, das es ja nicht so ist und der Intervall auch so läuft.
Jetzt wollte ich das gleiche noch mit meinen Deconz (Zigbee) Sensoren umsetzen, damit habe ich nur leider das Problem das die Objekt Ordner nur Nummern und nicht so wie bei den Sonoffs spezifische Namen haben. Wenn ich jetzt das Topic auslese kriege ich nur Nummern und muss erst mal nachschauen welcher Sensor es ist. Kann man da auch irgendwie die Namen der Objekte auslesen oder müsste ich die Ordner alle umbenennen, wobei ich nicht weiß ob das irgendwelche negativen Auswirkungen hätte. -
@frankyboy73 sagte in MSG Payload werte auslesen:
Gibt es denn in den Ordnern (also weiter unten in der Hierachie? ) keinen Wert der mit Klartext das Gerät bezeichnet?
Ansonsten gäbe es noch folgende Alternativen. Du erstellst selbst ein JSON String bzw. Java Objekt als Übersetzungstabelle oder machst Dir eine herstellerunabhängige Alias-Struktur - das ist zwar erst mal eine Menge Aufwand aber dann hast Du immer die gleiche Struktur. Wenn ein Hersteller diese Struktur nicht anbietet bleibt sie halt leer.
Ich mach mal einen Screenshot - wie ich das gelöst habe:
Oben sind das Parameter aus dem Shelly Baum - unten aus dem Tasmota Baum
Hab aber auch nicht alles drin - z. Bsp Zigbees sind aber auch streng genommen keine Schalter und Relais.
-
@frankyboy73 Ich habe noch was entdeckt - soweit ich sehe enthält doch der Name den Klartext. Wenn Du mit dem iobroker list node arbeitest bekommst Du doch immer die kompletten Objekte. Unter common.name sollte doch der name im Klartext stehen.
Ich habe gerade festgestellt, dass wen der iobroker list topic mit dem * auf einen Ordner verweist, dann werden alle Objekte unter dem Ordner aufgelistet, d.h Du musst ggf. sowieso filtern.
-
@mickym Hi, die Alias sind schon mal ne gute Idee, mal schauen wenn ich ganz viel Zeit habe, ob ich das umsetzte.
Die List Node kann mir auch den Namen auslesen wenn ich sie richtig einstelle. Danke für den Denkanstoß.
Bei den Zigbee Sensoren ist es so das sie sich in bestimmten Intervallen melden, der Batterienwert wird aktualisiert. Das werte ich mit ner Input Node und nem Trigger aus. Gibt es eine bestimmte Zeit keine Aktualisierung, sage ich Sensor soundso meldet sich nicht. Da hatte ich bis jetzt für jede Node nen eigenen Trigger und ne festen Text verwendet. Durch deine Idee mit der List Node führe ich die Input Nodes jetzt alle durch einen Trigger bei dem ich sage "ürgsprüngliches msg senden", mit ner List Node dahinter, bei der ich das Topic Feld frei lasse. Damit wird jetzt das Topic Feld von der Input Node beschrieben die sich nicht mehr meldet und ich kann den Namen auslesen. Super, ich liebe Node Red. Klappt bis jetzt einwandfrei.
Sorry dafür das ich immer noch ne Funktion Node zum Text erstellen nutze, aber damit kenne ich mich besser aus.
-
@mickym Zusätzlich kriege ich jetzt noch ne Meldung wenn eine der Batterien unter 10% ist mit dem passenden Namen. Ich musste nur noch die Reihenfolge der Nodes ändern.
-
@frankyboy73 Genau bei den Zigbees habe ich ein Interval von 2 Std. genutzt und das funktioniert ganz gut.
Ursprünglich war ich etwas verwirrt bei Deinem ersten Flow - weil Du den Trigger vor anstelle hinter die List Node gestellt hast, aber im letzten Flow hast Du es ja dann korrigiert.
Und dafür dass Du Deine Function Node für die Textausgabe nutzt - ist ja OK. Ich mach mal einen Screenshot wie es mit einem Change Node funktionieren würde. Da ich ja jetzt den Inhalt Deiner Function Node kenne.
-
@mickym Ah, ok, dann werde ich das jetzt mal mit der change Node umsetzen. Danke. Dann werde ich auch mal so nach und nach meine anderen Funktion Nodes (Texterstellung) dadurch ersetzen. Und für die Zukunft habe ich ja jetzt deine Vorlage.
-
@frankyboy73 sagte in MSG Payload werte auslesen:
@mickym Ah, ok, dann werde ich das jetzt mal mit der change Node umsetzen. Danke. Dann werde ich auch mal so nach und nach meine anderen Funktion Nodes (Texterstellung) dadurch ersetzen. Und für die Zukunft habe ich ja jetzt deine Vorlage.
Musst Du nicht. - Da machst ja auch nicht viel kaputt in Deiner Übersicht. Um was es mir ging habe ich ja am Anfang dieses Threads mit einem Beispiel versucht zu verdeutlichen. Bei komplexen Funktionen nimmt man sich halt die Möglichkeiten der Visualisierung eines Programmflows - das ja eine der Stärken von Node-Red ist. Letztlich ist jedes Programm, ob Blockly oder Javascript oder auch sonstiges Programm ja eine Abfolge von Anweisungen, die abgearbeitet werden und somit auch einen Flow darstellen.
Manchmal geht es ja auch nicht anders und deswegen gibt es ja auch die Function Nodes. Ich kann auch nur aus eigener Erfahrung sagen, dass ich am Anfang auch viele Function Nodes genutzt habe und dann irgendwann festgestellt habe, dass ich immer weniger verwende.
Ich nutze auch manchmal function Nodes die gar nichts machen (also nur "return msg") um einen Flow grafisch besser zu strukturieren.
-
Hallo Leute,
vielleicht könnt ihr mir ja weiterhelfen. Ich bekomme es nicht zusammen hier einzelne Objekte z.b die Temperatur als Zahl für weitere Verarbeitung raus zu bekommen.