UNPKG

@frangoteam/fuxa

Version:

Web-based Process Visualization (SCADA/HMI/Dashboard) software

228 lines (201 loc) 8.13 kB
/** * Calculator for DAQ value array (integrale, max, min, average...) */ 'use strict'; const utils = require("../utils"); function getFunctionValues(values, fromts, tots, fnc, interval, format) { if (fnc === ReportFunctionType.min) { return getMin(values, fromts, tots, interval); } else if (fnc === ReportFunctionType.max) { return getMax(values, fromts, tots, interval); } else if (fnc === ReportFunctionType.average) { return getAverage(values, fromts, tots, interval, format); } else if (fnc === ReportFunctionType.sum) { return getSum(values, fromts, tots, interval); } } /** * * @param {*} values * @param {*} fnc * @param {*} intervalType hour / day * @returns */ function getMin(timeserie, fromts, tots, intervalType) { let result = getInterval(fromts, tots, intervalType, Number.MAX_VALUE); // sort to start with the oldest let sorted = timeserie.sort(function (a, b) { return a.dt - b.dt; }); let addToInterval = (intervals, intervalIndex, value) => { if (!intervals[intervalIndex]) { intervals[intervalIndex] = Number.MAX_VALUE; } else if (intervals[intervalIndex] > value) { intervals[intervalIndex] = value; } } for (let i = 0; i < sorted.length; i++) { let intervalIndex = getIntervalTime(sorted[i].dt, intervalType, false).getTime(); addToInterval(result, intervalIndex, utils.parseFloat(sorted[i].value, 5)); } return result; } function getMax(timeserie, fromts, tots, intervalType) { let result = getInterval(fromts, tots, intervalType, utils.SMALLEST_NEGATIVE_INTEGER); // sort to start with the oldest let sorted = timeserie.sort(function (a, b) { return a.dt - b.dt; }); let addToInterval = (intervals, intervalIndex, value) => { if (!intervals[intervalIndex]) { intervals[intervalIndex] = utils.SMALLEST_NEGATIVE_INTEGER; } else if (intervals[intervalIndex] < value) { intervals[intervalIndex] = value; } } for (let i = 0; i < sorted.length; i++) { let intervalIndex = getIntervalTime(sorted[i].dt, intervalType, false).getTime(); addToInterval(result, intervalIndex, utils.parseFloat(sorted[i].value, 5)); } return result; } function getAverage(timeserie, fromts, tots, intervalType, format) { let result = getInterval(fromts, tots, intervalType, null); let counts = getInterval(fromts, tots, intervalType, 0); // sort to start with the oldest let sorted = timeserie.sort(function (a, b) { return a.dt - b.dt; }); let addToInterval = (intervals, counters, intervalIndex, value) => { if (utils.isNullOrUndefined(intervals[intervalIndex])) { intervals[intervalIndex] = value; } else { intervals[intervalIndex] += value; } counters[intervalIndex]++; } for (let i = 0; i < sorted.length; i++) { let intervalIndex = getIntervalTime(sorted[i].dt, intervalType, false).getTime(); addToInterval(result, counts, intervalIndex, parseFloat(sorted[i].value)); } // average Object.keys(result).forEach(k => { if (counts[k]) { result[k] = utils.parseFloat(result[k] / counts[k], format || 5); } }); return result; } function getSum(timeserie, fromts, tots, intervalType) { let result = getInterval(fromts, tots, intervalType, 0); // sort to start with the oldest let sorted = timeserie.sort(function (a, b) { return a.dt - b.dt; }); let addToInterval = (intervals, intervalIndex, value) => { if (utils.isNullOrUndefined(intervals[intervalIndex])) { intervals[intervalIndex] = 0; } else { intervals[intervalIndex] += value; intervals[intervalIndex] = utils.parseFloat(intervals[intervalIndex], 5) } } for (let i = 0; i < sorted.length; i++) { let intervalIndex = getIntervalTime(sorted[i].dt, intervalType, false).getTime(); addToInterval(result, intervalIndex, parseFloat(sorted[i].value)); } return result; } function getIntegral(timeserie, fromts, tots, intervalType) { let result = getInterval(fromts, tots, intervalType, Number.MAX_VALUE); // sort to start with the oldest let sorted = timeserie.sort(function (a, b) { return a.dt - b.dt; }); let addToInterval = (intervals, intervalIndex, value) => { if (!intervals[intervalIndex]) { intervals[intervalIndex] = value; } else if (intervals[intervalIndex] > value) { intervals[intervalIndex] += value; } } let lastRecord = null;// : TimeValue { dt: number, value: number }; let lastIntervalIndex = null; for (let i = 0; i < sorted.length; i++) { let intervalIndex = getIntervalTime(sorted[i].dt, intervalType, false).getTime(); // check missing value to fill intervalsIndex while (lastIntervalIndex && lastIntervalIndex < intervalIndex) { let nextIntervalIndex = getIntervalTime(lastRecord.dt, intervalType, true).getTime(); let delta = nextIntervalIndex - lastRecord.dt; addToInterval(result, nextIntervalIndex, parseFloat(lastRecord.value) * (delta / 1000)); lastIntervalIndex = nextIntervalIndex; lastRecord.dt = nextIntervalIndex; } // sum left => skip the first one if (lastRecord) { let delta = sorted[i].dt - lastRecord.dt; addToInterval(result, intervalIndex, parseFloat(sorted[i].value) * (delta / 1000)); } lastRecord = sorted[i]; lastIntervalIndex = intervalIndex; } return result; } function getInterval(fromts, tots, type, defvalue) { let result = {}; let dt = getStepDate(fromts, type, 0); while (dt.getTime() < tots) { result[dt.getTime()] = defvalue; dt = getStepDate(dt, type, 1); } return result; } function getIntervalTime(millyDt, _interval, next) { let dt = new Date(millyDt); let toadd = (next) ? 1 : 0; return getStepDate(dt, _interval, toadd); } function getStepDate(ts, type, toadd) { var dtRange; let dt = new Date(ts); if (type === ReportIntervalType.day) { dtRange = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate(), 0, 0, 0); dtRange.setDate(dt.getDate() + toadd); } else if (type === ReportIntervalType.hour) { dtRange = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate(), dt.getHours(), 0, 0); dtRange.setHours(dt.getHours() + toadd); } else if (type === ReportIntervalType.min30) { dtRange = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate(), dt.getHours(), 0, 0); var minutesRange = parseInt(dt.getMinutes() / 30); dtRange.setMinutes((minutesRange + toadd) * 30); } else if (type === ReportIntervalType.min10) { dtRange = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate(), dt.getHours(), 0, 0); var minutesRange = parseInt(dt.getMinutes() / 10); dtRange.setMinutes((minutesRange + toadd) * 10); } else { //if (type === ReportIntervalType.min5) { dtRange = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate(), dt.getHours(), 0, 0); var minutesRange = parseInt(dt.getMinutes() / 5); dtRange.setMinutes((minutesRange + toadd) * 5); } return dtRange; } module.exports = { getFunctionValues: getFunctionValues, getMin: getMin, getMax: getMax, getAverage: getAverage, getSum: this.getSum, }; const ReportIntervalType = { min5: 'min5', min10: 'min10', min30: 'min30', hour: 'hour', day: 'day', } const ReportFunctionType = { min: 'min', max: 'max', average: 'average', sum: 'sum', }