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. Wert von mehreren empf. Objekten in eine Tabelle darstellen

    NEWS

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

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    Wert von mehreren empf. Objekten in eine Tabelle darstellen

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

      So eigentlich noch schöner und universeller ist, wenn jeder eintreffende Wert sich selbst in die Tabelle einordnet. Das habe ich auch mit dem Beispielcode geschafft, aber .....

      Mit diesen 3 Nodes baut sich die Tabelle selbst auf - ich habe nur mal das topic in ein Array umgewandelt, erst Sensor und dann Eigenschaft:

      7d0e3084-550c-45ac-87b3-cb49d07cd239-image.png

      Die erste Regel kann man sich inzwischen sparen, da man ja in den iobroker IN Nodes nun angeben kann, ob man . oder / als Pfadtrenner verwenden will:

      30d4a5c7-333e-4501-a9b8-c785f87d22d9-image.png

      Wichtig ist dann der JSONATA Code in der letzten Regel, um einzelne Daten in die Tabelle zu schreiben - und auch so aus der table Node Beschreibung entnommen:

      {
         "command":"updateOrAddData",
         "arguments": [
             [
                 {
                     "id":topic[0],
                     topic[1]:payload             
                 }         
             ]     
         ],
         "returnPromise": false 
      }
      

      [
         {
             "id": "369345985dd6f79e",
             "type": "change",
             "z": "78ab47508f21e87e",
             "name": "",
             "rules": [
                 {
                     "t": "change",
                     "p": "topic",
                     "pt": "msg",
                     "from": "/",
                     "fromt": "str",
                     "to": ".",
                     "tot": "str"
                 },
                 {
                     "t": "change",
                     "p": "topic",
                     "pt": "msg",
                     "from": "0_userdata\\.0\\.Test\\.(.*)$",
                     "fromt": "re",
                     "to": "$1",
                     "tot": "str"
                 },
                 {
                     "t": "set",
                     "p": "topic",
                     "pt": "msg",
                     "to": "$split(topic, \".\")\t",
                     "tot": "jsonata"
                 },
                 {
                     "t": "set",
                     "p": "payload",
                     "pt": "msg",
                     "to": "{\t   \"command\":\"updateOrAddData\",\t   \"arguments\": [\t       [\t           {\t               \"id\":topic[0],\t               topic[1]:payload             \t           }         \t       ]     \t   ],\t   \"returnPromise\": false \t}",
                     "tot": "jsonata"
                 }
             ],
             "action": "",
             "property": "",
             "from": "",
             "to": "",
             "reg": false,
             "x": 530,
             "y": 1220,
             "wires": [
                 [
                     "83c0855690cffc44"
                 ]
             ]
         },
         {
             "id": "83c0855690cffc44",
             "type": "ui_table",
             "z": "78ab47508f21e87e",
             "group": "744968de.91c328",
             "name": "table 2",
             "order": 0,
             "width": 0,
             "height": 0,
             "columns": [
                 {
                     "field": "id",
                     "title": "Name",
                     "width": "",
                     "align": "left",
                     "formatter": "plaintext",
                     "formatterParams": {
                         "target": "_blank"
                     }
                 },
                 {
                     "field": "temperature",
                     "title": "Temperatur",
                     "width": "",
                     "align": "left",
                     "formatter": "plaintext",
                     "formatterParams": {
                         "target": "_blank"
                     }
                 },
                 {
                     "field": "humidity",
                     "title": "Luftfeuchtigkeit",
                     "width": "",
                     "align": "left",
                     "formatter": "plaintext",
                     "formatterParams": {
                         "target": "_blank"
                     }
                 }
             ],
             "outputs": 0,
             "cts": false,
             "x": 710,
             "y": 1220,
             "wires": []
         },
         {
             "id": "e0f981911a65efca",
             "type": "ioBroker in",
             "z": "78ab47508f21e87e",
             "name": "",
             "topic": "0_userdata.0.Test.*",
             "payloadType": "value",
             "onlyack": "",
             "func": "all",
             "gap": "",
             "fireOnStart": "false",
             "x": 290,
             "y": 1220,
             "wires": [
                 [
                     "369345985dd6f79e"
                 ]
             ]
         },
         {
             "id": "744968de.91c328",
             "type": "ui_group",
             "name": "Tabelle ui_table",
             "tab": "2ce144dc.d7472c",
             "order": 6,
             "disp": true,
             "width": "10",
             "collapse": false,
             "className": ""
         },
         {
             "id": "2ce144dc.d7472c",
             "type": "ui_tab",
             "name": "test",
             "icon": "dashboard",
             "order": 23,
             "disabled": false,
             "hidden": false
         }
      ]
      

      Das ABER ist aber 😉 - dass leider nach jedem Refresh die Tabelle wieder leer ist. Ich habe keine Ahnung warum. Wenn man die Tabelle wie im vorigen Flow aufbaut und die ganze Tabelle schickt - ist alles gut und sie übersteht auch einen Refresh.

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

        @mickym So hier der optimierte Flow - um die gesamte Tabelle vollständig nach jedem Update zu senden:

        f56cf6a0-63e2-4736-ad67-1c61a0d07406-image.png

        entspricht also dem unteren Flow.

        [
           {
               "id": "14d18ea35afed3ac",
               "type": "change",
               "z": "78ab47508f21e87e",
               "name": "",
               "rules": [
                   {
                       "t": "change",
                       "p": "topic",
                       "pt": "msg",
                       "from": "/",
                       "fromt": "str",
                       "to": ".",
                       "tot": "str"
                   },
                   {
                       "t": "change",
                       "p": "topic",
                       "pt": "msg",
                       "from": "0_userdata\\.0\\.Test\\.(.*)$",
                       "fromt": "re",
                       "to": "$1",
                       "tot": "str"
                   },
                   {
                       "t": "set",
                       "p": "topic",
                       "pt": "msg",
                       "to": "$split(topic, \".\")\t",
                       "tot": "jsonata"
                   },
                   {
                       "t": "set",
                       "p": "sensors",
                       "pt": "flow",
                       "to": "$merge([$flowContext(\"sensors\"),{topic[0]:$merge([$flowContext(\"sensors\" & [topic[0]]),{topic[1]: payload,\"id\": topic[0]}])}])\t",
                       "tot": "jsonata"
                   },
                   {
                       "t": "set",
                       "p": "payload",
                       "pt": "msg",
                       "to": "$each($flowContext(\"sensors\"), function($v) {$v})",
                       "tot": "jsonata"
                   }
               ],
               "action": "",
               "property": "",
               "from": "",
               "to": "",
               "reg": false,
               "x": 370,
               "y": 1080,
               "wires": [
                   [
                       "6fa31df0682a73eb"
                   ]
               ]
           },
           {
               "id": "6fa31df0682a73eb",
               "type": "ui_table",
               "z": "78ab47508f21e87e",
               "group": "744968de.91c328",
               "name": "table 3",
               "order": 0,
               "width": 0,
               "height": 0,
               "columns": [
                   {
                       "field": "id",
                       "title": "Name",
                       "width": "",
                       "align": "left",
                       "formatter": "plaintext",
                       "formatterParams": {
                           "target": "_blank"
                       }
                   },
                   {
                       "field": "temperature",
                       "title": "Temperatur",
                       "width": "",
                       "align": "left",
                       "formatter": "plaintext",
                       "formatterParams": {
                           "target": "_blank"
                       }
                   },
                   {
                       "field": "humidity",
                       "title": "Luftfeuchtigkeit",
                       "width": "",
                       "align": "left",
                       "formatter": "plaintext",
                       "formatterParams": {
                           "target": "_blank"
                       }
                   }
               ],
               "outputs": 0,
               "cts": false,
               "x": 550,
               "y": 1080,
               "wires": []
           },
           {
               "id": "8575576d459c22cc",
               "type": "ioBroker in",
               "z": "78ab47508f21e87e",
               "name": "",
               "topic": "0_userdata.0.Test.*",
               "payloadType": "value",
               "onlyack": "",
               "func": "all",
               "gap": "",
               "fireOnStart": "false",
               "x": 150,
               "y": 1080,
               "wires": [
                   [
                       "14d18ea35afed3ac"
                   ]
               ]
           },
           {
               "id": "744968de.91c328",
               "type": "ui_group",
               "name": "Tabelle ui_table",
               "tab": "2ce144dc.d7472c",
               "order": 6,
               "disp": true,
               "width": "10",
               "collapse": false,
               "className": ""
           },
           {
               "id": "2ce144dc.d7472c",
               "type": "ui_tab",
               "name": "test",
               "icon": "dashboard",
               "order": 23,
               "disabled": false,
               "hidden": false
           }
        ]
        

        Den Umweg über den Flow-Kontext muss man halt gehen, um bei der gesamten Tabelle nicht immer alles neu zu schicken.

        @rewenode Wie sieht das bei direkter Nutzung tabulator und template Node aus. Kann man da einzelne Werte ändern oder Zeilen hinzufügen und überstehen die einen Browserrefresh? Ich weiss, dass man bei den Template Node generell auch die Daten neu schreiben musste, deswegen hatte ich meist ein ui_control vorne dran und hab dann den Kontext nochmal geschickt:

        fb6921cd-fc31-42aa-97fa-3e8335c788db-image.png

        Das was Du genutzt hast, den letzten Wert nochmals zu verwenden - scheint bei mir auch nicht gegangen zu sein.

        3b409f5f-a168-424a-86c1-61bc7f0273b2-image.png

        R 2 Replies Last reply Reply Quote 1
        • G
          Garf @mickym last edited by

          @mickym sagte in Wert von mehreren empf. Objekten in eine Tabelle darstellen:

          sorry ich wollte Dich gar nicht persönlich als Anfänger bezeichnen,

          Keine Sorge hatte ich so auch nicht aufgefasst. Bei Node Red schwanke ich immer zwischen Anfänger und Mittelmaßwissen. Node Red hat so vielfältige Möglichkeiten die anfallenden Dinge zu lösen, da ist es dann aber auch kein Wunder. Einzig die Möglichkeiten mit dem Dashboard machen mir nicht immer Freude. Deshalb hatte ich mich schon häufiger mit den html-Scrips beschäftigt.

          Ich arbeite mich mal durch deine Beiträge und Flows, Danke dafür. Mit den Tabellebeispielen von rewenode habe ich auf meinem Testsystem schon einmal begonnen.

          Danke euch nochmals für eure Hilfe. Ohne wäre ich wahrscheinlich nicht soweit gekommen. Damit dann wohl doch eher Anfängerstatus. 😁

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

            @mickym sagte in Wert von mehreren empf. Objekten in eine Tabelle darstellen:

            @rewenode Wie sieht das bei direkter Nutzung tabulator und template Node aus. Kann man da einzelne Werte ändern oder Zeilen hinzufügen und überstehen die einen Browserrefresh? Ich weiss, dass man bei den Template Node generell auch die Daten neu schreiben musste, deswegen hatte ich meist ein ui_control vorne dran und hab dann den Kontext nochmal geschickt:

            Ist kein Problem. Hier mal auf die Schnelle mein modifizierter Flow:

            [
               {
                   "id": "3d54326a34d7b285",
                   "type": "comment",
                   "z": "7f6e6cb859163193",
                   "name": "egal in welcher gruppe, wirkt für alle Tabellen dieser Seite",
                   "info": "",
                   "x": 550,
                   "y": 220,
                   "wires": []
               },
               {
                   "id": "cad117ac93c02a8a",
                   "type": "ui_template",
                   "z": "7f6e6cb859163193",
                   "group": "866e364cfd7328d1",
                   "name": "load tsbulstor.js/.css",
                   "order": 1,
                   "width": 0,
                   "height": 0,
                   "format": "<link href=\"https://unpkg.com/tabulator-tables@5.4/dist/css/tabulator.min.css\" rel=\"stylesheet\">\n<script type=\"text/javascript\" src=\"https://unpkg.com/tabulator-tables@5.4/dist/js/tabulator.min.js\"></script>",
                   "storeOutMessages": true,
                   "fwdInMessages": true,
                   "resendOnRefresh": true,
                   "templateScope": "global",
                   "className": "",
                   "x": 440,
                   "y": 300,
                   "wires": [
                       []
                   ]
               },
               {
                   "id": "357fbc37c1b58e1a",
                   "type": "comment",
                   "z": "7f6e6cb859163193",
                   "name": "nur einmal für die komplette site nötig",
                   "info": "",
                   "x": 490,
                   "y": 260,
                   "wires": []
               },
               {
                   "id": "365d1147f14c9f81",
                   "type": "comment",
                   "z": "7f6e6cb859163193",
                   "name": "externe libs/css",
                   "info": "",
                   "x": 660,
                   "y": 300,
                   "wires": []
               },
               {
                   "id": "8d802595263190fa",
                   "type": "inject",
                   "z": "7f6e6cb859163193",
                   "name": "sample data in payload",
                   "props": [
                       {
                           "p": "payload"
                       },
                       {
                           "p": "topic",
                           "vt": "str"
                       }
                   ],
                   "repeat": "",
                   "crontab": "",
                   "once": true,
                   "onceDelay": 0.1,
                   "topic": "",
                   "payload": "[{\"id\":1,\"Name\":\"na sowas\",\"Age\":\"30\",\"Color\":\"lime\",\"Prog\":70,\"Star\":\"3\"},{\"id\":2,\"Name\":\"<i>DCJ</i>\",\"Age\":\"50\",\"Color\":\"dodgerblue\",\"Prog\":\"45\",\"Star\":2,\"Pass\":false,\"web\":\"\"},{\"id\":3,\"Name\":\"Nick\",\"Age\":\"40\",\"Color\":\"darkred\",\"Prog\":95,\"Star\":\"5\",\"Pass\":true,\"web\":\"http://nodered.org\"},{\"id\":4,\"Name\":\"Oli\"}]",
                   "payloadType": "json",
                   "x": 170,
                   "y": 440,
                   "wires": [
                       [
                           "d22d110ea73b8fa6"
                       ]
                   ]
               },
               {
                   "id": "d22d110ea73b8fa6",
                   "type": "ui_template",
                   "z": "7f6e6cb859163193",
                   "group": "d38200b70febfed9",
                   "name": "tabulator html/script",
                   "order": 1,
                   "width": "0",
                   "height": "0",
                   "format": "<!-- \n    Tabulator js/css is only needes if this the only table on this site \n    <script type=\"text/javascript\" src=https://unpkg.com/tabulator-tables@5.4/dist/js/tabulator.min.js></script>\n    <link rel=\"stylesheet\" href=https://unpkg.com/tabulator-tables@5.4/dist/css/tabulator.min.css />\n//-->\n\n<!-- \n    for syntax see https://tabulator.info\n\n//-->\n\n<div id=\"example-table\"></div>\n<script>\n    var table = new Tabulator(\"#example-table\", {\n        height:\"500px\",\n        placeholder:\"Keine Daten verfügbar!\",\n        layout:\"fitColumns\",\n        columns:[\n            {title:\"id\", field:\"id\", width:20},\n            {title:\"Name\", field:\"Name\", width:200},\n            {title:\"Age\", field:\"Age\" },\n            {title:\"web\", field:\"web\", formatter: \"link\"},    \n        ],\n    });\n\n    (function(scope) {\n        scope.$watch('msg', function(msg) {\n            if(msg) {\n                setTimeout(function() {\n                    if ('update' in msg) {\n                        var tabledata = msg.update;\n                        table.updateData(msg.update);\n                        //console.log(msg.update);\n                    } else {\n                        var tabledata = msg.payload;\n                        table.replaceData(tabledata);\n                        //console.log('replace');\n                    }\n                }, 200);\n            }\n        });\n    })(scope);\n\n</script>",
                   "storeOutMessages": true,
                   "fwdInMessages": true,
                   "resendOnRefresh": true,
                   "templateScope": "local",
                   "className": "",
                   "x": 440,
                   "y": 440,
                   "wires": [
                       []
                   ]
               },
               {
                   "id": "c0c06c204207e4be",
                   "type": "comment",
                   "z": "7f6e6cb859163193",
                   "name": "simple table without ui-table node",
                   "info": "",
                   "x": 480,
                   "y": 400,
                   "wires": []
               },
               {
                   "id": "f0b213e9e4ddcd73",
                   "type": "inject",
                   "z": "7f6e6cb859163193",
                   "name": "updateData",
                   "props": [
                       {
                           "p": "payload"
                       },
                       {
                           "p": "topic",
                           "vt": "str"
                       }
                   ],
                   "repeat": "",
                   "crontab": "",
                   "once": true,
                   "onceDelay": 0.1,
                   "topic": "",
                   "payload": "[{\"id\":2,\"Name\":\"das is der neue Name\"}]",
                   "payloadType": "json",
                   "x": 130,
                   "y": 540,
                   "wires": [
                       [
                           "f1a152b35f503d8d"
                       ]
                   ]
               },
               {
                   "id": "f1a152b35f503d8d",
                   "type": "change",
                   "z": "7f6e6cb859163193",
                   "name": "",
                   "rules": [
                       {
                           "t": "set",
                           "p": "update",
                           "pt": "msg",
                           "to": "payload",
                           "tot": "msg"
                       }
                   ],
                   "action": "",
                   "property": "",
                   "from": "",
                   "to": "",
                   "reg": false,
                   "x": 450,
                   "y": 540,
                   "wires": [
                       [
                           "d22d110ea73b8fa6"
                       ]
                   ]
               },
               {
                   "id": "9e6ff78efa829e02",
                   "type": "comment",
                   "z": "7f6e6cb859163193",
                   "name": "initialtable in msg.payload",
                   "info": "",
                   "x": 150,
                   "y": 400,
                   "wires": []
               },
               {
                   "id": "c8dd0376be227fc4",
                   "type": "comment",
                   "z": "7f6e6cb859163193",
                   "name": "rows to update in msg.update",
                   "info": "",
                   "x": 160,
                   "y": 500,
                   "wires": []
               },
               {
                   "id": "866e364cfd7328d1",
                   "type": "ui_group",
                   "name": "helpers",
                   "tab": "464d85dfac9971a2",
                   "order": 4,
                   "disp": false,
                   "width": "1",
                   "collapse": false,
                   "className": "helperGroup"
               },
               {
                   "id": "d38200b70febfed9",
                   "type": "ui_group",
                   "name": "simple table",
                   "tab": "702f174cb9f60360",
                   "order": 1,
                   "disp": true,
                   "width": "10",
                   "collapse": false,
                   "className": ""
               },
               {
                   "id": "464d85dfac9971a2",
                   "type": "ui_tab",
                   "d": true,
                   "name": "Listen",
                   "icon": "dashboard",
                   "order": 1,
                   "disabled": false,
                   "hidden": false
               },
               {
                   "id": "702f174cb9f60360",
                   "type": "ui_tab",
                   "name": "simpleTable",
                   "icon": "fa-thin fa-table",
                   "order": 3,
                   "disabled": false,
                   "hidden": false
               }
            ]
            

            ce17c7e4-7920-47a7-8815-83097534b9b4-image.png
            Allerdings musst du dann die Funktion updateData() verwenden.
            Im Beispiel stelle ich die initial-daten in msg.payload zur Verfügung.
            Zeilen, die upgedatet werden sollen in msg.update.
            Allerdings müssen die Datensätze der Tabelle id's haben. Findest du alles in (https://tabulator.info/docs/5.4/update#alter-update)

            Achtung
            Der Einfachheit halber teste ich bei der Datenübernahme, ob es ein Property msg.update gibt. Falls ja mach ich updateData() sonst replaceData().
            Bei der initialen Datenbefüllung darf es alse msg.update nicht geben.
            Die setTimeout Funktion ist nötig um sicherzustellen, dass die Tabelle intern aufgebaut ist, bevor die Daten aktualisiert werden.
            Das geht sicher auch besser zu implementieren, ist nur so auf die Schnelle gemacht.

            Gruß
            Reiner

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

              @mickym sagte in Wert von mehreren empf. Objekten in eine Tabelle darstellen:

              überstehen die einen Browserrefresh?

              Beim Browser-reload hast du wieder die Originaldaten. Die werden ja nicht zurückgeschrieben. Allerdings könnte man das durchaus machen. updatdeData() gibt ein promise zurück wo man sowas machen könnte. Aber das ist wohl nur sinnvoll, wenn innerhalb des Browsers die daten geändert werden.
              Werden nur ioB Daten angezeigt, abboniere ich die States, erstelle daraus immer eine aktuelle Tabelle als Datenpunkt. Mit JSONata aktualisiere ich dort die entsprechende Zeile und gebe sie dann immer per replaceData() aus.

              Das geht jedenfalls bei mir ohne sichtbare Verzögerung, wobei meine größte Tabelle derzeit nur etwa 100 Zeilen umfaßt.

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

                @rewenode OK - das ist wahrscheinlich auch das "returnPromise:true", dass man wohl dem Kommando mitgeben muss und dann irgendwie darauf reagieren sollte.

                Ok ich hab gerade gesehen - in dem Beispiel Flow, der mit der Node mitgeliefert wird, wird auch im Kontext gespeichert und über function Node reagiert.

                1 Reply Last reply Reply Quote 0
                • G
                  Garf @rewenode last edited by Garf

                  Ich habe durch Zufall eine html Tabellen Erstellungshilfe gefunden. Praktisch fand ich die Möglichkeit die Gestaltung von Textgröße Schriftfarbe usw. festlegen zu können. Dann noch die dynamischen Werte einfügen und fertig war die Tabelle. Am Ende schon ein wenig mehr Arbeit wie gedacht. Meine beiden Wunschziele sind auch nur zur Hälfte erfüllt worden. Die Tabellenansicht sollte Platz sparen und übersichtlicher sein. Letzteres hat funktioniert. Der Platzbedarf pro Zeile ist jedoch gleich geblieben. Hier mal das Ergebnis. Die farblichen Werte variieren je nach Zustand oder Wert in rot, gelb oder grün.

                  4e2b9a12-0593-4d97-ac3c-7eac63758417-grafik.png

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

                    @rewenode Lieber Reiner,

                    ich wollte hier mal mit Deiner Lösung direkt den Tabulator nutzen - allerdings habe ich bei einem Browser Refresh immer das Problem, dass die Tabellen nicht angezeigt werden - auch mit neuem Inject der payload.

                    Manchmal gehts:

                    2ea77f46-8982-4954-b2ba-9fcb3cb714a2-image.png

                    und dann bekomme ich nach einem Refresh die Tabelle nicht mehr.

                    Ich muss dann auf eine andere Dashboard Seite wechseln und manchmal bekomme ich die Tabelle wieder - so ist das mit der template Node nicht brauchbar. Hast Du eine Lösung?

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

                      @mickym Grad nochmal mit Safari und Chrome getestet. Bei mir geht es.
                      Hier nochmal der Flow:

                      65bc0aba-14ab-4fe5-886d-19eb225c926d-image.png

                      [{"id":"aafca175.713c8","type":"tab","label":"tabulatorListen","disabled":false,"info":""},{"id":"d60fe817296f815e","type":"group","z":"aafca175.713c8","name":"Offene Fenster Liste","style":{"stroke":"#ff0000","fill":"#ffbfbf","label":true,"label-position":"ne","color":"#ff0000"},"nodes":["e8d529b3.f22c2","3fe0826048ba89f9"],"x":8,"y":93,"w":1184,"h":942},{"id":"3ad46637969fb5a2","type":"group","z":"aafca175.713c8","name":"Zigbee Status Liste","style":{"stroke":"#ff0000","fill":"#ffbfbf","label":true,"label-position":"ne","color":"#ff0000"},"nodes":["4d2bb33c.ceede4","fe0a9da8604d3da9"],"x":8,"y":1053,"w":1184,"h":1002},{"id":"e8d529b3.f22c2","type":"group","z":"aafca175.713c8","g":"d60fe817296f815e","name":"dashboard atus aller Fenster/Türen","style":{"stroke":"#7fb7df","fill":"#bfdbef","label":true,"label-position":"se","color":"#0070c0"},"nodes":["f2ddf748.82e668","5ea641e4.0d8778","9c9ffcde.eb843","8b6d1b45.86532","3ecadb89.9009e4","78ed36ed.fbf648","cfd1382e.7bb07","84de031a.a11c48","3d01a357.45b1dc","1c82ffd0.645fd8","b819e5c9.0049d8","90d54a6d.2fe6f8","93e967d8.c676e","b327bff3.e99e68","5b6644f.289713c","16c79608255f20d4","90a4533a8d678b84","0290c407d514dec4","cf00f4f88b2deda8","e873af39181c1488","a581db2f51797939","43cc8f4a073a0b74","d402a4e01eeb1a18","51acb0c41a5a3c8b","37d480be75e1b730","a361f3170fba9d32","b4a8be01fbfd149c"],"x":34,"y":119,"w":1132,"h":550},{"id":"3fe0826048ba89f9","type":"group","z":"aafca175.713c8","g":"d60fe817296f815e","name":"Alexa Ausgabe","style":{"stroke":"#0070c0","fill":"#bfdbef","label":true,"label-position":"se","color":"#0070c0"},"nodes":["81e30c3affba3357","741e9952a4580fcb","fd00a38cb4325da6","fbb64bb4f72b1303","092de80e71cf8b77","46e2d522abf039d3","b098d543ec4cdd48","14158bc52538a7af","caa3dc4abf8c7933","81a025e604c7b237"],"x":34,"y":719,"w":1132,"h":290},{"id":"4d2bb33c.ceede4","type":"group","z":"aafca175.713c8","g":"3ad46637969fb5a2","name":"read and prepare status list","style":{"stroke":"#ffC000","label":true,"fill":"#ffefbf","label-position":"se","color":"#ffC000"},"nodes":["6201855d.6560dc","c6a820cd.cf90c","5af872ee.29181c","67a56ace.f3ed74","9071405a.26389","35550dc7.d0e5ca","240db1de.c36ab6","64a53f55.740f68","50a1b532.b416e4","b0f14ab73055aaf3","0a26114d17f264f1","9aadcfc7d24edcaa","597bb03a35a2ec6f","70840258b6eaad30","197dcd3f06c47e58","efd6cca4e206cfac","d29bf45e7a5b7f58"],"x":34,"y":1079,"w":1132,"h":450},{"id":"fe0a9da8604d3da9","type":"group","z":"aafca175.713c8","g":"3ad46637969fb5a2","name":"dashboard","style":{"stroke":"#ffC000","fill":"#ffefbf","label":true,"label-position":"se","color":"#ffC000"},"nodes":["7881cef3788f9d70","5784a7a9.3216f8","bfe60d8f4830d372","8234fae3e5bab215","d3f2a42.3a07158","8fb4b730a1ce650f","2034383eebef2368","624b81db.a1888","fca53d88.24ff98","7809a6eff59ce2e5","ee336567898a1b41","eb5998891bcbaa5d","5bdfd3a9.16f09c","c26eb18d.2e1bc8","a546d666c3208d76","1a6ee6a9fd605642","06c3cbf0fc7c0a7d"],"x":34,"y":1559,"w":1132,"h":470},{"id":"f2ddf748.82e668","type":"ioBroker in","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"","topic":"alias.0.Verschluss.*","payloadType":"object","onlyack":"","func":"rbe","gap":"","fireOnStart":"false","x":490,"y":160,"wires":[["90d54a6d.2fe6f8"]]},{"id":"5ea641e4.0d8778","type":"comment","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"1. abboniere alias.0.Verschluss.*","info":"","x":190,"y":160,"wires":[]},{"id":"9c9ffcde.eb843","type":"change","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"prepare windowsStatusList","rules":[{"t":"set","p":"payload","pt":"msg","to":"(\t   /* old Statuslist if not exist, -> []*/ \t   $windowsStatusList := $.windowsStatusList ? $.windowsStatusList :[];\t   \t   /* local Time */\t   $local := function($uxTs) {$fromMillis($uxTs, '[D01].[M01].[Y01] [h01]:[m01]:[s01]','+0200')};\t\t   /* window from input */\t   $window := $.windowsTopic.$split('/')[3];\t   \t   /* only for regular windows */\t   ($boolean($window) \t         ?   /* topic => use input */\t            (\t                $newObjectStatus := \t                {\t                    /* new object status */\t                    \"window\": $window,\t                    \"status\": $.payload.val = true ? 'open' : 'closed',\t                    \"ts\": $.payload.ts ~> $local(),\t                    \"ort\": $.ort\t                };\t                \t                $windowsStatusList[window = $window] /* windows in old list ? */ \t                    ? /* replace */\t                       $windowsStatusList ~> $map(function($v) {\t                                                $v.window = $window ? $newObjectStatus: $v \t                                                }) \t                    : /* append */ \t                       $windowsStatusList ~> $append($newObjectStatus);\t            )\t         : $windowsStatusList)^(ort, >status, >ts);   /* no topic => only read from $flowContext */ \t)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":380,"wires":[["93e967d8.c676e","90a4533a8d678b84","b4a8be01fbfd149c"]]},{"id":"8b6d1b45.86532","type":"comment","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"4. Fensterstatusliste aktualisieren","info":"","x":190,"y":380,"wires":[]},{"id":"3ecadb89.9009e4","type":"comment","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"5. Tabelle in ui-template definieren und ausgeben","info":"","x":240,"y":480,"wires":[]},{"id":"78ed36ed.fbf648","type":"comment","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"helper read list on page reload","info":"","x":190,"y":620,"wires":[]},{"id":"cfd1382e.7bb07","type":"inject","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"read list manuell","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":440,"y":620,"wires":[["84de031a.a11c48"]]},{"id":"84de031a.a11c48","type":"link out","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"","links":["3d01a357.45b1dc"],"x":575,"y":620,"wires":[]},{"id":"3d01a357.45b1dc","type":"link in","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"","links":["b5d57b3b.eb665","84de031a.a11c48","37d480be75e1b730"],"x":345,"y":320,"wires":[["1c82ffd0.645fd8"]]},{"id":"1c82ffd0.645fd8","type":"ioBroker get","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"","topic":"0_userdata.0.windowsStatusList","attrname":"windowsStatusList","payloadType":"value","errOnInvalidState":"false","x":540,"y":320,"wires":[["16c79608255f20d4","9c9ffcde.eb843"]]},{"id":"b819e5c9.0049d8","type":"comment","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"3. lese Fensterstatusliste","info":"","x":170,"y":320,"wires":[]},{"id":"90d54a6d.2fe6f8","type":"change","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"topic -> windowsTopic","rules":[{"t":"set","p":"windowsTopic","pt":"msg","to":"topic","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":730,"y":160,"wires":[["5b6644f.289713c","cf00f4f88b2deda8"]]},{"id":"93e967d8.c676e","type":"link out","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"","links":["43cc8f4a073a0b74","11c8419344560a93"],"x":715,"y":400,"wires":[]},{"id":"b327bff3.e99e68","type":"comment","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"6. Fensterstatusliste sichern","info":"","x":180,"y":540,"wires":[]},{"id":"5b6644f.289713c","type":"debug","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1070,"y":160,"wires":[]},{"id":"81e30c3affba3357","type":"change","z":"aafca175.713c8","g":"3fe0826048ba89f9","name":"prepare Alexa String for open windows","rules":[{"t":"set","p":"payload","pt":"msg","to":"(\t    $speakVolume := '50';\t        \t    /* get array of names and eliminate special characters*/\t    $openWindows := $.windowsStatusList[status = 'open'].window ~> $map(function($v){$replace($v, /:|,|#|;|-|_|[ ]/, ' ')});\t    \t    /* define function for build complete Alexastring */\t    $make_string := function($arr, $x,  $st){  /* $x = abort condition, $arr = array of strings */\t        (         \t            $x < 1 ? ( /* return string */\t                $substring($st, 1); /* without first ';' */\t            ) :\t            (  /* recursion*/  \t                $st  :=  $st & \t                        (  \t                            $n := ($length($st) + $length( $arr[$count($arr) - $x])) % 100; /* new length % 100*/\t                            $a := $length($st) % 100;                                       /* old length % 100*/\t                            $n > $a ?  ',' : ';' ;      /* if segment length < 100 , otherwise ;*/\t                        ) & \t                        $arr[$count($arr) - $x]; \t                $make_string($arr, $x-1, $st);\t            )\t        ) \t    };\t    $speakText := $make_string($openWindows, $count($openWindows)); /* recursiv */\t    $speakText := $speakVolume & ';offene Fenster oder Türen,' & ($exists($speakText) ? $speakText : 'keine')\t)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":500,"y":900,"wires":[["741e9952a4580fcb","b098d543ec4cdd48"]]},{"id":"741e9952a4580fcb","type":"debug","z":"aafca175.713c8","g":"3fe0826048ba89f9","name":"Alexa speak string","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1030,"y":900,"wires":[]},{"id":"fd00a38cb4325da6","type":"inject","z":"aafca175.713c8","g":"3fe0826048ba89f9","name":"manuell for test","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":440,"y":820,"wires":[["fbb64bb4f72b1303"]]},{"id":"fbb64bb4f72b1303","type":"ioBroker get","z":"aafca175.713c8","g":"3fe0826048ba89f9","name":"","topic":"0_userdata.0.windowsStatusList","attrname":"windowsStatusList","payloadType":"value","errOnInvalidState":"nothing","x":720,"y":820,"wires":[["81e30c3affba3357"]]},{"id":"092de80e71cf8b77","type":"comment","z":"aafca175.713c8","g":"3fe0826048ba89f9","name":"2. Fenster Statusliste holen","info":"","x":180,"y":820,"wires":[]},{"id":"46e2d522abf039d3","type":"comment","z":"aafca175.713c8","g":"3fe0826048ba89f9","name":"3. Alexa String erstellen","info":"### Format des Ausgabe strings\n\nvolume;Text\n\nIst der Text > 100 Zeichen, muss er in Blöcke\ngeteilt werden, die jeweils mit einem ; getrennt sein müssen","x":160,"y":900,"wires":[]},{"id":"b098d543ec4cdd48","type":"ioBroker out","z":"aafca175.713c8","g":"3fe0826048ba89f9","name":"speak","topic":"alexa2.0.Echo-Devices.G2A1EF0311820049.Commands.speak","ack":"false","autoCreate":"false","stateName":"","role":"","payloadType":"","readonly":"","stateUnit":"","stateMin":"","stateMax":"","x":390,"y":960,"wires":[]},{"id":"14158bc52538a7af","type":"comment","z":"aafca175.713c8","g":"3fe0826048ba89f9","name":"4. Alexa Ausgabe","info":"","x":150,"y":960,"wires":[]},{"id":"caa3dc4abf8c7933","type":"ioBroker in","z":"aafca175.713c8","g":"3fe0826048ba89f9","name":"vOpenWindows","topic":"javascript.0.Alexa-trigger.vOpenWindows","payloadType":"value","onlyack":"","func":"all","gap":"","fireOnStart":"false","x":420,"y":760,"wires":[["fbb64bb4f72b1303"]]},{"id":"81a025e604c7b237","type":"comment","z":"aafca175.713c8","g":"3fe0826048ba89f9","name":"1. abboniere Alexa Trigger   ","info":"vOpenWindows ist ein state (javascript.0.Alexa-trigger.vOpenWindows).\nDieser ist im ioT Adapter als smartHome Schalter freigegeben.\n\nEine Alexa-Routine (kann nur in der Alexa-Handy-App administriert werden)\nSchaltet den dann bei:\n\n\"Alexa welche Fenster sind offen?\"","x":170,"y":760,"wires":[]},{"id":"16c79608255f20d4","type":"debug","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1070,"y":320,"wires":[]},{"id":"90a4533a8d678b84","type":"debug","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1070,"y":380,"wires":[]},{"id":"43cc8f4a073a0b74","type":"link in","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"","links":["93e967d8.c676e"],"x":355,"y":540,"wires":[["0290c407d514dec4"]]},{"id":"0290c407d514dec4","type":"ioBroker out","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"0_userdata.0.windowsStatusList","topic":"0_userdata.0.windowsStatusList","ack":"true","autoCreate":"true","stateName":"windows list","role":"list","payloadType":"object","readonly":"false","stateUnit":"","stateMin":"","stateMax":"","x":540,"y":540,"wires":[]},{"id":"cf00f4f88b2deda8","type":"ioBroker list","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"","topic":"","objType":"state","regex":"","asArray":"true","onlyIDs":"false","withValues":"true","x":460,"y":240,"wires":[["a581db2f51797939"]]},{"id":"e873af39181c1488","type":"comment","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"2. lese enum.ort","info":"","x":140,"y":240,"wires":[]},{"id":"a581db2f51797939","type":"change","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"","rules":[{"t":"set","p":"ort","pt":"msg","to":"$lookup(payload.enums, payload.enums.$sift(function($v, $k) {$k ~> /^enum.ort./}).$keys()[0])\t\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":240,"wires":[["1c82ffd0.645fd8","d402a4e01eeb1a18"]]},{"id":"d402a4e01eeb1a18","type":"debug","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"debug 12","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1060,"y":240,"wires":[]},{"id":"51acb0c41a5a3c8b","type":"ui_template","z":"aafca175.713c8","g":"e8d529b3.f22c2","group":"87e32ce83242e0f3","name":"event onLoad/Reload","order":2,"width":0,"height":0,"format":"<script>\n(function() {\n    (function(scope) {\n        scope.send({payload: Date.now()}); // this gets sent when the view is opened in the browser\n    })(scope);\n})();\n</script>\n","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"local","className":"","x":720,"y":620,"wires":[["37d480be75e1b730"]]},{"id":"37d480be75e1b730","type":"link out","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"","links":["3d01a357.45b1dc"],"x":865,"y":620,"wires":[]},{"id":"a361f3170fba9d32","type":"ui_template","z":"aafca175.713c8","g":"e8d529b3.f22c2","group":"87e32ce83242e0f3","name":"tabulator html/scr/css ","order":1,"width":0,"height":0,"format":"<!-- not needed if ui-table installed\n<script type=\"text/javascript\" src=\"/tabulator-tables/dist/js/tabulator.min.js\"></script>\n<link rel=\"stylesheet\" href=\"/tabulator-tables/dist/css/tabulator_semanticui.min.css\" />\n\n<link href=\"https://unpkg.com/tabulator-tables@5.4/dist/css/tabulator.min.css\" rel=\"stylesheet\">\n<script type=\"text/javascript\" src=\"https://unpkg.com/tabulator-tables@5.4/dist/js/tabulator.min.js\"></script>\n//-->\n\n<!-- see http://tabulator.info/examples/5.4#theming \ndark: /dist/css/tabulator_midnight.min.css\nadjustable: /dist/css/tabulator.min.css\n\n//-->\n\n\n<div id=\"openWindowsTable\"></div>\n<script>\n    var openWindowsTable = new Tabulator(\"#openWindowsTable\", {\n        height:\"700px\" ,\n        placeholder:\"Keine Daten verfügbar!\",\n        layout: \"fitDataStretch\",\n        /*fit columns to width of table*/\n        \n        //pagination: \"local\",\n        /*paginate the data*/\n        \n        //paginationSize: 40,\n        /*allow 40 rows per page of data*/\n        \n        movableColumns: true,\n        /*allow column order to be changed*/\n        \n        /*colums format definitions*/\n        columns: [{\n                title: \"Fenster\",\n                field: \"window\",\n                width: 250\n            },\n            {\n                title: \"Status\",\n                field: \"status\",\n                formatter: function(cell, formatterParams, onRendered){\n                        //cell - the cell component\n                        //formatterParams - parameters set for the column\n                        //onRendered - function to call when the formatter has been rendered\n                        return \"<span style='color:Black; font-weight:bold;'>\" + cell.getValue() + \"</span>\"\n                    },\n            },\n            {\n                title: \"Zeit\",\n                field: \"ts\",\n                //sorter: \"date\"\n                /* need moment.js\n                see https://github.com/olifolkerd/tabulator/issues/1631#issuecomment-716460821\n                */\n            },\n        ],\n         \n        columnDefaults:{ \n            tooltip:true,\n        },\n        \n        /*initial sorting */\n        initialSort:[\n            {column:\"status\", dir:\"desc\"}, //sort by this first\n            {column:\"ts\", dir:\"desc\"}, //then sort by this second\n        ],\n        \n        /* group by ort*/\n        groupBy: \"ort\",\n        groupStartOpen: true,\n\n        /* format groupHeader */\n        groupHeader: function(value, count, data, group) {\n            var r = \"<span style='color:Black; margin-left:10px;'>(\" + count + \" Fenster)</span>\";\n            return value + r;\n        },\n        \n        /*format individal cell*/\n        rowFormatter: function(row) {\n            const cl = row.getCells();\n            cl[1].getElement().style.backgroundColor = (cl[1]._cell.value === 'open' ? '#F1948A' : '#82E0AA');\n        },\n\n    });\n\n    /* events */\n    \n    openWindowsTable.on(\"renderComplete\",function() {\n        let data = openWindowsTable.getData();\n        let groupHeaderList = document.querySelectorAll(\".tabulator-row.tabulator-group\");\n        let groups = Array.from(groupHeaderList, (group) => group.outerText.split('(')[0]);\n        \n        for (let i = 0; i < groups.length; i++) { const group=groups[i]; const statusOpen=data.some(g=> g.ort === group &&\n            g.status === 'open');\n            groupHeaderList[i].style.backgroundColor = (statusOpen) ? '#E74C3C' : '#2ECC71';\n        }\n    });\n\n    (function(scope) { \n        scope.$watch('msg', function(msg) {\n            if(msg && \"openWindows\" in msg) {\n                setTimeout(function() {\n                    var tabledata = msg.openWindows;\n                    openWindowsTable.replaceData(tabledata);\n                }, 200);\n            }\n        });\n    })(scope);\n\n</script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":560,"y":480,"wires":[[]]},{"id":"c26eb18d.2e1bc8","type":"ui_template","z":"aafca175.713c8","g":"fe0a9da8604d3da9","group":"3bde884a8ebcdf18","name":"event onLoad/Reload","order":5,"width":2,"height":1,"format":"<script>\n(function() {\n    (function(scope) {\n        scope.send({payload: Date.now()}); // this gets sent when the view is opened in the browser\n    })(scope);\n})();\n</script>\n","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"local","className":"","x":180,"y":1920,"wires":[["a546d666c3208d76","1a6ee6a9fd605642"]]},{"id":"5bdfd3a9.16f09c","type":"comment","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"getState if dashboard load/reload","info":"https://groups.google.com/forum/#!topic/node-red/WUp__e4rmBQ","x":200,"y":1880,"wires":[]},{"id":"624b81db.a1888","type":"ioBroker get","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"","topic":"0_userdata.0.deviceList.zigbeeListNew","attrname":"payload","payloadType":"value","x":580,"y":1720,"wires":[["fca53d88.24ff98","06c3cbf0fc7c0a7d"]]},{"id":"fca53d88.24ff98","type":"debug","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1070,"y":1720,"wires":[]},{"id":"5784a7a9.3216f8","type":"ui_button","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"new read","group":"3bde884a8ebcdf18","order":3,"width":3,"height":1,"passthru":false,"label":"Aktualisieren","tooltip":"Aktualisieren","color":"","bgcolor":"","className":"","icon":"sync","payload":"","payloadType":"date","topic":"topic","topicType":"msg","x":480,"y":1600,"wires":[["d3f2a42.3a07158","bfe60d8f4830d372"]]},{"id":"d3f2a42.3a07158","type":"delay","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"outputs":1,"x":500,"y":1660,"wires":[["624b81db.a1888"]]},{"id":"bfe60d8f4830d372","type":"link out","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"","mode":"link","links":["9aadcfc7d24edcaa"],"x":595,"y":1600,"wires":[]},{"id":"7881cef3788f9d70","type":"comment","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"1. manuel new read from dashboard","info":"","x":200,"y":1600,"wires":[]},{"id":"8234fae3e5bab215","type":"comment","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"2. enough time for read and prepare data","info":"","x":220,"y":1660,"wires":[]},{"id":"8fb4b730a1ce650f","type":"comment","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"3. get status list from dp","info":"","x":170,"y":1720,"wires":[]},{"id":"7809a6eff59ce2e5","type":"comment","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"4. show list on dashboard","info":"","x":170,"y":1780,"wires":[]},{"id":"2034383eebef2368","type":"link in","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"","links":["5889a2db71617308","a546d666c3208d76"],"x":355,"y":1720,"wires":[["624b81db.a1888"]]},{"id":"eb5998891bcbaa5d","type":"comment","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"things for dashboard","info":"","x":160,"y":1840,"wires":[]},{"id":"ee336567898a1b41","type":"ui_template","z":"aafca175.713c8","g":"fe0a9da8604d3da9","group":"3bde884a8ebcdf18","name":"Tabulator html/scr/css ","order":1,"width":18,"height":11,"format":"<!-- \n    Tabulator js/css is only needes if this the only table on this site \n//-->\n\n<!-- not needed if ui-table installed\n<script type=\"text/javascript\" src=\"/tabulator-tables/dist/js/tabulator.min.js\"></script>\n<link rel=\"stylesheet\" href=\"/tabulator-tables/dist/css/tabulator_semanticui.min.css\" />\n\n<script type=\"text/javascript\" src=\"/node_modules/tabulator-tables/dist/js/tabulator.min.js\"></script>\n<link rel=\"stylesheet\" href=\"/node_modules/tabulator-tables/dist/css/tabulator_semanticui.min.css\" />\n\n<link href=\"https://unpkg.com/tabulator-tables@5.4/dist/css/tabulator.min.css\" rel=\"stylesheet\">\n<script type=\"text/javascript\" src=\"https://unpkg.com/tabulator-tables@5.4/dist/js/tabulator.min.js\"></script>\n//-->\n\n<div id=\"zigbeeTable\"></div>\n\n<script>\n\n    var zigbeeTable = new Tabulator(\"#zigbeeTable\", {\n        height:\"700px\" ,\n        placeholder:\"Keine Daten verfügbar!\",\n        layout: \"fitDataStretch\",\n        /*fit columns to width of table*/\n\n        movableColumns: true,\n        /*allow column order to be changed*/\n\n        /*set rows to 40px height*/\n        rowHeight: 25,\n        \n        /*colums format definitions*/\n        columns: [\n            {title: \"id\", field: \"id\", width: 150, hozAlign: \"left\", vertAlign: \"middle\",},\n            {title: \"\", field: \"icon\", width: 50, formatter:\"image\", formatterParams:{width:\"20px\",},},\n            {title: \"Gerät\", field: \"device\", width: 230, hozAlign: \"left\", vertAlign: \"middle\",headerFilter: true,},\n            {title: \"ok\", field: \"available_val\", width: 65, formatter:\"tickCross\",},\n            {title: \"Batterie\", field: \"battery_val\", width: 100, hozAlign: \"left\", vertAlign: \"middle\",formatter:\"progress\", formatterParams:{\n                    min:0,\n                    max:100,\n                    color:[\"#F1948A\", \"orange\", \"#82E0AA\"],\n                    legend: value => value ? \"<span style='color:Black; font-weight:bold;'>\" + value + \"%\" +  \"</span>\" : \"\",\n                    legendAlign:\"left\",\n                }},\n            {title: \"Funk\", field: \"link_quality_val\", width: 100, hozAlign: \"left\", vertAlign: \"middle\",formatter:\"progress\", formatterParams:{\n                    min:0,\n                    max:150,\n                    color:[\"#F1948A\", \"orange\", \"#82E0AA\"],\n                    legend: value => value ? \"<span style='color:Black; font-weight:bold;'>\" + value +  \"</span>\" : \"\",\n                    legendAlign:\"left\",\n                }},\n            {title: \"Batt.\", field: \"batt\", width: 90, hozAlign: \"right\", vertAlign: \"middle\",},\n            {title: \"Zeit\", field: \"available_ts\", width: 90, hozAlign: \"right\", vertAlign: \"middle\",},\n        ],\n         \n        columnDefaults:{ \n            tooltip:true,\n        },\n        \n        /*initial sorting */\n        /*\n        initialSort:[\n            {column:\"status\", dir:\"desc\"}, //sort by this first\n            {column:\"ts\", dir:\"desc\"}, //then sort by this second\n        ],\n        */\n        \n    });\n\n    /* events */\n\n    /* fill/replace data */\n    (function(scope) {\n        scope.$watch('msg', function(msg) {\n            if(msg && \"zigbeeTable\" in msg) {\n                setTimeout(function() {\n                    var tabledata = msg.zigbeeTable;\n                    zigbeeTable.replaceData(tabledata);\n                }, 300);\n            }\n        });\n    })(scope);\n</script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":720,"y":1780,"wires":[[]]},{"id":"a546d666c3208d76","type":"link out","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"","mode":"link","links":["2034383eebef2368"],"x":375,"y":1920,"wires":[]},{"id":"6201855d.6560dc","type":"inject","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"every hour","props":[{"p":"timestamp","v":"","vt":"date"},{"p":"topic","vt":"str"}],"repeat":"3600","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":430,"y":1120,"wires":[["5af872ee.29181c"]]},{"id":"c6a820cd.cf90c","type":"ioBroker list","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"State from topic (states in reqex))","topic":"","objType":"state","regex":"battery|available|link_quality","asArray":"true","onlyIDs":"false","withValues":"true","x":500,"y":1360,"wires":[["240db1de.c36ab6","d29bf45e7a5b7f58"]]},{"id":"5af872ee.29181c","type":"change","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"device topic to read","rules":[{"t":"set","p":"topic","pt":"msg","to":"zigbee.0.*","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":1180,"wires":[["67a56ace.f3ed74"]]},{"id":"67a56ace.f3ed74","type":"ioBroker list","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"devices from Object DB","topic":"","objType":"","regex":"","asArray":"true","onlyIDs":"false","withValues":"true","x":470,"y":1240,"wires":[["9071405a.26389"]]},{"id":"9071405a.26389","type":"change","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"devices to msg.devices","rules":[{"t":"set","p":"devices","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":1300,"wires":[["c6a820cd.cf90c"]]},{"id":"35550dc7.d0e5ca","type":"comment","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"1. cycle for read devices ","info":"","x":170,"y":1120,"wires":[]},{"id":"240db1de.c36ab6","type":"change","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"prepare states and combine with devices","rules":[{"t":"set","p":"payload","pt":"msg","to":"(\t    /* array of state-objects to object with id as key and states as key/values pairs */\t    $st := $map($.payload, function($s) {\t            (\t            $n :=  $s._id.$split('.')[3]; /* state_name */\t            $i :=  $s._id.$split('.')[2]; /* id */\t                {\t                    \"id\": $i,\t                    $n & \"_ts\": $fromMillis($s.ts, '[D01].[M01].[Y01] [h01]:[m01]:[s01]','+0200'),\t                    $n & \"_val\": $s.val    \t                } \t            )\t        }){`id`:$ ~> $merge()}; /* group by id => array of states =>  merge them to one object*/\t    \t    /* simple array of devices and  modify (transform) device objects. add state-object for identical ids*/\t    $map($.devices[type='device' and $not($contains(_id, /group/)) ], function($v) {\t       (\t            {\t                \"id\": $v.native.id,\t                \"device\": $v.common.name,\t                \"icon\":  \"/zigbee_img/\" & $v.common.icon,\t                \"batt\": $lookup($v.enums,$v.enums.$sift(function($v, $k) {$k ~> /^enum.favorites.batt./}).$keys())\t             } ;\t       )\t    }) ~> | * | $lookup($st, id) |;\t)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":1420,"wires":[["64a53f55.740f68","197dcd3f06c47e58"]]},{"id":"64a53f55.740f68","type":"ioBroker out","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"0_userdata.0.deviceList.zigbeeListNew","topic":"0_userdata.0.deviceList.zigbeeListNew","ack":"false","autoCreate":"true","stateName":"Zigbee Available","role":"","payloadType":"array","readonly":"false","stateUnit":"","stateMin":"","stateMax":"","x":520,"y":1480,"wires":[]},{"id":"50a1b532.b416e4","type":"comment","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"5. read states ","info":"","x":130,"y":1360,"wires":[]},{"id":"b0f14ab73055aaf3","type":"comment","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"2. topic to read","info":"","x":140,"y":1180,"wires":[]},{"id":"0a26114d17f264f1","type":"comment","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"3. read devices ","info":"","x":140,"y":1240,"wires":[]},{"id":"9aadcfc7d24edcaa","type":"link in","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"","links":["bfe60d8f4830d372","638d8cc6466b6f79"],"x":305,"y":1180,"wires":[["5af872ee.29181c"]]},{"id":"597bb03a35a2ec6f","type":"comment","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"4. safe devices to msg.devices","info":"","x":190,"y":1300,"wires":[]},{"id":"70840258b6eaad30","type":"comment","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"6. combine states and devices","info":"","x":190,"y":1420,"wires":[]},{"id":"197dcd3f06c47e58","type":"debug","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1050,"y":1420,"wires":[]},{"id":"efd6cca4e206cfac","type":"comment","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"7. safe pretared status list","info":"","x":170,"y":1480,"wires":[]},{"id":"d29bf45e7a5b7f58","type":"debug","z":"aafca175.713c8","g":"4d2bb33c.ceede4","name":"debug 11","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1060,"y":1360,"wires":[]},{"id":"1a6ee6a9fd605642","type":"debug","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"debug 15","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":420,"y":1980,"wires":[]},{"id":"b65c0c9fbb201d89","type":"ui_template","z":"aafca175.713c8","group":"3bde884a8ebcdf18","name":"Load Tabulator.js/css","order":2,"width":0,"height":0,"format":"<div ng-bind-html=\"msg.payload\"></div>\n<script type=\"text/javascript\" src=\"/node_modules/tabulator-tables/dist/js/tabulator.min.js\"></script>\n<link rel=\"stylesheet\" href=\"/node_modules/tabulator-tables/dist/css/tabulator_midnight.min.css\" />","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","className":"","x":140,"y":60,"wires":[[]]},{"id":"06c3cbf0fc7c0a7d","type":"change","z":"aafca175.713c8","g":"fe0a9da8604d3da9","name":"payload->zigbeetable","rules":[{"t":"set","p":"zigbeeTable","pt":"msg","to":"payload","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"{}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":1780,"wires":[["ee336567898a1b41"]]},{"id":"b4a8be01fbfd149c","type":"change","z":"aafca175.713c8","g":"e8d529b3.f22c2","name":"","rules":[{"t":"set","p":"openWindows","pt":"msg","to":"payload","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"{}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":420,"wires":[["a361f3170fba9d32"]]},{"id":"061df26c9b022c22","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":3,"width":3,"height":1},{"id":"794d44cbb06bf320","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":9,"width":12,"height":1},{"id":"b17b179164421b4a","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":11,"width":10,"height":1},{"id":"08ec8d5e90bc91d9","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":12,"width":10,"height":1},{"id":"21ab437b734ed1f2","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":13,"width":10,"height":1},{"id":"da7a823d84b1557e","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":14,"width":10,"height":1},{"id":"6a6c3f62efade984","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":15,"width":10,"height":1},{"id":"f33659b0bfc5565a","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":16,"width":10,"height":1},{"id":"f487ec1dcdac622f","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":17,"width":10,"height":1},{"id":"bae736f793619cbd","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":18,"width":10,"height":1},{"id":"e12681c6a1eb925c","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":19,"width":10,"height":1},{"id":"087c649df68be618","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":20,"width":10,"height":1},{"id":"209beb9e02fd36ff","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":21,"width":10,"height":1},{"id":"06dd74f8bce471f5","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":22,"width":10,"height":1},{"id":"d099fdc1921aea0c","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"f7f6be9c.45971","order":23,"width":10,"height":1},{"id":"dd64e8dfec08b485","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"3bde884a8ebcdf18","order":4,"width":3,"height":1},{"id":"7d6749c704527f56","type":"ui_spacer","z":"aafca175.713c8","name":"spacer","group":"3bde884a8ebcdf18","order":6,"width":10,"height":1},{"id":"87e32ce83242e0f3","type":"ui_group","name":"offene Fenster","tab":"dd02675508a72454","order":2,"disp":true,"width":9,"collapse":true,"className":""},{"id":"3bde884a8ebcdf18","type":"ui_group","name":"Zigbee Liste","tab":"dd02675508a72454","order":1,"disp":true,"width":"18","collapse":true,"className":""},{"id":"f7f6be9c.45971","type":"ui_group","name":"Device Listen neu","tab":"","order":1,"disp":true,"width":"18","collapse":false},{"id":"dd02675508a72454","type":"ui_tab","name":"Listen ","icon":"list","disabled":false,"hidden":false}]
                      

                      Für den Refresh ist das separate HTML Template zuständig.

                      c7274c54-bdcd-478f-8a12-cbf7e6ea0385-image.png

                      So 1:1 wirst du den Flow sicher nicht verwenden können, aber das Prinzip sollte klar sein. Wenn ich helfen kann, gerne.

                      Gruß
                      Reiner

                      KES777 created this issue in olifolkerd/tabulator

                      closed moment is not defined at tabulator.js #1631

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

                        @rewenode Ok - danke schön - muss ich mir dann nochmal später in Ruhe ansehen, ob ich irgendwelche Unterschiede erkennen kann. Vorerst mach ich erst noch mal mit der table Node weiter - auch wenn da auch manche Dinge nicht ganz passen. 😉

                        Ich melde mich wieder, wenn ich dann hier wieder weiter mache. 😉

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

                        Support us

                        ioBroker
                        Community Adapters
                        Donate

                        686
                        Online

                        31.7k
                        Users

                        79.7k
                        Topics

                        1.3m
                        Posts

                        6
                        56
                        5727
                        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