Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. Node-Red
    5. Vergleich von zwei Eingangswerten um Wert festzulegen

    NEWS

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    Vergleich von zwei Eingangswerten um Wert festzulegen

    This topic has been deleted. Only users with topic management privileges can see it.
    • mickym
      mickym Most Active @Claus1985 0 last edited by mickym

      @claus1985-0 Hier als Gruppe und einer eigenen Node für die Zukunft.

      [{"id":"6433d2174606172b","type":"group","z":"7eaefb9168296580","name":"Kinderzimmer","style":{"fill":"#ffefbf","label":true},"nodes":["6a8ef99635e6f249","e57c65b90a155939","b5094973c356d401"],"x":714,"y":1959,"w":392,"h":142},{"id":"f4f4c909aa9c4507","type":"subflow","name":"Status Jalousie","info":"","category":"","in":[{"x":40,"y":120,"wires":[{"id":"f2ea2908d88f1ab2"}]}],"out":[{"x":1340,"y":160,"wires":[{"id":"afb323cfc1bf25c8","port":0},{"id":"9b551e2006fd93dc","port":0},{"id":"6520234fe5d0f6b1","port":0}]}],"env":[],"meta":{},"color":"#3FADB5","outputLabels":["Stopped (2)","Increasing (1)","Decreasing (0)"],"icon":"node-red/sort.svg"},{"id":"f2ea2908d88f1ab2","type":"join","z":"f4f4c909aa9c4507","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":170,"y":120,"wires":[["22c744f5d81e7ba6"]]},{"id":"22c744f5d81e7ba6","type":"switch","z":"f4f4c909aa9c4507","name":"Not(wert1 ODER wert2)","property":"$not(payload.hoch or payload.runter)","propertyType":"jsonata","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":410,"y":120,"wires":[["afb323cfc1bf25c8"],["ad9f71d56fb6f349"]]},{"id":"afb323cfc1bf25c8","type":"change","z":"f4f4c909aa9c4507","name":"Stopped = 2","rules":[{"t":"set","p":"payload","pt":"msg","to":"2","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1150,"y":100,"wires":[[]]},{"id":"7be3c438b8976f82","type":"switch","z":"f4f4c909aa9c4507","name":"Rolladen runter = Increasing","property":"payload.runter","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":900,"y":160,"wires":[["9b551e2006fd93dc"]]},{"id":"44c83453fbeb6c4b","type":"switch","z":"f4f4c909aa9c4507","name":"Rolladen hoch = decreasing","property":"payload.hoch","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":900,"y":220,"wires":[["6520234fe5d0f6b1"]]},{"id":"9b551e2006fd93dc","type":"change","z":"f4f4c909aa9c4507","name":"Increasing = 1","rules":[{"t":"set","p":"payload","pt":"msg","to":"1","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1140,"y":160,"wires":[[]]},{"id":"6520234fe5d0f6b1","type":"change","z":"f4f4c909aa9c4507","name":"Decreasing = 0","rules":[{"t":"set","p":"payload","pt":"msg","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1140,"y":220,"wires":[[]]},{"id":"ad9f71d56fb6f349","type":"switch","z":"f4f4c909aa9c4507","name":"Ausfiltern beides 1","property":"$not(payload.hoch and payload.runter)","propertyType":"jsonata","rules":[{"t":"true"}],"checkall":"true","repair":false,"outputs":1,"x":630,"y":180,"wires":[["44c83453fbeb6c4b","7be3c438b8976f82"]]},{"id":"6a8ef99635e6f249","type":"change","z":"7eaefb9168296580","g":"6433d2174606172b","name":"runter","rules":[{"t":"set","p":"topic","pt":"msg","to":"runter","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":2060,"wires":[["b5094973c356d401"]]},{"id":"e57c65b90a155939","type":"change","z":"7eaefb9168296580","g":"6433d2174606172b","name":"hoch","rules":[{"t":"set","p":"topic","pt":"msg","to":"hoch","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":2000,"wires":[["b5094973c356d401"]]},{"id":"b5094973c356d401","type":"subflow:f4f4c909aa9c4507","z":"7eaefb9168296580","g":"6433d2174606172b","name":"","env":[],"x":1000,"y":2040,"wires":[["d318f1935ef49ef5"]]}]
      

      398a7ddf-1f3c-442e-b60c-b7c7585b8247-image.png

      Wenn Du nur die Node benutzt - musst halt immer Bedenken, dass den topic hoch und topic runter setzt bevor Du die Node fütterst. Kannst Dir ja auch einen Hilfetext dazu schreiben.

      1 Reply Last reply Reply Quote 0
      • R
        rewenode @mickym last edited by

        @mickym sagte in Vergleich von zwei Eingangswerten um Wert festzulegen:

        Ich habe jetzt meine function Nodes - die alle Objekteigenschaften überprüft haben durch folgende logische Nodes ersetzt:

        Super👍

        Du kannst die Ausdrücke noch um Einiges vereinfachen. Hier mal am Beispiel der OR mit den 2 Augängen:

        (
         $withOR := function($i, $j){$i or $j};
         $reduce(
         $each(
         payload,
         function($v) {$v}
         ),$withOR
         );
        )
        

        kannst du ersetzen durch:

        $reduce(payload.*, function($i, $j){$i or $j})
        

        Gruß
        Reiner

        mickym 1 Reply Last reply Reply Quote 0
        • mickym
          mickym Most Active @rewenode last edited by

          @rewenode Wow - danke - ob ich dass dann aber in paar Monaten noch verstehe. 🙂 Aber probiere ich gleich aus.

          Lieben Dank!!! 🙂

          1 Reply Last reply Reply Quote 0
          • F
            frankyboy73 last edited by frankyboy73

            Hi, ich will hier ja jetzt nicht den Lehrmeister oder so rauskehren, aber ist nicht immer die rede davon Node Red soll verständlich, übersichtlich und nachvollziehbar sein? Man sollte von Funktion Node absehen?
            Die meisten meiner Funktion Nodes habe ich mitlerweile ersetzen können. Aber bei meinen Funktion Nodes bin ich immer noch durchgestiegen, was wo und wann passiert. Aber jetzt mit Change Nodes oder Switch Nodes zu arbeiten in denen Funktionen bzw. Json benutzt wird, da bin ich raus. Ich verstehe bei den Inhalten nur noch Bahnhof. Es funktioniert, aber wieso? Keine Ahnung. Da bleibe ich für mich doch lieber bei längeren/größeren Flows mit Standartsachen die ich auch verstehe/nachvollziehen kann.
            Ist nicht negativ gemeint, jeder soll es so umsetzen wie er damit am besten klar kommt.

            Das hier verstehe ich ja noch. Enthält das payload.* ein true setze ich den einen Ausgang, sonst den anderen Ausgang.
            Join1.jpg

            Aber was passiert hier? Kann mir das vielleicht jemand übersetzen? Schon mal Danke im voraus.

            $reduce(payload.*, function($i, $j){$i or $j}) 
            

            Was ist $i und $j?

            R mickym 2 Replies Last reply Reply Quote 0
            • R
              rewenode @frankyboy73 last edited by

              @frankyboy73 sagte in Vergleich von zwei Eingangswerten um Wert festzulegen:

              Aber was passiert hier? Kann mir das vielleicht jemand übersetzen? Schon mal Danke im voraus.

              Achtung, die Aussagen sind stark vereinfacht!
              JSONata hat erstmal nicht direkt mit Node-Red oder JavaScript zu tun. Es ist vielmehr eine eigene Scriptsprache, die speziell für die einfache universelle Abfrage/Bearbeitung von JSON-Objekten entwickelt wurde.
              Auf Grund ihrer Mächtigkeit wurde sie relativ früh in Node-Red an vielen Stellen benutzt und ist inzwischen in vielen Nodes direkt integriert.
              JSONata hat allerdings eine eigene Syntax, nicht nicht wirklich was mit JavaScript gemein hat.
              Um den Einstieg zu erleichtern, ist in einigen Nodes im JSONata-Editor neben der Befehlsreferenz eine Testmöglichkeit implementiert.
              2021-11-30_18-53-28.png

              In das linke Fenster "Beispielnachricht" kannst ein gültiges JSON-Objekt reinschreiben und im Ergebnisfenster erscheint das Ergebnis des JSONata-Ausdruckes, den du im oberen Fenster eintragen kannst.

              Zurück zum $reduce().
              Dabei handelt es sich um eine in JSONata eingebaute Funktion. Die allgemeine Syntax ist:

              $reduce(array, function [, init])
              

              Sie durchläuft ein array, wendet auf jedes Element die function an und gibt das Gesamtergebnis zurück.
              Die Funktion hat mindestens 2 Parameter. (genaues erfährst du im Link)
              Der erster Parameter ist der Accumulator, der das Ergebnis speichert. Hier $i genannt.
              Der zweite Parameter ($j) ist der aktuelle Array-Wert beim Durchlaufen des array.
              Die Benennung mit $i und $j ist dabei willkürlich.

              Das Array wird durch den Ausdruck payload.* aus dem payload Objekt gebildet.
              Aus der payload

               {
                  "W1": true,
                  "W2": false,
                  "W3": true
              }
              

              erzeugt der JSONata-Ausdruck payload.* das Array

              [true, false, true]
              

              Auf dieses Array wird nun für alle Elemente die funktion angewendet.

              $i = $i or $j  // $i steht für das bisherige Ergebnis und $j für den aktuellen Wert
              

              Am Ende liefert also $reduce() den Wert $i also die or-Verknüpfung aller array-Werte zurück.

              Ich hoffe, ich habs auf die Schnelle einigermaßen verständlich rübergebracht.

              Also
              Braucht man unbedingt JSONata in Node-Red?
              Klare Antwort: Nein
              Aaaber, mit JSONata lassen sich äußerst komplexe JSON-Objekte teils als Einzeiler abfragen/bearbeiten. Etwa vergleichbar mit regEx.

              Gruß
              Reiner, der hier nur an der Oberfläche gekratzt hat ;-(

              F 1 Reply Last reply Reply Quote 0
              • F
                frankyboy73 @rewenode last edited by frankyboy73

                @rewenode Danke, ich glaube es wird klarer. Also wäre hier $i im Prinzip der Name der Nachricht und $j der jeweilige Wert.
                Und mit $i or $j sage ich ist eine der Nachrichten true (bzw. nicht null) ist die Bedingung erfüllt. Bei „and“ dann $i and $j , sind alle Nachrichten True (bzw. nicht null) dann ist die Bedingung erfüllt.
                Geht das auch umgekehrt? Also wenn alle Nachrichten false bzw. Null sind, dann ist die Bedingung erfüllt?

                Edit: Ok, ich hab da wohl doch noch nen Denkfehler, was i und j sind. Ich lese mich da wohl mal erst etwas ein.

                R mickym 2 Replies Last reply Reply Quote 0
                • R
                  rewenode @frankyboy73 last edited by

                  @frankyboy73 sagte in Vergleich von zwei Eingangswerten um Wert festzulegen:

                  $i im Prinzip der Name der Nachricht und $j der jeweilige Wert

                  Fast. der $reduce() "reduziert" das ganze array in dem es auf alle Werte des array die Funktion anwendet.
                  Für die $i könntest du auch $ergebnis schreiben und für $j z.B. auch $aktueller_array_wert

                  Wie die einzelnen array-Werte mit dem $ergebnis verknüpft werden bestimmt die Funktion. im Beispiel ist das or. Könnte aber auch jede beliebige "berechnung" wie and, +/-/* usw oder auch wieder eine eigene Funktion sein.
                  Bei dem simplen Bepiel-array mit den 3 Werten [true, false, true] wird das array (in einer Schleife) 3 mal durchlaufen. Ich nehm mal wieder $i und $j.

                  1. $i noch nicht initialisiert, $j ist true => $i bekommt den Wert $j also true 
                  2. $i = true, $j jetzt false => $i = true or false = true
                  3. $i = true, $j jetzt true => $i = true or true = true
                  

                  Da $i zurückgegeben wird ist das Ergebnis true. Das array wurde also auf den Wert true (der oder-Verknüpfung aller array-Werte) reduziert.

                  1 Reply Last reply Reply Quote 0
                  • mickym
                    mickym Most Active @frankyboy73 last edited by mickym

                    @frankyboy73 sagte in Vergleich von zwei Eingangswerten um Wert festzulegen:

                    Hi, ich will hier ja jetzt nicht den Lehrmeister oder so rauskehren, aber ist nicht immer die rede davon Node Red soll verständlich, übersichtlich und nachvollziehbar sein? Man sollte von Funktion Node absehen?

                    Ich bin doch immer noch bei Dir - und es gibt wie @rewenode gesagt hat für ein paar Standardfunktionen - zum Beispiel alle Eigenschaften eines Objektes die nur true oder false aufweisen.
                    Ich nutze generell - für solche einmal erstellte Nodes nun die lokale Bibliothek, so dass auch diese Nodes immer greifbar sind:

                    b9370775-f40f-4fd2-be79-264f3d8afb16-image.png

                    Wie würde denn ein normaler Flow (in dem Fall eher unübersichtlich und müsste immer wieder so gemacht werden - zum Beispiel UND Node aussehen - OK ich kann ihn noch in einen Subflow verpacken:

                    3bc7c10b-134b-490e-8911-b9e72d67b115-image.png

                    [
                       {
                           "id": "3f11d184.ea903e",
                           "type": "change",
                           "z": "5f34a973.9a1f88",
                           "name": "AND ?",
                           "rules": [
                               {
                                   "t": "set",
                                   "p": "payload",
                                   "pt": "msg",
                                   "to": "(\t $withAND := function($i, $j){$i and $j};\t $reduce(\t $each(\t payload,\t function($v) {$v}\t ),$withAND\t );\t)",
                                   "tot": "jsonata"
                               }
                           ],
                           "action": "",
                           "property": "",
                           "from": "",
                           "to": "",
                           "reg": false,
                           "x": 590,
                           "y": 440,
                           "wires": [
                               [
                                   "2138bf11.3010b"
                               ]
                           ]
                       },
                       {
                           "id": "1de7ee66.c7a392",
                           "type": "inject",
                           "z": "5f34a973.9a1f88",
                           "name": "Fenster geschlossen (1 geöffnet)",
                           "props": [
                               {
                                   "p": "payload"
                               }
                           ],
                           "repeat": "",
                           "crontab": "",
                           "once": false,
                           "onceDelay": 0.1,
                           "topic": "",
                           "payload": "{\"Büro Balkon\":true,\"Schlafzimmer Balkon\":true,\"Wohnzimmer Balkon\":true,\"Wohnzimmer rechtes Fenster\":false,\"Wohnzimmer linkes Fenster\":true}",
                           "payloadType": "json",
                           "x": 370,
                           "y": 460,
                           "wires": [
                               [
                                   "3f11d184.ea903e"
                               ]
                           ]
                       },
                       {
                           "id": "9398470c.0c4e68",
                           "type": "inject",
                           "z": "5f34a973.9a1f88",
                           "name": "Fenster geschlossen (alle geschlossen)",
                           "props": [
                               {
                                   "p": "payload"
                               }
                           ],
                           "repeat": "",
                           "crontab": "",
                           "once": false,
                           "onceDelay": 0.1,
                           "topic": "",
                           "payload": "{\"Büro Balkon\":true,\"Schlafzimmer Balkon\":true,\"Wohnzimmer Balkon\":true,\"Wohnzimmer rechtes Fenster\":true,\"Wohnzimmer linkes Fenster\":true}",
                           "payloadType": "json",
                           "x": 350,
                           "y": 420,
                           "wires": [
                               [
                                   "3f11d184.ea903e"
                               ]
                           ]
                       },
                       {
                           "id": "2138bf11.3010b",
                           "type": "debug",
                           "z": "5f34a973.9a1f88",
                           "name": "",
                           "active": true,
                           "tosidebar": true,
                           "console": false,
                           "tostatus": false,
                           "complete": "false",
                           "statusVal": "",
                           "statusType": "auto",
                           "x": 800,
                           "y": 440,
                           "wires": []
                       },
                       {
                           "id": "bcb4130d.771a8",
                           "type": "inject",
                           "z": "5f34a973.9a1f88",
                           "name": "Fenster geschlossen (1 geöffnet)",
                           "props": [
                               {
                                   "p": "payload"
                               }
                           ],
                           "repeat": "",
                           "crontab": "",
                           "once": false,
                           "onceDelay": 0.1,
                           "topic": "",
                           "payload": "{\"Büro Balkon\":true,\"Schlafzimmer Balkon\":true,\"Wohnzimmer Balkon\":true,\"Wohnzimmer rechtes Fenster\":false,\"Wohnzimmer linkes Fenster\":true}",
                           "payloadType": "json",
                           "x": 370,
                           "y": 600,
                           "wires": [
                               [
                                   "cf63c700.820c08"
                               ]
                           ]
                       },
                       {
                           "id": "f3ff4478.a406d8",
                           "type": "inject",
                           "z": "5f34a973.9a1f88",
                           "name": "Fenster geschlossen (alle geschlossen)",
                           "props": [
                               {
                                   "p": "payload"
                               }
                           ],
                           "repeat": "",
                           "crontab": "",
                           "once": false,
                           "onceDelay": 0.1,
                           "topic": "",
                           "payload": "{\"Büro Balkon\":true,\"Schlafzimmer Balkon\":true,\"Wohnzimmer Balkon\":true,\"Wohnzimmer rechtes Fenster\":true,\"Wohnzimmer linkes Fenster\":true}",
                           "payloadType": "json",
                           "x": 350,
                           "y": 560,
                           "wires": [
                               [
                                   "cf63c700.820c08"
                               ]
                           ]
                       },
                       {
                           "id": "cf63c700.820c08",
                           "type": "split",
                           "z": "5f34a973.9a1f88",
                           "name": "",
                           "splt": "\\n",
                           "spltType": "str",
                           "arraySplt": 1,
                           "arraySpltType": "len",
                           "stream": false,
                           "addname": "",
                           "x": 590,
                           "y": 580,
                           "wires": [
                               [
                                   "6de9d377.2ff4fc"
                               ]
                           ]
                       },
                       {
                           "id": "19c4904b.9656",
                           "type": "switch",
                           "z": "5f34a973.9a1f88",
                           "name": "",
                           "property": "payload",
                           "propertyType": "msg",
                           "rules": [
                               {
                                   "t": "true"
                               },
                               {
                                   "t": "false"
                               }
                           ],
                           "checkall": "true",
                           "repair": false,
                           "outputs": 2,
                           "x": 930,
                           "y": 580,
                           "wires": [
                               [
                                   "2ce40a79.8f7f36"
                               ],
                               [
                                   "b859c7a3.b180d8"
                               ]
                           ]
                       },
                       {
                           "id": "6de9d377.2ff4fc",
                           "type": "change",
                           "z": "5f34a973.9a1f88",
                           "name": "",
                           "rules": [
                               {
                                   "t": "set",
                                   "p": "result",
                                   "pt": "msg",
                                   "to": "true",
                                   "tot": "bool"
                               }
                           ],
                           "action": "",
                           "property": "",
                           "from": "",
                           "to": "",
                           "reg": false,
                           "x": 760,
                           "y": 580,
                           "wires": [
                               [
                                   "19c4904b.9656"
                               ]
                           ]
                       },
                       {
                           "id": "b859c7a3.b180d8",
                           "type": "change",
                           "z": "5f34a973.9a1f88",
                           "name": "",
                           "rules": [
                               {
                                   "t": "set",
                                   "p": "result",
                                   "pt": "msg",
                                   "to": "false",
                                   "tot": "bool"
                               }
                           ],
                           "action": "",
                           "property": "",
                           "from": "",
                           "to": "",
                           "reg": false,
                           "x": 1110,
                           "y": 600,
                           "wires": [
                               [
                                   "2ce40a79.8f7f36"
                               ]
                           ]
                       },
                       {
                           "id": "2ce40a79.8f7f36",
                           "type": "join",
                           "z": "5f34a973.9a1f88",
                           "name": "",
                           "mode": "auto",
                           "build": "string",
                           "property": "payload",
                           "propertyType": "msg",
                           "key": "topic",
                           "joiner": "\\n",
                           "joinerType": "str",
                           "accumulate": "false",
                           "timeout": "",
                           "count": "",
                           "reduceRight": false,
                           "x": 1270,
                           "y": 560,
                           "wires": [
                               [
                                   "6258741.4061e8c"
                               ]
                           ]
                       },
                       {
                           "id": "8ae29da1.0edd",
                           "type": "debug",
                           "z": "5f34a973.9a1f88",
                           "name": "",
                           "active": true,
                           "tosidebar": true,
                           "console": false,
                           "tostatus": false,
                           "complete": "false",
                           "statusVal": "",
                           "statusType": "auto",
                           "x": 1630,
                           "y": 560,
                           "wires": []
                       },
                       {
                           "id": "6258741.4061e8c",
                           "type": "change",
                           "z": "5f34a973.9a1f88",
                           "name": "",
                           "rules": [
                               {
                                   "t": "set",
                                   "p": "payload",
                                   "pt": "msg",
                                   "to": "result",
                                   "tot": "msg"
                               }
                           ],
                           "action": "",
                           "property": "",
                           "from": "",
                           "to": "",
                           "reg": false,
                           "x": 1440,
                           "y": 560,
                           "wires": [
                               [
                                   "8ae29da1.0edd"
                               ]
                           ]
                       }
                    ]
                    

                    Und soviel Code ist es auch nicht. Ich bin ja auch erst dabei bisschen mehr in das JSONATA einzuarbeiten.

                    Wir sind ja beide auch Anhänger nicht gleich wegen jeder Kleinigkeit irgendwelche Nodes oder Adapter einzubinden, sondern versuchen das mit Hausmitteln zu lösen.

                    Mit JSONATA - kann man so auch easy zum Beispiel mit 2 Tagesperioden in einer Switch Node zu basteln. Erinnerst Du Dich noch an die Change NOdes, die über JSONATA moment nun diese Node überflüssig machen:

                    da8a113d-744f-44e6-b377-0676e2300765-image.png

                    https://flows.nodered.org/node/node-red-contrib-moment

                    Mit JSONATA kann man dann auch eine Switch Node nutzen - im Prinzip hast Du mich ja auf die Idee gebracht, da ich JSONATA vorher noch nie als Selektionskriterium genutzt habe. 😉

                    [
                       {
                           "id": "c38b4c7c513c582b",
                           "type": "switch",
                           "z": "7eaefb9168296580",
                           "name": "Ist Tag?",
                           "property": "(\t   $time:= $moment().locale(\"de\").tz('Europe/Berlin').format('HH:mm');\t   $time >= \"10:30\" and $time < \"16:30\";\t)",
                           "propertyType": "jsonata",
                           "rules": [
                               {
                                   "t": "true"
                               },
                               {
                                   "t": "false"
                               }
                           ],
                           "checkall": "true",
                           "repair": false,
                           "outputs": 2,
                           "x": 520,
                           "y": 3340,
                           "wires": [
                               [
                                   "f01d19782f844e07"
                               ],
                               [
                                   "584862fcb3f9e6ab"
                               ]
                           ],
                           "outputLabels": [
                               "Tag (zwischen 10:30 und 16:29)",
                               "Nacht (zwischen 16:30 und 10:29)"
                           ]
                       }
                    ]
                    

                    15aa71a8-7437-49ab-947d-c460dffde91f-image.png

                    Also im Großen und Ganzen - bleibe ich unserer Philosophie schon treu - wenn es sich aber immer um die gleiche Aufgabenstellung handelt - dann macht es meines Erachtens schon Sinn - die Logik aus Sicht der Übersichtlichkeit zusammenzufassen. Es ändert sich an dieser Logik ja nicht - zudem solche Flowfragmente ja mehrfach wieder eingesetzt werden.

                    Ich denke, dass wir trotzdem noch dasselbe Verständnis haben- ich hatte da vorher auch Function Nodes und da sind die JSONATA Funktionen trotzdem noch einfacher, weil sie eben in CHange und Switch Nodes direkt verwendet werden können.

                    1 Reply Last reply Reply Quote 0
                    • mickym
                      mickym Most Active @frankyboy73 last edited by mickym

                      @frankyboy73 sagte in Vergleich von zwei Eingangswerten um Wert festzulegen:

                      @rewenode Danke, ich glaube es wird klarer. Also wäre hier $i im Prinzip der Name der Nachricht und $j der jeweilige Wert.
                      Und mit $i or $j sage ich ist eine der Nachrichten true (bzw. nicht null) ist die Bedingung erfüllt. Bei „and“ dann $i and $j , sind alle Nachrichten True (bzw. nicht null) dann ist die Bedingung erfüllt.
                      Geht das auch umgekehrt? Also wenn alle Nachrichten false bzw. Null sind, dann ist die Bedingung erfüllt?

                      Edit: Ok, ich hab da wohl doch noch nen Denkfehler, was i und j sind. Ich lese mich da wohl mal erst etwas ein.

                      In der Doku : https://docs.jsonata.org/higher-order-functions

                      feb219a7-2a66-45fc-b634-8cd793642a7c-image.png

                      Siehst Du das immer einfach der letzte mit dem vorletzen Element genutzt werden. In der Doku werden also 1. mit 0. Zahl multipliziert, dann 2. mit 1. Zahl, dann 3. Zahl mit Produkt aus 1 und 2. Zahl.

                      021be2e2-6a43-413a-9a55-2185afa74513-image.png

                      Geht das auch umgekehrt? Also wenn alle Nachrichten false bzw. Null sind, dann ist die Bedingung erfüllt

                      Das machst Du mit der Funktion, die auf einen Wert reduziert:

                      Für dieses Reduce definierst Du ja eine eigene Funktion:

                      (
                         $withAND := function($i, $j){$i and $j};
                         $reduce(
                             $each(
                       payload,
                       function($v) {$not($v)}
                       ),
                             $withAND
                         )
                      )
                      

                      Du musst halt die Eingabe verneinen. Wobei ich wohl dann besser eine ODER Node verwenden würde und einfach das Ergebnis verneinen. Das wäre logischer.

                      Im Übrigen gibt es diese Reduce Funktion auch in der JOIN Node - das habe ich neulich ausprobiert. 😉

                      So hier mal die Reduce Funktion in der JOIN Node - funktioniert ähnlich wie die reduce Funktion in JSONATA - es wird immer mit dem Vorgänger verknüpft:

                      Hier mal die AND Node - dass alles true sein muss:

                      f608efeb-8242-442a-94b4-cd4485d74454-image.png

                      Eigentlich ist das auch schon kurz 😉 - Insofern könnte man das auch anstelle JSONATA und der UND nutzen: 😉

                      [
                         {
                             "id": "bcb4130d.771a8",
                             "type": "inject",
                             "z": "5f34a973.9a1f88",
                             "name": "Fenster geschlossen (1 geöffnet)",
                             "props": [
                                 {
                                     "p": "payload"
                                 }
                             ],
                             "repeat": "",
                             "crontab": "",
                             "once": false,
                             "onceDelay": 0.1,
                             "topic": "",
                             "payload": "{\"Büro Balkon\":true,\"Schlafzimmer Balkon\":true,\"Wohnzimmer Balkon\":true,\"Wohnzimmer rechtes Fenster\":false,\"Wohnzimmer linkes Fenster\":true}",
                             "payloadType": "json",
                             "x": 370,
                             "y": 600,
                             "wires": [
                                 [
                                     "cf63c700.820c08"
                                 ]
                             ]
                         },
                         {
                             "id": "f3ff4478.a406d8",
                             "type": "inject",
                             "z": "5f34a973.9a1f88",
                             "name": "Fenster geschlossen (alle geschlossen)",
                             "props": [
                                 {
                                     "p": "payload"
                                 }
                             ],
                             "repeat": "",
                             "crontab": "",
                             "once": false,
                             "onceDelay": 0.1,
                             "topic": "",
                             "payload": "{\"Büro Balkon\":true,\"Schlafzimmer Balkon\":true,\"Wohnzimmer Balkon\":true,\"Wohnzimmer rechtes Fenster\":true,\"Wohnzimmer linkes Fenster\":true}",
                             "payloadType": "json",
                             "x": 350,
                             "y": 560,
                             "wires": [
                                 [
                                     "cf63c700.820c08"
                                 ]
                             ]
                         },
                         {
                             "id": "cf63c700.820c08",
                             "type": "split",
                             "z": "5f34a973.9a1f88",
                             "name": "",
                             "splt": "\\n",
                             "spltType": "str",
                             "arraySplt": 1,
                             "arraySpltType": "len",
                             "stream": false,
                             "addname": "",
                             "x": 590,
                             "y": 580,
                             "wires": [
                                 [
                                     "2ce40a79.8f7f36"
                                 ]
                             ]
                         },
                         {
                             "id": "2ce40a79.8f7f36",
                             "type": "join",
                             "z": "5f34a973.9a1f88",
                             "name": "",
                             "mode": "reduce",
                             "build": "string",
                             "property": "payload",
                             "propertyType": "msg",
                             "key": "topic",
                             "joiner": "\\n",
                             "joinerType": "str",
                             "accumulate": false,
                             "timeout": "",
                             "count": "",
                             "reduceRight": false,
                             "reduceExp": "$A and payload",
                             "reduceInit": "true",
                             "reduceInitType": "bool",
                             "reduceFixup": "",
                             "x": 730,
                             "y": 580,
                             "wires": [
                                 [
                                     "8505d9e0.19a638"
                                 ]
                             ]
                         },
                         {
                             "id": "8505d9e0.19a638",
                             "type": "debug",
                             "z": "5f34a973.9a1f88",
                             "name": "",
                             "active": true,
                             "tosidebar": true,
                             "console": false,
                             "tostatus": false,
                             "complete": "false",
                             "statusVal": "",
                             "statusType": "auto",
                             "x": 890,
                             "y": 580,
                             "wires": []
                         }
                      ]
                      

                      Mit dieser Funktion der JOIN Node hat es auch gebraucht bis ich das kapiert habe - macht aber nichts anderes als die reduce Funktion unter JSONATA:

                      8316124b-ab6c-4d07-93a3-290e8f801cbd-image.png

                      Hier mal mit dem Hilfetext der JOIN - Node - damit man das gleich vergleichen kann.

                      Das heißt die JSONATA Eingabe:

                      $A and payload
                      

                      entspricht dem Funktionsaufruf der reduce Funktion in JSONATA.

                      R F 2 Replies Last reply Reply Quote 0
                      • R
                        rewenode @mickym last edited by rewenode

                        @mickym Ja, dieses Sequenz reduzieren des Join Node ist ja intern nichts anderes als ein JSONata $reduce().

                        Übrigens

                        $each(
                         payload,
                         function($v) {$v}
                         )
                        

                        macht aus aus dem Eingangs-payload-objekt

                        {
                         "wert1":0,
                         "wert2":1,
                         "wert3":0
                        }
                        

                        folgendes array

                        [0,1,0]
                        

                        Macht also genau dasselbe wie:

                        payload.*
                        

                        Und deshalb kannst du es weglassen und stattdessen

                        $reduce(payload.*, function($i, $j){$i and $j})
                        

                        schreiben.

                        mickym 1 Reply Last reply Reply Quote 0
                        • mickym
                          mickym Most Active @rewenode last edited by

                          @rewenode Ah OK - das heißt ich muss nicht mit $each durch das Array durchgehen.

                          R 1 Reply Last reply Reply Quote 0
                          • R
                            rewenode @mickym last edited by rewenode

                            @mickym Nop. Aber schaden tut's auch nicht 😊

                            PS. der $each() geht nicht durch ein array, sondern durch ein objekt. Und da der $reduce() ein array benötigt, nimmst du den $each(), weil der ein array draus macht.
                            Die eigentliche Arbeit macht sowieso der $reduce()

                            mickym 1 Reply Last reply Reply Quote 0
                            • mickym
                              mickym Most Active @rewenode last edited by mickym

                              @rewenode sagte in Vergleich von zwei Eingangswerten um Wert festzulegen:

                              @mickym Nop. Aber schaden tut's auch nicht 😊

                              PS. der $each() geht nicht durch ein array, sondern durch ein objekt. Und da der $reduce() ein array benötigt, nimmst du den $each(), weil der ein array draus macht.
                              Die eigentliche Arbeit macht sowieso der $reduce()

                              Da hast Du natürlich Recht - ich muss mal schauen, ob mit Deiner Syntax eventuell diese Fehlermeldung nicht auftaucht - während der Initialisierung:

                              oder definiere noch ein leeres Objekt:

                              
                              node-red.0
                              2021-12-01 00:38:48.406	error	1 Dec 00:38:48 - [error] [change:AND ?] Ungültiger JSONata Ausdruck: Argument 1 of function "each" does not match function signature1 Dec 00:38:48 - [error] [change:AND ?] Ungültiger JSONata Ausdruck: Argument 1 of function "each" does not match function signature
                              
                              node-red.0
                              2021-12-01 00:38:48.403	error	1 Dec 00:38:48 - [error] [change:AND ?] Ungültiger JSONata Ausdruck: Argument 1 of function "each" does not match function signature
                              
                              node-red.0
                              2021-12-01 00:38:48.401	error	1 Dec 00:38:48 - [error] [change:AND ?] Ungültiger JSONata Ausdruck: Argument 1 of function "each" does not match function signature
                              
                              node-red.0
                              2021-12-01 00:38:48.400	error	1 Dec 00:38:48 - [error] [change:AND ?] Ungültiger JSONata Ausdruck: Argument 1 of function "each" does not match function signature
                              
                              node-red.0
                              2021-12-01 00:38:48.396	error	1 Dec 00:38:48 - [error] [change:AND ?] Ungültiger JSONata Ausdruck: Argument 1 of function "each" does not match function signature
                              
                              node-red.0
                              2021-12-01 00:38:48.392	error	1 Dec 00:38:48 - [error] [change:AND ?] Ungültiger JSONata Ausdruck: Argument 1 of function "each" does not match function signature
                              

                              Habs gerade ausprobiert - Deine Syntax ist besser:

                              9aba3986-e6a0-4028-b3c7-d05f482b8e15-image.png

                              Es wird kein Error erzeugt, sondern ein undefined - was OK ist.

                              R 1 Reply Last reply Reply Quote 0
                              • R
                                rewenode @mickym last edited by

                                @mickym Habe lange Zeit nichts mehr mit NR und ioB gemacht. Weil never change..😀
                                Bin echt beeindruckt, was ihr da inzwischen so zaubert! Und ich kenne nicht mal alle neuen nodes😞

                                Da kommt mir der tread grade recht😁
                                So, genug gelabert.

                                mickym 1 Reply Last reply Reply Quote 0
                                • mickym
                                  mickym Most Active @rewenode last edited by mickym

                                  @rewenode Eine Frage habe ich noch.

                                  Wenn ich das reduce mit payload.* übergebe, dann habe ich halt keine Möglichkeit die Werte noch zu verändern, so wie ich das hier gemacht habe:

                                  (
                                     $withAND := function($i, $j){$i and $j};
                                     $reduce(
                                         $each(
                                   payload,
                                   function($v) {$not($v)}
                                   ),
                                         $withAND
                                     )
                                  )
                                  
                                  

                                  also bei Umwandlung der Objekteigenschaften in das Array noch Einfluß zu nehmen. Im Prinzip müsste ich im Vorfeld noch eine Typprüfung vornehmen und ggf. ein leeres Objekt übergeben.

                                  Also wenn man das übergebene Array noch manipulieren will, kann mit einer Typ-Prüfung den Fehler noch abfangen und ein leeres Objekt übergeben:

                                  (
                                     $withAND := function($i, $j){$i and $j};
                                     $reduce(
                                         $each(
                                             $type(payload) = 'object' ? payload : {},
                                             function($v) {$not($v)}
                                   ),
                                         $withAND
                                   );
                                     )
                                  

                                  anders bekomme ich es nicht hin. 😉

                                  1 Reply Last reply Reply Quote 0
                                  • R
                                    rewenode last edited by

                                    @mickym sagte in Vergleich von zwei Eingangswerten um Wert festzulegen:

                                    Im Prinzip müsste ich im Vorfeld noch eine Typprüfung vornehmen und ggf. ein leeres Objekt übergeben.

                                    Kommt darauf an, was genau du machen willst. Hast du ein Object und du willst z.B. das Array für den $reduce() aus eigenen Elementen erstellen/berechen, dann nimmst du z.B. den $each(). Dabei meine ich nicht, dass du die key/value Paare des Objektes filtern mußt, das geht einfacher.

                                    Willst du hingegen die Array-Werte manipulieren, bevor der $reduce() drüberläuft, kannst du das entweder vorher mit der $map() Funktion machen.
                                    Willst du z.B. alle Elemente des Array vorher negieren und somit das Ergebnis, kannst du das nehmen.

                                    $reduce(
                                       $map(*,function($v){$not($v)}),
                                       function($i, $j){($i or $j)}
                                    )
                                    

                                    Allerdings kannst du das ganz bequem auch in der function vom $reduce() machen, der läuft ja sowieso über alle Elemente des array.
                                    Aaaber, dabei kann es Probleme geben. Im Beispiel mit dem or würde es Probleme geben, weil der erste Wert ja direkt im $i landet, bevor er negiert werden kann.
                                    Deshalb kennt der $reduce() den Startwert, den du zusätzlich übergeben kannst.

                                    $reduce(payload.*, function($i, $j){($i or $not($j))}, false)
                                    

                                    Dieser $reduce() macht also genau das selbe, wobei die Negation direkt in der function erfolgt.

                                    Natürlich kann man in diesem simplen or-Beispiel gleich das Ergebnis negieren, was aufs Selbe hinaus läuft.

                                    $not($reduce(*,function($i, $j){($i or ($j))}))
                                    

                                    Aber das Beispiel sollte ja auch nur zeigen, dass man eigentlich alle Manipulationen an den Array-Werten auch direkt in der $reduce()-function machen kann.

                                    mickym 1 Reply Last reply Reply Quote 0
                                    • mickym
                                      mickym Most Active @rewenode last edited by mickym

                                      @rewenode OK - das muss ich mir mal ansehen, wenn ich noch mehr geistige Kapazitäten hatte.

                                      Soweit war ich

                                      $reduce(payload.*, function($i, $j){$i or $not($j)}, false)
                                      

                                      Warum nochmal die Klammer was bringen soll? - Verstehe ich nicht.
                                      Aber nach meinen Test funktioniert auch Deine beiden Varianten nicht.

                                      $reduce(
                                         $map(*,function($v){$not($v)}),
                                         function($i, $j){($i or $j)}
                                      )
                                      

                                      als auch

                                      $reduce(payload.*, function($i, $j){($i or $not($j))}, false)
                                      

                                      liefert grundsätzlich true, auch wenn eine Eigenschaft true ist. Es soll ja nur true werden, wenn alle false sind. Es geht ja um die Manipulation des arrays (also vor Übergabe an die reduce Funktion).
                                      sowohl

                                      {
                                          "Büro Balkon": true,
                                          "Schlafzimmer Balkon": false,
                                          "Wohnzimmer Balkon": false,
                                          "Wohnzimmer rechtes Fenster": false,
                                          "Wohnzimmer linkes Fenster": false
                                      }
                                      

                                      liefert aber auch true - was ja nicht der Fall sein dürfte.

                                      Das ODER einfach negieren - habe ich schon vorgeschlagen, da scheint bei Dir aber irgendwie ein Fehler in der letzten Zeile irgendwie vorzuliegen:

                                      Ich habe es so und damit geht es:

                                      $not($reduce(payload.*,function($i, $j){$i or $j}))
                                      

                                      ===================================================================

                                      So mit dem map geht es - da es aber umgedreht wird muss man eine logische AND Verknüpfung machen:

                                      $reduce(
                                         $map(payload.*,function($v){$not($v)}),
                                         function($i, $j){$i and $j}
                                      ) 
                                      

                                      bei der anderen Version funktioniert es nicht.

                                      R 1 Reply Last reply Reply Quote 0
                                      • R
                                        rewenode @mickym last edited by

                                        @mickym sagte in Vergleich von zwei Eingangswerten um Wert festzulegen:

                                        Es soll ja nur true werden, wenn alle false sind

                                        Ja, da mußt du ein and nehmen. Wenn du jeden Array Wert negierst, heißt das ja, dass nur true rauskommen soll wenn alle true (weil negiert) sind. Und das ist eine einfache UND-Verknüpfung.

                                        $reduce(payload.*, function($i, $j){$i and $not($j)})
                                        

                                        Oder halt das Ergebnis des OR negieren wie du es jetzt gemacht hast.

                                        mickym 1 Reply Last reply Reply Quote 0
                                        • mickym
                                          mickym Most Active @rewenode last edited by

                                          @rewenode sagte in Vergleich von zwei Eingangswerten um Wert festzulegen:

                                          $reduce(payload.*, function($i, $j){$i and $not($j)})

                                          Das tut nicht - kommt false raus, wenn alles false ist und true, wenn alle false aber einer true. Ich meine mit dem Mapping geht es ja.

                                          Ist aber egal - mit dem maping geht es und mit dem map erzeugt ein Nicht-Objekt zumindest kein Error - sondern ein undefined. Die Funktionen die einen Fehler erzeugen oder nicht, sind da wohl sehr unterschiedlich. Wie gesagt mit dem mapping habe ich ja auch eine gute Lösung.

                                          R 1 Reply Last reply Reply Quote 0
                                          • R
                                            rewenode @mickym last edited by rewenode

                                            @mickym sagte in Vergleich von zwei Eingangswerten um Wert festzulegen:

                                            Das tut nicht - kommt false raus, wenn alles false ist und true, wenn alle false aber einer true. Ich meine mit dem Mapping geht es ja.

                                            Ja sorry, copy/paste Fehler. Habe den Start-Wert vergessen.

                                            $reduce(payload.*, function($i, $j){$i and $not($j)}, true)
                                            

                                            Doch schon zu spät. Muss natürlich payload.* sein. ;-(

                                            mickym 1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post

                                            Support us

                                            ioBroker
                                            Community Adapters
                                            Donate

                                            814
                                            Online

                                            31.7k
                                            Users

                                            79.8k
                                            Topics

                                            1.3m
                                            Posts

                                            5
                                            53
                                            9935
                                            Loading More Posts
                                            • Oldest to Newest
                                            • Newest to Oldest
                                            • Most Votes
                                            Reply
                                            • Reply as topic
                                            Log in to reply
                                            Community
                                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                            The ioBroker Community 2014-2023
                                            logo