Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. ioBroker Allgemein
    4. sendTo & InfluxDB -> ??? [gelöst]

    NEWS

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

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    sendTo & InfluxDB -> ??? [gelöst]

    This topic has been deleted. Only users with topic management privileges can see it.
    • M
      MCU @legro last edited by

      @legro Das hört sich doch gut an. Muss man erst drauf kommen. Besser ist es sowas als Array zu speichern, dann kann man auch besser nachschauen.

      L 1 Reply Last reply Reply Quote 0
      • L
        legro @MCU last edited by legro

        @mcu sagte in sendTo & InfluxDB -> ???:

        @legro .. Besser ist es sowas als Array zu speichern, ..

        Das ist auch das Ziel.🙂

        Wie ich oben schrieb, möchte ich mich von InfluxDB, Grafana & Co. lösen und stattdessen den FlexCharts-Adapter von @jrbwh verwenden. In einer ersten Stufe möchte ich die in InfluxDB gespeicherten Daten in Arrays einlesen, um sie dem FlexCharts-Adapter zur Anzeige zu übergeben.

        In einer zweiten Phase werde ich alle bisher in InfluxDB gespeicherte Daten in einer eigen Datenstruktur ablegen, sodass ich InfluxDB nicht mehr benötige.

        1 Reply Last reply Reply Quote 0
        • L
          legro @MCU last edited by legro

          @mcu

          Mittlerweile bin ich an der Verarbeitung der Daten, die ich mittels sendTo aus InfluxDB ausgelesen habe.

          Hier ein Beispiel für die gelieferten Werte ..

          [
            [
              { 
                result: '_result',
                table: 0,
                _start: '2023-01-16T07:25:56.533063965Z',
                _stop: '2023-02-15T07:25:56.533063965Z',
                _time: '2023-01-23T11:00:01.025Z',
                _value: 6.949600000079954,
                _field: 'value',
                _measurement: 'gasTag',
                ts: 1674471601025 },
              { 
                result: '_result',
                table: 0,
                _start: '2023-01-16T07:25:56.533063965Z',
                _stop: '2023-02-15T07:25:56.533063965Z',
                _time: '2023-01-24T11:00:01.053Z',
                _value: 6.713639999830775,
                _field: 'value',
                _measurement: 'gasTag',
                ts: 1674558001053
              },
              {
                result: '_result',
                table: 0,
                _start: '2023-01-16T07:25:56.533063965Z',
                _stop: '2023-02-15T07:25:56.533063965Z',
                _time: '2023-01-25T11:00:01.059Z',
                _value: 7.05180000008113,
                _field: 'value',
                _measurement: 'gasTag',
                ts: 1674644401059
              },
              ...
            ],
            [
              {
                result: '_result',
                table: 1,
                ...
              },
              ..
            ]
          ]
          
          

          Das Ergebnis ist ein zweidimensionales Array. Für jede Abfrage (s. table: 0, ..)wird ein Array erzeugt, das wiederum die einzelnen Werte als Objekte in einem (Unter)Array ablegt.

          Das Ganze kommt ziemlich aufgeblasen daher. So ist es völlig redundant, stets in jedem Datensatz die Werte table, _start, _stop anzugeben. Sei's d'rum! Man muss sich halt aus dem ganze Zeug die interessierenden Felder in eine eigenes Array umpacken.

          M 1 Reply Last reply Reply Quote 0
          • M
            MCU @legro last edited by MCU

            @legro Für jede Abfrage? Zeig mal bitte die Abfragen. Wofür sind die unterschiedlichen table?

            L 1 Reply Last reply Reply Quote 0
            • W
              wolfi913 @MCU last edited by

              @mcu sagte in sendTo & InfluxDB -> ???:

              @legro Und als option

              options: {
                      end:       Date.now(),
                      count:     1000,
                      aggregate: 'onchange'
                  }
              

              Das dürfte mit Werten >500 momentan immer noch nicht funktionieren, da Dein PR immer noch nicht übernommen wurde.
              https://github.com/ioBroker/ioBroker.influxdb/issues/391
              https://github.com/ioBroker/ioBroker.influxdb/pull/392

              mcuiobroker created this issue in ioBroker/ioBroker.influxdb

              open Problem with limit setting -> it is not set #391

              mcuiobroker created this issue in ioBroker/ioBroker.influxdb

              open Update main.js Change count in options #392

              M 1 Reply Last reply Reply Quote 0
              • M
                MCU @wolfi913 last edited by

                @wolfi913 Hab ich schon gar nicht mehr dran gedacht. Danke für den Hinweis.

                1 Reply Last reply Reply Quote 0
                • L
                  legro @MCU last edited by legro

                  @mcu sagte in sendTo & InfluxDB -> ???:

                  @legro .. Zeig mal bitte die Abfragen. Wofür sind die unterschiedlichen table?

                  Mir gelang es nur mittels flux vernünftige Ergebnisse zu erzielen. Über 'history' - anstelle von 'query' - erhielt ich nur Unsinn oder gar nichts.

                  sendTo('influxdb.0', 'query', 'from(bucket: "db_iobroker") |> range(start: -745d, stop: -727d) |> filter(fn: (r) => r._measurement == "gasTag") |> filter(fn: (r) => r["_field"] == "value")', function (query) {
                      let abfrage = JSON.stringify(query.result)
                      let qry = JSON.parse(abfrage)
                  
                      console.log(qry)
                  

                  Man kann mehrere Abfragen in einer query-Anweisung angeben. Diese werden dann in einem zweiten, dritten, .. Array abgespeichert. Die Angabe table reflektiert die jeweilige Abfrage.

                  Beispiele ..

                  qry[0][1] -> zweites Objekt {..} in der ersten Abfrage
                  qry[1][0] -> erstes Objekt in der zweiten Abfrage
                  qry[0].length -> Anzahl der Elemente in der ersten Abfrage

                  M 1 Reply Last reply Reply Quote 0
                  • M
                    MCU @legro last edited by

                    @legro Dann bitte auch die Lösung schreiben. danke.

                    L 4 Replies Last reply Reply Quote 0
                    • L
                      legro @MCU last edited by

                      @mcu

                      Die Lösung steht doch hier. Auch die möglichen Ergebnisse habe ich doch auch angegeben.

                      1 Reply Last reply Reply Quote 0
                      • L
                        legro @MCU last edited by

                        @mcu

                        NACHTRAG

                        Die Zeitangaben können auch in der üblichen Linux-Notation erfolgen ..

                        sendTo('influxdb.0', 'query',
                            //'from(bucket: "db_iobroker") |> range(start: -745d, stop: 0d) |> filter(fn: (r) => r._measurement == "gasTag") |> filter(fn: (r) => r["_field"] == "value")',
                            'from(bucket: "db_iobroker") |> range(start: 2023-01-24T00:00:00Z, stop: 2023-01-30T00:00:00Z) |> filter(fn: (r) => r._measurement == "gasTag") |> filter(fn: (r) => r["_field"] == "value")',
                            function (query) {
                                let qry = JSON.parse(JSON.stringify(query.result))
                                let werte = []
                                for (let i=0; i<qry[0].length; i++) {
                                    werte.push(qry[0][i]._value)
                            }
                            setState('0_userdata.0.Gaszähler.gasTag_Test', JSON.stringify(werte), true)
                        
                        1 Reply Last reply Reply Quote 1
                        • L
                          legro @MCU last edited by

                          @mcu sagte in sendTo & InfluxDB -> ??? [gelöst]:

                          @legro Dann bitte auch die Lösung schreiben.

                          Apropos Lösung ..

                          Im Nachgang gestaltet sich alles viel schwieriger als gedacht. Der Grund liegt offensichtlich in dem asynchronen Verhalten von sendTo.

                          Hier meine Leidensgeschichte ..

                          Meine Versuche, die Min-/Max-Werte aus InfluxDB in der an sendTo übergebenen callback-Funktion zu ermitteln, waren zwar nicht erfolglos, aber aufs Äußerste frustrierend. Vieles hängt offenbar von den jeweiligen Gegebenheiten und - man mag es nicht glauben - auch vom Zufall ab.

                          function getMinMax(abfrage) {
                          
                              let tblMinMax = JSON.parse(getState('0_userdata.0.Gaszähler.Test_TempMinMax').val)
                          
                              sendTo('influxdb.0', 'query', abfrage,
                                  function (query) {
                                      let qry = JSON.parse(JSON.stringify(query.result))
                                      let werte = []
                                      let min = qry[0][0]._value
                                      let max = qry[0][0]._value
                                      for (let i=0; i<qry[0].length; i++) {
                                          werte.push(qry[0][i]._value)
                                          if (werte[i] < min) {min=werte[i]}
                                          if (max < werte[i]) {max=werte[i]}
                                      }
                                  
                                  let tblMinMax = JSON.parse(getState('0_userdata.0.Gaszähler.Test_TempMinMax').val)
                                  tblMinMax.push({min,max})
                                  setState('0_userdata.0.Gaszähler.Test_TempMinMax', JSON.stringify(tblMinMax), true)
                                  
                              });
                          
                              setState('0_userdata.0.Gaszähler.Test_TempMinMax', JSON.stringify(tblMinMax), true)
                          
                          }
                          
                          let d = ''
                          let tag = ''
                          
                          setState('0_userdata.0.Gaszähler.Test_TempMinMax', JSON.stringify([]), true)
                          
                          for (let i=1; i<32; i++ ) {
                              d = '0' + i
                              d = d.slice(-2)
                              tag = `from(bucket: "db_iobroker") |> range(start: 2024-12-${d}T00:00:00.000Z, stop: 2024-12-${d}T23:59:59.999Z) |> filter(fn: (r) => r._measurement == "AußenTemperatur") |> filter(fn: (r) => r["_field"] == "value")`
                              getMinMax(tag)
                          }
                          

                          An diesem Programm wird die Problematik deutlich.

                          Es wird in einer (äußeren) for-Schleife die Funktion getMinMax aufgerufen, die mittels sendTo die Min/Max-Temperaturwerte eines Tages ermitteln und an das Array im Datenpunkt Test_TempMinMax anfügen soll. Das funktioniert sogar, aber nur einzeln. Rufe ich für jeden Tag die Funktion getMinMax(..) einzeln auf, so baut sich das Array auf und enthält die Elemente {min: <Zahl>, max: <Zahl>} für die Tage, die beim Aufruf übergeben wurden.

                          Und nun das Verrückte: Rufe ich die Funktion getMinMax in der for-Schleife auf, so fehlen in dem Array jede Menge Wertepaare; mal sind 20, mal 15 und zuweilen gar weniger als 10 darin zu finden. Als wäre das nicht genug Chaos, JavaScript schafft es, die Reihenfolge wild durcheinander gewürfelt in dem Datenpunkt Test_TempMinMax abzulegen.

                          .. und hier die Auflösung des Rätsels ..

                          Mein Fazit: Die Aufrufe von sendTo werden offenbar durch die äußerste for-Schleife, in der die Aufrufe von getMinMax erfolgen, angestoßen und laufen parallel (asynchron zum Hauptprogramm) ab, wobei sie unterschiedlich lange Zeiten benötigen und zu verschiedenen Zeitpunkten fertig werden; hierdurch lässt sich die durcheinander gewirbelte Reihenfolge erklären. Darüber hinaus verschluckt sich das System, da vermutlich die Aufrufe von sendTo beim Abspeichern auf die gemeinsam genutzte Ressource (Datenpunkt mit dem Array) sich gegenseitig blockieren; was wiederum das Fehlen von Daten erklären mag.

                          Kann man ersteres nachvollziehen, so ist das Fehlen von Datensätzen jedoch ein absolutes Unding.

                          mein weiteres Vorgehen ..

                          Ich teste nun die Konstrukte asynch/await und die Verwendung promises sowie callback-Funktionen aus, um damit eine Lösung zurechtzuzimmern. Sollte mir dies gelingen, werde ich die Ergebnisse hier einstellen.

                          1 Reply Last reply Reply Quote 0
                          • L
                            legro @MCU last edited by legro

                            @mcu

                            Wenigstens das Problem der verlorenen Datensätze konnte ich mit einer (weiteren) callback-Funktion in den Griff bekommen.

                            Mein Vorgehen ..

                            Innerhalb der sendTo übergebenen (anonymen) callback-Funktion habe ich eine weitere callback-Funktion getResults(..) (s. Zeile 16) eingefügt. Diese Funktion ermöglicht es sozusagen überhaupt erst, dass die Ergebnisse von sendTo an die Außenwelt gelangen können und somit eine Rückmeldung von sendTo zu erhalten.

                            Zur Kontrolle habe ich in getResults das an sendTo übergebene Datum der jeweiligen Tagesabfrage - neben den Min/Max-Werten - ebenfalls zurückliefern lassen.

                            Die modifizierte callback-Funktion getResults liefert leider nicht die korrekte Reihenfolge in dem Datenpunkt, die müsste ich somit noch dem Datum sortieren.

                            function getMinMax(abfrage) {
                            
                                sendTo('influxdb.0', 'query', abfrage,
                                    //'from(bucket: "db_iobroker") |> range(start: -745d, stop: 0d) |> filter(fn: (r) => r._measurement == "gasTag") |> filter(fn: (r) => r["_field"] == "value")',
                                    //'from(bucket: "db_iobroker") |> range(start: 2025-01-20T00:00:00.000Z, stop: 2025-01-20T23:59:59.999Z) |> filter(fn: (r) => r._measurement == "AußenTemperatur") |> filter(fn: (r) => r["_field"] == "value")',
                                    function (query) {
                                        let qry = query.result)
                                        let werte = []
                                        let min = qry[0][0]._value
                                        let max = qry[0][0]._value
                                        for (let i=0; i<qry[0].length; i++) {
                                            werte.push(qry[0][i]._value)
                                            if (werte[i] < min) {min=werte[i]}
                                            if (max < werte[i]) {max=werte[i]}
                                        }
                                        getResults(abfrage.substring(44,55),{min,max})
                                    }
                                );
                            
                            }
                            
                            let tblMinMax = []
                            setState('0_userdata.0.Gaszähler.Test_TempMinMax', JSON.stringify(tblMinMax), true)
                            
                            function getResults(Datum,MinMax) {
                            
                             //diese Funktion liefert die nach Datum sortierten Werte im Datenpunkt ' .. Test_TempMinMax'
                            
                                tblMinMax[Number(Datum.substring(8,10))-1] = MinMax
                                setState('0_userdata.0.Gaszähler.Test_TempMinMax', JSON.stringify(tblMinMax), true)
                            
                            }
                            
                            /*
                            function getResults(Datum,MinMax) {  //Diese Funktion liefert die ungeordnete Ausgabe
                                console.log(Datum + ' min: ' + MinMax.min + ', max: ' + MinMax.max)
                            }
                            */
                            
                            let d = ''
                            let tag = ''
                            
                            for (let i=1; i<32; i++ ) {
                                d = ('0' + i).slice(-2)
                                tag = `from(bucket: "db_iobroker") |> range(start: 2024-12-${d}T00:00:00.000Z, stop: 2024-12-${d}T23:59:59.999Z) |> filter(fn: (r) => r._measurement == "AußenTemperatur") |> filter(fn: (r) => r["_field"] == "value")`
                                getMinMax(tag)
                            }
                            

                            Nun fehlt in den Ergebnissen kein Datensatz mehr ..

                            javascript.0	09:44:59.087	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-01T min: -1.3, max: 6.2
                            javascript.0	09:44:59.098	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-02T min: 4, max: 11.4
                            javascript.0	09:44:59.192	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-04T min: 2.7, max: 5.4
                            javascript.0	09:44:59.197	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-03T min: 2, max: 7
                            javascript.0	09:44:59.202	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-05T min: 2.8, max: 6.7
                            javascript.0	09:44:59.267	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-11T min: 2.1, max: 4.2
                            javascript.0	09:44:59.273	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-08T min: 0.5, max: 6.7
                            javascript.0	09:44:59.291	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-06T min: 3.2, max: 8.5
                            javascript.0	09:44:59.305	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-15T min: 2.2, max: 8.6
                            javascript.0	09:44:59.343	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-31T min: -5.1, max: 1.3
                            javascript.0	09:44:59.348	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-07T min: 4.4, max: 9.3
                            javascript.0	09:44:59.357	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-24T min: 1.8, max: 23.5
                            javascript.0	09:44:59.370	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-12T min: 0.2, max: 2.1
                            javascript.0	09:44:59.378	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-28T min: -2.8, max: 15.6
                            javascript.0	09:44:59.400	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-19T min: 2.8, max: 13.1
                            javascript.0	09:44:59.403	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-17T min: 5, max: 9.1
                            javascript.0	09:44:59.418	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-21T min: 4.5, max: 8.9
                            javascript.0	09:44:59.422	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-23T min: 1.9, max: 6.1
                            javascript.0	09:44:59.426	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-18T min: 5.1, max: 11.9
                            javascript.0	09:44:59.431	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-09T min: 3.6, max: 5.1
                            javascript.0	09:44:59.435	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-30T min: -2.3, max: 4.7
                            javascript.0	09:44:59.440	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-20T min: 1.9, max: 5.5
                            javascript.0	09:44:59.446	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-13T min: -3, max: 1.8
                            javascript.0	09:44:59.451	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-27T min: -1.5, max: 14.3
                            javascript.0	09:44:59.456	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-10T min: 4.1, max: 5.5
                            javascript.0	09:44:59.459	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-26T min: 0.1, max: 9.8
                            javascript.0	09:44:59.465	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-14T min: -3.5, max: 3.9
                            javascript.0	09:44:59.480	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-16T min: 8.3, max: 11.5
                            javascript.0	09:44:59.485	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-25T min: 4.9, max: 9
                            javascript.0	09:44:59.500	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-29T min: -2.1, max: 1
                            javascript.0	09:44:59.505	info	script.js._Test.InfluxDB_Abfrage_1: 2024-12-22T min: 1.3, max: 8.3
                            
                            

                            Und hier die nach Datum geordneten Werte ..

                            [
                              {
                                "min": -1.3,
                                "max": 6.2
                              },
                              {
                                "min": 4,
                                "max": 11.4
                              },
                              {
                                "min": 2,
                                "max": 7
                              },
                              {
                                "min": 2.7,
                                "max": 5.4
                              },
                              {
                                "min": 2.8,
                                "max": 6.7
                              },
                              {
                                "min": 3.2,
                                "max": 8.5
                              },
                              {
                                "min": 4.4,
                                "max": 9.3
                              },
                              {
                                "min": 0.5,
                                "max": 6.7
                              },
                              {
                                "min": 3.6,
                                "max": 5.1
                              },
                              {
                                "min": 4.1,
                                "max": 5.5
                              },
                              {
                                "min": 2.1,
                                "max": 4.2
                              },
                              {
                                "min": 0.2,
                                "max": 2.1
                              },
                              {
                                "min": -3,
                                "max": 1.8
                              },
                              {
                                "min": -3.5,
                                "max": 3.9
                              },
                              {
                                "min": 2.2,
                                "max": 8.6
                              },
                              {
                                "min": 8.3,
                                "max": 11.5
                              },
                              {
                                "min": 5,
                                "max": 9.1
                              },
                              {
                                "min": 5.1,
                                "max": 11.9
                              },
                              {
                                "min": 2.8,
                                "max": 13.1
                              },
                              {
                                "min": 1.9,
                                "max": 5.5
                              },
                              {
                                "min": 4.5,
                                "max": 8.9
                              },
                              {
                                "min": 1.3,
                                "max": 8.3
                              },
                              {
                                "min": 1.9,
                                "max": 6.1
                              },
                              {
                                "min": 1.8,
                                "max": 23.5
                              },
                              {
                                "min": 4.9,
                                "max": 9
                              },
                              {
                                "min": 0.1,
                                "max": 9.8
                              },
                              {
                                "min": -1.5,
                                "max": 14.3
                              },
                              {
                                "min": -2.8,
                                "max": 15.6
                              },
                              {
                                "min": -2.1,
                                "max": 1
                              },
                              {
                                "min": -2.3,
                                "max": 4.7
                              },
                              {
                                "min": -5.1,
                                "max": 1.3
                              }
                            ]
                            
                            1 Reply Last reply Reply Quote 0
                            • ofri2607
                              ofri2607 last edited by

                              @legro

                              … asynchronen Verhalten von sendTo

                              Sieh‘ dir dazu sendToAsync an - https://github.com/ioBroker/ioBroker.javascript/blob/master/docs/en/javascript.md#sendtoasync
                              Und für die Lösung im for-Loop findet sich unter dem Suchbegriff „javascript promise for loop“ zahlreiche Informationen, z.B. hier - https://stackoverflow.com/questions/40328932/javascript-es6-promise-for-loop
                              Pkt. 4 aus der ersten Antwort ist mE das was du benötigst.

                              L 1 Reply Last reply Reply Quote 0
                              • L
                                legro @ofri2607 last edited by legro

                                @ofri2607

                                Vielen Dank für die vielen Hinweise. Bei den vielen Knoten, die ich im Kopf habe, kann ich jede Hilfe gebrauchen.😕

                                Mittlerweile bin ich dabei, das ganze Zeug rund um promises zu verstehen, um damit mir eine Lösung zusammen zu basteln. Die Problematik bei sendTo ist, dass dieser Aufruf ja nichts (direkt) zurückmeldet. Wenn ich die vielen Beispiele richtig überblicke, wird (immer) mit timeouts gearbeitet, die nach Ablauf einer vorgegebenen Zeitspanne auslösen. Das ist aber nicht das, was ich möchte. Mein Wunsch ist, eine Rückmeldung zu erhalten, die definitiv ein eindeutiges Ergebnis (à la: hat geklappt oder auch nicht) liefert.

                                Daher bin ich auf die oben beschriebene Idee gekommen, eine callback-Funktion getResults in die (anonyme) an sendTo übergebene Funktion einzusetzen. Diese versuche ich nur für resolve in einem promise zu nutzen.

                                Irgendwie sehe ich den Wald vor lauter Bäumen (immer noch) nicht.😟

                                ofri2607 1 Reply Last reply Reply Quote 0
                                • ofri2607
                                  ofri2607 @legro last edited by

                                  @legro

                                  Gerne.
                                  Sieh dir dazu nochmal das Beispiel zu sentToAsync an:

                                  const res = await sendToAsync('sql.0', 'getEnabledDPs', {});
                                  log(JSON.stringify(res));
                                  

                                  Du wirst etwas vom Promis der sentToAsync Abfrage zurückbekommen.

                                  In den Beispielen zu Promise wird meist das timeout verwendet, da es bei dem Thema um den zeitlichen Ablauf („Zeitverzögerung“) im Code geht. Sinngemäß ist das auch so bei dem sentToAsync; das hat seine „Bearbeitungszeit“ mit der Anfrage und Auswertung an die influxDB. Das ist das was du, vereinfacht gesagt, mit dem await im for-loop machst, du wartest damit bis die Rückmeldung vom Promise kommt und erst dann erfolgt der nächste Schleifendurchlauf. Ohne dem wird nicht gewartet, sonder es geht sofort in den nächsten Schleifendurchlauf.

                                  Ich würde es in etwa so lösen:
                                  Baue die Funktion getMinMax(abfrage) auf ein Promise um:

                                  function getMinMax(abfrage)
                                     return new Promise(async (resolve, reject) => {
                                       try {
                                          const query = await sentToAsync('influxdb.0', 'query', abfrage);
                                          log(query) //nur zum Testen
                                          let qry = JSON.parse(JSON.stringify(query.result));
                                          //… usw. mit deinem Code
                                          resolve(true);
                                        } catch(err) {
                                           log(err.message, „warn“);
                                           reject(false);
                                        }
                                     })
                                  }
                                  

                                  Und in deiner for-Schleife, die in einer async function eingebettet ist, rufst du dann

                                     const success = await getMinMax(tag);
                                     log((success ? „erfolgreich“ : „NICHT erfolgreich“), „info“);
                                  

                                  auf.

                                  L 2 Replies Last reply Reply Quote 0
                                  • L
                                    legro @ofri2607 last edited by legro

                                    @ofri2607

                                    Vielen Dank für deine Unterstützung. Dank deines entscheidenden Hinweises auf die Funktion sendToAsync konnte ich mein Vorhaben umsetzen. Da eine async function ja stets (implizit) mit einem promise verknüpft ist, fiel die Lösung erstaunlich kurz aus.🙂

                                    Auf die nachfolgende Basislösung aufbauend werde ich mir mein Vorhaben realisieren können.

                                    Hier meine Basislösung ..

                                    async function queryInfluxDB() {
                                      try {
                                        const query = 'from(bucket: "db_iobroker") |> range(start: 2025-01-20T00:00:00.000Z, stop: 2025-01-20T23:59:59.999Z) |> filter(fn: (r) => r._measurement == "AußenTemperatur") |> filter(fn: (r) => r["_field"] == "value")';
                                        const result = await sendToAsync('influxdb.0', 'query', query);
                                        console.log(JSON.stringify(result))
                                      } catch (error) {
                                        console.error('Fehler bei der Abfrage:', error);
                                      }
                                    }
                                    
                                    queryInfluxDB();
                                    

                                    .. und das Ergebnis ..

                                    {"result":"_result","table":0,"_start":"2025-01-20T00:00:00Z","_stop":"2025-01-20T23:59:59.999Z","_time":"2025-01-20T00:10:43.242Z","_value":-2.7,"_field":"value","_measurement":"AußenTemperatur","ts":1737331843242},
                                    {"result":"_result","table":0,"_start":"2025-01-20T00:00:00Z","_stop":"2025-01-20T23:59:59.999Z","_time":"2025-01-20T00:20:43.924Z","_value":-2.7,"_field":"value","_measurement":"AußenTemperatur","ts":1737332443924},
                                    {"result":"_result","table":0,"_start":"2025-01-20T00:00:00Z","_stop":"2025-01-20T23:59:59.999Z","_time":"2025-01-20T00:30:43.535Z","_value":-2.7,"_field":"value","_measurement":"AußenTemperatur","ts":1737333043535},
                                    {"result":"_result","table":0,"_start":"2025-01-20T00:00:00Z","_stop":"2025-01-20T23:59:59.999Z","_time":"2025-01-20T00:40:43.189Z","_value":-2.7,"_field":"value","_measurement":"AußenTemperatur","ts":1737333643189},
                                    [ .. und jede Menge weitere Ergebnisse .. ]
                                    
                                    1 Reply Last reply Reply Quote 0
                                    • L
                                      legro @ofri2607 last edited by legro

                                      @ofri2607

                                      Zu früh gefreut.☹

                                      Das ganze Zeug funktioniert noch immer nicht. Die Ergebnisse sind wild durcheinander gewürfelt. Der Zusatz await in Zeile 7 bewirkt offenbar rein gar nichts. ☹

                                      Das folgende Skript ..

                                      async function queryInfluxDB(tag) {
                                      
                                          let d = tag
                                      
                                          try {
                                              const query = `from(bucket: "db_iobroker") |> range(start: 2025-01-${d}T00:00:00.000Z, stop: 2025-01-${d}T23:59:59.999Z) |> filter(fn: (r) => r._measurement == "AußenTemperatur") |> filter(fn: (r) => r["_field"] == "value")`;
                                              const result = await sendToAsync('influxdb.0', 'query', query);
                                      
                                              let qry = result.result
                                              let werte = []
                                              let min = qry[0][0]._value
                                              let max = qry[0][0]._value
                                              for (let i=0; i<qry[0].length; i++) {
                                                  werte.push(qry[0][i]._value)
                                                  if (werte[i] < min) {min=werte[i]}
                                                  if (max < werte[i]) {max=werte[i]}
                                              }
                                      
                                              console.log({tag, min,max})
                                              //getResults(abfrage.substring(44,54),{min,max}) //der 1. Parameter liefert das Tagesatum String
                                      
                                      
                                          } catch (error) {
                                              console.error('Fehler bei der Abfrage:', error);
                                          }
                                      }
                                      
                                      let d = ''
                                      let tag = ''
                                      
                                      for (let i=1; i<32; i++ ) {
                                          queryInfluxDB(d = ('0' + i).slice(-2))
                                      }
                                      

                                      .. liefert folgende Ergebnisse ..

                                      javascript.0	15:30:03.525	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '01', min: 0.7, max: 7.3 }
                                      javascript.0	15:30:03.545	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '02', min: 0.7, max: 6.8 }
                                      javascript.0	15:30:03.703	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '03', min: -0.1, max: 2.4 }
                                      javascript.0	15:30:03.729	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '05', min: -0.7, max: 10.5 }
                                      javascript.0	15:30:03.741	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '04', min: -0.5, max: 3.5 }
                                      javascript.0	15:30:03.755	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '06', min: 4.7, max: 12.9 }
                                      javascript.0	15:30:03.817	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '07', min: 2.3, max: 5.4 }
                                      javascript.0	15:30:03.835	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '13', min: -6.6, max: -0.4 }
                                      javascript.0	15:30:03.836	error	script.js._Test.InfluxDB_Abfrage_3: Fehler bei der Abfrage:
                                      javascript.0	15:30:03.838	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '12', min: -1.6, max: 2.7 }
                                      javascript.0	15:30:03.855	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '08', min: 0, max: 3.9 }
                                      javascript.0	15:30:03.875	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '29', min: 5.2, max: 9.2 }
                                      javascript.0	15:30:03.949	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '25', min: 6.2, max: 13.2 }
                                      javascript.0	15:30:03.952	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '27', min: 6.3, max: 10.5 }
                                      javascript.0	15:30:03.977	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '18', min: -3.5, max: 2.5 }
                                      javascript.0	15:30:03.979	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '09', min: -0.8, max: 0.9 }
                                      javascript.0	15:30:03.999	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '24', min: 3, max: 9.4 }
                                      javascript.0	15:30:04.001	error	script.js._Test.InfluxDB_Abfrage_3: Fehler bei der Abfrage:
                                      javascript.0	15:30:04.004	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '23', min: 2.8, max: 5.7 }
                                      javascript.0	15:30:04.010	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '28', min: 3.8, max: 9.4 }
                                      javascript.0	15:30:04.016	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '10', min: -1.6, max: 2.4 }
                                      javascript.0	15:30:04.020	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '11', min: -0.4, max: 1.5 }
                                      javascript.0	15:30:04.029	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '26', min: 2.9, max: 7.7 }
                                      javascript.0	15:30:04.038	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '21', min: -3.7, max: 3.7 }
                                      javascript.0	15:30:04.043	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '15', min: 0.9, max: 3.9 }
                                      javascript.0	15:30:04.049	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '22', min: -1.7, max: 4.6 }
                                      javascript.0	15:30:04.055	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '14', min: -7.5, max: 1.7 }
                                      javascript.0	15:30:04.070	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '20', min: -2.9, max: 0.6 }
                                      javascript.0	15:30:04.072	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '19', min: -4.7, max: -0.8 }
                                      javascript.0	15:30:04.075	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '16', min: -2.8, max: 3.8 }
                                      javascript.0	15:30:04.077	info	script.js._Test.InfluxDB_Abfrage_3: { tag: '17', min: -2.8, max: 1.1 }
                                      

                                      .. und funktioniert damit schlechter als zuvor - fehlt wenigstens bei dieser Lösung kein Datensatz.

                                      Mich frustriert das Ganze mittlerweile gewaltig. JavaScript kommt mir vor wie eine Art Agrarinformatik: Kraut&Rüben😩

                                      ofri2607 1 Reply Last reply Reply Quote 0
                                      • ofri2607
                                        ofri2607 @legro last edited by ofri2607

                                        @legro

                                        Ich würde es so machen (wie ich in meinem obigen Post schon geschrieben) - mit Promise in der Funktion und for in einer async function mit await im loop::

                                        let minMaxObj = {};
                                        function queryInfluxDB(tag) {
                                            return new Promise(async (resolve, reject) => {
                                                //let d = tag        für was hast du das eingebaut?
                                                try {
                                                     const query = `from(bucket: "db_iobroker") |> range(start: 2025-01-${tag}T00:00:00.000Z, stop: 2025-01-${tag}T23:59:59.999Z) |> filter(fn: (r) => r._measurement == "AußenTemperatur") |> filter(fn: (r) => r["_field"] == "value")`;
                                                     const result = await sendToAsync('influxdb.0', 'query', query);
                                         
                                                     let qry = result.result
                                                     let werte = []
                                                     let min = qry[0][0]._value
                                                     let max = qry[0][0]._value
                                                     for (let i=0; i<qry[0].length; i++) {
                                                         werte.push(qry[0][i]._value)
                                                         if (werte[i] < min) {min=werte[i]}
                                                         if (max < werte[i]) {max=werte[i]}
                                                     }
                                         
                                                     log({tag, min,max})
                                                     minMaxObj[tag] = {
                                                          min: min,
                                                          max: max
                                                     };
                                                     //getResults(abfrage.substring(44,54),{min,max}) //der 1. Parameter liefert das Tagesatum String
                                                    resolve(true);
                                                } catch (error) {
                                                     log("Fehler bei der Abfrage Tag " + tag + ":" + error.message, "error");
                                                     //reject(false); EDIT: => liefert ohne Behandlung mit try-catch im Aufruf einen unbehandelten Fehler, daher
                                                     resolve(false);
                                                }
                                           })
                                        }
                                        
                                        async function callLoop() {
                                            for (let i=1;  i<32;  i++) {
                                                const success = await queryInfluxDB(('0' + i).slice(-2));
                                                log(i + " = " + (success ? „erfolgreich“ : „NICHT erfolgreich“), „info“);
                                            }
                                            log("Datensätze: " + JSON.stringify(minMaxObj), "info");
                                        }
                                        
                                        callLoop();
                                        

                                        Das durcheinander gewürfelte ist klar, denn bei deiner Lösung "feuert" der for-Loop eines nach dem anderen sofort ab und wartet nicht bis die aufgerufene Funktion fertig abgearbeitet wurde. Welche aufgerufene Funktion queryInfluxDB dann schneller ist, hat gewonnen.
                                        Daher die Lösung mit dem await im for-Loop, damit wird, vereinfacht gesagt, gewartet bis das Promise aus der Funktion zurückgemeldet hat.

                                        Die Frage die sich mir nur auch stellt ist, warum ist dir die Reihenfolge überhaupt so wichtig?
                                        Wenn du ein Object ausserhalb der Funktion queryInfluxDB definierst, dass du mit der Funktion befüllst, ist die Reihenfolge an sich irrelevant, habe es dir oben als Beispiel dazu eingebaut.

                                        EDIT: reject(false) im obigen Code-Beispiel durch resolve(false) ausgetauscht => siehe auch mein unten folgendes Post

                                        L 2 Replies Last reply Reply Quote 0
                                        • L
                                          legro @ofri2607 last edited by

                                          @ofri2607 sagte in sendTo & InfluxDB -> ??? [gelöst]:

                                          Die Frage die sich mir nur auch stellt ist, warum ist dir die Reihenfolge überhaupt so wichtig?

                                          Die Reihenfolge wird zum Erstellen von Diagrammen benötigt, wie ich sie zur Überwachung unserer Hybridheizung benötige.

                                          Wenn du ein Object ausserhalb der Funktion queryInfluxDB definierst, dass du mit der Funktion befüllst, ist die Reihenfolge an sich irrelevant, habe es dir oben als Beispiel dazu eingebaut.

                                          Vielen Dank für deine detaillierten Vorschläge. Ich versuche einmal nachzuvollziehen, wie du dies konstruiert hast.

                                          1 Reply Last reply Reply Quote 0
                                          • L
                                            legro @ofri2607 last edited by legro

                                            @ofri2607 sagte in sendTo & InfluxDB -> ??? [gelöst]:

                                            Daher die Lösung mit dem await im for-Loop, damit wird, vereinfacht gesagt, gewartet bis das Promise aus der Funktion zurückgemeldet hat.

                                            Nun habe ich mich bereits einige Tage mit promises und async/await herumgeschlagen. Da spricht man von der callback-hell, aber diese beiden Konstrukte kommen mir nicht viel weniger diabolisch daher.😞 Was mich offenbar durcheinander bringt, ist die gleichzeitige Verwendung dieser beiden Methoden in deinem Lösungsvorschlag.

                                            Dennoch: Ganz langsam scheinen sich das Dunkel und die Knoten in meinem Kopf aufzulösen. Hier meine (vorläufigen?) Einsichten:

                                            Du verwendest sowohl ein promise [und somit hatte ich erwartet, dass die Weiterverarbeitung mittels .then(), .catch() und finally() erfolgt] als auch async/await [wobei durch try die eigentliche Verarbeitung des Ergebnisses erfolgen sollte].

                                            Liege ich damit richtig, oder habe ich‘s immer noch nicht richtig verstanden?😟

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

                                            Support us

                                            ioBroker
                                            Community Adapters
                                            Donate
                                            FAQ Cloud / IOT
                                            HowTo: Node.js-Update
                                            HowTo: Backup/Restore
                                            Downloads
                                            BLOG

                                            1.0k
                                            Online

                                            31.7k
                                            Users

                                            79.6k
                                            Topics

                                            1.3m
                                            Posts

                                            5
                                            51
                                            2029
                                            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