NEWS
sendTo & InfluxDB -> ??? [gelöst]
-
@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(..) (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 nun auch die korrekte Reihenfolge in dem Datenpunkt
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 } ]
-
… 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. -
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.
-
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.
-
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 .. ]
-
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
-
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); } }) } 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. -
@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.