NEWS
Blockly - Mit getHistory Daten aus InfluxDB auslesen
-
@hant0r sagte in Blockly - Mit getHistory Daten aus InfluxDB auslesen:
sende die Daten über ein Javascript in die Datenbank
der Block spricht aber die ioBroker Datenbank Adapter an.
Was nicht darüber rein geht, bekommst du darüber auch nicht raus. -
@homoran Ah ok, schade
Bekommt man auf anderem Wege an Daten auf ner influxdb?
-
@hant0r probiere bitte mal dieses Script, ist aber eventuell noch nicht fix. poste mal die Log Ausgabe
const InfluxInstance = 'influxdb.0'; const ende = new Date() const endeiso = ende.toISOString(); const start = new Date().setHours(0, 0, 0); const test = new Date (start); const testiso = test.toISOString(); function Abfrage() { let query = [ 'from(bucket: "smarthome")', '|> range(start: ' + testiso + ', stop: ' + endeiso + ')', '|> filter(fn: (r) => r._measurement == "energy")', '|> filter(fn: (r) => r._field == "exportedWh")', '|> difference()', '|> sum()', '|> yield(name: "_result")'].join(''); console.log('Query: ' + query); sendTo(InfluxInstance, 'query', query, function (result) { if (result.error) { console.error('Fehler: ' + result.error); } else { // show result console.log(result) for (let r = 0; r < result.result.length; r++) { for (let i = 0; i < result.result[r].length; i++) { let value = result.result[r][i]._value; console.log(' Ergebnis ' + value ) } } }); }; Abfrage();
-
@tt-tom
vielen lieben Dank ...es fehlte am Ende zwar noch eine geschweifte Klammer, danach bekam ich aber das gewünschte Ergebnis. -
Okay, sag mal wo dann kann ich den Post nochmal anpassen.
-
@tt-tom unten beim Else Zweig.
So wäre es korrekt:const InfluxInstance = 'influxdb.0'; const ende = new Date() const endeiso = ende.toISOString(); const start = new Date().setHours(0, 0, 0); const test = new Date (start); const testiso = test.toISOString(); function Abfrage() { let query = [ 'from(bucket: "smarthome")', '|> range(start: ' + testiso + ', stop: ' + endeiso + ')', '|> filter(fn: (r) => r._measurement == "energy")', '|> filter(fn: (r) => r._field == "exportedWh")', '|> difference()', '|> sum()', '|> yield(name: "_result")'].join(''); console.log('Query: ' + query); sendTo(InfluxInstance, 'query', query, function (result) { if (result.error) { console.error('Fehler: ' + result.error); } else { // show result console.log(result) for (let r = 0; r < result.result.length; r++) { for (let i = 0; i < result.result[r].length; i++) { let value = result.result[r][i]._value; console.log(' Ergebnis ' + value ) } } } }); }; Abfrage();
-
@hant0r sagte in Blockly - Mit getHistory Daten aus InfluxDB auslesen:
Leider komme ich nicht dahinter, wie dieser Baustein funktioniert.
Der Baustein bietet nur die Standard getHistory-Funktionen und ist nur ein erster Wurf. Der kann bei weitem nicht alles, was Flux kann, weil er eben auch mit dem History-Adapter und SQL-Adapter arbeiten muss. Die Schnittstelle ist also sehr generisch und die darunter liegenden Adapter machen aus der Anfrage dann SQL, Flux, InfluxQL oder was auch immer nötig ist.
Für sehr spezielle Anfragen ist es also nach wie vor besser
query
zu nutzen (wie vorgeschlagen). Der Vollständigkeit halber noch die Doku: https://github.com/ioBroker/ioBroker.influxdb#custom-queries -
Ich versuche gerade das Skript als Blockly-Baustein laufen zu lassen und einen return zu bekommen.
Könnt ihr mir sagen, wo der Fehler ist, dass ich den Wert nicht zurück bekomme?const InfluxInstance = 'influxdb.0'; const ende = new Date() const endeiso = ende.toISOString(); const start = new Date().setHours(0, 0, 0); const test = new Date (start); const testiso = test.toISOString(); let value = 0; let query = [ 'from(bucket: "smarthome")', '|> range(start: ' + testiso + ', stop: ' + endeiso + ')', '|> filter(fn: (r) => r._measurement == "energy")', '|> filter(fn: (r) => r._field == "exportedWh")', '|> difference()', '|> sum()', '|> yield(name: "_result")'].join(''); sendTo(InfluxInstance, 'query', query, function (result) { if (result.error) { console.error('Fehler: ' + result.error); } else { // show result //console.log(result) for (let r = 0; r < result.result.length; r++) { for (let i = 0; i < result.result[r].length; i++) { value = result.result[r][i]._value; //console.log(' Ergebnis ' + value ) } } } }); return value;
-
@hant0r Das wird nicht gehen, weil der Callback später ausgeführt wird. Eventuell könntest Du das mit einem Promise lösen. Ich glaube alle Funktionen werden mit
await
aufgerufen. Dann sollte das gehen. Aber nie getestet:return new Promise((resolve, reject) => { const InfluxInstance = 'influxdb.0'; const ende = new Date() const endeiso = ende.toISOString(); const start = new Date().setHours(0, 0, 0); const test = new Date (start); const testiso = test.toISOString(); let value = 0; let query = [ 'from(bucket: "smarthome")', '|> range(start: ' + testiso + ', stop: ' + endeiso + ')', '|> filter(fn: (r) => r._measurement == "energy")', '|> filter(fn: (r) => r._field == "exportedWh")', '|> difference()', '|> sum()', '|> yield(name: "_result")'].join(''); sendTo(InfluxInstance, 'query', query, function (result) { if (result.error) { reject(result.error); } else { for (let r = 0; r < result.result.length; r++) { for (let i = 0; i < result.result[r].length; i++) { value = result.result[r][i]._value; } } resolve(value); } }); });
Das mit den 2 For-Schleifen ist so aber nicht der Hit - das würde ich noch ändern.
Stichworte für Google sind:
- async / await
- Promises
- Promise vs. callback
-
@haus-automatisierung
klasse danke dir - klappt
Da habe ich noch einiges zu lernen wenn ich sehe wie schnell ihr hier antworten auf die "Probleme" habt -
@hant0r sagte in Blockly - Mit getHistory Daten aus InfluxDB auslesen:
Da habe ich noch einiges zu lernen
Naja, in der JavaScript-Programmierung direkt mit asynchronen Logiken anzufangen ist eventuell auch ein paar Schritte zu weit.
Wichtig wäre in Deinem Beispiel erstmal zu verstehen, dass Du eine Funktion als Parameter an sendTo übergibst und dass das nicht nacheinander abgearbeitet wird. Alternativ hätte man mit
sendToAsync
undawait
arbeiten können. Aber das geht gerade zu weit -
Moin zusammen,
ich würde das Thema gerne nochmal kurz aufgreifen.
Ich versuche mit dem getHistory-Block Daten aus der normalen History auszulesen.
Allerdings fällt es mir schwer die Ausgabe zu parsen. Hat da vielleicht nochmal jemand ein Beispiel für, wie das mit Blockly geht?
Wie bekomme zum Beispiel den ersten und den letzten Wert aus dem Ergebnis?Ich habe mir folgenden Forum-Beitrag dazu angesehen:
https://forum.iobroker.net/topic/5978/json-in-blockly-parsen/9Aber da ich irgendwie keine "Objekt-Namen" habe, weiß ich nicht wie ich anders an den Index des jeweiligen Objekts komme.
[{'val':19449.052,'ts':1695247278863},{'val':19449.06,'ts':1695248178856},{'val':19449.068,'ts':1695249078870},{'val':19449.076,'ts':1695249998821},{'val':19449.084000000003,'ts':1695250888829},{'val':19449.092,'ts':1695251788894},{'val':19449.1,'ts':1695252678869},{'val':19449.107,'ts':1695253568871},{'val':19449.115,'ts':1695254498882},{'val':19449.129,'ts':1695255388912},{'val':19449.137000000002,'ts':1695256288903},{'val':19449.144,'ts':1695257178918},{'val':19449.152000000002,'ts':1695258078937},{'val':19449.17,'ts':1695258978931},{'val':19449.18,'ts':1695259898917},{'val':19449.188000000002,'ts':1695260798945},{'val':19449.195,'ts':1695261688969},{'val':19449.203,'ts':1695262588974},{'val':19449.214,'ts':1695263488995},{'val':19449.225,'ts':1695264389017},{'val':19449.399,'ts':1695265278973},{'val':19449.541,'ts':1695266178985},{'val':19449.686999999998,'ts':1695267099060},{'val':19449.876,'ts':1695267988996},{'val':19450.09,'ts':1695268889020},{'val':19450.402000000002,'ts':1695269779062},{'val':19450.726000000002,'ts':1695270699066},{'val':19450.762000000002,'ts':1695270709103},{'val':19451.263,'ts':1695271609127},{'val':19451.698,'ts':1695272499091},{'val':19452.165,'ts':1695273399103},{'val':19452.747,'ts':1695274309109},{'val':19453.234,'ts':1695275209095},{'val':19453.654000000002,'ts':1695276099151},{'val':19454.012000000002,'ts':1695276999160},{'val':19454.458,'ts':1695277899183},{'val':19454.801,'ts':1695278789152},{'val':19455.179,'ts':1695279709191},{'val':19455.659,'ts':1695280609216},{'val':19456.067000000003,'ts':1695281509247},{'val':19456.527000000002,'ts':1695282399224},{'val':19456.970999999998,'ts':1695283299199},{'val':19457.487,'ts':1695284209236},{'val':19457.968,'ts':1695285109236},{'val':19458.484,'ts':1695286009221},{'val':19458.974000000002,'ts':1695286899247},{'val':19459.372,'ts':1695287799267},{'val':19459.756,'ts':1695288689291},{'val':19460.190000000002,'ts':1695289609233},{'val':19460.631,'ts':1695290499339},{'val':19461.017,'ts':1695291389319},{'val':19461.481,'ts':1695292309347},{'val':19461.953999999998,'ts':1695293199288},{'val':19462.305,'ts':1695294099288},{'val':19462.652000000002,'ts':1695294989363},{'val':19462.983,'ts':1695295909379},{'val':19463.333,'ts':1695296809334},{'val':19463.747,'ts':1695297699333},{'val':19464.191,'ts':1695298599357},{'val':19464.581,'ts':1695299489419},{'val':19464.957000000002,'ts':1695300409387},{'val':19465.397,'ts':1695301299455},{'val':19465.764000000003,'ts':1695302199403},{'val':19466.135000000002,'ts':1695303089419}]
Wäre über eine kurze Hilfestellung froh
Danke und Gruß!
-
@yunkie Ich habe das gleiche Problem bzw. ein Verständnisproblem mit dem neuen Block "getHistory".
Parsen aus einem Text ginge - wenn ich denn einen Text bekommen würde...Mein Testskript:
09:34:45.644 info javascript.0 (589275) Stop script script.js.99_TEST.Test_Kueche 09:34:45.698 info javascript.0 (589275) Start javascript script.js.99_TEST.Test_Kueche 09:34:45.729 info javascript.0 (589275) script.js.99_TEST.Test_Kueche: Plain ausserhalb: 09:34:45.730 info javascript.0 (589275) script.js.99_TEST.Test_Kueche: undefined 09:34:45.733 info javascript.0 (589275) script.js.99_TEST.Test_Kueche: | Ausserhalb des Blocks: undefined 09:34:45.733 info javascript.0 (589275) script.js.99_TEST.Test_Kueche: registered 0 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions 09:34:45.747 info javascript.0 (589275) script.js.99_TEST.Test_Kueche: Plain: 09:34:45.748 info javascript.0 (589275) script.js.99_TEST.Test_Kueche: [{'val':null,'ts':1695452205337},{'val':true,'ts':1695452325439},{'val':false,'ts':1695452326548},{'val':true,'ts':1695452541572},{'val':false,'ts':1695452549833},{'val':true,'ts':1695453778238},{'val':false,'ts':1695453780078},{'val':true,'ts':1695454483574},{'val':false,'ts':1695454484386}] 09:34:45.748 info javascript.0 (589275) script.js.99_TEST.Test_Kueche: | Als Text im Block: [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Komischerweise bekomme ich "result" nur was angezeigt, wenn ich es direkt an "debug" IM GETHISTORY Block ran hänge.
Warum kann ich das als Text nicht verarbeiten? Zusätzlich "Nach String" funktioniert ebenfalls nicht.
Wie bekomme ich "result" außerhalb des Blocks bzw. in eine Variable übergeben?
Gibt es eine andere Möglichkeit in Blockly zu prüfen, ob ein State innerhalb eines definierten Zeitraums "true" war?
Hintergrund: Triggern auf "true" funktioniert in meinem Fall nicht, da der Zustand "trze" nur wenige ms beträgt, allerdings wird "true" in History richtig geloggt.
Danke und Gruß,
Tobias.Nachtrag:
Es muss nach dem getHistroy mindestens 1 Sekunde Pause eingebaut werden... Das Skript wartet sonst nicht auf das Ergebnis von getHistory... -
@tobias78 sagte in Blockly - Mit getHistory Daten aus InfluxDB auslesen:
Komischerweise bekomme ich "result" nur was angezeigt, wenn ich es direkt an "debug" IM GETHISTORY Block ran hänge.
Ja, so funktionieren alle sendTo Funktionen (mit Callback). Sonst als JavaScript mit Promise implementieren.
Nachtrag:
Es muss nach dem getHistroy mindestens 1 Sekunde Pause eingebaut werden... Das Skript wartet sonst nicht auf das Ergebnis von getHistory...Das ist eine ziemlich unschöne Lösung und basiert auf Zufall ob das klappt oder nicht
-
@yunkie Ich hoffe, du hast dein Problem inzwischen lösen können. Falls nicht (und für alle anderen, die diesen Thread finden): Das ist kein json, sondern Attribute von Objekten in einer Liste. Man muss daher auch nichts parsen, sondern kann in Blockly direkt damit arbeiten:
Eigentlich total logisch und einfach (nachdem ich erstmal über die "ungültige JSON Syntax" geflucht hatte...).
-
@tobi55222 Danke dafür, das hat mir die Tage sehr geholfen.
Kann es sein das wenn man einen zu großen Zeitabschnitt auswerten will das ganze dann nicht mehr funktioniert?
Ich wollte die Werte vom letzten Jahr mal rausziehen und addieren aber da sind scheinbar zuviel Daten hintendran.
Wenn ich monatlich auswerte stimmt die Debug Ausgabe, meine Idee war das dann in kleinere Abschnitte aufzuteilen und in einer Schleife durchzugehen. Das kommt aber scheinbar auch durcheinander weil die Funktion ja irgendwie mit Callbacks arbeitet.
Gibts da nen Trick um auf den getHistory Baustein passend zu warten? (Am besten per Blocky )
-
Also so richtig werde ich nicht schlau mit dem getHistory, ich dachte wenn im else Zweig zum Schluss etwas steht wird dieser erst aufgerufen wenn der Callback kommt? Aber der wird immer ausgeführt auch wenn eigl noch gewartet werden soll.
getHistory({ id: 'ID auswählen', start: /* start of day */ (() => { const d = new Date(); d.setHours(0, 0, 0, 0); return d.getTime(); })(), end: /* end of day */ (() => { const d = new Date(); d.setHours(23, 59, 59, 999); return d.getTime(); })(), aggregate: 'none', removeBorderValues: true, }, async (err, result) => { if (err) { console.error(err); } else { ???Hier wird nur ausgeführt beim Callback??? } });
Wie kann dieser Baustein je Sinn in Blockly machen? In anderen Threats sind da noch awaits reingefummelt aber dann ists ja kein Blockly mehr.