NEWS
Skript, JSON und mein Problem
-
Hallo zusammen,
bin gerade dabei so etwas zu Realisieren:
Detailansicht Jahr: Im Oberen Fenster werden die Monate des ausgewählten Jahres Dargestellt
Detailansicht Monat: Im unteren Fenster werden die Tage des ausgewählten Monats dargestellt, oder ausgeblendet
Hier ein Skript das alle Monate, die in Influx gespeichert sind, ausliest und als JSON speichern soll.
const INFLUXDB_INSTANZ='0'; const WET_DP='javascript.0.Wetterstation'; let result = [], temps = [], wind = [], regen = []; let Tiefstwert, Hoechstwert, Temp_Durchschnitt, Max_Windboe, Max_Regenmenge; let tage = []; let monat = []; let y = 0; function main() { for (let tag = 1; tag < 32; tag ++) { let start = Date.parse(tag + ' Oct 2021 00:00:00 GMT'); let end = Date.parse(tag + ' Oct 2021 23:59:59 GMT'); result = []; temps = []; wind = []; regen = []; sendTo('influxdb.'+INFLUXDB_INSTANZ, 'query', 'select * FROM "' + WET_DP + '.Aussentemperatur" WHERE time >= ' + (start *1000000) + ' AND time <= ' + (end *1000000) + '; select * FROM "' + WET_DP + '.Wind_max" WHERE time >= ' + (start *1000000) + ' AND time <= ' + (end *1000000) + '; select * FROM "' + WET_DP + '.Regen_Tag" WHERE time >= ' + (start *1000000) + ' AND time <= ' + (end *1000000) , function (result) { //Anlegen der Arrays + befüllen mit den relevanten Daten if (result.error) { console.error('Fehler beim Lesen der InfluxDB: '+result.error); } else { //log('Rows: ' + JSON.stringify(result.result[0])); for (let i = 0; i < result.result[0].length; i++) { temps[i] = result.result[0][i].value; } for (let i = 0; i < result.result[1].length; i++) { wind[i] = result.result[1][i].value; } for (let i = 0; i < result.result[2].length; i++) { regen[i] = result.result[2][i].value; } } //Temperaturen Tiefstwert = Math.min(...temps); Hoechstwert = Math.max(...temps); Math.sum = (...temps) => Array.prototype.reduce.call(temps,(a,b) => a+b); Temp_Durchschnitt = Number((Math.sum(...temps)/temps.length).toFixed(2)); Max_Windboe = Math.max(...wind); Max_Regenmenge = Math.max(...regen); tage[y] = {}; tage[y].Tiefstwert = Tiefstwert.toFixed(2); tage[y].Hoechstwert = Hoechstwert.toFixed(2); tage[y].Durchschnitt = Temp_Durchschnitt; tage[y].Max_Windboe = Max_Windboe.toFixed(2); tage[y].Regenmenge = Max_Regenmenge.toFixed(2); y++; log(tage) }); //sendto }; // for monat.push(JSON.stringify(tage)); log('monat: ' + monat); //log('monat: ' + monat); };// function main();
Das Skript ist aus dem Wetterstatistik-Skript von SBorg, und umgebaut.
Aber jetzt stehe ich voll auf dem Schlauch:Die Variablen die ausserhalb der Function deklariert werden sind doch im dem Skript überall verfügbar, oder?
z.B: tage[] darauf müßte ich doch innerhalb der Funktion Main überall drauf zugreifen können?
Weil, wenn ich y nach "}); //sendto" erhöhe, funktioniert es nicht, genauso kann ich nach "}; // for" nicht auf tage[] zugreifen.Denke ich da komplett falsch?
Es soll so sein, nach "}; // for" will ich tage[] in einen Datenpunkt als Json schreiben "setState('datenpunkt', JSON.stringify(tage), true);".
Bitte um Hilfe!!!
MfG
Wastl -
warum willst du das ergebnisobjekt von influx nochmal transformieren?
das ist ja schon ein javascriptobjekt.
evtl kannst du das sql so anpassen, das dir influx schon die entsprechenden berechnungen inklusive aggregieren (max,min,average-werte), gruppieren (nach monaten und jahren ) berechnet. dann musst du das nur noch in eine tabelle eintragen (json-table oder json-template mit genauerer ausgabekontrolle)https://influxdbcom.readthedocs.io/en/latest/content/docs/v0.6/api/aggregate_functions/
du kannst sogar mehrere abfragen hintereinander stapeln (UNION), so das ein aus mehreren SQL-Befehlen ein gemeinsames Objekt erstellt wird (also eine Abfrage mit Temp Min, eine mit Temp-Max eine mit Temp-Avg usw.
Dann hast du direkt dein Ergebnisobjekt ohne groß mit javascript noch was zu machen. -
Hallo,
Callbackfunktion laufen nicht sychron zum Rest den Skripts. Dein Skript läuft so ab
function main() { //1 for (let tag = 1; tag < 32; tag ++) { //2 sendTo('influxdb.'+INFLUXDB_INSTANZ, 'query', , function (result) { //5 }); //sendto //3 }; // for //4 monat.push(JSON.stringify(tage)); };// function main();
beheben kannst du das Problem in dem du folgendes (das den Code aus //4 enthält) in deinen Sendto Callback ans ende setzt (variable bitte an den Anfang des Skripts)
var timeout = null; // in sendto if (timeout) clearTimeout() timeout = setTimeout(function(){ monat.push(JSON.stringify(tage)); log('monat: ' + monat); }),3000; }); //sendto
Das ist nix anderes als ein Timer über 3 Sekunden der bei jedem Durchlauf von Sendto zurück gesetzt wird. Kann jedoch passieren, das du mit den Tagen durcheinander kommst, da du dich nicht 100% darauf verlassen solltest, das deine Anfragen sychron bearbeitet werden.
-
Danke für Deine schnelle Antwort.
Ich habe Deinen Vorschlag mal eingebaut, hoffe es ist so richtig:
const INFLUXDB_INSTANZ='0'; const WET_DP='javascript.0.Wetterstation'; let result = [], temps = [], wind = [], regen = []; let Tiefstwert, Hoechstwert, Temp_Durchschnitt, Max_Windboe, Max_Regenmenge; let tage = []; let monat = []; let y = 0; let json = "["; var timeout = null; function main() { for (let tag = 1; tag < 32; tag ++) { let start = Date.parse(tag + ' Oct 2021 00:00:00 '); let end = Date.parse(tag + ' Oct 2021 23:59:59 '); result = []; temps = []; wind = []; regen = []; sendTo('influxdb.'+INFLUXDB_INSTANZ, 'query', 'select * FROM "' + WET_DP + '.Aussentemperatur" WHERE time >= ' + (start *1000000) + ' AND time <= ' + (end *1000000) + '; select * FROM "' + WET_DP + '.Wind_max" WHERE time >= ' + (start *1000000) + ' AND time <= ' + (end *1000000) + '; select * FROM "' + WET_DP + '.Regen_Tag" WHERE time >= ' + (start *1000000) + ' AND time <= ' + (end *1000000) , function (result) { //Anlegen der Arrays + befüllen mit den relevanten Daten if (result.error) { console.error('Fehler beim Lesen der InfluxDB: '+result.error); } else { //log('Rows: ' + JSON.stringify(result.result[0])); for (let i = 0; i < result.result[0].length; i++) { temps[i] = result.result[0][i].value; } for (let i = 0; i < result.result[1].length; i++) { wind[i] = result.result[1][i].value; } for (let i = 0; i < result.result[2].length; i++) { regen[i] = result.result[2][i].value; } }; //Temperaturen Tiefstwert = Math.min(...temps); Hoechstwert = Math.max(...temps); Math.sum = (...temps) => Array.prototype.reduce.call(temps,(a,b) => a+b); Temp_Durchschnitt = Number((Math.sum(...temps)/temps.length).toFixed(2)); Max_Windboe = Math.max(...wind); Max_Regenmenge = Math.max(...regen); if (timeout) clearTimeout() timeout = setTimeout(function() { json = json + JSON.stringify({"Tiefstwert": Tiefstwert.toString(), "Hoechstwert": Hoechstwert.toString(), "Durchschnitt": Temp_Durchschnitt.toString(), "Max_Windboe": Max_Windboe.toString(), "Regenmenge": Max_Regenmenge.toString()}); if (tag < 31) { json = json + ","; } else { json = json + "]"; log(json) //setState('0_userdata.0.Tabellen.WetterStatistik.2021.Oktober', json, true); }; }),3000; });//sendto }; // for };// function main(); function clearTimeout() {timeout = null};
Ergebnis:
[ {"Tiefstwert":"0.5","Hoechstwert":"18.88","Durchschnitt":"9.73","Max_Windboe":"11.1","Regenmenge":"-Infinity"},{"Tiefstwert":"4.27","Hoechstwert":"20.61","Durchschnitt":"11.91","Max_Windboe":"14.8","Regenmenge":"-Infinity"},{"Tiefstwert":"6.38","Hoechstwert":"20.5","Durchschnitt":"11.76","Max_Windboe":"11.1","Regenmenge":"9.1"},{"Tiefstwert":"7.27","Hoechstwert":"20.5","Durchschnitt":"12.54","Max_Windboe":"11.1","Regenmenge":"3.3"},{"Tiefstwert":"3.38","Hoechstwert":"20.5","Durchschnitt":"10.31","Max_Windboe":"20.11","Regenmenge":"3.3"}, {"Tiefstwert":"-1.11","Hoechstwert":"20.5","Durchschnitt":"9.27","Max_Windboe":"20.11","Regenmenge":"9.1"}, {"Tiefstwert":"-0.72","Hoechstwert":"19.38","Durchschnitt":"6.38","Max_Windboe":"16.57","Regenmenge":"9.1"}, {"Tiefstwert":"-2.27","Hoechstwert":"18.61","Durchschnitt":"6.68","Max_Windboe":"16.57","Regenmenge":"9.1"}, {"Tiefstwert":"-2.27","Hoechstwert":"18.61","Durchschnitt":"7.32","Max_Windboe":"16.57","Regenmenge":"9.1"}, {"Tiefstwert":"-4.5","Hoechstwert":"13.88","Durchschnitt":"4.12","Max_Windboe":"16.57","Regenmenge":"9.1"}, {"Tiefstwert":"-3","Hoechstwert":"18.38","Durchschnitt":"5.11","Max_Windboe":"20.11","Regenmenge":"9.1"}, {"Tiefstwert":"-2.27","Hoechstwert":"12.61","Durchschnitt":"4.23","Max_Windboe":"16.57","Regenmenge":"9.1"}, {"Tiefstwert":"-0.27","Hoechstwert":"14.27","Durchschnitt":"8.81","Max_Windboe":"47.96","Regenmenge":"9.1"}, {"Tiefstwert":"-2.72","Hoechstwert":"13.5","Durchschnitt":"5.15","Max_Windboe":"47.96","Regenmenge":"9.1"},{"Tiefstwert":"0","Hoechstwert":"20.77","Durchschnitt":"12.31","Max_Windboe":"23.81","Regenmenge":"9.1"}, {"Tiefstwert":"0","Hoechstwert":"11.72","Durchschnitt":"6.27","Max_Windboe":"21.88","Regenmenge":"9.1"}, {"Tiefstwert":"0","Hoechstwert":"13.61","Durchschnitt":"6.45","Max_Windboe":"14.8","Regenmenge":"9.1"}, {"Tiefstwert":"-2.38","Hoechstwert":"15.72","Durchschnitt":"5.5","Max_Windboe":"14.8","Regenmenge":"9.1"}, {"Tiefstwert":"-1.27","Hoechstwert":"13.38","Durchschnitt":"4.59","Max_Windboe":"14.8","Regenmenge":"9.1"},{"Tiefstwert":"0.11","Hoechstwert":"15.22","Durchschnitt":"7.98","Max_Windboe":"14.8","Regenmenge":"9.1"}, {"Tiefstwert":"-3.61","Hoechstwert":"11.77","Durchschnitt":"3.16","Max_Windboe":"14.8","Regenmenge":"9.1"},{"Tiefstwert":"0.11","Hoechstwert":"11.77","Durchschnitt":"6.81","Max_Windboe":"14.8","Regenmenge":"10.2"}, {"Tiefstwert":"-2.11","Hoechstwert":"12.38","Durchschnitt":"4.55","Max_Windboe":"14.8","Regenmenge":"10.2"},{"Tiefstwert":"0.11","Hoechstwert":"12.38","Durchschnitt":"6.36","Max_Windboe":"14.8","Regenmenge":"12.7"}, {"Tiefstwert":"-0.22","Hoechstwert":"14.38","Durchschnitt":"6.24","Max_Windboe":"14.8","Regenmenge":"12.7"}, {"Tiefstwert":"-0.22","Hoechstwert":"14.38","Durchschnitt":"6.24","Max_Windboe":"14.8","Regenmenge":"12.7"}, {"Tiefstwert":"-0.22","Hoechstwert":"15.5","Durchschnitt":"7.34","Max_Windboe":"14.8","Regenmenge":"12.7"},{"Tiefstwert":"2.38","Hoechstwert":"20.5","Durchschnitt":"9.65","Max_Windboe":"14.8","Regenmenge":"12.7"} ]
Es ist ein funktionierender JSON, aber:
- Es sind nicht 31 Tage sondern nur 25 Tage
- Viele Werte wieder holen sich z.B. Max_Windböe am Ende 8 x der gleiche Wert.
Wenn ich mir das in Grafana anschaue stimmen die Werte hier nicht.
Auch dafür eine Idee?
Vielen Dank im voraus
MfG
Wastl -
Danke für die schnelle Antwort.
Ich bin ganz am Anfang mit InfluxDB, JavaScript oder einfacher Ausgedrückt, mit allem.
Des weiteren habe ich oben im Text einen Fehler, ich möchte alle Tage eines Monats, einzeln auslesen und die Min, Max usw. in einen JSON schreiben. Ich weiß nicht, ob das einen Einfluss auf Deinen Vorschlag hat?
Wenn Du mir da einen Tip geben kannst, immer her damit.
MfG
Wastl -
@langer
Das ist falsch.Ich versuche mal eine Erklärung in deinem ursprünglichen Skript gibts du der DB 31 mal den Auftrag Werte zu ermitteln und in einem Array zu sichern. Jedoch bearbeitest du das Array lange bevor die DB Zeit hatte das Array überhaupt zu beschreiben.
Im 2. Versuch sicherst du die Werte erst nach 3 Sekunden was falsch ist. Da nachfolgenden Durchläufen den Timer beenden und dann keine Werte gesichert werden. Nimm das Skript vom Anfang und füge meine Code dort ein, wo ich beschrieben haben.
die Lösung ist: Du beschreibst das Tage Array wie in deinem ersten Versuch. Jedoch nutzt du den Timeout wie ich in dir gezeigt habe um das komplette Tage Array als Json zu sichern. Wenn das nicht vollständig ist, erhöhst du die 3000 (das steht für 3 Sekunden)