First running version

This commit is contained in:
rxf
2023-03-24 13:49:54 +01:00
parent be8d364116
commit d10b274fe0
18 changed files with 1377 additions and 645 deletions
+4 -1
View File
@@ -6,11 +6,14 @@ import path from 'path'
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
const app = express() const app = express()
export let url2call
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename); const __dirname = path.dirname(__filename);
import indexRouter from './routes/index.js' import indexRouter from './routes/index.js'
import apiRouter from './routes/api.js'
// import getdataRouter from './routes/getdata.js' // import getdataRouter from './routes/getdata.js'
// import putdataRouter from './routes/putdata.js' // import putdataRouter from './routes/putdata.js'
@@ -24,6 +27,7 @@ app.use(express.urlencoded({ extended: false }));
app.use(cookieParser()); app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public'))); app.use(express.static(path.join(__dirname, 'public')));
app.use('/api', apiRouter)
app.use('/', indexRouter); app.use('/', indexRouter);
// app.use('/users', usersRouter); // app.use('/users', usersRouter);
@@ -43,5 +47,4 @@ app.use(function(err, req, res, next) {
res.render('error'); res.render('error');
}); });
export default app export default app
+596 -455
View File
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -11,13 +11,14 @@
"www": "./bin/www.js" "www": "./bin/www.js"
}, },
"dependencies": { "dependencies": {
"axios": "^1.3.4",
"cookie-parser": "~1.4.4", "cookie-parser": "~1.4.4",
"cors": "^2.8.5", "cors": "^2.8.5",
"debug": "~2.6.9", "debug": "~2.6.9",
"express": "~4.16.1", "express": "^4.18.2",
"http-errors": "~1.6.3", "http-errors": "~1.6.3",
"morgan": "~1.9.1", "morgan": "~1.9.1",
"pug": "2.0.0-beta11", "pug": "^3.0.2",
"sass": "^1.58.3" "sass": "^1.58.3"
} }
} }
+134
View File
@@ -0,0 +1,134 @@
// Sh0w the hour average chart
import {logit, logerror} from './logit.js'
import * as utils from './chart_utilities.js'
import {DateTime, Duration} from "./luxon.min.js"
// ******************************************************************
// PlotDayAVG_Noise
// ******************************************************************
export const showDayavg = async (params) => {
await PlotDayAVG_Noise(params.sid)
}
const PlotDayAVG_Noise = async function (sid) {
let series1 = []
let series2 = []
// read the data from the server
const url = `${utils.url}/getsensordata?sensorid=${sid}&data=davg`
let ret = await fetch(url)
.catch(e => {
logerror(e)
})
let data = await ret.json()
if(!data.err) {
// Put values into the serieses
let cnt = 0
data.values.forEach((x) => {
if(x.n_AVG != -1) {
let dat = new Date(x.datetime).getTime() // retrieve the date
series1.push([dat, x.n_AVG])
series2.push([dat, x.peakcount])
}
})
} else {
utils.showError(data.err)
}
let dlt = DateTime.now() // retrieve the date
dlt = dlt.minus({day:30})
// Plot-Options
let options = utils.createGlobObtions()
options.xAxis.plotBands = utils.calcWeekends(data, true)
options.xAxis.tickInterval = 24 * 3600 * 1000
options.xAxis.title = 'Date'
options.xAxis.labels = {
formatter: function () {
return this.axis.defaultLabelFormatter.call(this);
}
}
options.chart.type = 'column'
options.yAxis = {
title: {
text: 'dbA',
useHTML: true,
},
min: utils.noise_ymin,
tickAmount: 10,
gridLineColor: 'lightgray',
}
options.series = [
{
name: 'Mean value LAeq',
data: series1,
color: utils.colors.eq,
type: 'column',
zIndex: 2,
},
]
options.plotOptions.column = {
pointWidth: 20,
groupPadding: 0.1
}
options.title.text = 'Noise daily mean values'
options.subtitle.text = 'Daily mean values of LAeq for each full day <br />&nbsp'
options.subtitle.useHTML = true
options.chart.zoomType = 'x'
options.chart.resetZoomButton= {
position: {
align: 'left',
// verticalAlign: 'bottom',
x: 20,
y: 300,
},
relativeTo: 'chart'
}
options.tooltip.formatter = function () {
let y = Math.round(this.y * 10) / 10
return '<div style="border: 2px solid ' + this.point.color + '; padding: 3px;">' +
DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat("dd.LL") + '<br />' +
'<span style="color: ' + this.point.color + '">&#9679;&nbsp;</span>' +
this.series.name + ':&nbsp; <b>' + y + '</b></div>'
}
// Do PLOT 1
let ch = Highcharts.chart('dday', options, function (chart) {
utils.addSensorID2chart(chart, {sid: data.sid, indoor: data.indoor}, document.getElementById('dday').offsetWidth)
})
/*
// Do PLOT 2
options.series[0] = {
name: 'Peaks',
data: series2,
color: utils.colors.peaks,
type: 'column'
}
options.title.text = 'Peaks more than ' + data.peak + ' dbA'
options.subtitle.text = 'Number of exceedances per hour <br />&nbsp'
options.yAxis = {
title: {
text: 'Counts',
useHTML: true,
},
tickAmount: 10,
allowDecimals: false,
gridLineColor: 'lightgray',
}
options.tooltip.formatter = function () {
let y = Math.round(this.y)
return '<div style="border: 2px solid ' + this.point.color + '; padding: 3px;">' +
DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat("dd.LL - HH'h'") + '<br />' +
'<span style="color: ' + this.point.color + '">&#9679;&nbsp;</span>' +
this.series.name + ':&nbsp; <b>' + y + '</b></div>'
}
let ch1 = Highcharts.chart('dpeak', options)
*/
}
+160
View File
@@ -0,0 +1,160 @@
// Sh0w the hour average chart
import {logit, logerror} from './logit.js'
import * as utils from './chart_utilities.js'
import {DateTime, Duration} from "./luxon.min.js"
// ******************************************************************
// PlotDayNightAVG_Noise
// ******************************************************************
export const showDaynight = async (params) => {
await PlotDayNight_Noise(params.sid)
}
const PlotDayNight_Noise = async function (sid) {
let series1 = []
let series2 = []
// read the data from the server
const url = `${utils.url}/getsensordata?sensorid=${sid}&data=daynight`
let ret = await fetch(url)
.catch(e => {
logerror(e)
})
let data = await ret.json()
if(!data.err) {
// Put values into the serieses
let cnt = 0
data.values.forEach((x) => {
if(x.n_AVG != -1) {
let dat = new Date(x.datetime).getTime() // retrieve the date
series1.push([dat, x.n_dayAVG])
series2.push([dat, x.n_nightAVG])
}
})
} else {
utils.showError(data.err)
}
let dlt = DateTime.now() // retrieve the date
dlt = dlt.minus({day:30})
// Plot-Options
let options = utils.createGlobObtions()
options.xAxis.plotBands = utils.calcWeekends(data, true)
options.xAxis.tickInterval = 24 * 3600 * 1000
options.xAxis.title = 'Date'
options.xAxis.labels = {
formatter: function () {
return this.axis.defaultLabelFormatter.call(this);
}
}
options.chart.type = 'column'
options.yAxis = {
title: {
text: 'dbA',
useHTML: true,
},
min: utils.noise_ymin,
tickAmount: 10,
gridLineColor: 'lightgray',
}
options.series = [
{
name: 'Day',
data: series1,
color: utils.colors.eq,
type: 'column',
zIndex: 2,
},
{
name: 'Night',
data: series2,
color: utils.colors.max,
type: 'column',
zIndex: 2,
},
]
options.plotOptions.series = {
animation: false
}
options.plotOptions.column = {
pointWidth: 20,
groupPadding: 0.3
}
options.title.text = 'Noise Average values during the day and night hours'
options.subtitle.text = 'Daily mean values of LAeq from 6h00 to 22h00 <br /> Nightly mean values of LAeq from 22h00 to 6h00'
options.subtitle.useHTML = true
options.chart.zoomType = 'x'
options.chart.resetZoomButton= {
position: {
align: 'left',
// verticalAlign: 'bottom',
x: 20,
y: 300,
},
relativeTo: 'chart'
}
options.tooltip.formatter = function () {
let n = this.series.name.startsWith('Night')
let d = DateTime.fromMillis(this.x, {zone: 'utc'})
let d1 = d.plus({days: 1})
let txt = n ? d.toFormat('dd') + '/' + d1.toFormat('dd.LL') :
d.toFormat('dd.LL')
return '<div style="border: 2px solid ' + this.point.color + '; padding: 3px;">' +
'&nbsp;&nbsp;' + txt + '<br />' +
'<span style="color: ' + this.point.color + '">&#9679;&nbsp;</span>' +
this.series.name + ':&nbsp; <b>' +
Highcharts.numberFormat(this.y, 1) +
'</b></div>';
}
/*
formatter = function () {
let y = Math.round(this.y * 10) / 10
return '<div style="border: 2px solid ' + this.point.color + '; padding: 3px;">' +
DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat("dd.LL") + '<br />' +
'<span style="color: ' + this.point.color + '">&#9679;&nbsp;</span>' +
this.series.name + ':&nbsp; <b>' + y + '</b></div>'
}
*/
// Do PLOT 1
let ch = Highcharts.chart('ddaynight', options, function (chart) {
utils.addSensorID2chart(chart, {sid: data.sid, indoor: data.indoor}, document.getElementById('ddaynight').offsetWidth)
})
/*
// Do PLOT 2
options.series[0] = {
name: 'Peaks',
data: series2,
color: utils.colors.peaks,
type: 'column'
}
options.title.text = 'Peaks more than ' + data.peak + ' dbA'
options.subtitle.text = 'Number of exceedances per hour <br />&nbsp'
options.yAxis = {
title: {
text: 'Counts',
useHTML: true,
},
tickAmount: 10,
allowDecimals: false,
gridLineColor: 'lightgray',
}
options.tooltip.formatter = function () {
let y = Math.round(this.y)
return '<div style="border: 2px solid ' + this.point.color + '; padding: 3px;">' +
DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat("dd.LL - HH'h'") + '<br />' +
'<span style="color: ' + this.point.color + '">&#9679;&nbsp;</span>' +
this.series.name + ':&nbsp; <b>' + y + '</b></div>'
}
let ch1 = Highcharts.chart('dpeak', options)
*/
}
+129
View File
@@ -0,0 +1,129 @@
// Sh0w the hour average chart
import {logit, logerror} from './logit.js'
import * as utils from './chart_utilities.js'
import {DateTime, Duration} from "./luxon.min.js"
// ******************************************************************
// PlotHourAVG_Noise
// ******************************************************************
export const showHouravg = async (params) => {
await PlotHourAVG_Noise(params.sid)
}
const PlotHourAVG_Noise = async function (sid) {
let series1 = []
let series2 = []
// read the data from the server
const url = `${utils.url}/getsensordata?sensorid=${sid}&data=havg`
let ret = await fetch(url)
.catch(e => {
logerror(e)
})
let data = await ret.json()
if(!data.err) {
// Put values into the serieses
let cnt = 0
data.values.forEach((x) => {
if (x.n_AVG != -1) {
let dat = new Date(x.datetime).getTime() // retrieve the date
series1.push([dat, x.n_AVG])
series2.push([dat, x.peakcount])
}
})
} else {
utils.showError(data.err)
}
let dlt = DateTime.now() // retrieve the date
dlt = dlt.minus({day:1})
// Plot-Options
let options = utils.createGlobObtions()
options.xAxis.tickInterval = 6 * 3600 * 1000
options.xAxis.plotBands = utils.calcWeekends(data, true)
options.xAxis.minTickInterval = 3600 * 1000
options.yAxis = {
title: {
text: 'dbA',
useHTML: true,
},
min: utils.noise_ymin,
tickAmount: 10,
gridLineColor: 'lightgray',
}
options.series = [
{
name: 'Mean value LAeq',
data: series1,
color: utils.colors.eq,
type: 'column',
zIndex: 2,
},
]
options.plotOptions.column = {
pointWidth: 8,
groupPadding: 0.5
}
options.title.text = 'Noise hourly mean values'
options.subtitle.text = 'Hourly mean values of LAeq for each full hour <br />&nbsp'
options.subtitle.useHTML = true
options.chart.zoomType = 'x'
options.chart.height = 350
options.chart.resetZoomButton= {
position: {
align: 'left',
// verticalAlign: 'bottom',
x: 20,
y: 300,
},
relativeTo: 'chart'
}
options.tooltip.formatter = function () {
let y = Math.round(this.y * 10) / 10
return '<div style="border: 2px solid ' + this.point.color + '; padding: 3px;">' +
DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat("dd.LL - HH'h'") + '<br />' +
'<span style="color: ' + this.point.color + '">&#9679;&nbsp;</span>' +
this.series.name + ':&nbsp; <b>' + y + '</b></div>'
}
// Do PLOT 1
let ch = Highcharts.chart('dhour', options, function (chart) {
utils.addSensorID2chart(chart, {sid: data.sid, indoor: data.indoor}, document.getElementById('dhour').offsetWidth)
})
// Do PLOT 2
options.series[0] = {
name: 'Peaks',
data: series2,
color: utils.colors.peaks,
type: 'column'
}
options.title.text = 'Peaks more than ' + data.peak + ' dbA'
options.subtitle.text = 'Number of exceedances per hour <br />&nbsp'
options.yAxis = {
title: {
text: 'Counts',
useHTML: true,
},
tickAmount: 10,
allowDecimals: false,
gridLineColor: 'lightgray',
}
options.tooltip.formatter = function () {
let y = Math.round(this.y)
return '<div style="border: 2px solid ' + this.point.color + '; padding: 3px;">' +
DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat("dd.LL - HH'h'") + '<br />' +
'<span style="color: ' + this.point.color + '">&#9679;&nbsp;</span>' +
this.series.name + ':&nbsp; <b>' + y + '</b></div>'
}
let ch1 = Highcharts.chart('dpeak', options)
}
+112
View File
@@ -0,0 +1,112 @@
// Sh0w the hour average chart
import {logit, logerror} from './logit.js'
import * as utils from './chart_utilities.js'
import {DateTime, Duration} from "./luxon.min.js"
// ******************************************************************
// PlotLDEN_Noise
// ******************************************************************
export const showLden = async (params) => {
await PlotLDEN_Noise(params.sid)
}
const PlotLDEN_Noise = async function (sid) {
let series1 = []
// read the data from the server
const url = `${utils.url}/getsensordata?sensorid=${sid}&data=lden`
let ret = await fetch(url)
.catch(e => {
logerror(e)
})
let data = await ret.json()
if (!data.err) {
// Put values into the serieses
let cnt = 0
data.values.forEach((x) => {
if(x.n_AVG != -1) {
let dat = new Date(x.datetime).getTime() // retrieve the date
series1.push([dat, x.lden])
}
})
} else {
utils.showError(data.err)
}
let dlt = DateTime.now() // retrieve the date
dlt = dlt.minus({day:30})
// Plot-Options
let options = utils.createGlobObtions()
options.xAxis.plotBands = utils.calcWeekends(data, true)
options.xAxis.tickInterval = 24 * 3600 * 1000
options.xAxis.title = 'Date'
options.xAxis.labels = {
formatter: function () {
let lbl = this.axis.defaultLabelFormatter.call(this);
this.value += 86400000;
let lbl1 = this.axis.defaultLabelFormatter.call(this);
return parseInt(lbl) + '/' + lbl1;
}
}
options.chart.type = 'column'
options.yAxis = {
title: {
text: 'dbA',
useHTML: true,
},
min: utils.noise_ymin,
tickAmount: 10,
gridLineColor: 'lightgray',
}
options.series = [
{
name: 'lden',
data: series1,
color: utils.colors.eq,
type: 'column',
zIndex: 2,
}
]
options.plotOptions.series = {
animation: false
}
options.plotOptions.column = {
pointWidth: 20,
groupPadding: 0.1
}
options.title.text = 'Noise L<sub>DEN</sub>-Index'
options.subtitle.text = 'Daily mean values of L<sub>DEN</sub>\-Index'
options.subtitle.useHTML = true
options.chart.zoomType = 'x'
options.chart.resetZoomButton= {
position: {
align: 'left',
// verticalAlign: 'bottom',
x: 20,
y: 300,
},
relativeTo: 'chart'
}
options.tooltip.formatter = function () {
let d = DateTime.fromMillis(this.x, {zone: 'utc'})
let d1 = d.plus({days: 1})
let txt = d.toFormat('dd') + '/' + d1.toFormat('dd.LL')
return '<div style="border: 2px solid ' + this.point.color + '; padding: 3px;">' +
'&nbsp;&nbsp;' + txt + '<br />' +
'<span style="color: ' + this.point.color + '">&#9679;&nbsp;</span>' +
this.series.name + ':&nbsp; <b>' +
Highcharts.numberFormat(this.y, 1) +
'</b></div>';
}
let ch = Highcharts.chart('dlden', options, function (chart) {
utils.addSensorID2chart(chart, {sid: data.sid, indoor: data.indoor}, document.getElementById('dlden').offsetWidth)
})
}
+30 -21
View File
@@ -1,22 +1,18 @@
// Show the live data chart // Show the live data chart
import {logit, logerror} from './logit.js' import {logit, logerror} from './logit.js'
import * as utils from './chart_utilities.js' import * as utils from './chart_utilities.js'
import {DateTime} from "./luxon.min.js";
// ****************************************************************** // ******************************************************************
// PlotDayLive_Noise // PlotDayLive_Noise
// ****************************************************************** // ******************************************************************
let noise_ymin = 30; // lowest value on y-axis for noise
let noise_ymax = 120; // highest value on y-axis for noise
let activeTab = 0; // active TAB number
let peaklim = 70; // threshold for peak count
export const showLive = async (params) => {
export const showLive = (params) => { await PlotDayLive_Noise(params.sid)
PlotDayLive_Noise(37833)
} }
export const PlotDayLive_Noise = async (sid) => { const PlotDayLive_Noise = async (sid) => {
let series1 = [] let series1 = []
let series2 = [] let series2 = []
@@ -26,27 +22,29 @@ export const PlotDayLive_Noise = async (sid) => {
let aktVal = {} let aktVal = {}
// read the data from the server // read the data from the server
const url = `http://localhost:3004/getsensordata?type=noise&sensorid=${sid}` const url = `/api/getsensordata?&sensorid=${sid}`
let ret = await fetch(url) let ret = await fetch(url)
.catch(e => { .catch(e => {
logerror(e) logerror(e)
}); });
let sensors = await ret.json() let data = await ret.json()
let lastidx = sensors.count-1
if(!data.err) {
let lastidx = data.count - 1
// Put values into the arrays // Put values into the arrays
let cnt = 0 let cnt = 0
sensors.values.forEach((x) => { data.values.forEach((x) => {
let dat = new Date(x.datetime).getTime() let dat = new Date(x.datetime).getTime()
series1.push([dat, x.noise_LAeq]) series1.push([dat, x.noise_LAeq])
series2.push([dat, x.noise_LA_max]) series2.push([dat, x.noise_LA_max])
series3.push([dat, x.noise_LA_min]) // put data and value into series array series3.push([dat, x.noise_LA_min]) // put data and value into series array
}) })
if (sensors.values.length != 0) { if (data.values.length != 0) {
// Aktuelle Werte speichern // Aktuelle Werte speichern
aktVal['LAeq'] = sensors.values[lastidx].noise_LAeq aktVal['LAeq'] = data.values[lastidx].noise_LAeq
aktVal['LAMax'] = sensors.values[lastidx].noise_LA_max aktVal['LAMax'] = data.values[lastidx].noise_LA_max
aktVal['LAMin'] = sensors.values[lastidx].noise_LA_min aktVal['LAMin'] = data.values[lastidx].noise_LA_min
// InfoTafel füllen // InfoTafel füllen
let infoTafel = let infoTafel =
@@ -65,10 +63,13 @@ export const PlotDayLive_Noise = async (sid) => {
'</div>' '</div>'
} }
let txtMeldung = false let txtMeldung = false
} else {
utils.showError(data.err)
}
// Plot-Options // Plot-Options
let options = utils.createGlobObtions() let options = utils.createGlobObtions('dd.LL HH:mm:ss')
let series_LAeq = { let series_LAeq = {
name: 'LAeq', name: 'LAeq',
@@ -138,10 +139,11 @@ export const PlotDayLive_Noise = async (sid) => {
color: 'black' color: 'black'
} }
}, },
max: noise_ymax, max: utils.noise_ymax,
min: noise_ymin, // min: utils.noise_ymin,
min: 20,
// opposite: true, // opposite: true,
tickAmount: 10, tickAmount: 11,
useHTML: true, useHTML: true,
} }
@@ -167,6 +169,13 @@ export const PlotDayLive_Noise = async (sid) => {
}, },
relativeTo: 'chart' relativeTo: 'chart'
} }
options.tooltip.formatter = function () {
let y = Math.round(this.y * 100) / 100
return '<div style="border: 2px solid ' + this.point.color + '; padding: 3px;">' +
DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat("dd.LL - HH:mm:ss") + '<br />' +
'<span style="color: ' + this.point.color + '">&#9679;&nbsp;</span>' +
this.series.name + ':&nbsp; <b>' + y + '</b></div>'
}
let noDataTafel = '<div class="errTafel">' + let noDataTafel = '<div class="errTafel">' +
@@ -180,7 +189,7 @@ export const PlotDayLive_Noise = async (sid) => {
let navtime = [-24, -12, 0, 12, 24] let navtime = [-24, -12, 0, 12, 24]
let chr = Highcharts.chart('dlive', options, function (chart) { let chr = Highcharts.chart('dlive', options, function (chart) {
utils.addSensorID2chart(chart, sensors.props, document.getElementById('dlive').offsetWidth) utils.addSensorID2chart(chart, {sid: data.sid, indoor: data.indoor}, document.getElementById('dlive').offsetWidth)
// let breit = $(window).width() // let breit = $(window).width()
// let navx = breit-350 // let navx = breit-350
// chart.renderer.label( // chart.renderer.label(
+31 -43
View File
@@ -13,15 +13,19 @@ let nbrofdaysforavg = 8; // Stundenmittel Anzahl Tagte (default =
let nbrofdaysfordaynight = 30; // use 30 days or day/night graphic let nbrofdaysfordaynight = 30; // use 30 days or day/night graphic
let stucols = 1; // Anzeige nur Balken (StundenMittel) let stucols = 1; // Anzeige nur Balken (StundenMittel)
export const noise_ymin = 30; // lowest value on y-axis for noise
export const noise_ymax = 120; // highest value on y-axis for noise
let activeTab = 0; // active TAB number
export let peaklim = 70; // threshold for peak count
export const url = '/api'
export function createGlobObtions() { export function createGlobObtions() {
var globObject = {};
// Options, die für alle Plots identisch sind // Options, die für alle Plots identisch sind
globObject = { let globObject = {
chart: { chart: {
height: 600, height: 600,
// width: 1000; // width: 1000,
spacingRight: 20, spacingRight: 20,
spacingLeft: 20, spacingLeft: 20,
spacingTop: 25, spacingTop: 25,
@@ -51,7 +55,7 @@ export function createGlobObtions() {
useHTML: true, useHTML: true,
}, },
subtitle: { subtitle: {
text: 'Gemessene Werte und ' + avgTime + 'min-gleitende Mittelwerte', // text: 'Gemessene Werte und ' + avgTime + 'min-gleitende Mittelwerte',
align: 'left', align: 'left',
}, },
tooltip: { tooltip: {
@@ -60,14 +64,6 @@ export function createGlobObtions() {
borderWidth: 0, borderWidth: 0,
borderRadius: 0, borderRadius: 0,
useHTML: true, useHTML: true,
formatter: function () {
return '<div style="border: 2px solid ' + this.point.color + '; padding: 3px;">' +
DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat('dd.LL HH:mm:ss') + '<br />' +
'<span style="color: ' + this.point.color + '">&#9679;&nbsp;</span>' +
this.series.name + ':&nbsp; <b>' +
Highcharts.numberFormat(this.y, 1) +
'</b></div>';
}
}, },
xAxis: { xAxis: {
type: 'datetime', type: 'datetime',
@@ -106,16 +102,16 @@ export function createGlobObtions() {
return globObject; return globObject;
} }
function calcWeekends(data, isyear) { export function calcWeekends(data, isyear) {
var weekend = []; let weekend = [];
var oldDay = 8; let oldDay = 8;
for (var i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
var mom = moment(data[i].date); let mom = moment(data[i].date);
if (isyear) { if (isyear) {
mom = moment(data[i]._id) mom = moment(data[i]._id)
} }
var day = mom.day(); let day = mom.day();
var st = mom.startOf('day'); let st = mom.startOf('day');
if (day != oldDay) { if (day != oldDay) {
if (day == 6) { if (day == 6) {
weekend.push({ weekend.push({
@@ -138,21 +134,21 @@ function calcWeekends(data, isyear) {
return weekend; return weekend;
} }
function calcDays(data, isyear) { export function calcDays(data, isyear) {
var days = []; let days = [];
if (data.length == 0) { if (data.length == 0) {
return days return days
} }
var oldday = moment(data[0].date).day(); let oldday = moment(data[0].date).day();
if (isyear) { if (isyear) {
oldday = moment(data[0]._id).day(); oldday = moment(data[0]._id).day();
} }
for (var i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
var m = moment(data[i].date); let m = moment(data[i].date);
if (isyear) { if (isyear) {
m = moment(data[i]._id); m = moment(data[i]._id);
} }
var tag = m.day() let tag = m.day()
if (tag != oldday) { if (tag != oldday) {
m.startOf('day'); m.startOf('day');
days.push({color: 'lightgray', value: m.valueOf(), width: 1, zIndex: 2}); days.push({color: 'lightgray', value: m.valueOf(), width: 1, zIndex: 2});
@@ -162,26 +158,12 @@ function calcDays(data, isyear) {
return days; return days;
}; };
function getIndoor(sensor) { export async function addSensorID2chart(chart, sensor, width) {
let p = new Promise(function (resolve, reject) {
let url = '/api/getdata?data=props&sensorid=' + sensor;
$.get(url, (data, err) => {
if (err != 'success') {
resolve(false)
} else {
resolve(data.values[0].indoor == 1)
}
})
})
return p
}
export async function addSensorID2chart(chart, props, width) {
console.log('widht: ',width); console.log('widht: ',width);
let indoor = props.location[0].indoor let indoor =sensor.indoor
console.log('indoor: ',indoor) console.log('indoor: ',indoor)
let sens = chart.renderer.label( let sens = chart.renderer.label(
`Sensor: ${props._id} ${indoor ? ' (indoor)' : ''}`, `Sensor: ${sensor.sid} ${indoor ? ' (indoor)' : ''}`,
width / 2 - 100, 65, width / 2 - 100, 65,
'text', 0, 0, true) 'text', 0, 0, true)
.css({ .css({
@@ -192,3 +174,9 @@ export async function addSensorID2chart(chart, props, width) {
zIndex: 5, zIndex: 5,
}).add(); }).add();
} }
export const showError = (err) => {
document.querySelector('.modal-body').setHTML(err)
let myModal = new bootstrap.Modal(document.getElementById('dialogError'))
myModal.show()
}
+23 -4
View File
@@ -5,6 +5,10 @@ import * as map from './map.js'
import * as dt from './datetime.js' import * as dt from './datetime.js'
import {logit} from './logit.js' import {logit} from './logit.js'
import * as chart_live from './chart_live.js' import * as chart_live from './chart_live.js'
import * as chart_houravg from './chart_houravg.js'
import * as chart_dayavg from './chart_dayavg.js'
import * as chart_daynight from './chart_daynight.js'
import * as chart_lden from './chart_lden.js'
(async () => { (async () => {
@@ -31,12 +35,19 @@ import * as chart_live from './chart_live.js'
const tabtable = [ const tabtable = [
{id: 'kartentab', func: map.showMap}, {id: 'kartentab', func: map.showMap},
{id: 'livetab', func: chart_live.showLive}, {id: 'livetab', func: chart_live.showLive},
// {id: 'houravgtab', func: chart_houravg.showHouravg}, {id: 'houravgtab', func: chart_houravg.showHouravg},
// {id: 'dayavgtab', func: chart_dayavg.showDayavg}, {id: 'dayavgtab', func: chart_dayavg.showDayavg},
// {id: 'daynighttab', func: chart_daynight.showDaynight}, {id: 'daynighttab', func: chart_daynight.showDaynight},
// {id: 'ldentab', func: chart_lden.showLden}, {id: 'ldentab', func: chart_lden.showLden},
] ]
const removeTabs = () => {
document.querySelector('#navi').style.display = 'none'
}
const showTabs = () => {
document.querySelector('#navi').style.display = 'block'
}
async function main() { async function main() {
// initialise tabs // initialise tabs
let triggerTabList = [].slice.call(document.querySelectorAll('.nav-link')) let triggerTabList = [].slice.call(document.querySelectorAll('.nav-link'))
@@ -78,7 +89,15 @@ const tabtable = [
// show version and version-date // show version and version-date
document.querySelector('#versn').setHTML(`Version: ${sysparams.version} vom ${sysparams.date.slice(0,10)}`) document.querySelector('#versn').setHTML(`Version: ${sysparams.version} vom ${sysparams.date.slice(0,10)}`)
const csid = parseInt(sysparams.csid)
if(csid !== -1) {
let triggerEl = document.querySelector('#livetab')
bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name
params.sid = csid
await chart_live.showLive(params)
}
// show the map // show the map
removeTabs()
map.showMap(params) map.showMap(params)
} }
main().catch(console.error) main().catch(console.error)
+24 -78
View File
@@ -1,15 +1,18 @@
// all function related to the map // all function related to the map
import * as dt from './datetime.js' import * as dt from './datetime.js'
import * as chart_live from "./chart_live.js";
let map let map = null
let bounds let bounds
let popuptext = '' let popuptext = ''
let clickedSensor = 0
const colorscale = ['#d53e4f', '#fc8d59', '#fee08b', '#e6f598', '#99d594', '#3288bd', '#808080']; const colorscale = ['#d53e4f', '#fc8d59', '#fee08b', '#e6f598', '#99d594', '#3288bd', '#808080'];
const dba = [100, 80, 60, 40, 20, 0, -999]; const dba = [100, 80, 60, 40, 20, 0, -999];
export const showMap = async (params) => { export const showMap = async (params) => {
if (map) return
map = L.map('map',{ scrollWheelZoom: false}).setView(params.center, parseInt(params.zoom)) map = L.map('map',{ scrollWheelZoom: false}).setView(params.center, parseInt(params.zoom))
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19, maxZoom: 19,
@@ -37,8 +40,21 @@ export const showMap = async (params) => {
return div return div
}; };
legend.addTo(map) legend.addTo(map)
let lastdate = await buildMarkers() let lastdate = await buildMarkers()
showLastDate(lastdate); showLastDate(lastdate);
map.on('popupopen', function () {
document.querySelector('.speciallink').addEventListener('click', async function (x) {
console.log(`Event clicked: ${clickedSensor}`)
document.querySelector('#navi').style.display = 'block'
params.sid = clickedSensor
let triggerEl = document.querySelector('#livetab')
bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name
await chart_live.showLive(params)
})
})
} }
@@ -59,81 +75,7 @@ function calcPolygon(bounds) {
}); });
; ;
} }
/*
async function plotMap(cid, poly) {
// if sensor nbr is give, find coordinates, else use Stuttgart center
debug_log('plotMap()');
let myLatLng;
if (cid != -1) {
myLatLng = await getSensorKoords(cid);
} else {
let stgt = await getCoords('Stuttgart');
myLatLng = {lat: parseFloat(stgt.lat), lng: parseFloat(stgt.lon)};
}
// generate map centered on Stuttgart
map = L.map('map').setView(myLatLng, firstZoom);
L.tileLayer('https://{s}.tile.openstreetmap.de/{z}/{x}/{y}.png', {
maxZoom: 17,
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
bounds = map.getBounds();
map.scrollWheelZoom.disable();
map.on('moveend', async function () {
bounds = map.getBounds();
await buildMarkers(bounds)
});
let legend = L.control({position: 'bottomright'});
legend.onAdd = function (map) {
let div = L.DomUtil.create('div', 'info legend');
let div_color = L.DomUtil.create('div', 'info legend inner', div);
div_color.innerHTML += 'dbA<br />';
// loop through our density intervals and generate a label with a colored square for each interval
for (let i = 0; i < dba.length - 1; i++) {
div_color.innerHTML +=
'<i style="background:' + colorscale[i] + '"></i>' +
'&nbsp;&nbsp;' + dba[i] + (i == 0 ? '+' : '') + '<br />';
}
div_color.innerHTML += '&nbsp;<i style="background:' + getColor(dba[dba.length - 1]) + '"></i> offline';
return div;
};
legend.addTo(map);
let infobutton = L.control({position: 'topright'});
infobutton.onAdd = function (map) {
let div = L.DomUtil.create('div');
div.innerHTML = '<button class="cb centerbutt">neu zentrieren</button>';
div.onclick = function () {
dialogCenter.dialog('open');
console.log('Clicked on Zentrieren');
}
return div;
}
infobutton.addTo(map);
if (useStgtBorder) {
fetchStuttgartBounds();
}
if (myLatLng.error != undefined) {
showError(3, "Kein Lärmsensor", cid);
} else {
await buildMarkers(bounds);
map.on('popupopen', function () {
$('.speciallink').click(function (x) {
showGrafik(clickedSensor);
});
});
}
}
*/
// With all Markers in cluster (markers) calculate the median // With all Markers in cluster (markers) calculate the median
// of the values. With this median fetch the color and return it. // of the values. With this median fetch the color and return it.
@@ -212,7 +154,7 @@ export async function buildMarkers() {
west: bounds.getWest(), south: bounds.getSouth(), west: bounds.getWest(), south: bounds.getSouth(),
east: bounds.getEast(), north: bounds.getNorth() east: bounds.getEast(), north: bounds.getNorth()
} }
const url = `http://localhost:3004/getmapdata?type=noise&box=${bounds.toBBoxString()}` const url = `/api/getmapdata?type=noise&box=${bounds.toBBoxString()}`
let ret = await fetch(url) let ret = await fetch(url)
.catch(e => { .catch(e => {
@@ -235,6 +177,9 @@ export async function buildMarkers() {
}); });
for (let x of sensors.values) { for (let x of sensors.values) {
if (x.value <= -4) {
continue
}
let marker = L.marker([x.location[1], x.location[0]], { let marker = L.marker([x.location[1], x.location[0]], {
icon: new L.Icon({ icon: new L.Icon({
iconUrl: buildIcon(getColor(parseInt(x.value)),0,x.indoor), iconUrl: buildIcon(getColor(parseInt(x.value)),0,x.indoor),
@@ -256,7 +201,7 @@ export async function buildMarkers() {
async function onMarkerClick(e, click) { async function onMarkerClick(e, click) {
let item = e.target.options; let item = e.target.options;
let clickedSensor = item.name; clickedSensor = item.name;
let offlinetext = ` let offlinetext = `
<tr><td colspan="2"><span style="color:red;">offline</span></td></tr> <tr><td colspan="2"><span style="color:red;">offline</span></td></tr>
@@ -283,6 +228,7 @@ async function onMarkerClick(e, click) {
if (click == true) { // if we clicked if (click == true) { // if we clicked
e.target.closePopup(); // show the popup e.target.closePopup(); // show the popup
} }
} }
async function getCoords(city) { async function getCoords(city) {
@@ -328,7 +274,7 @@ async function showLastDate(ld) {
// console.log(e) // console.log(e)
// } // }
// fetch all sensors // fetch all sensors
const url = `http://localhost:3004/getmapdata?type=noise` const url = `/api/getmapdata?type=noise`
let ret = await fetch(url) let ret = await fetch(url)
.catch(e => { .catch(e => {
console.log(e) console.log(e)
+10 -2
View File
@@ -154,10 +154,18 @@ footer #author #versn {
margin-top: 44px; margin-top: 44px;
} }
#dlive, #dhour, #dday, #ddaynight, #dlden { #dlive, #dhour, #dday, #ddaynight, #dlden, #dpeak {
width: 98vw; width: 100%;
height: 100%; height: 100%;
margin: auto; margin: auto;
} }
#dialogError {
color: red;
}
.modal-content {
border: red solid 2px;
}
/*# sourceMappingURL=style.css.map */ /*# sourceMappingURL=style.css.map */
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sourceRoot":"","sources":["style.sass"],"names":[],"mappings":"AAWA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;EACA;EACA;EAEA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE,kBA7BoB;;AA+BpB;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;;;AAEJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;EACA;;AACA;EACE;;;AAEN;EACE;EAEA;EACA;EACA,eA3Ec;EA4Ed;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACF;EACE;EACA;;;AAEJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AACF;EACE;EACA;;;AAEJ;EACE,kBA/FoB;;AAiGpB;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;;;AAGN;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA","file":"style.css"} {"version":3,"sourceRoot":"","sources":["style.sass"],"names":[],"mappings":"AAWA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;EACA;EACA;EAEA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE,kBA7BoB;;AA+BpB;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;;;AAEJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;EACA;;AACA;EACE;;;AAEN;EACE;EAEA;EACA;EACA,eA3Ec;EA4Ed;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACF;EACE;EACA;;;AAEJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AACF;EACE;EACA;;;AAEJ;EACE,kBA/FoB;;AAiGpB;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;;;AAGN;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE","file":"style.css"}
+8 -2
View File
@@ -150,7 +150,13 @@ footer
.tab-pane .tab-pane
margin-top: 44px margin-top: 44px
#dlive, #dhour, #dday, #ddaynight, #dlden #dlive, #dhour, #dday, #ddaynight, #dlden, #dpeak
width: 98vw width: 100%
height: 100% height: 100%
margin: auto margin: auto
#dialogError
color: red
.modal-content
border: red solid 2px
+37
View File
@@ -0,0 +1,37 @@
import express from 'express'
import pkg from '../package.json' assert { type: "json" }
import axios from 'axios'
const router = express.Router()
const { name, version, date } = pkg
let APIHOST = process.env.APIHOST || 'http://localhost:3004'
/* GET home page. */
router.get('/:cmd', async function(req, res, next) {
const cmd = req.params.cmd
let url = APIHOST
if(isNaN(cmd)) {
url += req.originalUrl
} else {
// cmd is a number ==> sid
url += `getsensordata?sid=${cmd}`
}
try {
const response = await axios(encodeURI(url));
if (response.status !== 200) {
res.json({err: `Error from servercall: status = ${response.status}`})
}
res.json(response.data)
} catch (e) {
res.json({err: `Error from servercall: ${e}`})
}
})
export default router
// ToDo
// Hier : getsensordata und getmapdata unterbringen und damit den externen Server aufrufen
+24 -1
View File
@@ -1,16 +1,39 @@
import express from 'express' import express from 'express'
import pkg from '../package.json' assert { type: "json" } import pkg from '../package.json' assert { type: "json" }
import axios from "axios";
const router = express.Router() const router = express.Router()
const { name, version, date } = pkg const { name, version, date } = pkg
let APIHOST = process.env.APIHOST || 'http://localhost:3004'
/* GET home page. */ /* GET home page. */
router.get('/', function(req, res, next) { router.get('/', function(req, res, next) {
res.render('index', { res.render('index', {
title: name, title: name,
version: version, version: version,
date: date date: date,
csensor: -1
}) })
}) })
router.get('/:sid', async function(req, res, next) {
const sid = req.params.sid
if(!isNaN(sid)) {
res.render('index', {
title: name,
version: version,
date: date,
csensor: sid
})
}
})
export default router export default router
// ToDo
// Hier : getsensordata und getmapdata unterbringen und damit den externen Server aufrufen
+20 -5
View File
@@ -18,9 +18,9 @@ block content
li.nav-item(role='presentation') li.nav-item(role='presentation')
button.nav-link#dayavgtab(data-bs-toggle="tab" data-bs-target="#t_dayavg" type="button" role="tab" aria-controls="dayavg" aria-selected="true") Day_AVG button.nav-link#dayavgtab(data-bs-toggle="tab" data-bs-target="#t_dayavg" type="button" role="tab" aria-controls="dayavg" aria-selected="true") Day_AVG
li.nav-item(role='presentation') li.nav-item(role='presentation')
button.nav-link#daynightab(data-bs-toggle="tab" data-bs-target="#t_daynight" type="button" role="tab" aria-controls="daynight" aria-selected="true") Day_Night button.nav-link#daynighttab(data-bs-toggle="tab" data-bs-target="#t_daynight" type="button" role="tab" aria-controls="daynight" aria-selected="true") Day_Night
li.nav-item(role='presentation') li.nav-item(role='presentation')
button.nav-link#ldenab(data-bs-toggle="tab" data-bs-target="#t_lden" type="button" role="tab" aria-controls="lden" aria-selected="true") L<sub>DEN</sub>-Index button.nav-link#ldentab(data-bs-toggle="tab" data-bs-target="#t_lden" type="button" role="tab" aria-controls="lden" aria-selected="true") L<sub>DEN</sub>-Index
#buttonsRight #buttonsRight
button.btn.btn-primary#btnSet(value='set') Settings button.btn.btn-primary#btnSet(value='set') Settings
button.btn.btn-primary#btnHelp(value='help') Info button.btn.btn-primary#btnHelp(value='help') Info
@@ -32,12 +32,27 @@ block content
#actsensors #actsensors
#mapdate #mapdate
.tab-pane.fade#t_live(role="tabpanel" aria-labelledby="live-tab") .tab-pane.fade#t_live(role="tabpanel" aria-labelledby="live-tab")
#dlive LiveTAB #dlive
.tab-pane.fade#t_houravg(role="tabpanel" aria-labelledby="map-tab") .tab-pane.fade#t_houravg(role="tabpanel" aria-labelledby="map-tab")
#dhour HourTAB #dhour
#dpeak
.tab-pane.fade#t_dayavg(role="tabpanel" aria-labelledby="map-tab") .tab-pane.fade#t_dayavg(role="tabpanel" aria-labelledby="map-tab")
#dday DayTAB #dday
.tab-pane.fade#t_daynight(role="tabpanel" aria-labelledby="map-tab") .tab-pane.fade#t_daynight(role="tabpanel" aria-labelledby="map-tab")
#ddaynight DayNightTAB #ddaynight DayNightTAB
.tab-pane.fade#t_lden(role="tabpanel" aria-labelledby="map-tab") .tab-pane.fade#t_lden(role="tabpanel" aria-labelledby="map-tab")
#dlden LdenTAB #dlden LdenTAB
// Error-Dialog
.modal.fade#dialogError(tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true")
.modal-dialog.modal-dialog-centered(role="document")
.modal-content
.modal-header
h5.modal-title.dialogErrorTitle Error
button(type="button" class="close" data-bs-dismiss="modal" aria-label="Close")
span(aria-hidden="true") &times;
.modal-body
.modal-footer
//button(type="button" class="btn btn-secondary" data-bs-dismiss="modal") Close
// button(type="button" class="btn btn-primary") Save changes
+2 -1
View File
@@ -15,7 +15,8 @@ html
script. script.
let sysparams = { let sysparams = {
version: '#{version}', version: '#{version}',
date: '#{date}' date: '#{date}',
csid: '#{csensor}'
} }
let urlParams = { let urlParams = {
// drawlines: '#{drawlines}' === 'true', // drawlines: '#{drawlines}' === 'true',