Files
sensorapi/actions/data4map.js
T
2023-03-08 16:17:02 +01:00

139 lines
4.4 KiB
JavaScript

// Fetch the actual (= newest) data out of the dbase to show it on the map
import {DateTime} from "luxon"
import {logit} from "../utilities/logit.js"
import * as mongo from "../databases/mongo.js"
import {reportError, returnOnError} from "../utilities/reporterror.js"
import * as ERR from "../utilities/errortexts.js"
// Default distance for center search ( in km)
const DEFAULT_DISTANCE = 10
// Relations between types and value type
const vtype2measurement = {
P1: 'pm', P2: 'pm', P0: 'pm',
temperature: 'thp', humidity: 'thp', pressure: 'thp',
noise_LAeq: 'noise',
counts_per_minute: 'radioactivity'
};
// find first value type from measurement
const getfieldfromtype = (typ) => {
for (const [key, value] of Object.entries(vtype2measurement)) {
if (value === typ) {
return key
}
}
return ' '
}
export const getData4map = async (params) => {
let start = DateTime.now()
let retur = { err: null, data: { params: params} }
// check parameters
if ((params.type === undefined) || (params.type === '')) {
return returnOnError(retur, ERR.NOTYP, getData4map.name)
}
const typ = params.type
let poly = []
let south = null, north = null, east = null, west = null, center = null
let distance = DEFAULT_DISTANCE
if (!((params.box === undefined) || (params.box == ""))) {
const box = params.box
if (!((box === undefined) || (box === ' ') || (box === 'null'))) {
south = parseFloat(box.south)
north = parseFloat(box.north)
east = parseFloat(box.east)
west = parseFloat(box.west)
logit(`getData4map: S=${south} N=${north} E=${east} W=${west}`)
}
}
if (!((params.poly === undefined) || (params.poly === ' '))){
poly = JSON.parse(params.poly)
}
if (params.center !== undefined) {
center = params.center
if ((params.distance !== undefined) &&
(params.distance >= 1) && (params.distance <= 1000)) {
distance = params.distance
}
}
const aktData = []
let lastDate = 0
let query = {type: typ}
// if polyline or box were given, set query
if (poly.length !== 0) { // polyline given
query.location = {
$geoWithin: {
$geometry: {
type: "Polygon",
coordinates: [poly],
}
}
}
} else if (south !== null) { // box given
query["location.loc"] = {
$geoWithin: {
$box: [
[west, south],
[east, north]
]
}
}
} else if (center !== null) { // center point given
query["location.loc"] = {
$nearSphere: {
$geometry: {
type: "Point",
coordinates: center
},
$maxDistance: distance * 1000
}
}
}
// depending of the type find the measurement field to fetch
const vtype = getfieldfromtype(typ)
// fetch mapdata from mongodb
try {
let { values, err } = await mongo.readMapdata(query, 0)
if(err) {
return returnOnError(retur, ERR.NOSENSFOUND, getData4map.name)
}
for (let item of values) {
const oneAktData = {
location: item.location.loc.coordinates,
id: item._id,
name: item.name,
indoor: item.location.indoor,
value: Math.round(item.value[vtype] * 100) / 100
}
let now = new Date().getTime()
let diff = now - item.timestamp
if (diff >= 7 * 24 * 3600 * 1000) {
oneAktData.value = -2
} else if (diff >= 2 * 3600 * 1000) {
oneAktData.value = -1
}
if (item.timestamp > lastDate) {
lastDate = item.timestamp
}
aktData.push(oneAktData)
}
logit(`Query duration: ${start.diffNow('seconds').toObject().seconds * -1} sec`)
retur.data.lastDate = lastDate
retur.data.valuetype = vtype
retur.data.count = aktData.length
retur.data.values = aktData
return retur
}
catch(e) {
return returnOnError(retur, `catch\n${e}`, getData4map.name)
}
}