Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. Change Node & JSONata

NEWS

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    22
    1
    1.2k

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    9.2k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    14
    1
    2.5k

Change Node & JSONata

Geplant Angeheftet Gesperrt Verschoben Skripten / Logik
13 Beiträge 2 Kommentatoren 2.7k Aufrufe
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • G Offline
    G Offline
    Garf
    schrieb am zuletzt editiert von
    #1

    Heute meinen RevPi mit allen Updates frisch gemacht. Dies hatte leider zur Folge, dass nun der Modbus-Server nicht mehr funktioniert. Warum auch immer. Da der Modbus so seine Eigenheiten hat, den Datenaustausch schnell auf MQTT umgestellt. Dann braucht man sich nicht mit den Variablentypen und Registern und dem ganzen IEEE-754 Zeug nicht mehr herumschlagen.

    Aber ganz so einfach ist es dann auch nicht, der MQTT Austausch erfolgt über eine Stringvariable. Diese müssen nun wieder auf einen Floatwert geparst und die Nachkommastellen auf eine eingekürzt werden. Mit einem Function-Node kein Problem. Davon sind aber schon so einige erforderlich. Jetzt gibt es da ja evtl. noch die Möglichkeit über JSONata den Ausgabewert in die richtige Form zu bringen. Aber leider weiß ich nicht wie. DIe ersten Versuche ein FlowContextVariable einzulesen hat mich schon an den Rand der Verzweifelung gebracht. Dabei war von Anfang an alles richtig nur der Contextwert ging leider immer verloren und so kam immer nur als Wert "Empty" zustande.

    Deshalb frage ich jetzt lieber mal im Vorfeld.

    Im Function Node sieht das Script wie folgt aus:

    ! ````
    var float = msg.payload;
    var AT = parseFloat(float);
    // Funktion Runden auf drei Nachkommastellen 10=1, 100=2, 1000=3,...
    function extround(zahl,n_stelle) {
    zahl = (Math.round(zahl * n_stelle) / n_stelle);
    return zahl;
    }
    msg.AT_RF = extround(AT, 1000);
    ! global.set("AT_RF_32bit",msg.AT_RF);
    return msg;

    
    Das Script ist noch etwas unaufgeräumt, mir war aber erst einmal wichtiger wieder ein paar Realwerte in mein Dashboard zu bekommen. Und jetzt bin ich sehr gespannt, ob man so etwas auch mit einem Change Node hinbekommt.
     ![3639_sc12.jpg](/assets/uploads/files/3639_sc12.jpg) 
     ![3639_sc11.jpg](/assets/uploads/files/3639_sc11.jpg) 
    
    Edit1:
    
    Einen Teilerfolg konnte ich schon erreichen:
    
    Die Umwandlung von String in Float mit JSONata funktioniert schon einmal.
     ![3639_sc13.jpg](/assets/uploads/files/3639_sc13.jpg) 
    Jetzt muss ich mal schauen, ob sich noch eine Lösung für die Nachkommastellen findet.
     ![3639_sc14.jpg](/assets/uploads/files/3639_sc14.jpg) 
    
    Soweit schon einmal sehr beeindruckend.
    1 Antwort Letzte Antwort
    0
    • R Offline
      R Offline
      rewenode
      schrieb am zuletzt editiert von
      #2

      Das war jetzt nicht wirklich … :D

      Da dein Code mit dem Screenshot nicht ganz übereinstimmt, hab ich mit dem Change-Node mal folgende Properties erzeugt:

      global.AT_RF32bit

      msg.AT_RF

      msg.raumtemp

      Falls du was Anderes brauchst, sollte die das change-node im flow zeigen, wie du das machst.

      Eigentlich ist der JSONata-Ausdruck simpel:

      $round($number(payload),3)
      

      3999_bild_1.png

      Hier der Flow

      ! ````
      [
      {
      "id": "e21d9d5e.1cf198",
      "type": "inject",
      "z": "4c7b95ed.8c2b44",
      "name": "",
      "topic": "",
      "payload": "20.700000762939453",
      "payloadType": "str",
      "repeat": "",
      "crontab": "",
      "once": false,
      "onceDelay": 0.1,
      "x": 180,
      "y": 180,
      "wires": [
      [
      "65f56b36.18cb0c",
      "25288ccf.48d6c4"
      ]
      ]
      },
      {
      "id": "3e7a9d5b.0308c2",
      "type": "comment",
      "z": "4c7b95ed.8c2b44",
      "name": "String inject",
      "info": "",
      "x": 190,
      "y": 140,
      "wires": []
      },
      {
      "id": "c63b6764.f6ecb",
      "type": "debug",
      "z": "4c7b95ed.8c2b44",
      "name": "converted",
      "active": true,
      "tosidebar": true,
      "console": false,
      "tostatus": false,
      "complete": "true",
      "x": 720,
      "y": 180,
      "wires": []
      },
      {
      "id": "65f56b36.18cb0c",
      "type": "debug",
      "z": "4c7b95ed.8c2b44",
      "name": "original",
      "active": true,
      "tosidebar": true,
      "console": false,
      "tostatus": false,
      "complete": "payload",
      "x": 460,
      "y": 120,
      "wires": []
      },
      {
      "id": "25288ccf.48d6c4",
      "type": "change",
      "z": "4c7b95ed.8c2b44",
      "name": "",
      "rules": [
      {
      "t": "set",
      "p": "AT_RF",
      "pt": "msg",
      "to": "$round($number(payload),3)",
      "tot": "jsonata"
      },
      {
      "t": "set",
      "p": "AT_RF32bit",
      "pt": "global",
      "to": "AT_RF",
      "tot": "msg"
      },
      {
      "t": "set",
      "p": "raumtemp",
      "pt": "msg",
      "to": "AT_RF",
      "tot": "msg"
      }
      ],
      "action": "",
      "property": "",
      "from": "",
      "to": "",
      "reg": false,
      "x": 480,
      "y": 180,
      "wires": [
      [
      "c63b6764.f6ecb"
      ]
      ]
      }
      ]

      1 Antwort Letzte Antwort
      0
      • G Offline
        G Offline
        Garf
        schrieb am zuletzt editiert von
        #3

        Daumen hoch. Da muss ich wohl anfangen umzudenken und die function-Nodes ersetzen.

        Ergebnis passt schon mal.
        3639_sc15.jpg

        Der umgerechnete Wert gibt die Raumfeuchtigkeit zurück. Soviele Sets sind nicht erforderlich der Wert muss nur noch als globale Variable weg geschrieben werden und damit wäre das ganze Function-Node schon ersetzt. Die Lösung dafür ist in deinem Beispiel ja auch schon enthalten.

        Jetzt muss ich wohl meine function-Nodes mal kritisch in Augenschein nehmen. Ich werde hier sicher noch die ein oder andere Frage dann stellen.

        Danke für die schnelle Rückantwort. Jetzt habe ich etwas Arbeit vor mir. :P

        1 Antwort Letzte Antwort
        0
        • R Offline
          R Offline
          rewenode
          schrieb am zuletzt editiert von
          #4

          Ach ja, wie man unter JSONata auf die node-red msg Properties zugreift findet du hier: https://github.com/node-red/cookbook.no … ta-Recipes

          Und eine genaue Beschreibung der JSONata Funktionen findet du hier: http://docs.jsonata.org/overview.html

          Häufig reicht auch die Funktionsreferenz des eingebauten JSONata Expression Editor. Im "Test"-Reiter kannst du solche Sachen auch ordentlich testen.

          3999_bild_2.png

          1 Antwort Letzte Antwort
          0
          • G Offline
            G Offline
            Garf
            schrieb am zuletzt editiert von
            #5

            @rewenode:

            Häufig reicht auch die Funktionsreferenz des eingebauten JSONata Expression Editor. Im "Test"-Reiter kannst du solche Sachen auch ordentlich testen. `
            Die Möglichkeit konnte ich bisher noch nicht wirklich nutzen. Da kommt fast immer eine Fehlermeldung. Da mache ich wohl noch etwas falsch. Mit dem JSONata Exerciser bin ich ganz gut klar gekommen http://try.jsonata.org/ryYn78Q0m.

            Eigentlich wollte ich hier schon die nächste Frage posten. Ich habe es aber auch selber schon hinbekommen. Aus einem Stringwert mussten div. Zeichen entfernt werden, dann der String zu einer Fließpunktzahl umgewandelt und die Stellen hinter dem Komma definiert werden. Dies alles in einer Zeile und mit den ganzen Klammern wollte mir nicht wirklich gelingen. Daher habe ich es dann mal mit der funktionalen Programmierung versucht.

            Das Ergebnis sieht nun so aus und funktioniert tadellos.

            ! ````
            (
            $laenge := $length(msg.payload)-1;
            $ZW := $substring(msg.payload, -0, $laenge);
            $round($number($ZW)*10,0)
            )

            
            Ich werfe im Moment ein function-Node nach dem anderen raus und ersetzte diese durch ein change-Node. :o
            
            Erstaunlich und erfreulich zugleich.
            
            Im Netz findet man diese Möglichkeit sehr selten, dafür aber um so häufiger die Programmierung über das function-Node.
            
            Schade eigentlich.
            1 Antwort Letzte Antwort
            0
            • R Offline
              R Offline
              rewenode
              schrieb am zuletzt editiert von
              #6

              @Garf:

              Da mache ich wohl noch etwas falsch. `
              Das liegt meist daran, dass ja kein Eingangs-payload zur Testzeit vorliegt. Deshalb muss man sich den Eingangspayload als "Example message", so wie in meinem letzen Post, im Test-Reiter anlegen.
              @Garf:

              Mit dem JSONata Exerciser bin ich ganz gut klar gekommen http://try.jsonata.org/ryYn78Q0m. `
              Ja, den nehme ich auch gerne her. Nur leider kann der natürlich nichts mit den node-red spezifischen Sachen anfangen.

              Sieht doch perfekt aus, deine Funktion. Hinweis: Solange du dich im root-context des Noldes bewegst, kannst du auf die msg-properties direkt zugreifen. Also payload statt msg.payload usw. https://github.com/node-red/cookbook.no … essing-msg

              @Garf:

              Ich werfe im Moment ein function-Node nach dem anderen raus und ersetzte diese durch ein change-Node. `

              Das ist zumindest eine gute Übung :D

              @Garf:

              Im Netz findet man diese Möglichkeit sehr selten, dafür aber um so häufiger die Programmierung über das function-Node.

              Schade eigentlich. `

              Ja, die Mächtigkeit von JSONata ist nicht so richtig bekannt. Und es ist auch nicht jedermanns Sache, Neben Javascript sich zusätzlich mit ner weiteren Syntax rumzuquälen. Und, naja, es gibt letztlich nichts in JSONata, was man mit Javascript nicht auch machen könnte.

              Die node-red Entwickler haben JSONata zum Glück gerade in letzter Zeit in weiteren Nodes implementiert.

              Ideal wäre ein ioBroker-node was einfach nur ein komplettes object ausgeben/kopieren kann.

              z.B. zigbee.0 –> payload.zigbee.0

              Da könnte man dann ein change-node dranhängen und nach Herzenslust per JSONata abfragen.

              Allseits frohe Weihnachten

              1 Antwort Letzte Antwort
              0
              • G Offline
                G Offline
                Garf
                schrieb am zuletzt editiert von
                #7

                Hi rewenode,

                bevor Du mir vor Langeweile noch das ganze Wochenende verschläfst, hier mal wieder eine Frage an den Experten. :lol:

                Ich wollte eine Uhrzeit mit JSONata in zwei Integerzahlen zerlegen, um diese dann per Modbus weitergeben zu können. Funktioniert auch teilweise, nur wenn die volle Stunde oder Minute mit einer 0 beginnt, dann kommt es zu einem Fehler. Mit Javascript im function Node und der parseInt Funktion geht es ohne Probleme. Wo liegt der Fehler?

                ! ````
                [{"id":"d39fe264.28fff","type":"inject","z":"342c6c5f.56269c","name":"","topic":"","payload":"08:04","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":2080,"wires":[["bc56ad.94ac715","4206f90e.204078"]]},{"id":"bc56ad.94ac715","type":"function","z":"342c6c5f.56269c","name":"msg","func":"var str=msg.payload;\nmsg.payload=parseInt(str.substring(0, 2));\nreturn msg;","outputs":1,"noerr":0,"x":420,"y":2020,"wires":[["be0857e0.29f52"]]},{"id":"be0857e0.29f52","type":"debug","z":"342c6c5f.56269c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":630,"y":2080,"wires":[]},{"id":"4206f90e.204078","type":"change","z":"342c6c5f.56269c","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$number($substringBefore(payload, ":"))\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":2080,"wires":[["be0857e0.29f52"]]}]

                
                 ![3639_sc11.jpg](/assets/uploads/files/3639_sc11.jpg) 
                 ![3639_sc12.jpg](/assets/uploads/files/3639_sc12.jpg) 
                1 Antwort Letzte Antwort
                0
                • R Offline
                  R Offline
                  rewenode
                  schrieb am zuletzt editiert von
                  #8

                  Normalerweise macht das $parseInteger()

                  $parseInteger($substringBefore(payload, ":"),'99')
                  

                  Aber das ist in der derzeitigen NR-JSONata Version noch nicht drin ;-(

                  Da bleibt nur z.B. mit einer kleinen function die führende Null zu entfernen. In der Art:

                  $n := "04";
                  $substring($n,0,1) = "0" ? $substring($n,1,1) : $n
                  
                  

                  Geht sicher einfacher, wenn ich drüber schlafe;-)

                  Einen schönen Sonntag

                  1 Antwort Letzte Antwort
                  0
                  • R Offline
                    R Offline
                    rewenode
                    schrieb am zuletzt editiert von
                    #9

                    oder, du trickst etwas:

                    ("0." & $substringBefore(payload, ":") ~> $number()) * 100
                    
                    
                    1 Antwort Letzte Antwort
                    0
                    • G Offline
                      G Offline
                      Garf
                      schrieb am zuletzt editiert von
                      #10

                      Da staune ich mal wieder Bauklötze.

                      Auf diesen Trick muss man erst einmal kommen.

                      Aber so 100% brauchbar ist es leider noch nicht. Mit parseInt() passiert so etwas nicht.

                      3639_sc13.jpg

                      Da ich mir eh einen anderen Weg überlegt habe, brauche ich es nicht mehr so wirklich. Es hatte mich halt mal interessiert wo das Problem liegt.

                      Wird $parseInteger() mit NodeRed v20.0 kommen?

                      1 Antwort Letzte Antwort
                      0
                      • R Offline
                        R Offline
                        rewenode
                        schrieb am zuletzt editiert von
                        #11

                        @Garf:

                        Wird $parseInteger() mit NodeRed v20.0 kommen? `
                        Angeblich ja (v0.20). Aber wer weis schon wie da die Prioritäten liegen. Vielleicht wird's ja doch erst zur v20.0 :lol:

                        1 Antwort Letzte Antwort
                        0
                        • R Offline
                          R Offline
                          rewenode
                          schrieb am zuletzt editiert von
                          #12

                          @Garf:

                          Auf diesen Trick muss man erst einmal kommen. `
                          Mit viel langer Weile geht auch so was :lol: :lol: :lol:

                          $reduce(payload.$split(":")[1].$split("").$number(),function($i, $j) {10*$i + $j})
                          
                          1 Antwort Letzte Antwort
                          0
                          • G Offline
                            G Offline
                            Garf
                            schrieb am zuletzt editiert von
                            #13

                            @rewenode:

                            Angeblich ja (v0.20). Aber wer weis schon wie da die Prioritäten liegen. Vielleicht wird's ja doch erst zur v20.0 :lol: `
                            O.K. erwischt. :mrgreen:

                            Mit der Version kann es noch dauern.
                            @rewenode:

                            Mit viel langer Weile geht auch so was :lol: :lol: :lol: `
                            Funktioniert absolut fehlerfrei.

                            1 Antwort Letzte Antwort
                            0
                            Antworten
                            • In einem neuen Thema antworten
                            Anmelden zum Antworten
                            • Älteste zuerst
                            • Neuste zuerst
                            • Meiste Stimmen


                            Support us

                            ioBroker
                            Community Adapters
                            Donate

                            811

                            Online

                            32.5k

                            Benutzer

                            81.7k

                            Themen

                            1.3m

                            Beiträge
                            Community
                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                            ioBroker Community 2014-2025
                            logo
                            • Anmelden

                            • Du hast noch kein Konto? Registrieren

                            • Anmelden oder registrieren, um zu suchen
                            • Erster Beitrag
                              Letzter Beitrag
                            0
                            • Home
                            • Aktuell
                            • Tags
                            • Ungelesen 0
                            • Kategorien
                            • Unreplied
                            • Beliebt
                            • GitHub
                            • Docu
                            • Hilfe