NEWS
Influx Datensatz in Funktion lesen
-
Ich versuche mir eine Funktion zu schreiben, mit der ich einen Wert zu einem bestimmten Zeitpunkt zurückgebe.
Wenn ich das ganze einfach in ein Skript schreibe geht das:
var end = new Date().getTime(); console.log("Skript Start"); sendTo('influxdb.0', 'getHistory', { id: 'javascript.0.Verbrauch.StromGesamt.ZaehlerstandOffiziell', options: { start: end - 600000, // vor 10 Minuten end: end, count: 1, aggregate: 'none' // or 'none' to get raw values } }, function (STResult) { var Ergebnis = 0; if (STResult.result.length > 0 ){Ergebnis = STResult.result[0].val}; console.log("Ergebnis = " + Ergebnis); });
liefert
14:44:04.384 info javascript.0 (15862) script.js.Programmieren.Influx.AlteWerteLesen: Skript Start 14:44:04.447 info javascript.0 (15862) script.js.Programmieren.Influx.AlteWerteLesen: Ergebnis = 105244.6021
Wenn ich das ganze aber in eine Funktion packen möchte, klappt das nicht, ich vermute dass die Funktion ein Ergebnis zurückliefert, bevor das "sendTo" abgearbeitet ist.
Wenn ich an das obige Skript
console.log("Strom gestern: " + ReadInflux("javascript.0.Verbrauch.StromGesamt.ZaehlerstandOffiziell", 1)); function ReadInflux(DP, NbDays){ console.log("DP: " + DP); var End = new Date().getTime(); var Start = End - NbDays * 1000 * 24 * 60 * 60; //Start = End - 600000; var Ergebnis = 0; console.log("Start: " + Start + " End: " + End); sendTo('influxdb.0', 'getHistory', { id: DP, options: { start: Start, end: End, count: 1, aggregate: 'none' // or 'none' to get raw values } }, function (SendToResult) { console.log("RR: " + SendToResult); if (SendToResult.result.length > 0){ Ergebnis = SendToResult.result[0].val; } }) return(Ergebnis); }
anfüge bekomme ich:
4:49:52.685 info javascript.0 (15862) script.js.Programmieren.Influx.AlteWerteLesen: Skript Start 14:49:52.686 info javascript.0 (15862) script.js.Programmieren.Influx.AlteWerteLesen: DP: javascript.0.Verbrauch.StromGesamt.ZaehlerstandOffiziell 14:49:52.686 info javascript.0 (15862) script.js.Programmieren.Influx.AlteWerteLesen: Start: 1657111792686 End: 1657198192686 14:49:52.687 info javascript.0 (15862) script.js.Programmieren.Influx.AlteWerteLesen: Strom gestern: 0 14:49:52.687 info javascript.0 (15862) script.js.Programmieren.Influx.AlteWerteLesen: registered 0 subscriptions and 0 schedules 14:49:52.712 info javascript.0 (15862) script.js.Programmieren.Influx.AlteWerteLesen: Ergebnis = 105244.6493 14:49:52.714 info javascript.0 (15862) script.js.Programmieren.Influx.AlteWerteLesen: RR: [object Object]
Wie liest man einen Influx Datensatz in einer Funktion aus? Ich vermute irgendwas mit sync/async/await.
-
@wolfgangfb sagte in Influx Datensatz in Funktion lesen:
Ich vermute irgendwas mit sync/async/await.
Richtig. Du musst mit Promises arbeiten. z.B.
async function readInflux(objId, nbDays) { return new Promise((resolve, reject) => { var end = new Date().getTime(); var start = end - nbDays * 1000 * 24 * 60 * 60; console.log(`Start: ${start}, End: ${end}`); sendTo('influxdb.0', 'getHistory', { id: objId, options: { start: start, end: end, count: 1, aggregate: 'none' } }, (SendToResult) => { console.log(`RR: ${JSON.stringify(SendToResult)}`); if (SendToResult.result.length > 0) { resolve(SendToResult.result[0].val); } else { reject('Received empty result'); } }); }); }
Dann so nutzen:
readInflux('yr.0.forecastHourly.0h.air_temperature', 2) .then(ergebnis => { console.log(`Ergebnis: ${ergebnis}`); }) .catch(err => { console.error(err); });
oder mit await (+ try/catch), wenn Du innerhalb einer asynchronen Funktion bist:
const ergebnis = await readInflux('yr.0.forecastHourly.0h.air_temperature', 2);
-
Hallo
Erstmal vielen Dank für die Hilfe, es funktioniert soweit, nur verstehe ich das ganze noch nicht.
Mir ist schon klar, dass wenn ich das ganze in eine Schleife packe, das Ergebnis leer ist (ich verstehe das so, dass mit der Ausgabe eben nicht gewartet wird, bis die readInflux Funktion etwas zurückliefert.
var DP = []; var Methode1 = []; var Methode2 = []; DP.push('alias.0.Raum.Arbeit.Temperatur.0.temperature'); DP.push("alias.0.Raum.Kueche.Temperatur.0.temperature"); for (var i=0; i< DP.length; i++){ readInflux(DP[i], 5) .then(ergebnis => { console.log(`Ergebnis: ${ergebnis}`); Methode1.push(ergebnis); }) .catch(err => { console.error(err); }); } console.log("Methode1=" + Methode1); console.log("Methode2=" + Methode2);
liefert
14:19:56.147 info javascript.0 (8944) script.js.Programmieren.Influx.InfluxPromises: Methode1= 14:19:56.147 info javascript.0 (8944) script.js.Programmieren.Influx.InfluxPromises: Methode2= 14:19:56.147 info javascript.0 (8944) script.js.Programmieren.Influx.InfluxPromises: registered 0 subscriptions and 0 schedules 14:19:56.165 info javascript.0 (8944) script.js.Programmieren.Influx.InfluxPromises: RR: {"result":[{"ack":true,"from":"system.adapter.esphome.0","q":0,"val":21.3,"ts":1657283000207}],"step":0,"error":null} 14:19:56.166 info javascript.0 (8944) script.js.Programmieren.Influx.InfluxPromises: Ergebnis: 21.3 14:19:56.168 info javascript.0 (8944) script.js.Programmieren.Influx.InfluxPromises: RR: {"result":[{"ack":true,"from":"system.adapter.zigbee.0","q":0,"val":23.2,"ts":1657296597286}],"step":0,"error":null} 14:19:56.168 info javascript.0 (8944) script.js.Programmieren.Influx.InfluxPromises: Ergebnis: 23.2
was ich aber nicht erstehe ist, dass wenn ich Methode2 einfüge am Ende auch Methode1 mit den richtigen Werten gesetzt ist.
for (var i=0; i< DP.length; i++){ readInflux(DP[i], 5) .then(ergebnis => { console.log(`Ergebnis: ${ergebnis}`); Methode1.push(ergebnis); }) .catch(err => { console.error(err); }); Methode2.push(await readInflux(DP[i], 5)); }
liefert manchmal
14:22:14.483 info javascript.0 (8944) script.js.Programmieren.Influx.InfluxPromises: Methode1=21.3 14:22:14.484 info javascript.0 (8944) script.js.Programmieren.Influx.InfluxPromises: Methode2=21.3,23.2
aber manchmal auch:
14:23:08.207 info javascript.0 (8944) script.js.Programmieren.Influx.InfluxPromises: Methode1=21.3,23.2 14:23:08.207 info javascript.0 (8944) script.js.Programmieren.Influx.InfluxPromises: Methode2=21.3,23.2
Heißt das, dass Methode 1 auf jeden Fall auch abgearbeitet wird, aber manchmal eben zum Zeitpunkt der Ausgabe noch nicht fertig ist?
Dann fällt mir noch auf, dass "await"rot unterkringelt ist (Fehler), das ganze aber funktioniert. Warum wird await markiert? Als Hinweis bekomme ich:
'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.(1375)
damit kann ich aber ehrlich gesagt nichts anfangen.
-
@wolfgangfb sagte in Influx Datensatz in Funktion lesen:
Heißt das, dass Methode 1 auf jeden Fall auch abgearbeitet wird, aber manchmal eben zum Zeitpunkt der Ausgabe noch nicht fertig ist?
Dann fällt mir noch auf, dass "await"rot unterkringelt ist (Fehler), das ganze aber funktioniert. Warum wird await markiert? Als Hinweis bekomme ich:Naja logisch, auf die erste Ausführung wartest Du ja auch nicht (mit await). Ich kann hier jetzt keine JavaScript-Grundlagen erklären. Stichworte für Google für dich sind
Promise, then/catch resolve/reject, await/async, try/catch
.Ich habe Dir zwei verschiedene Varianten aufgezeigt. Einmal mit then und einmal mit await. Es kommt auf den Context an, in welchem Du dich bewegst. await kannst Du nur in asynchronen Funktionen verwenden.
Methode1 wird asynchron ausgeführt. Ob alles danach schneller oder langsamer ist, ist reiner Zufall. Daher wäre für dich wahrscheinlich await besser (falls eine async function drumrum ist).
var Methode2 = []; for (var i = 0; i < DP.length; i++) { try { Methode2.push(await readInflux(DP[i], 5)); } catch (err) { console.log(err); } }
Da das bei dir aber nicht der Fall sein wird (steht da ja -> await nicht auf top level), kannst Du auch eine anonyme Funktion definieren, welche sofort ausgeführt wird:
(async () => { var Methode2 = []; for (var i = 0; i < DP.length; i++) { try { Methode2.push(await readInflux(DP[i], 5)); } catch (err) { console.log(err); } } })();
Da man das meiste aber eh innerhalb von Triggern machen wird, kann man die Callbacks einfach asynchron definieren. z.B.
schedule('0 0 * * *', async () => { var Methode2 = []; for (var i = 0; i < DP.length; i++) { try { Methode2.push(await readInflux(DP[i], 5)); } catch (err) { console.log(err); } } });