Compare commits

..

10 Commits

Author SHA1 Message Date
admin 74776e1762 Version erhöht, Log beim Anmelden an der Mongo entfernt 2026-06-30 16:38:10 +00:00
admin 75ccb0b8ea Package.json updated
getporpertie leist nun auch die Chipdaten aus prop_flux
2025-09-15 16:11:13 +00:00
admin 41ef7a06b2 logfile ins .gitignore 2025-08-08 06:03:13 +00:00
admin 4458d773c2 added deploy.sh 2024-11-11 17:24:32 +00:00
admin dc723f7941 getaddress: send User-Agent to Nominatim 2024-11-11 11:09:49 +00:00
admin 3fbe3fb025 add message at start of program
Version updated
2023-11-29 16:18:56 +00:00
admin c10001754f getCityCoords added
remove 'noise_' on every value
2023-11-28 15:12:20 +00:00
admin c6b56207dd return csv string 2023-11-21 21:07:47 +00:00
admin 70f928d961 viele Anpassungen 2023-11-07 08:05:54 +00:00
admin 91e55f58bf get addresse as object
actions/getaddress.js
   - return address as object

sensorspecials/noise.js
   - use mongo instead of influx
2023-07-02 20:24:37 +02:00
19 changed files with 5251 additions and 1939 deletions
+9
View File
@@ -0,0 +1,9 @@
build_and_copy.sh
Dockerfile_sensorapi
docker-compose.yml
.vscode
log
mocks
test
node_modules
doc
+1
View File
@@ -2,3 +2,4 @@ node_modules/
.idea .idea
.env* .env*
.DS_Store .DS_Store
sensorapi.log
+46 -7
View File
@@ -4,6 +4,24 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch reception",
"skipFiles": [
"<node_internals>/**"
],
"env": {
"DEBUG": "sensorapi:*",
"INFLUXHOST": "192.168.178.190",
"INFLUXTOKEN": "gHGGgjaK0lmM6keMa01JeuDpqOE_vRq8UimsU4QKb2miI5BDh2PfWynEbwKizdJapXy8jVbTat5mVZLQTNmSdw==",
"MONGOHOST": "192.168.178.190",
"MONGOAUTH": "true",
"MONGOUSRP": "admin:mongo4noise",
// "DBASE": "influx",
},
"program": "${workspaceFolder}/bin/www.js"
},
{ {
"type": "node", "type": "node",
"request": "launch", "request": "launch",
@@ -13,23 +31,44 @@
], ],
"program": "${workspaceFolder}/bin/www.js", "program": "${workspaceFolder}/bin/www.js",
"env": { "env": {
"INFLUXHOST": "esprimo", "DEBUG": "sensorapi:*",
"INFLUXTOKEN": "uhsrE9MZtlVD18JnP19y0O0NW9C8HaQV3ElyAT_VwUlreluNsc9rM4djI9H10f6Dcw4oMFUzSngAo9dxtLjUoA==", "MONGOUSRP": "admin:mongo4noise",
"MONGOHOST": "esprimo", "MONGOPORT": "27037",
"MONGOPORT": "27098" "MONGOHOST": "217.72.203.152",
//"MONGOUSRP": "rexfue:5g2h4j3XC$$C$§442dcdsvDCx",
"MONGOAUTH": "true",
"INFLUXTOKEN": "q35XUBaElzcy8dDd9HF2_mpeHvYCampZg_9mJNP5jeBQRopq3EWIzNTZ555QLSIXhZC05RXCoFgjiaT7VzyNkQ==",
"DEVELOP": "true",
} }
}, },
{ {
"type": "node", "type": "node",
"request": "launch", "request": "launch",
"name": "Launch strato", "name": "Ralf",
"skipFiles": [ "skipFiles": [
"<node_internals>/**" "<node_internals>/**"
], ],
"program": "${workspaceFolder}/bin/www.js", "program": "${workspaceFolder}/bin/www.js",
"env": { "env": {
"MONGOHOST": "h3006374.stratoserver.net", "MONGOHOST": "192.168.51.22",
"MONGOPORT": "27097" "MONGOAUTH": "true",
"MONGOUSRP": "rexfue:s25BMmW2gg",
}
},
{
"type": "node",
"request": "launch",
"name": "Launch localhost",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/bin/www.js",
"env": {
"INFLUXHOST": "localhost",
"INFLUXTOKEN": "Pt7cDkKS1pAI2a0qsAhfSY97EVsfeNwJxo-ZdiNvfwC4kBiqxmoj7WbR7XkNRr23YELydv_9HXrN2SMofq9vhQ==",
"MONGOHOST": "localhost",
"MONGOPORT": "27017",
"DEBUG": "sensorapi:*"
} }
} }
] ]
+10 -6
View File
@@ -9,7 +9,7 @@ const DEFAULT_DISTANCE = 10
// Value to use fpr map // Value to use fpr map
const value4map = [ const value4map = [
{ typ: 'noise', value: 'noise_LA_max'}, { typ: 'noise', value: 'LA_max'},
{ typ: 'pm', value: 'P1'}, { typ: 'pm', value: 'P1'},
{ typ: 'thp', value: 'temperature'}, { typ: 'thp', value: 'temperature'},
{ typ: 'radioactivity', value: 'counts_per_minute'}, { typ: 'radioactivity', value: 'counts_per_minute'},
@@ -29,7 +29,7 @@ const getValue4Map = (t) => {
const vtype2measurement = { const vtype2measurement = {
P1: 'pm', P2: 'pm', P0: 'pm', P1: 'pm', P2: 'pm', P0: 'pm',
temperature: 'thp', humidity: 'thp', pressure: 'thp', temperature: 'thp', humidity: 'thp', pressure: 'thp',
noise_LAeq: 'noise', LAeq: 'noise',
counts_per_minute: 'radioactivity' counts_per_minute: 'radioactivity'
}; };
@@ -135,8 +135,9 @@ export var getData4map = async (params) => {
} }
let v4map = getValue4Map(typ) let v4map = getValue4Map(typ)
for (let sensor of properties) { for (let sensor of properties) {
let id = sensor._id let oneAktData = {}
const oneAktData = { if (sensor.values !== undefined) {
oneAktData = {
location: sensor.location[0].loc.coordinates, location: sensor.location[0].loc.coordinates,
id: sensor._id, id: sensor._id,
name: sensor.name[0].name, name: sensor.name[0].name,
@@ -144,7 +145,6 @@ export var getData4map = async (params) => {
lastseen: sensor.values.timestamp lastseen: sensor.values.timestamp
} }
let now = new Date().getTime() let now = new Date().getTime()
oneAktData.value = -1
if(oneAktData.lastseen !== '') { if(oneAktData.lastseen !== '') {
let diff = now - oneAktData.lastseen.getTime() let diff = now - oneAktData.lastseen.getTime()
if (diff >= 365 * 24 * 3600 * 1000) { if (diff >= 365 * 24 * 3600 * 1000) {
@@ -166,9 +166,13 @@ export var getData4map = async (params) => {
if (sensor.values.timestamp > lastDate) { if (sensor.values.timestamp > lastDate) {
lastDate = sensor.values.timestamp lastDate = sensor.values.timestamp
} }
} else {
oneAktData.value = -5
oneAktData.weeks = 0
oneAktData.lastseen = ''
}
aktData.push(oneAktData) aktData.push(oneAktData)
} }
// logit(`Query duration: ${start.diffNow('seconds').toObject().seconds * -1} sec`)
ret = { ret = {
err: null, err: null,
options: { options: {
+30 -3
View File
@@ -2,8 +2,27 @@ import {returnOnError} from "../utilities/reporterror.js"
import axios from 'axios' import axios from 'axios'
import {logit} from "../utilities/logit.js" import {logit} from "../utilities/logit.js"
import {getOneProperty} from "./getproperties.js" import {getOneProperty} from "./getproperties.js"
import { response } from "express"
const NOMINATIM_URL = `https://nominatim.openstreetmap.org/reverse?lat=${'xx'}&lon=${'yy'}&format=json` const NOMINATIM_URL = `https://nominatim.openstreetmap.org/reverse?lat=${'xx'}&lon=${'yy'}&format=json`
const NOMINATIM_CITY_URL = `https://nominatim.openstreetmap.org/?q="${'xx'}"&format=json`
export const getCityCoords = async (params) => {
let ret = {coords: [], city: params.city, err: null}
let url = NOMINATIM_CITY_URL.replace('xx', params.city)
// let url = 'https://nominatim.openstreetmap.org/?q="K%C3%B6ln"&format=json'
try {
const response = await axios(url)
if (response.status !== 200) {
return returnOnError(ret, 'RESPSTATUS', getCityCoord.name, response.status)
}
ret.coords = [response.data[0].lat,response.data[0].lon]
logit(JSON.stringify(ret.coords))
} catch (e) {
return returnOnError(ret, e, getCityCoords.name)
}
return ret
}
export const getAddress = async (params) => { export const getAddress = async (params) => {
let ret = {address: "", err: null} let ret = {address: "", err: null}
@@ -14,12 +33,16 @@ export const getAddress = async (params) => {
let coord = props.location[0].loc.coordinates let coord = props.location[0].loc.coordinates
let url = NOMINATIM_URL.replace('xx', coord[1]).replace('yy', coord[0]) let url = NOMINATIM_URL.replace('xx', coord[1]).replace('yy', coord[0])
try { try {
const response = await axios(encodeURI(url)); const response = await axios(encodeURI(url),{
headers: {
'User-Agent': 'Firefox 132.0.1'
}
});
if (response.status !== 200) { if (response.status !== 200) {
return returnOnError(ret, 'RESPSTATUS', getAddress.name, response.status) return returnOnError(ret, 'RESPSTATUS', getAddress.name, response.status)
} }
let akt = response.data.address let akt = response.data.address
logit(JSON.stringify(akt)) // logit(JSON.stringify(akt))
const CITY = ['city', 'town', 'village', 'suburb', 'county'] const CITY = ['city', 'town', 'village', 'suburb', 'county']
let city = "unknown" let city = "unknown"
for (let c of CITY) { for (let c of CITY) {
@@ -28,7 +51,11 @@ export const getAddress = async (params) => {
break break
} }
} }
ret.address = `${(akt.road ? akt.road : "")} ${(akt.postcode ? akt.postcode : "")} ${city}`; // ret.address = `${(akt.road ? akt.road : "")} ${(akt.postcode ? akt.postcode : "")} ${city}`;
ret.address = {
street: `${(akt.road ? akt.road : "")}`,
plz: `${(akt.postcode ? akt.postcode : "")}`,
city: `${city}`}
} catch (e) { } catch (e) {
return returnOnError(ret, e, getAddress.name) return returnOnError(ret, e, getAddress.name)
} }
+8 -10
View File
@@ -1,26 +1,24 @@
// Fetch the properties for the given sensor // Fetch the properties for the given sensor
import * as mongo from "../databases/mongo.js" import * as mongo from "../databases/mongo.js"
import * as mock from "../mocks/mongo_mock.js"
import {returnOnError} from "../utilities/reporterror.js" import {returnOnError} from "../utilities/reporterror.js"
import checkParams from "../utilities/checkparams.js" import checkParams from "../utilities/checkparams.js"
const mockdb = false let readProperties = mongo.readProperties
let readChipData = mongo.readChipData
let readProperties
if (mockdb) {
readProperties = mock.readProperties
} else {
readProperties = mongo.readProperties
}
// Read properties for sensorid and properties for all other sensors on same location // Read properties for sensorid and properties for all other sensors on same location
export const getOneProperty = async (params) => { export const getOneProperty = async (params) => {
let properties = {props: {}, err: null} let properties = {err: null, props: {}, chip: {}}
let {opts, err} = checkParams(params, {mandatory:[{name:'sensorid', type: 'int'}], optional:[]}) let {opts, err} = checkParams(params, {mandatory:[{name:'sensorid', type: 'int'}], optional:[]})
if (err) { if (err) {
return returnOnError(properties, err, getOneProperty.name) return returnOnError(properties, err, getOneProperty.name)
} }
// read 'chip'-data (special for noise sensors)
const chipdata = await readChipData(opts.sensorid)
if (chipdata.err === null) {
properties.chip = chipdata
}
let sensorEntries = []; let sensorEntries = [];
try { try {
let pp = await readProperties({sid: opts.sensorid}); // read for given sensorID let pp = await readProperties({sid: opts.sensorid}); // read for given sensorID
+15 -13
View File
@@ -1,5 +1,6 @@
// get data for one sensor // get data for one sensor
const DBASE = process.env.DBASE || 'mongo'
import {DateTime} from "luxon" import {DateTime} from "luxon"
import * as influx from "../databases/influx.js" import * as influx from "../databases/influx.js"
import * as mongo from "../databases/mongo.js" import * as mongo from "../databases/mongo.js"
@@ -86,18 +87,18 @@ export const calcRange = (opts) => {
let start, end let start, end
let ret = { start: start, stop: end, err: null} let ret = { start: start, stop: end, err: null}
if((opts.datetime === null) || (opts.datetime === undefined) || (opts.datetime === '')) { if((opts.datetime === null) || (opts.datetime === undefined) || (opts.datetime === '')) {
start = end = DateTime.local() start = end = DateTime.local().toUTC()
start = start.minus({days: opts.span}) start = start.minus({days: opts.span})
} else { } else {
start = end = DateTime.fromISO(opts.datetime) start = end = DateTime.fromISO(opts.datetime).toUTC()
end = end.plus({days: opts.span}) end = end.plus({days: opts.span})
} }
if(opts.daystart) { if(opts.daystart) {
start = start.startOf("day") start = start.startOf("day")
end = end.startOf("day") end = end.startOf("day")
} }
start = start.toUTC() // start = start.toUTC()
end = end.toUTC() // end = end.toUTC()
// if(opts.avg !== undefined) { // if(opts.avg !== undefined) {
// start = start.minus({minutes: opts.avg}) // start = start.minus({minutes: opts.avg})
// } // }
@@ -150,11 +151,12 @@ export async function getSensorData(params) {
// export const getActData = async (opts) => { // export const getActData = async (opts) => {
export async function getActData(opts) { export async function getActData(opts) {
// let retI = await influx.fetchActData(opts) if (DBASE === 'mongo') {
// retI.mongo = false return await mongo.fetchActData(opts)
let retM = await mongo.fetchActData(opts) } else if (DBASE === 'influx') {
retM.mongo = true return await influx.fetchActData(opts)
return retM }
return {err: 'DBASEUNKNOWN', values: []}
} }
@@ -248,8 +250,8 @@ export var getLongAvg = async (params) => {
// return // return
// JSON // JSON
// { avgs: [ // { avgs: [
// { location: [ 9.00, 48.80 ], id: 29174, lastSeen: "2019-10-23T12:03:00.000Z", noise_max: "65" } // { location: [ 9.00, 48.80 ], id: 29174, lastSeen: "2019-10-23T12:03:00.000Z", max: "65" }
// { location: [ 9.10, 49.80 ], id: 28194, lastSeen: "2019-10-22T16:03:00.000Z", noise_max: "45" } // { location: [ 9.10, 49.80 ], id: 28194, lastSeen: "2019-10-22T16:03:00.000Z", max: "45" }
// ......... // .........
// ], lastDate: "2019-10-29T15:05:59.000Z" } // ], lastDate: "2019-10-29T15:05:59.000Z" }
// //
@@ -293,8 +295,8 @@ export const getMAPaktData = async (opt) => {
oneAktData['noise_max'] = -1 // -1 zurückgeben oneAktData['noise_max'] = -1 // -1 zurückgeben
} else { } else {
oneAktData['noise_max'] = -5 // bedutet -> nicht anzeigen oneAktData['noise_max'] = -5 // bedutet -> nicht anzeigen
if (item.values.hasOwnProperty('noise_LA_max')) { if (item.values.hasOwnProperty('LA_max')) {
oneAktData['noise_max'] = item.values.noise_LA_max.toFixed(0) // und merken oneAktData['noise_max'] = item.values.LA_max.toFixed(0) // und merken
} }
if (dati > lastDate) { if (dati > lastDate) {
lastDate = dati lastDate = dati
+5
View File
@@ -6,6 +6,9 @@ import cors from 'cors'
import i18next from 'i18next' import i18next from 'i18next'
import i18nextMiddleware from 'i18next-http-middleware' import i18nextMiddleware from 'i18next-http-middleware'
import Backend from 'i18next-node-fs-backend' import Backend from 'i18next-node-fs-backend'
import {logit} from "./utilities/logit.js"
import pkg from './package.json' with { type: "json" }
const app = express() const app = express()
@@ -58,4 +61,6 @@ app.use(function(err, req, res, next) {
res.send(`ERROR: ${err.status}, ${err.stack}`) res.send(`ERROR: ${err.status}, ${err.stack}`)
}) })
logit(`Start of Program Version: ${pkg.version} vom ${pkg.date}`)
export default app export default app
+4 -2
View File
@@ -5,10 +5,11 @@
*/ */
import app from '../app.js' import app from '../app.js'
import debug from 'debug' import Debug from 'debug'
import http from 'http' import http from 'http'
// const debug = 'untitled1:server' const debug = Debug('sensorapi:*')
/** /**
* Get port from environment and store in Express. * Get port from environment and store in Express.
*/ */
@@ -88,4 +89,5 @@ function onListening() {
? 'pipe ' + addr ? 'pipe ' + addr
: 'port ' + addr.port; : 'port ' + addr.port;
debug('Listening on ' + bind); debug('Listening on ' + bind);
console.log('Listening on ' + bind);
} }
+3 -3
View File
@@ -9,9 +9,9 @@ import {csv2Json} from "../utilities/csv2json.js";
let INFLUXHOST = process.env.INFLUXHOST || "localhost" let INFLUXHOST = process.env.INFLUXHOST || "localhost"
let INFLUXPORT = process.env.INFLUXPORT || 8086 let INFLUXPORT = process.env.INFLUXPORT || 8086
let INFLUXTOKEN = process.env.INFLUXTOKEN || let INFLUXTOKEN = process.env.INFLUXTOKEN || ""
//"rklEClT22KfdXZhA47eyJhbqcvekb8bcKCqlUG7n72uDSmR2xGvif0CmGJe0WQtXB96y29mmt-9BdsgWA5npfg==" //"rklEClT22KfdXZhA47eyJhbqcvekb8bcKCqlUG7n72uDSmR2xGvif0CmGJe0WQtXB96y29mmt-9BdsgWA5npfg=="
"BNR6cGdb006O1T6hQkGcfB8tgH-UPO6QkOPToeAvrP7LATJbCuWi1wYf3HBpVdZQEBxHxNSrNenZsOSMogX-lg==" //"BNR6cGdb006O1T6hQkGcfB8tgH-UPO6QkOPToeAvrP7LATJbCuWi1wYf3HBpVdZQEBxHxNSrNenZsOSMogX-lg=="
let INFLUXDATABUCKET = process.env.INFLUXDATABUCKET || "sensor_data" let INFLUXDATABUCKET = process.env.INFLUXDATABUCKET || "sensor_data"
let INFLUXORG = process.env.INFLUXORG || "citysensor" let INFLUXORG = process.env.INFLUXORG || "citysensor"
@@ -142,7 +142,7 @@ esum = data
|> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value") |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
|> rename(columns: {"E10tel_eq" : "n_sum"}) |> rename(columns: {"E10tel_eq" : "n_sum"})
peak = data peak = data
|> filter(fn: (r) => r._field == "noise_LA_max") |> filter(fn: (r) => r._field == "LA_max")
|> aggregateWindow( |> aggregateWindow(
every: 1h, every: 1h,
fn: (column, tables=<-) => tables fn: (column, tables=<-) => tables
View File
+57 -12
View File
@@ -14,23 +14,23 @@ let MONGOUSRP = process.env.MONGOUSRP;
let MONGOBASE = process.env.MONGOBASE; let MONGOBASE = process.env.MONGOBASE;
if (MONGOHOST === undefined) { MONGOHOST = 'localhost';} if (MONGOHOST === undefined) { MONGOHOST = 'localhost';}
if (MONGOPORT === undefined) { MONGOPORT = 27097; } if (MONGOPORT === undefined) { MONGOPORT = 27017; }
if (MONGOAUTH === undefined) { MONGOAUTH = 'false'; } if (MONGOAUTH === undefined) { MONGOAUTH = 'false'; }
if (MONGOBASE === undefined) { MONGOBASE = 'allsensors'; } if (MONGOBASE === undefined) { MONGOBASE = 'sensor_data'; }
let MONGO_URL = 'mongodb://'+MONGOHOST+':'+MONGOPORT; // URL to mongo database let MONGO_URL = 'mongodb://'+MONGOHOST+':'+MONGOPORT; // URL to mongo database
if (MONGOAUTH === 'true') { if (MONGOAUTH === 'true') {
MONGO_URL = 'mongodb://'+MONGOUSRP+'@' + MONGOHOST + ':' + MONGOPORT + '/?authSource=' + MONGOBASE; // URL to mongo database // MONGO_URL = 'mongodb://'+MONGOUSRP+'@' + MONGOHOST + ':' + MONGOPORT + '/?authSource=' + MONGOBASE; // URL to mongo database
MONGO_URL = 'mongodb://'+MONGOUSRP+'@' + MONGOHOST + ':' + MONGOPORT + '/?authSource=admin'; // URL to mongo database
} }
export const properties_collection = 'pptest' export const properties_collection = 'properties'
export const connectMongo = async () => { export const connectMongo = async () => {
try { try {
// logit(`Try to connect to ${MONGO_URL}`) // logit(`Try to connect to ${MONGO_URL}`)
// let client = await MongoClient.connect(MONGO_URL, { useNewUrlParser: true , useUnifiedTopology: true })
let client = await MongoClient.connect(MONGO_URL) let client = await MongoClient.connect(MONGO_URL)
logit(`Mongodbase connected to ${MONGO_URL}`) // logit(`Mongodbase connected to ${MONGO_URL}`)
return client return client
} }
catch(error){ catch(error){
@@ -68,6 +68,21 @@ export const readProperties = async (query, limit = 0) => {
return ret return ret
} }
export const readChipData = async (sid) => {
let ret = { err: null, chipdata: null}
let client = await connectMongo()
try {
ret.chipdata = await client.db(MONGOBASE).collection('prop_flux').findOne({_id: sid},{projection: {chip: 1, _id: 0}})
} catch (e) {
ret.err = e
}
finally {
client.close()
}
return ret
}
// read mapdata from database // read mapdata from database
export const readMapdata = async (query, limit) => { export const readMapdata = async (query, limit) => {
let ret = {err: null, mapdata: []} let ret = {err: null, mapdata: []}
@@ -104,7 +119,7 @@ export const getOneproperty = async (sid) => {
let ret = {error: false} let ret = {error: false}
let client = await connectMongo() let client = await connectMongo()
try { try {
ret.properties = await client.db(MONGOBASE).collection("properties_collection") ret.properties = await client.db(MONGOBASE).collection(properties_collection)
.findOne({_id: sid}) .findOne({_id: sid})
} catch (e) { } catch (e) {
ret = {error: true, errortext: e} ret = {error: true, errortext: e}
@@ -154,8 +169,30 @@ export const fetchActData = async (opts) => {
let options = { projection: {_id: 0, values: 1, datetime: 1}, sort: {datetime: 1}} let options = { projection: {_id: 0, values: 1, datetime: 1}, sort: {datetime: 1}}
let client = await connectMongo() let client = await connectMongo()
try { try {
ret.values = await client.db(MONGOBASE).collection('sensors') // ret.values = await client.db(MONGOBASE).collection('noise_sensors')
.find(query, options).toArray() // .find(query, options).toArray()
ret.values = await client.db(MONGOBASE).collection('noise_sensors').aggregate([
{$match: query},
{$sort: { datetime: 1}},
// {$replaceWith:
// {
// '$values.LA_min': '$values.noise_LA_min'
// }
// },
{$replaceWith:
{
datetime: {$dateToString: {format: '%Y-%m-%dT%H:%M:%SZ', date: '$datetime'}},
LA_min: '$values.LA_min',
LA_minx: '$values.noise_LA_min',
LA_max: '$values.LA_max',
LAeq: '$values.LAeq',
E10tel_eq: '$values.E10tel_eq' }
},
// {$project: {
// datetime: {$dateToString: {format: '%Y-%m-%dT%H:%M:%SZ', date: '$datetime'}},
// _id: 0, values:1
// }},
]).toArray()
} }
catch(e) { catch(e) {
ret.err = e ret.err = e
@@ -165,6 +202,14 @@ export const fetchActData = async (opts) => {
} }
return ret return ret
} }
/*
Try to connect to mongodb://rexfue:s25BMmW2gg@192.168.51.22:27017
Try to connect to mongodb://rexfue:s25BMmW2gg@192.168.51.22:27017
*/
/* /*
let docs = await collection.find( let docs = await collection.find(
{ datetime: { datetime:
@@ -271,7 +316,7 @@ export const fetchNoiseAVGData = async (opts) => {
let grpId = {$dateToString: {format: '%Y-%m-%dT%H:00:00Z', date: '$datetime'}} let grpId = {$dateToString: {format: '%Y-%m-%dT%H:00:00Z', date: '$datetime'}}
let client = await connectMongo() let client = await connectMongo()
try { try {
docs = await client.db(MONGOBASE).collection('sensors').aggregate([ docs = await client.db(MONGOBASE).collection('noise_sensors').aggregate([
{$sort: sorting}, // sort by date {$sort: sorting}, // sort by date
{$match: datRange}, // select only values in give data range {$match: datRange}, // select only values in give data range
{ {
@@ -279,7 +324,7 @@ export const fetchNoiseAVGData = async (opts) => {
_id: grpId, _id: grpId,
n_average: {$avg: "$values.E10tel_eq"}, // calculate the average n_average: {$avg: "$values.E10tel_eq"}, // calculate the average
n_sum: {$sum: "$values.E10tel_eq"}, // calculate the sum n_sum: {$sum: "$values.E10tel_eq"}, // calculate the sum
peakcount: {$sum: {$cond: [{$gte: ["$values.noise_LA_max", peak]}, 1, 0]}}, // count peaks peakcount: {$sum: {$cond: [{$gte: ["$values.LA_max", peak]}, 1, 0]}}, // count peaks
count: {$sum: 1}, // count entries count: {$sum: 1}, // count entries
} }
}, },
@@ -345,7 +390,7 @@ async function getAverageData(db,opt) {
_id: grpId, _id: grpId,
n_average: {$avg: '$E10tel_eq'}, // calculate the average n_average: {$avg: '$E10tel_eq'}, // calculate the average
n_sum: {$sum: '$E10tel_eq'}, // calculate the sum n_sum: {$sum: '$E10tel_eq'}, // calculate the sum
peakcount: {$sum: {$cond: [{$gte: ["$noise_LA_max", peak]}, 1, 0]}}, // count peaks peakcount: {$sum: {$cond: [{$gte: ["$LA_max", peak]}, 1, 0]}}, // count peaks
count: {$sum: 1}, // count entries count: {$sum: 1}, // count entries
} }
}, },
Executable
+53
View File
@@ -0,0 +1,53 @@
# Deploy Docker-Projekt auf das docker registry (docker.citysensor.de)
#
# V 1.1 2024-09-25 rxf
# - geht nun für verscheiden Files, Übergabe des Namens
#
# v 1.0 2024-09-01 rxf
# erste Version
#set -x
registry=docker.citysensor.de
name=''
usage()
{
echo "Usage ./deploy.sh fname"
echo " Build docker container 'fname' and deploy to $registry"
echo " Params:"
echo " -h show this usage"
}
while getopts h? o
do
case "$o" in
h) usage; exit 0;;
*) usage; exit 1;;
esac
done
shift $((OPTIND-1))
while [ $# -gt 0 ]; do
if [[ -z "$fname" ]]; then
name=$1
shift
else
echo "bad option $1"
# exit 1
shift
fi
done
if [[ -z "$name" ]]; then
echo "No name given"
usage
exit 1
fi
./build_and_copy.sh localhost
docker tag $name docker.citysensor.de/$name:latest
dat=`date +%Y%m%d%H%M`
docker tag $name docker.citysensor.de/$name:V_$dat
docker push docker.citysensor.de/$name
+6
View File
@@ -0,0 +1,6 @@
# Sensor-API
### Allgemein
* **ALLE** Zeiten werden in UTC ausgegeben.
Wird beim Aufruf die Zeit im ISO-Format **ohne** Zonenbezeichnung eingegeben, wird sie in UTC umgerechnet und auch so ausgegeben. Wenn die Eingabe schon UTC ist (Z ale letztes Zeichen) dann bleibt es so.
+4898 -1809
View File
File diff suppressed because it is too large Load Diff
+19 -18
View File
@@ -1,10 +1,11 @@
{ {
"name": "sensorapi", "name": "sensorapi",
"version": "1.3.0", "version": "1.4.2",
"date": "2023-05-09", "date": "2023-11-29 16:00 UTC",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "node ./bin/www.js", "start": "node ./bin/www.js >>/var/log/sensorapi.log 2>&1",
"dev": "node ./bin/www.js",
"test": "mocha ./test/test.js" "test": "mocha ./test/test.js"
}, },
"type": "module", "type": "module",
@@ -12,24 +13,24 @@
"www": "./bin/www.js" "www": "./bin/www.js"
}, },
"dependencies": { "dependencies": {
"@influxdata/influxdb-client": "^1.24.0", "@influxdata/influxdb-client": "^1.35.0",
"@influxdata/influxdb-client-apis": "^1.24.0", "@influxdata/influxdb-client-apis": "^1.35.0",
"axios": "^0.26.1", "axios": "^1.12.2",
"cookie-parser": "~1.4.4", "cookie-parser": "~1.4.7",
"cors": "^2.8.5", "cors": "^2.8.5",
"debug": "~2.6.9", "debug": "~4.4.3",
"express": "^4.18.2", "express": "^5.1.0",
"http-errors": "~1.6.3", "http-errors": "~2.0.0",
"i18next": "^22.4.15", "i18next": "^25.5.2",
"i18next-http-middleware": "^3.3.0", "i18next-http-middleware": "^3.8.0",
"i18next-node-fs-backend": "^2.1.3", "i18next-node-fs-backend": "^2.1.3",
"luxon": "^2.3.1", "luxon": "^3.7.2",
"mongodb": "^4.4.1", "mongodb": "^6.19.0",
"morgan": "~1.9.1", "morgan": "~1.10.1",
"pug": "^3.0.2", "pug": "^3.0.3",
"ws": "^8.5.0" "ws": "^8.18.3"
}, },
"devDependencies": { "devDependencies": {
"mocha": "^9.2.2" "mocha": "^11.7.2"
} }
} }
+1
View File
@@ -15,6 +15,7 @@ const cmdTable = [
{cmd: 'getoneproperty', func: getProps.getOneProperty}, {cmd: 'getoneproperty', func: getProps.getOneProperty},
{cmd: 'getakwdata', func: getAKWs.getakwdata}, {cmd: 'getakwdata', func: getAKWs.getakwdata},
{cmd: 'getaddress', func: holAddr.getAddress}, {cmd: 'getaddress', func: holAddr.getAddress},
{cmd: 'getcitycoords', func: holAddr.getCityCoords},
{cmd: 'getsensordata', func: getData.getSensorData}, {cmd: 'getsensordata', func: getData.getSensorData},
{cmd: 'getmapdata', func: getData4map} {cmd: 'getmapdata', func: getData4map}
] ]
+1 -1
View File
@@ -6,7 +6,7 @@ const router = express.Router();
/* GET home page. */ /* GET home page. */
router.get('/', function(req, res, next) { router.get('/', function(req, res, next) {
res.status(200).json({message: trans('NOTHIMG')}) res.status(200).json({message: trans('NOTHING')})
}); });
export default router export default router
+42 -12
View File
@@ -1,5 +1,6 @@
// Data preparation for fetching noise data // Data preparation for fetching noise data
// rxf 2023-03-05 // rxf 2023-03-05
const DBASE = process.env.DBASE || 'mongo'
import {returnOnError} from "../utilities/reporterror.js"; import {returnOnError} from "../utilities/reporterror.js";
import { getActData, getAvgData, getLongAvg, calcRange} from "../actions/getsensorData.js" import { getActData, getAvgData, getLongAvg, calcRange} from "../actions/getsensorData.js"
@@ -35,13 +36,16 @@ export const getNoiseData = async (params, possibles, props) => {
opts.start = start opts.start = start
opts.stop = stop opts.stop = stop
let erg = await x.func(opts) // get the data let erg = await x.func(opts) // get the data
if (opts.csv === true) {
ret = erg
} else {
ret = { ret = {
err: erg.err, err: erg.err,
options: { options: {
sid: opts.sensorid, sid: opts.sensorid,
indoor: props.location[0].indoor, indoor: props.location[0].indoor,
span: opts.span, span: opts.span,
start: DateTime.fromISO(opts.start.slice(7)), start: DateTime.fromISO(opts.start.slice(7)).toUTC().toFormat("yyyy-LL-dd'T'HH:mm:ss'Z'"),
data: opts.data, data: opts.data,
peak: opts.peak, peak: opts.peak,
count: erg.values.length, count: erg.values.length,
@@ -54,6 +58,7 @@ export const getNoiseData = async (params, possibles, props) => {
if(ret.values.length === 0) { if(ret.values.length === 0) {
ret.err = trans('NODATA') ret.err = trans('NODATA')
} }
}
return ret return ret
} }
} }
@@ -73,8 +78,8 @@ export const getNoiseData = async (params, possibles, props) => {
// return: // return:
// JSON: // JSON:
// { sid: 29212, span: 1, start: "2019-10-23T00:00", count: 381, values: [ // { sid: 29212, span: 1, start: "2019-10-23T00:00", count: 381, values: [
// { datetime: "2019-10-22T22:05:34.000Z", noise_LAeq: 42.22, noise_LA_min: 39.91, noise_LA_max: 45.18, E10tel_eq: 16672.47212551061 }, // { datetime: "2019-10-22T22:05:34.000Z", LAeq: 42.22, LA_min: 39.91, LA_max: 45.18, E10tel_eq: 16672.47212551061 },
// { datetime: "2019-10-22T22:07:59.000Z", noise_LAeq: 53.72, noise_LA_min: 39.97, noise_LA_max: 63.54, E10tel_eq: 235504.9283896009 }, // { datetime: "2019-10-22T22:07:59.000Z", LAeq: 53.72, LA_min: 39.97, LA_max: 63.54, E10tel_eq: 235504.9283896009 },
// ......... // .........
// ]} // ]}
// CSV // CSV
@@ -87,6 +92,21 @@ export const getNoiseData = async (params, possibles, props) => {
// ********************************************* // *********************************************
const getLiveData = async (opts) => { const getLiveData = async (opts) => {
const erg = await getActData(opts) const erg = await getActData(opts)
if (opts.csv) {
let csvStr = "datetime,LAeq,LAmax,LAmin,10^(LAeq/10)\n"
if (!erg.err) {
for (let item of erg.values) {
if (item.n_AVG != -1) {
csvStr += item.datetime + ','
+ item.LAeq + ','
+ item.LA_max + ','
+ item.LA_min+ ','
+ item.E10tel_eq + '\n'
}
}
}
return csvStr
}
return erg return erg
} }
@@ -177,7 +197,7 @@ async function getdavgData(opts) {
pk += item.peakcount; pk += item.peakcount;
if (werte.datetime === undefined) { if (werte.datetime === undefined) {
let dt = DateTime.fromISO(item.datetime) let dt = DateTime.fromISO(item.datetime)
werte.datetime = dt.startOf('day').toISO() werte.datetime = dt.startOf('day').toFormat("yyyy-LL-dd'T'HH:mm:ss'Z'")
} }
} }
} }
@@ -205,7 +225,7 @@ async function getdavgData(opts) {
const addDatetime = (werte, item) => { const addDatetime = (werte, item) => {
if (werte.datetime === undefined) { if (werte.datetime === undefined) {
let dt = DateTime.fromISO(item.datetime) let dt = DateTime.fromISO(item.datetime)
werte.datetime = dt.startOf('day').toISO() werte.datetime = dt.startOf('day').toFormat("yyyy-LL-dd'T'HH:mm:ss'Z'")
} }
} }
@@ -422,8 +442,18 @@ const getAPIprops = (opt) => {
} }
const getNoiseAVGData = async (opts) => { const getNoiseAVGData = async (opts) => {
let ret = await influx.fetchNoiseAVGData(opts) let ret
let retM = await mongo.fetchNoiseAVGData(opts) if (DBASE === 'mongo') {
ret = await mongo.fetchNoiseAVGData(opts)
} else if (DBASE === 'influx') {
ret = await influx.fetchNoiseAVGData(opts)
// Influx stores the average from 00:00h to 01:00h as 01:00h, so we have to shift the time 1 hour back
for (let x=0; x < ret.values.length; x++) {
ret.values[x].datetime = DateTime.fromISO(ret.values[x].datetime).toUTC().minus({hours:1}).toFormat("yyyy-LL-dd'T'HH:mm:ss'Z'")
}
} else {
ret.err = 'DBASEUNKNOWN'
}
if(ret.err) { if(ret.err) {
return returnOnError(ret, ret.err, getNoiseAVGData.name) return returnOnError(ret, ret.err, getNoiseAVGData.name)
@@ -441,19 +471,19 @@ const getNoiseAVGData = async (opts) => {
if (opts.long) { if (opts.long) {
emptyValues.n_sum = -1 emptyValues.n_sum = -1
} }
const misshours = DateTime.fromISO(ret.values[0].datetime).get('hour') const misshours = DateTime.fromISO(ret.values[0].datetime).toUTC().get('hour')
let hoursArr = new Array(opts.span * 24 + misshours); // generate new array let hoursArr = new Array(opts.span * 24 + misshours); // generate new array
hoursArr.fill(emptyValues) // fill array with 'empty' values hoursArr.fill(emptyValues) // fill array with 'empty' values
let startDay = DateTime.fromISO(ret.values[0].datetime).get('day') // calc first day let startDay = DateTime.fromISO(ret.values[0].datetime).toUTC().get('day') // calc first day
let k = 0 let k = 0
for (let d of ret.values) { // loop through docs for (let d of ret.values) { // loop through docs
let stunde = DateTime.fromISO(d.datetime).get('hour') // get current hour let stunde = DateTime.fromISO(d.datetime).toUTC().get('hour') // get current hour
let day = DateTime.fromISO(d.datetime).get('day') // get current day let day = DateTime.fromISO(d.datetime).toUTC().get('day') // get current day
if (day != startDay) { // if date has changed if (day != startDay) { // if date has changed
k += 24 // increment index by 24 k += 24 // increment index by 24
startDay = day startDay = day
} }
hoursArr[k+stunde] = d // copy date into hourArray hoursArr[k + stunde] = d // copy date into hourArray
} }
return { err: ret.err, values: hoursArr} return { err: ret.err, values: hoursArr}
} }