NEWS
Gleitender Durchschnitt, Min., Max. über def. Zeitraum
-
@passuff sagte:
In der Datenauswertung werden in allem mir bekannten Tools nur die Anzahl der Samples definiert.
Wenn man die Zykluszeit kennt, ist das auch kein Problem (Kopf- oder Taschenrechner).
-
@sigi234 sagte:
Habe den DP Statisic Json
Der enthält nur die Datenpunkt-IDs und die Temperatur-Listen. Die berechneten Werte sind nicht enthalten.
-
@paul53 sagte in Gleitender Durchschnitt, Min., Max. über def. Zeitraum:
@sigi234 sagte:
Habe den DP Statisic Json
Der enthält nur die Datenpunkt-IDs und die Temperatur-Listen. Die berechneten Werte sind nicht enthalten.
Doch:
[{"value":"javascript.0.Status.Temperatur.Bad","max24h":"javascript.0.Status.Temperatur.Bad.Max_24h","min24h":"javascript.0.Status.Temperatur.Bad.Min_24h","mean24h":"javascript.0.Status.Temperatur.Bad.Mean_24h","median24h":"javascript.0.Status.Temperatur.Bad.Median_24h","max1h":"javascript.0.Status.Temperatur.Bad.Max_1h","min1h":"javascript.0.Status.Temperatur.Bad.Min_1h","mean1h":"javascript.0.Status.Temperatur.Bad.Mean_1h","data":[23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.9,23.9,23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.8,24,24,24,24,24,24,24.1,24,24.1,24.1,24.1,24.2,24.2,24.4,24.6,24.2,24.3,24.4,24.3,24.1,24.1,24.1,24.1,24.1,24.1,24.1,24.2,24.1,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.3,24.3,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.2,24.1,24.2,24.2,24.2,24.2,24.2,24.2,24.1,24.1,24.1,24.1,24.1,24.1,24.1,24.1,24.1,24.1,24,24.1,24.1,24,24,24,24,24,24,24,24,24,24.1,24,24,24,24,24,24,24,24,23.9,24,24,24,23.9,23.9,23.9,23.9,23.9,23.9,23.9,23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.8,23.8]},{"value":"javascript.0.Status.Luftfeuchtigkeit.Bad","max24h":"javascript.0.Status.Luftfeuchtigkeit.Bad.Max_24h","min24h":"javascript.0.Status.Luftfeuchtigkeit.Bad.Min_24h","mean24h":"javascript.0.Status.Luftfeuchtigkeit.Bad.Mean_24h","median24h":"javascript.0.Status.Luftfeuchtigkeit.Bad.Median_24h","max1h":"javascript.0.Status.Luftfeuchtigkeit.Bad.Max_1h","min1h":"javascript.0.Status.Luftfeuchtigkeit.Bad.Min_1h","mean1h":"javascript.0.Status.Luftfeuchtigkeit.Bad.Mean_1h","data":[59,59,59,60,60,60,61,61,61,61,61,61,61,61,61,61,61,61,62,62,62,62,63,63,64,64,64,64,65,65,64,64,64,64,64,65,65,66,67,68,69,70,72,71,74,75,71,64,59,58,58,58,58,58,59,59,59,59,59,60,60,60,60,60,60,60,60,61,61,61,61,61,61,61,61,61,61,60,60,60,60,60,61,61,61,61,61,61,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,62,62,62]},{"value":"javascript.0.Status.Temperatur.Außen","max24h":"javascript.0.Status.Temperatur.Außen.Max_24h","min24h":"javascript.0.Status.Temperatur.Außen.Min_24h","mean24h":"javascript.0.Status.Temperatur.Außen.Mean_24h","median24h":"javascript.0.Status.Temperatur.Außen.Median_24h","max1h":"javascript.0.Status.Temperatur.Außen.Max_1h","min1h":"javascript.0.Status.Temperatur.Außen.Min_1h","mean1h":"javascript.0.Status.Temperatur.Außen.Mean_1h","data":[20,20,20,20,19,19,19,19,19,19,18,18,18,18,18,18,17,17,17,17,17,17,16,16,16,16,16,16,15,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,18,18,18,18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17,17,17,17,17,17,17,17,16,16,16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15]},{"value":"javascript.0.Status.Luftfeuchtigkeit.Außen","max24h":"javascript.0.Status.Luftfeuchtigkeit.Außen.Max_24h","min24h":"javascript.0.Status.Luftfeuchtigkeit.Außen.Min_24h","mean24h":"javascript.0.Status.Luftfeuchtigkeit.Außen.Mean_24h","median24h":"javascript.0.Status.Luftfeuchtigkeit.Außen.Median_24h","max1h":"javascript.0.Status.Luftfeuchtigkeit.Außen.Max_1h","min1h":"javascript.0.Status.Luftfeuchtigkeit.Außen.Min_1h","mean1h":"javascript.0.Status.Luftfeuchtigkeit.Außen.Mean_1h","data":[67,67,67,67,74,74,74,74,74,74,80,80,80,80,80,80,84,84,84,84,84,84,87,87,87,87,87,87,86,82,82,82,82,82,82,79,79,79,79,79,79,76,76,76,76,76,76,72,72,72,72,72,72,68,68,68,68,68,68,66,66,66,66,66,66,69,69,69,69,69,69,73,73,73,73,73,73,78,78,78,78,78,78,81,81,81,81,81,81,75,75,75,75,75,75,72,72,72,72,72,72,75,75,75,75,75,75,81,81,81,81,81,81,86,86,86,86,86,86,88,88,88,88,88,88,89,89,89,89,89,89,89,89,89,89,89,89,90,90,90,90,90,90,90]}]
-
@sigi234 sagte:
Doch:
Nein. Beispiel:
"value":"javascript.0.Status.Luftfeuchtigkeit.Bad",
Bezeichner ist "value", Wert ist "javascript.0.Status.Luftfeuchtigkeit.Bad" (ID).
-
@paul53 sagte in Gleitender Durchschnitt, Min., Max. über def. Zeitraum:
@sigi234 sagte:
Doch:
Nein. Beispiel:
"value":"javascript.0.Status.Luftfeuchtigkeit.Bad",
Bezeichner ist "value", Wert ist "javascript.0.Status.Luftfeuchtigkeit.Bad" (ID).
Ok, was sind dann die Werte nach "data"?
-
@sigi234 sagte:
sind dann die Werte nach "data"?
Das ist die Werte-Liste zum jeweiligen Sensor, aus der die Berechnungen erfolgen.
-
@paul53 sagte in Gleitender Durchschnitt, Min., Max. über def. Zeitraum:
@sigi234 sagte:
sind dann die Werte nach "data"?
Das ist die Werte-Liste zum jeweiligen Sensor, aus der die Berechnungen erfolgen.
Ok, Danke.......werde mir mal eine Vis basteln, DP sind ja da und geht ja auch mit dem History Adapter und Flot.
-
@sigi234
Du kannst mal die erweiterte Funktion testen, die ein JSON mit Werten erzeugen soll. Den Datenpunkt zu idTable musst Du erzeugen und die ID im Skript deklarieren und zuweisen.//Berechnung der Werte function calcStatData() { if (!listStatData || (idData.length != listStatData.length)) { initializeStatData(); } //logDebug('starting calcStatData'); var table = []; for (var i = 0; i < idData.length; i++) { var obj = {}; var sensor = listStatData[i].value.split('.'); obj.Sensor = sensor[4] + ' ' + sensor[3]; listStatData[i].data.pop(); //Remove the last element of an array var x = parseFloat(getState(idData[i][0]).val); obj.Wert = x; listStatData[i].data.unshift(x); //Add new items to the beginning of an array setState(listStatData[i].value, x); var min = x; var max = x; var sum = 0.0; for (var j = 0; j < statDataLength24; j++) { var s = parseFloat(listStatData[i].data[j]); if (s < min) min = s; if (s > max) max = s; sum += s; if (j == (statDataLength1-1)) { setState(listStatData[i].min1h, min); setState(listStatData[i].max1h, max); setState(listStatData[i].mean1h, round(sum / statDataLength1, 2)); } } setState(listStatData[i].min24h, min); setState(listStatData[i].max24h, max); setState(listStatData[i].mean24h, round(sum / statDataLength24, 2)); setState(listStatData[i].median24h, getMedian(listStatData[i].data)); obj.Min_24h = min; obj.Max_24h = max; obj.Mean_24h = round(sum / statDataLength24, 2); obj.Median_24h = getMedian(listStatData[i].data); table[i] = obj; } setState(dpData, JSON.stringify(listStatData)); setState(idTable, JSON.stringify(table), true); }
-
@paul53 sagte in Gleitender Durchschnitt, Min., Max. über def. Zeitraum:
@sigi234
Du kannst mal die erweiterte Funktion testen, die ein JSON mit Werten erzeugen soll. Den Datenpunkt zu idTable musst Du erzeugen und die ID im Skript deklarieren und zuweisen.//Berechnung der Werte function calcStatData() { if (!listStatData || (idData.length != listStatData.length)) { initializeStatData(); } //logDebug('starting calcStatData'); var table = []; for (var i = 0; i < idData.length; i++) { var obj = {}; var sensor = listStatData[i].value.split('.'); obj.Sensor = sensor[4] + ' ' + sensor[3]; listStatData[i].data.pop(); //Remove the last element of an array var x = parseFloat(getState(idData[i][0]).val); obj.Wert = x; listStatData[i].data.unshift(x); //Add new items to the beginning of an array setState(listStatData[i].value, x); var min = x; var max = x; var sum = 0.0; for (var j = 0; j < statDataLength24; j++) { var s = parseFloat(listStatData[i].data[j]); if (s < min) min = s; if (s > max) max = s; sum += s; if (j == (statDataLength1-1)) { setState(listStatData[i].min1h, min); setState(listStatData[i].max1h, max); setState(listStatData[i].mean1h, round(sum / statDataLength1, 2)); } } setState(listStatData[i].min24h, min); setState(listStatData[i].max24h, max); setState(listStatData[i].mean24h, round(sum / statDataLength24, 2)); setState(listStatData[i].median24h, getMedian(listStatData[i].data)); obj.Min_24h = min; obj.Max_24h = max; obj.Mean_24h = round(sum / statDataLength24, 2); obj.Median_24h = getMedian(listStatData[i].data); table[i] = obj; } setState(dpData, JSON.stringify(listStatData)); setState(idTable, JSON.stringify(table), true); }
Danke, also Skript ist nicht mein Ding, aber ich versuche es mal.Ist das ein eigens Skript oder gehört es in meines?
Also hier: setState(idTable, JSON.stringify(table), true); muss der neue DP rein
und die ID im Skript deklarieren und zuweisen?
-
@sigi234 sagte:
Ist das ein eigens Skript oder gehört es in meines?
Das ist eine erweiterte Funktion calcStatData(), die Teil Deines Skriptes ist.
@sigi234 sagte in Gleitender Durchschnitt, Min., Max. über def. Zeitraum:
die ID im Skript deklarieren und zuweisen?
Ziemlich am Anfang des Skriptes (Vorschlag)
const idTable = 'javascript.0.Status.Tabelle'; createState(idTable, '', {type: 'string'});
-
@paul53 sagte in Gleitender Durchschnitt, Min., Max. über def. Zeitraum:
@sigi234 sagte:
Ist das ein eigens Skript oder gehört es in meines?
Ok, habe es so gemacht: Edit 2
// ######################################################################################################## // Berechnung von gleitendem Durchschnitt, Minimum und Maximum über einen Zeitraum // Version 1.4.1 // ######################################################################################################## "use strict"; const idTable = 'javascript.0.Status.Tabelle'; createState(idTable, '', {type: 'string'}); // // // // Berechnet Min/Max, Durschschnitt und Median über die letzten 24h. // Berechnet Min/Max, Durschschnitt über die letzte 1h. // // IDs aller benötigten Datenpunkte // // Als Array im Array mit folgendem Format: // 1\. original Datenpunktname // 2\. neuer Datenpunktname // Beispiel: javascript.0.Status.Temperatur.Außen // javascript.0.Status.Luftfeuchtigkeit.Außen // 3\. Beschreibung des Messwertes (zur Erzeugung neue Datenpunkte) // Beispliele: Temperatur // Luftfeuchtigkeit // 4\. Einheit (zur Erzeugung neue Datenpunkte) // Beispiele: °C, % // // Ist beliebig erweiterbar und für beliebige Werte nutzbar. // Beispiel 1: // const idData = [['hm-rpc.3.CUX3200312.1.TEMPERATURE','javascript.0.Status.Temperatur.Außen','Temperatur','°C'], // ['hm-rpc.3.CUX9002580.1.HUMIDITY' ,'javascript.0.Status.Luftfeuchtigkeit.Außen','Luftfeuchtigkeit','%']]; // // Beispiel 2: // const idData = [['hm-rpc.3.CUX3200312.1.TEMPERATURE','javascript.0.Status.Außen.Temperatur','Temperatur','°C'], // ['hm-rpc.3.CUX9002580.1.HUMIDITY' ,'javascript.0.Status.Außen.Luftfeuchtigkeit','Luftfeuchtigkeit','%'], // ['hm-rpc.3.CUX4007637.1.Data' ,'javascript.0.Status.Außen.Lichtstärke','Lichtstärke','lux']]; // const idData = [['hm-rpc.1.OEQ0670648.1.TEMPERATURE','javascript.0.Status.Temperatur.Bad','Temperatur','°C'], ['hm-rpc.1.OEQ0670648.1.HUMIDITY','javascript.0.Status.Luftfeuchtigkeit.Bad','Luftfeuchtigkeit','%'], ['daswetter.0.NextHours.Location_1.Day_1.current.temp_value','javascript.0.Status.Temperatur.Außen','Temperatur','°C'], ['daswetter.0.NextHours.Location_1.Day_1.current.humidity_value','javascript.0.Status.Luftfeuchtigkeit.Außen','Luftfeuchtigkeit','%'], ]; //Datenpunkt zur Speicherung aller internen Daten const dpData='javascript.0.Status.Statistic'; // ######################################################################################################## // Implementierung -- hier nichts mehr ändern // ######################################################################################################## // globale Konstanten const tc = 10; // Abtastrate in Minuten const statDataLength24 = Math.round((24 * 60) / tc); // Anzahl der Werte für 24h const statDataLength1 = Math.round(60 / tc); // Anzahl der Werte für stündlich // globale Variablen var listStatData; //interne Speicherung aller Werte //Funktion zum einmaligem initialisieren aller Datenpunkte function initializeStatData() { // Datenpunkt zur Speicherung der internen Werte erzeugen createState(dpData, 0, false, { name: "StatisticData", read: true, write: true, desc: 'Statistische Daten', type: 'string', def: '', role: 'json' }); //internes Array initialisieren var needInit = false; try { listStatData = JSON.parse(getState(dpData).val); } catch (ex) { needInit = true; } if (needInit || !listStatData || (listStatData.length < idData.length)) { listStatData = new Array(idData.length); } //logDebug('initializeStatData for', dpData, listStatData); for (var i = 0; i < idData.length; i++) { if (!listStatData[i]) { listStatData[i] = {}; } listStatData[i].value = idData[i][1]; listStatData[i].max24h = idData[i][1] + '.Max_24h'; listStatData[i].min24h = idData[i][1] + '.Min_24h'; listStatData[i].mean24h = idData[i][1] + '.Mean_24h'; listStatData[i].median24h = idData[i][1] + '.Median_24h'; listStatData[i].max1h = idData[i][1] + '.Max_1h'; listStatData[i].min1h = idData[i][1] + '.Min_1h'; listStatData[i].mean1h = idData[i][1] + '.Mean_1h'; createState(listStatData[i].value, 0, false, { name: idData[i][2], read: true, write: true, desc: idData[i][2]+ ' Aktueller Wert', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); createState(listStatData[i].max24h, 0, false, { name: 'Maximum_24h', read: true, write: true, desc: idData[i][2] + ' Maximum', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); createState(listStatData[i].min24h, 0, false, { name: 'Minimum_24h', read: true, write: true, desc: idData[i][2] + ' Minimum', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); createState(listStatData[i].mean24h, 0, false, { name: 'Mittelwert_24h', read: true, write: true, desc: idData[i][2] + ' Mittelwert', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); createState(listStatData[i].median24h, 0, false, { name: 'Median_24h', read: true, write: true, desc: idData[i][2] + ' Median', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); createState(listStatData[i].max1h, 0, false, { name: 'Maximum_1h', read: true, write: true, desc: idData[i][2] + ' Maximum', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); createState(listStatData[i].min1h, 0, false, { name: 'Minimum_1h', read: true, write: true, desc: idData[i][2] + ' Minimum', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); createState(listStatData[i].mean1h, 0, false, { name: 'Mittelwert_1h', read: true, write: true, desc: idData[i][2] + ' Mittelwert', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); if (needInit || !listStatData[i].data || (listStatData[i].data.length != statDataLength24)) { listStatData[i].data = new Array(statDataLength24); // 1\. Script start: Liste und String-Datenpunkt füllen var x = getState(idData[i][0]).val; for (var j = 0; j < statDataLength24; j++) { listStatData[i].data[j] = x; } //logDebug(listStatData[i], i); setStateDelayed(listStatData[i].value, x, false, 1000); setStateDelayed(listStatData[i].min24h, x, false, 1000); setStateDelayed(listStatData[i].max24h, x, false, 1000); setStateDelayed(listStatData[i].mean24h, x, false, 1000); setStateDelayed(listStatData[i].median24h, x, false, 1000); setStateDelayed(listStatData[i].min1h, x, false, 1000); setStateDelayed(listStatData[i].max1h, x, false, 1000); setStateDelayed(listStatData[i].mean1h, x, false, 1000); } } setState(dpData, JSON.stringify(listStatData)); } //Berechnung der Werte function calcStatData() { if (!listStatData || (idData.length != listStatData.length)) { initializeStatData(); } //logDebug('starting calcStatData'); var table = []; for (var i = 0; i < idData.length; i++) { var obj = {}; var sensor = listStatData[i].value.split('.'); obj.Sensor = sensor[4] + ' ' + sensor[3]; listStatData[i].data.pop(); //Remove the last element of an array var x = parseFloat(getState(idData[i][0]).val); obj.Wert = x; listStatData[i].data.unshift(x); //Add new items to the beginning of an array setState(listStatData[i].value, x); var min = x; var max = x; var sum = 0.0; for (var j = 0; j < statDataLength24; j++) { var s = parseFloat(listStatData[i].data[j]); if (s < min) min = s; if (s > max) max = s; sum += s; if (j == (statDataLength1-1)) { setState(listStatData[i].min1h, min); setState(listStatData[i].max1h, max); setState(listStatData[i].mean1h, round(sum / statDataLength1, 2)); } } setState(listStatData[i].min24h, min); setState(listStatData[i].max24h, max); setState(listStatData[i].mean24h, round(sum / statDataLength24, 2)); setState(listStatData[i].median24h, getMedian(listStatData[i].data)); obj.Min_24h = min; obj.Max_24h = max; obj.Mean_24h = round(sum / statDataLength24, 2); obj.Median_24h = getMedian(listStatData[i].data); table[i] = obj; } setState(dpData, JSON.stringify(listStatData)); setState(idTable, JSON.stringify(table), true); } function getMedian(args) { if (!args.length) {return 0} var numbers = args.slice(0).sort((a,b) => a - b); var middle = Math.floor(numbers.length / 2); var isEven = numbers.length % 2 === 0; return isEven ? (numbers[middle] + numbers[middle - 1]) / 2 : numbers[middle]; } /** * round a number * @param value to round * @param exp exponent to round * @returns the round number */ function round(value, exp) { if (typeof exp === 'undefined' || +exp === 0) return Math.round(value); value = +value; exp = +exp; if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) return NaN; // Shift var values = value.toString().split('e'); value = Math.round(+(values[0] + 'e' + (values[1] ? (+values[1] + exp) : exp))); // Shift back var values = value.toString().split('e'); return +(values[0] + 'e' + (values[1] ? (+values[1] - exp) : -exp)); } initializeStatData(); schedule('*/' + tc + ' * * * *', function () { calcStatData(); });
-
@sigi234 sagte :
javascript.0.Status.Tabelle
Funktioniert es, so dass Du den Datenpunkt "javascript.0.Status.Tabelle" in Vis verwenden kannst ?
-
@paul53 sagte in Gleitender Durchschnitt, Min., Max. über def. Zeitraum:
@sigi234 sagte :
javascript.0.Status.Tabelle
Funktioniert es, so dass Du den Datenpunkt "javascript.0.Status.Tabelle" in Vis verwenden kannst ?
Ja, Danke einfach perfekt..........
-
Das sieht ja super aus!
Fehlt nur noch die Standardabweichung.
Mein Geigerzähler hat seit Oktober 2017 schon 4 Fehlalarme produziert, weil ich wohl die Grenzen etwas zu stramm habe. Da hülfe wohl die Kenntnis der Standardabweichung. -
Hallo zusammen,
sorry für Anfängerfragen - aber habe erst diese Woche mit iobroker angefangen:
Hat schon jemand den export von history Daten benutzt (https://github.com/ioBroker/ioBroker.history/blob/master/docs/de/README.md - "Zugriff auf History Werte mit JavaScript") um damit für Sensoren eine Gleitmittelung bzw min max der letzten x Werte durchzuführen ?
Wäre für ein Beispiel dankbar...
-
-
Ich habe das Skript mit meinen Xiaomi Sensoren unter "const idData" gefüttert und ansonsten nichts verändert.
`// ######################################################################################################## // Berechnung von gleitendem Durchschnitt, Minimum und Maximum über einen Zeitraum // Version 1.4.1 // ######################################################################################################## "use strict"; // // // Berechnet Min/Max, Durschschnitt und Median über die letzten 24h. // Berechnet Min/Max, Durschschnitt über die letzte 1h. // // IDs aller benötigten Datenpunkte // // Als Array im Array mit folgendem Format: // 1\. original Datenpunktname // 2\. neuer Datenpunktname // Beispiel: javascript.0.Status.Temperatur.Außen // javascript.0.Status.Luftfeuchtigkeit.Außen // 3\. Beschreibung des Messwertes (zur Erzeugung neue Datenpunkte) // Beispliele: Temperatur // Luftfeuchtigkeit // 4\. Einheit (zur Erzeugung neue Datenpunkte) // Beispiele: °C, % // // Ist beliebig erweiterbar und für beliebige Werte nutzbar. // Beispiel 1: // const idData = [['hm-rpc.3.CUX3200312.1.TEMPERATURE','javascript.0.Status.Temperatur.Außen','Temperatur','°C'], // ['hm-rpc.3.CUX9002580.1.HUMIDITY' ,'javascript.0.Status.Luftfeuchtigkeit.Außen','Luftfeuchtigkeit','%']]; // // Beispiel 2: // const idData = [['hm-rpc.3.CUX3200312.1.TEMPERATURE','javascript.0.Status.Außen.Temperatur','Temperatur','°C'], // ['hm-rpc.3.CUX9002580.1.HUMIDITY' ,'javascript.0.Status.Außen.Luftfeuchtigkeit','Luftfeuchtigkeit','%'], // ['hm-rpc.3.CUX4007637.1.Data' ,'javascript.0.Status.Außen.Lichtstärke','Lichtstärke','lux']]; // const idData = [['mihome.0.devices.weather_v1_158d0002c8f3ab.temperature','javascript.0.Status.Temperatur.Balkon','Temperatur','°C'], ['mihome.0.devices.weather_v1_158d0002c8f3ab.humidity','javascript.0.Status.Luftfeuchtigkeit.Balkon','Luftfeuchtigkeit','%']; //Datenpunkt zur Speicherung aller internen Daten const dpData='javascript.0.Status.Statistic'; // ######################################################################################################## // Implementierung -- hier nichts mehr ändern // ######################################################################################################## // globale Konstanten const tc = 10; // Abtastrate in Minuten const statDataLength24 = Math.round((24 * 60) / tc); // Anzahl der Werte für 24h const statDataLength1 = Math.round(60 / tc); // Anzahl der Werte für stündlich // globale Variablen var listStatData; //interne Speicherung aller Werte //Funktion zum einmaligem initialisieren aller Datenpunkte function initializeStatData() { // Datenpunkt zur Speicherung der internen Werte erzeugen createState(dpData, 0, false, { name: "StatisticData", read: true, write: true, desc: 'Statistische Daten', type: 'string', def: '', role: 'json' }); //internes Array initialisieren var needInit = false; try { listStatData = JSON.parse(getState(dpData).val); } catch (ex) { needInit = true; } if (needInit || !listStatData || (listStatData.length < idData.length)) { listStatData = new Array(idData.length); } //logDebug('initializeStatData for', dpData, listStatData); for (var i = 0; i < idData.length; i++) { if (!listStatData[i]) { listStatData[i] = {}; } listStatData[i].value = idData[i][1]; listStatData[i].max24h = idData[i][1] + '.Max_24h'; listStatData[i].min24h = idData[i][1] + '.Min_24h'; listStatData[i].mean24h = idData[i][1] + '.Mean_24h'; listStatData[i].median24h = idData[i][1] + '.Median_24h'; listStatData[i].max1h = idData[i][1] + '.Max_1h'; listStatData[i].min1h = idData[i][1] + '.Min_1h'; listStatData[i].mean1h = idData[i][1] + '.Mean_1h'; createState(listStatData[i].value, 0, false, { name: idData[i][2], read: true, write: true, desc: idData[i][2]+ ' Aktueller Wert', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); createState(listStatData[i].max24h, 0, false, { name: 'Maximum_24h', read: true, write: true, desc: idData[i][2] + ' Maximum', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); createState(listStatData[i].min24h, 0, false, { name: 'Minimum_24h', read: true, write: true, desc: idData[i][2] + ' Minimum', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); createState(listStatData[i].mean24h, 0, false, { name: 'Mittelwert_24h', read: true, write: true, desc: idData[i][2] + ' Mittelwert', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); createState(listStatData[i].median24h, 0, false, { name: 'Median_24h', read: true, write: true, desc: idData[i][2] + ' Median', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); createState(listStatData[i].max1h, 0, false, { name: 'Maximum_1h', read: true, write: true, desc: idData[i][2] + ' Maximum', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); createState(listStatData[i].min1h, 0, false, { name: 'Minimum_1h', read: true, write: true, desc: idData[i][2] + ' Minimum', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); createState(listStatData[i].mean1h, 0, false, { name: 'Mittelwert_1h', read: true, write: true, desc: idData[i][2] + ' Mittelwert', type: 'number', def: 0, unit: idData[i][3], role: 'value' }); if (needInit || !listStatData[i].data || (listStatData[i].data.length != statDataLength24)) { listStatData[i].data = new Array(statDataLength24); // 1\. Script start: Liste und String-Datenpunkt füllen var x = getState(idData[i][0]).val; for (var j = 0; j < statDataLength24; j++) { listStatData[i].data[j] = x; } //logDebug(listStatData[i], i); setStateDelayed(listStatData[i].value, x, false, 1000); setStateDelayed(listStatData[i].min24h, x, false, 1000); setStateDelayed(listStatData[i].max24h, x, false, 1000); setStateDelayed(listStatData[i].mean24h, x, false, 1000); setStateDelayed(listStatData[i].median24h, x, false, 1000); setStateDelayed(listStatData[i].min1h, x, false, 1000); setStateDelayed(listStatData[i].max1h, x, false, 1000); setStateDelayed(listStatData[i].mean1h, x, false, 1000); } } setState(dpData, JSON.stringify(listStatData)); } //Berechnung der Werte function calcStatData() { if (!listStatData || (idData.length != listStatData.length)) { initializeStatData(); } //logDebug('starting calcStatData'); for (var i = 0; i < idData.length; i++) { listStatData[i].data.pop(); //Remove the last element of an array var x = parseFloat(getState(idData[i][0]).val); listStatData[i].data.unshift(x); //Add new items to the beginning of an array setState(listStatData[i].value, x); var min = x; var max = x; var sum = 0.0; for (var j = 0; j < statDataLength24; j++) { var s = parseFloat(listStatData[i].data[j]); if (s < min) min = s; if (s > max) max = s; sum += s; if (j == (statDataLength1-1)) { setState(listStatData[i].min1h, min); setState(listStatData[i].max1h, max); setState(listStatData[i].mean1h, round(sum / statDataLength1, 2)); } } setState(listStatData[i].min24h, min); setState(listStatData[i].max24h, max); setState(listStatData[i].mean24h, round(sum / statDataLength24, 2)); setState(listStatData[i].median24h, getMedian(listStatData[i].data)); } setState(dpData, JSON.stringify(listStatData)); } function getMedian(args) { if (!args.length) {return 0} var numbers = args.slice(0).sort((a,b) => a - b); var middle = Math.floor(numbers.length / 2); var isEven = numbers.length % 2 === 0; return isEven ? (numbers[middle] + numbers[middle - 1]) / 2 : numbers[middle]; } /** * round a number * @param value to round * @param exp exponent to round * @returns the round number */ function round(value, exp) { if (typeof exp === 'undefined' || +exp === 0) return Math.round(value); value = +value; exp = +exp; if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) return NaN; // Shift var values = value.toString().split('e'); value = Math.round(+(values[0] + 'e' + (values[1] ? (+values[1] + exp) : exp))); // Shift back var values = value.toString().split('e'); return +(values[0] + 'e' + (values[1] ? (+values[1] - exp) : -exp)); } initializeStatData(); schedule('*/' + tc + ' * * * *', function () { calcStatData(); });`
Es werden aber keine Datenpunkte erzeugt.
Im Log finde ich nur:
javascript.0 2020-09-30 18:14:21.682 info (16357) script.js.Meine_Scripts.Temperatur_Min_Max: registered 0 subscriptions and 0 schedules javascript.0 2020-09-30 18:14:21.671 info (16357) Start javascript script.js.Meine_Scripts.Temperatur_Min_Max
-
-
@paul53 said in Gleitender Durchschnitt, Min., Max. über def. Zeitraum:
d am Ende sind Zeich
Danke!
Jetzt kommt eine ganze Reihe an Warnungen mit denen ich nichts anfangen kann:
javascript.0 2020-09-30 18:55:11.308 info (16357) script.js.Meine_Scripts.Temperatur_Min_Max: registered 0 subscriptions and 1 schedule javascript.0 2020-09-30 18:55:11.300 warn (16357) at script.js.Meine_Scripts.Temperatur_Min_Max:271:1 javascript.0 2020-09-30 18:55:11.299 warn (16357) at initializeStatData (script.js.Meine_Scripts.Temperatur_Min_Max:199:4) javascript.0 2020-09-30 18:55:11.299 warn (16357) at setState (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1358:20) javascript.0 2020-09-30 18:55:11.296 warn (16357) State "javascript.0.Status.Statistic" not found javascript.0 2020-09-30 18:55:11.290 warn (16357) at script.js.Meine_Scripts.Temperatur_Min_Max:271:1 javascript.0 2020-09-30 18:55:11.289 warn (16357) at initializeStatData (script.js.Meine_Scripts.Temperatur_Min_Max:71:33) javascript.0 2020-09-30 18:55:11.285 warn (16357) getState "javascript.0.Status.Statistic" not found (3) javascript.0 2020-09-30 18:55:11.242 info (16357) Start javascript script.js.Meine_Scripts.Temperatur_Min_Max javascript.0 2020-09-30 18:55:11.078 info (16357) Stop script script.js.Meine_Scripts.Temperatur_Min_Max
-
@martin
In Zeile 35 fehlt am Ende (vor dem Semikolon) eine schließende eckige Klammer.