Alte Version abgeändert auf neue Datebank /-Struktur).
This commit is contained in:
482
routes/fsdata.js
Normal file
482
routes/fsdata.js
Normal file
@@ -0,0 +1,482 @@
|
||||
"use strict";
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const moment = require('moment');
|
||||
const mathe = require('mathjs');
|
||||
const util = require('./utilities');
|
||||
|
||||
// Mongo wird in app.js geöffnet und verbunden und bleibt immer verbunden !!
|
||||
|
||||
let sv_factor = {'SBM-20': 1 / 2.47, 'SBM-19': 1 / 9.81888, 'Si22G': 0.081438};
|
||||
|
||||
//Get readings for all data out ot the database
|
||||
router.get('/getfs/:week', function (req, res) {
|
||||
let week = req.params.week;
|
||||
let db = req.app.get('dbase');
|
||||
let st = req.query.start;
|
||||
let sid = parseInt(req.query.sensorid);
|
||||
let sname = req.query.sensorname;
|
||||
let avg = req.query.avgTime;
|
||||
let live = (req.query.live == 'true');
|
||||
let movingAvg = (req.query.moving=='true');
|
||||
let longAVG = req.query.longAVG;
|
||||
let system = req.query.os;
|
||||
|
||||
if (week == 'oneday') {
|
||||
console.log(`Operating System = ${system}`);
|
||||
getDWMData(db, sid, st, avg, live, movingAvg, 1, longAVG)
|
||||
.then(erg => res.json(erg));
|
||||
} else if (week == 'oneweek') {
|
||||
getDWMData(db, sid, st, avg, live, movingAvg, 7)
|
||||
.then(erg => res.json(erg));
|
||||
} else if (week == 'onemonth') {
|
||||
getDWMData(db, sid, st, 1440, false, false, 31)
|
||||
.then(erg => res.json(erg));
|
||||
} else if (week == 'korr') {
|
||||
getSensorProperties(db,sid)
|
||||
.then(erg => res.json(erg));
|
||||
} else {
|
||||
res.json({'error': 'MIST VERDAMMTER!!'});
|
||||
}
|
||||
});
|
||||
|
||||
// fetch name of given sensor-id
|
||||
function getSensorName(db,sid) {
|
||||
const p = new Promise((resolve,reject) => {
|
||||
let coll = db.collection('properties');
|
||||
coll.findOne({_id: parseInt(sid)})
|
||||
.then(erg => {
|
||||
// name is now an array, get the current (last) entry
|
||||
if (erg && erg.name && Array.isArray(erg.name)) {
|
||||
resolve(erg.name[erg.name.length - 1].name);
|
||||
} else {
|
||||
resolve(erg ? erg.name : null);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.log('getSensorName',err);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
return p
|
||||
}
|
||||
|
||||
// fetch the properties for the given sensor
|
||||
async function getSensorProperties(db,sid) {
|
||||
let start = new Date();
|
||||
console.log("Get properties for", sid,"from DB");
|
||||
let sensorEntries = [{'sid':sid}];
|
||||
let coll = db.collection('properties');
|
||||
let properties;
|
||||
try {
|
||||
properties = await coll.findOne({_id: sid});
|
||||
}
|
||||
catch(e) {
|
||||
console.log("getSensorProperties",e);
|
||||
return {};
|
||||
}
|
||||
console.log("got properties - time:", new Date() - start);
|
||||
if(properties == null) return null;
|
||||
// name is now an array, get the current (last) entry
|
||||
let currentName = properties.name;
|
||||
if (Array.isArray(properties.name)) {
|
||||
currentName = properties.name[properties.name.length - 1].name;
|
||||
}
|
||||
|
||||
// Overwrite name field with string for frontend compatibility
|
||||
properties.name = currentName;
|
||||
sensorEntries[0]['name'] = currentName;
|
||||
|
||||
// Check if othersensors exists (might not in new DB structure)
|
||||
if (!properties.othersensors || properties.othersensors.length === 0) {
|
||||
properties.othersensors = sensorEntries;
|
||||
return properties;
|
||||
}
|
||||
|
||||
let mustbeobject = false;
|
||||
for(let i = 0, j=1; i<properties.othersensors.length; i++) {
|
||||
let es = properties.othersensors[i];
|
||||
let e = {};
|
||||
if (es != null) {
|
||||
if ( typeof es === 'object') {
|
||||
mustbeobject=true;
|
||||
e.sid = es.id;
|
||||
e.name = es.name;
|
||||
} else {
|
||||
if(mustbeobject) { continue; }
|
||||
e.sid = es;
|
||||
e.name = await getSensorName(db, es);
|
||||
}
|
||||
}
|
||||
sensorEntries[j] = e;
|
||||
j++;
|
||||
}
|
||||
sensorEntries.sort(function (a, b) {
|
||||
if (a.sid < b.sid) {
|
||||
return -1;
|
||||
}
|
||||
if (a.sid > b.sid) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
properties.othersensors = sensorEntries;
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
||||
async function readRadiationMovingAverage(db, sid, start, end, average, factor) {
|
||||
let docs = [];
|
||||
let collection = db.collection('radioactivity_sensors');
|
||||
try {
|
||||
docs = await collection.find({
|
||||
sensorid: sid,
|
||||
datetime: {
|
||||
$gte: new Date(start),
|
||||
$lt: new Date(end)
|
||||
}
|
||||
}, {sort: {datetime: 1}}).toArray();
|
||||
} catch (e) {
|
||||
console.log('readRadiationMovingAverage',e);
|
||||
return [];
|
||||
}
|
||||
if (docs.length == 0) {
|
||||
return [];
|
||||
} else {
|
||||
let d = await util.calcMovingAverage(db, sid, docs, average , false, factor);
|
||||
return d.RAD;
|
||||
}
|
||||
}
|
||||
|
||||
async function readRadiationAverages(db, sid, start, end, average, factor) {
|
||||
let docs = [];
|
||||
let collection = db.collection('radioactivity_sensors');
|
||||
try {
|
||||
docs = await collection.aggregate([
|
||||
{$match: {sensorid: sid, datetime: {$gte: new Date(start), $lt: new Date(end)}}},
|
||||
{$sort: {datetime: 1}},
|
||||
{
|
||||
$group: {
|
||||
_id: {
|
||||
$toDate: {
|
||||
$subtract: [
|
||||
{$toLong: '$datetime'},
|
||||
{$mod: [{$toLong: '$datetime'}, 1000 * 60 * average]} // aggregate every average minutes
|
||||
]
|
||||
}
|
||||
},
|
||||
cpmAvg: {$avg: '$values.counts_per_minute'},
|
||||
cpmSum: {$sum: '$values.counts_per_minute'},
|
||||
count: {$sum: 1}
|
||||
}
|
||||
},
|
||||
{ $addFields: { uSvphAvg: { $multiply: ["$cpmAvg", factor]}}},
|
||||
{$sort: {_id: 1}}
|
||||
]).toArray();
|
||||
}
|
||||
catch(e) {
|
||||
console.log('readRadiationAverages', e);
|
||||
return [];
|
||||
}
|
||||
return docs;
|
||||
}
|
||||
|
||||
async function readClimateAverages(db, sid, start, end, average) {
|
||||
let docs = [];
|
||||
let collection = db.collection('thp_sensors');
|
||||
try {
|
||||
docs = await collection.aggregate([
|
||||
{$match: {sensorid: sid, datetime: {$gte: new Date(start), $lt: new Date(end)}}},
|
||||
{$sort: {datetime: 1}},
|
||||
{
|
||||
$group: {
|
||||
_id: {
|
||||
$toDate: {
|
||||
$subtract: [
|
||||
{$toLong: '$datetime'},
|
||||
{$mod: [{$toLong: '$datetime'}, 1000 * 60 * average]} // aggregate every average min
|
||||
]
|
||||
}
|
||||
},
|
||||
tempAvg: {$avg: '$values.temperature'}, // average over every 10min
|
||||
humiAvg: {$avg: '$values.humidity'},
|
||||
pressSeaAvg: {$avg: '$values.pressure_at_sealevel'},
|
||||
count: {$sum: 1}
|
||||
}
|
||||
},
|
||||
{$sort: {_id: 1}}
|
||||
]).toArray();
|
||||
}
|
||||
catch(e) {
|
||||
console.log('readClimateAverage', e);
|
||||
return [];
|
||||
}
|
||||
return docs;
|
||||
}
|
||||
|
||||
function calcTimeRange(st, range, live, avg) {
|
||||
let start = moment(st);
|
||||
let end = moment(st);
|
||||
if(range == 1) { // one day
|
||||
if (live == true) {
|
||||
start.subtract(24, 'h');
|
||||
start.subtract(avg, 'm');
|
||||
} else {
|
||||
start.subtract(avg, 'm');
|
||||
end.add(24, 'h');
|
||||
}
|
||||
} else if (range == 7) { // one week (7 days)
|
||||
if (live == true) {
|
||||
start.subtract(24 * 8, 'h');
|
||||
} else {
|
||||
start.subtract(24 * 8, 'h');
|
||||
// end.add(24 * 7, 'h');
|
||||
console.log(start.format(), end.format());
|
||||
}
|
||||
} else if (range == 31) { // one month (31 days)
|
||||
start=start.startOf('day');
|
||||
end = end.startOf('day');
|
||||
start.subtract(33, 'd');
|
||||
} else if (range >= 48) { // 48 hours
|
||||
if(live == true) {
|
||||
start.subtract(range, 'h')
|
||||
}
|
||||
}
|
||||
return { start: start, end: end };
|
||||
}
|
||||
|
||||
// get data for one day, one week or one month from the database
|
||||
async function getDWMData(db, sensorid, st, avg, live, doMoving, span, longAVG) {
|
||||
let docs = [];
|
||||
let ret = {radiation: [], climate: []};
|
||||
// first fetch properties for this sensor
|
||||
let properties = await getSensorProperties(db,sensorid);
|
||||
// calculate time range
|
||||
let timerange = calcTimeRange(st, span, live, avg);
|
||||
for (let n = 0; n<properties.othersensors.length; n++) {
|
||||
let sid = properties.othersensors[n].sid;
|
||||
let sname = properties.othersensors[n].name;
|
||||
try {
|
||||
if (sname.startsWith("Radiation")) {
|
||||
let factor = sv_factor[sname.substring(10)] / 60;
|
||||
if(doMoving) {
|
||||
docs = await readRadiationMovingAverage(db, sid, timerange.start, timerange.end, avg, factor);
|
||||
} else {
|
||||
docs = await readRadiationAverages(db, sid, timerange.start, timerange.end, avg, factor);
|
||||
}
|
||||
let avg48 = null;
|
||||
if (longAVG != undefined) {
|
||||
let tr = calcTimeRange(st, longAVG, true, avg);
|
||||
let avg48_docs = await readRadiationAverages(db, sid, tr.start, tr.end, longAVG*60, factor);
|
||||
avg48 = avg48_docs[0];
|
||||
}
|
||||
ret['radiation'] = {sid: sid, sname: sname, avg48: avg48, values: docs};
|
||||
} else if (sname == "BME280") {
|
||||
docs = await readClimateAverages(db, sid, timerange.start, timerange.end, 10);
|
||||
if (docs.length != 0) {
|
||||
ret['climate'] = {sid: sid, sname: sname, values: docs};
|
||||
}
|
||||
} else {
|
||||
ret['error'] = "Sensor not of right type (unknown)";
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('getDayData', e);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// für die Wochenanzeige die Daten als gleitenden Mittelwert über 24h durchrechnen
|
||||
// ===============================================================
|
||||
// PM (FEINSTAUB) FUNCTIONS REMOVED - Not needed in new DB
|
||||
// ===============================================================
|
||||
/*
|
||||
// und in einem neuen Array übergeben
|
||||
function movAvgSDSWeek(data) {
|
||||
var neuData = [];
|
||||
const oneDay = 3600*24;
|
||||
|
||||
// first convert date to timestam (in secs)
|
||||
for (var i=0; i<data.length; i++) {
|
||||
data[i].datetime = ( new Date(data[i].datetime)) / 1000; // the math does the convertion
|
||||
}
|
||||
|
||||
// now calculate the moving average over 24 hours
|
||||
let left=0, roll_sum=0, nd = [];
|
||||
for (let right =0; right < data.length; right++) {
|
||||
// if(right == 200) {
|
||||
// console.log("right = 200");
|
||||
// }
|
||||
|
||||
if(data[right].P1 != undefined) {
|
||||
roll_sum += data[right].P1;
|
||||
}
|
||||
if(data[right].P10 != undefined) {
|
||||
roll_sum += data[right].P10;
|
||||
}
|
||||
|
||||
while( data[left].datetime <= data[right].datetime - oneDay) {
|
||||
if(data[left].P1 != undefined) {
|
||||
roll_sum -= data[left].P1;
|
||||
}
|
||||
if(data[left].P10 != undefined) {
|
||||
roll_sum -= data[left].P10;
|
||||
}
|
||||
left += 1;
|
||||
}
|
||||
nd[right] = { 'P1024': roll_sum/ (right-left+1)+5};
|
||||
}
|
||||
|
||||
for (var i=1, j=0; i< data.length; i++, j++) {
|
||||
var sum1=0, sum2 = 0, cnt1 = 0, cnt2 = 0;
|
||||
var di = data[i].datetime;
|
||||
for (var k=i; k>=0 ; k--) {
|
||||
if (data[k].datetime+oneDay < di) {
|
||||
break;
|
||||
}
|
||||
if (data[k].P1 !== undefined) {
|
||||
sum1 += data[k].P1;
|
||||
cnt1++;
|
||||
}
|
||||
if (data[k].P2 !== undefined) {
|
||||
sum2 += data[k].P2;
|
||||
cnt2++;
|
||||
}
|
||||
if (data[k].P10 !== undefined) {
|
||||
sum1 += data[k].P10;
|
||||
cnt1++;
|
||||
}
|
||||
if (data[k].P2_5 !== undefined) {
|
||||
sum2 += data[k].P2_5;
|
||||
cnt2++;
|
||||
}
|
||||
}
|
||||
neuData[j] = {'P10': sum1 / cnt1, 'P2_5': sum2 / cnt2, 'date': data[i].datetime} ;
|
||||
}
|
||||
// finally shrink datasize, so that max. 1000 values will be returned
|
||||
var neu1 = [];
|
||||
var step = Math.round(neuData.length / 500);
|
||||
// if (step == 0) step = 1;
|
||||
step = 1;
|
||||
for (var i = 0, j=0; i < neuData.length; i+=step, j++) {
|
||||
var d = neuData.slice(i,i+step)
|
||||
var p1=0, p2=0;
|
||||
for(var k=0; k<d.length; k++) {
|
||||
if (d[k].P10 > p1) {
|
||||
p1 = d[k].P10;
|
||||
}
|
||||
if (d[k].P2_5 > p2) {
|
||||
p2 = d[k].P2_5;
|
||||
}
|
||||
}
|
||||
neu1[j] = {'P10': p1, 'P2_5': p2, 'date': neuData[i].date*1000} ;
|
||||
}
|
||||
return { 'ndold': neu1, 'ndnew': nd };
|
||||
}
|
||||
|
||||
|
||||
|
||||
function calcMinMaxAvgSDS(data,isp10) {
|
||||
var p1=[], p2=[];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (data[i].P10 != undefined) {
|
||||
p1.push(data[i].P10);
|
||||
}
|
||||
if (data[i].P2_5 != undefined) {
|
||||
p2.push(data[i].P2_5);
|
||||
}
|
||||
if (data[i].P1 != undefined) {
|
||||
p1.push(data[i].P1);
|
||||
}
|
||||
if (data[i].P2 != undefined) {
|
||||
p2.push(data[i].P2);
|
||||
}
|
||||
}
|
||||
return {
|
||||
'P10_max': mathe.max(p1),
|
||||
'P2_5_max': mathe.max(p2),
|
||||
'P10_min': mathe.min(p1),
|
||||
'P2_5_min': mathe.min(p2),
|
||||
'P10_avg' : mathe.mean(p1),
|
||||
'P2_5_avg' : mathe.mean(p2) };
|
||||
}
|
||||
*/
|
||||
|
||||
function calcMinMaxAvgDHT(data) {
|
||||
var t=[], h=[];
|
||||
for (var i=0; i<data.length; i++) {
|
||||
if(data[i].temperature != undefined) {
|
||||
t.push(data[i].temperature);
|
||||
}
|
||||
if(data[i].humidity != undefined) {
|
||||
h.push(data[i].humidity);
|
||||
}
|
||||
}
|
||||
return {
|
||||
'temp_max': mathe.max(t),
|
||||
'humi_max': mathe.max(h),
|
||||
'temp_min': mathe.min(t),
|
||||
'humi_min': mathe.min(h),
|
||||
'temp_avg' : mathe.mean(t),
|
||||
'humi_avg' : mathe.mean(h) };
|
||||
}
|
||||
|
||||
|
||||
async function calcMinMaxAvgBMP(db, sid, data) {
|
||||
var t = [], p = [];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (data[i].temperature != undefined) {
|
||||
t.push(data[i].temperature);
|
||||
}
|
||||
if (data[i].pressure != undefined) {
|
||||
p.push(data[i].pressure);
|
||||
}
|
||||
}
|
||||
let altitude = await util.getAltitude(db, sid);
|
||||
p = util.calcSealevelPressure(p, '', altitude);
|
||||
return {
|
||||
'temp_max': mathe.max(t), 'press_max': mathe.max(p),
|
||||
'temp_min': mathe.min(t), 'press_min': mathe.min(p),
|
||||
'temp_avg': mathe.mean(t), 'press_avg': mathe.mean(p)
|
||||
};
|
||||
}
|
||||
|
||||
async function calcMinMaxAvgBME(db, sid, data) {
|
||||
var t = [], h = [], p = [], sumt = 0;
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (data[i].temperature != undefined) {
|
||||
t.push(data[i].temperature);
|
||||
}
|
||||
if (data[i].humidity != undefined) {
|
||||
h.push(data[i].humidity);
|
||||
}
|
||||
if (data[i].pressure != undefined) {
|
||||
p.push(data[i].pressure);
|
||||
}
|
||||
}
|
||||
let altitude = await util.getAltitude(db, sid);
|
||||
p = util.calcSealevelPressure(p, '', altitude);
|
||||
return {
|
||||
'temp_max': mathe.max(t), 'humi_max': mathe.max(h), 'press_max': mathe.max(p),
|
||||
'temp_min': mathe.min(t), 'humi_min': mathe.min(h), 'press_min': mathe.min(p),
|
||||
'temp_avg': mathe.mean(t), 'humi_avg': mathe.mean(h), 'press_avg': mathe.mean(p)
|
||||
};
|
||||
}
|
||||
|
||||
/* PM (FEINSTAUB) FUNCTIONS REMOVED
|
||||
function isPM(name) {
|
||||
if ((name == "SDS011") || (name.startsWith("PPD")) || (name.startsWith("PMS"))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Statistiken für den Sensor holen und übergeben - PM only
|
||||
async function getStatistics(db,sensorid) {
|
||||
// REMOVED - Was PM-specific
|
||||
return { error: 'PM statistics removed in new DB' };
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user