NEWS
sendTo & InfluxDB -> ??? [gelöst]
-
@legro Es müssten doch 760 Tage sein und nicht nur 480, oder?
-
Ja, wohl zu früh gefreut. Ich habe keine Ahnung, was die Lücken hervorruft.
In Grafana hingegen fehlt nichts.
Was ist das alles doch für ein Mist.
Wenigstens habe ich's nun geschafft, dass in InfluxDB wohl alle Datensätze angezeigt werden. Man musste hierzu das Aggregieren löschen.
-
Jetzt hoffe ich das Rätsel endgültig gelöst zu haben.
Es sieht ganz danach aus, dass sich ioBroker bei der Ausgabe der Datensätze schlichtweg verschluckt. Ich habe die Datensätze in 35-er Portionen ausgegeben, dabei fehlte nichts.
-
@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.
-
@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.
-
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.
-
@legro Für jede Abfrage? Zeig mal bitte die Abfragen. Wofür sind die unterschiedlichen table?
-
@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 -
@wolfi913 Hab ich schon gar nicht mehr dran gedacht. Danke für den Hinweis.
-
@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 -
@legro Dann bitte auch die Lösung schreiben. danke.
-
Die Lösung steht doch hier. Auch die möglichen Ergebnisse habe ich doch auch angegeben.
-
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)
-
@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.
-
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(..) eingefügt. Diese Funktion ermöglicht es sozusagen überhaupt erst, dass die Ergebnisse von sendTo an die Außenwelt gelangen können.
Zur Kontrolle habe ich das an sendTo übergebene Datum der jeweiligen Tagesabfrage - neben den Min/Max-Werten - ebenfalls zurückliefern lassen.
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 = 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]} } 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 } ]