bd5cf9978d
mongo.js, influx_post.js und logit.js lagen in beiden Komponenten doppelt
und waren auseinandergelaufen - so ist der Zeitzonen-Fehler entstanden, den
readin seit jeher richtig loest und readFromcsv.js zwei Jahre lang nicht.
Sie liegen jetzt einmal unter common/.
Wo die Fassungen sich widersprachen:
- MONGOAUTH wird als String verglichen. Die readarchive-Fassung pruefte nur
auf truthy, dadurch schaltete auch MONGOAUTH=false die Auth ein.
- writeDataArray(client, coll, data) nimmt den Collection-Namen direkt;
readarchive baut ihn mit dem neuen dataCollName(styp).
- getallProperties liefert das Array selbst. Die readarchive-Fassung mit
{error, properties} war dort ungenutzt.
- properties_collection heisst einheitlich property_coll.
Das Sammelobjekt statistics lag in readin/readdata.js und wurde von
mongo.js und influx_post.js importiert. Es liegt jetzt in
common/statistics.js, damit die gemeinsamen Module readin nicht kennen
muessen.
Der Build-Kontext beider Images ist dadurch das Repository-Wurzelverzeichnis;
das Layout im Image spiegelt das Repository, damit ../common/... unveraendert
aufgeht. Die Volume-Zeile von readin im Compose zieht deshalb auf
/opt/app/readin/data um.
readarchive folgt jetzt den Konventionen des Stacks: deploy.sh statt
build_and_copy.sh, Dockerfile_readarchive statt Dockerfile_rfcsv, und die
eigene docker-compose.yml entfaellt - der Dienst haengt als Profil "tools"
im Compose des Stacks und wird mit Parametern gestartet:
docker compose run --rm readarchive -t noise -s 2026-07-25 -e 2026-07-29
Getestet: beide Images gebaut, beide gegen Testdatenbanken laufen lassen.
Nicht deployt - die Images in der Registry sind unveraendert.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
135 lines
4.9 KiB
JavaScript
135 lines
4.9 KiB
JavaScript
import { DateTime } from 'luxon'
|
|
import { logit, logerror } from '../../common/logit.js'
|
|
import { returnOnError } from './reporterror.js'
|
|
import * as mongo from '../../common/mongo.js'
|
|
|
|
// Check lat/lon and convert to float
|
|
function checkLatLon(w) {
|
|
let loc = 0.0;
|
|
if (!((w === undefined) || (w == null) || (w == ''))) {
|
|
try {
|
|
loc = parseFloat(w)
|
|
} catch (e) {
|
|
logerror(`Math error with lat/lon, ${e}`)
|
|
}
|
|
}
|
|
return loc
|
|
}
|
|
|
|
|
|
const buildNewEntry = (item, cdate, indoor, name, typ) => {
|
|
return {
|
|
_id: parseInt(item.sensor_id),
|
|
type: typ,
|
|
name: [{
|
|
name: name,
|
|
since: cdate,
|
|
}],
|
|
location: [{
|
|
loc: {
|
|
type: "Point",
|
|
coordinates: [
|
|
checkLatLon(item.lon),
|
|
checkLatLon(item.lat)
|
|
]
|
|
},
|
|
id: parseInt(item.location),
|
|
altitude: 0,
|
|
since: cdate,
|
|
exact_loc: 0,
|
|
indoor: indoor,
|
|
country: ''
|
|
}]
|
|
}
|
|
}
|
|
|
|
// Check for new properties
|
|
export const checkProperties = async (client, item, indoor, name, typ, dt, newProps) => {
|
|
if(name === "laerm") {
|
|
name = 'DNMS (Laerm)'
|
|
}
|
|
let ret
|
|
try {
|
|
ret = await mongo.getOneproperty(client, parseInt(item.sensor_id) ) // read properties for
|
|
if(ret.error) {
|
|
logerror(`Error reading properties: ${ret.errortext}`)
|
|
return null
|
|
}
|
|
} catch (e) {
|
|
logerror(`Error reading properties: ${e}`)
|
|
return null
|
|
}
|
|
let changed = false
|
|
let entry = ret.property
|
|
let cdate = DateTime.fromISO(dt + 'T00:00:00', { zone: 'utc' }).toJSDate()
|
|
// read entry from actualprops
|
|
if (entry === null) { // not in properties => new sensor
|
|
entry = buildNewEntry(item, cdate, indoor, name, typ) // so build a new entry
|
|
changed = true
|
|
} else {
|
|
// check for change of collection
|
|
let ok = false
|
|
for(let i = 0; i < entry.location.length; i++) {
|
|
if(entry.location[i].id === parseInt(item.location)) {
|
|
ok = true // same location found
|
|
}
|
|
}
|
|
if( !ok) {
|
|
// new location found:
|
|
if (newProps.findIndex((obj) => {
|
|
return (obj.updateOne.update.$set.location[0].id === item.location)
|
|
}) === -1) { // not in newProps array
|
|
const newloc = {
|
|
loc: {
|
|
type: "Point",
|
|
coordinates: [
|
|
checkLatLon(item.lon),
|
|
checkLatLon(item.lat)
|
|
]
|
|
},
|
|
id: parseInt(item.location),
|
|
altitude: 0,
|
|
since: cdate,
|
|
exact_loc: 0,
|
|
indoor: indoor
|
|
}
|
|
entry.location.push(newloc) // add new lolcation to array
|
|
changed = true
|
|
logit(`New location ${item.location} for sensor ${item.sensor_id}`)
|
|
}
|
|
} else {
|
|
// same location, check the date
|
|
if (entry.location[0].since > cdate) { // new date is older than old date
|
|
entry.location[0].since = cdate // so set new date
|
|
changed = true
|
|
}
|
|
}
|
|
// Check für new name
|
|
if (entry.name[0].name.toUpperCase() !== name.toUpperCase()) { // have got a new name
|
|
if (newProps.findIndex(
|
|
(obj) => {
|
|
return (obj.updateOne.update.$set.name[0].name === name)
|
|
}) === -1) {
|
|
let newname = {
|
|
name: name,
|
|
since: cdate
|
|
}
|
|
entry.name.push(newname)
|
|
changed = true
|
|
logit(`New name ${name} for sensor ${item.sensor_id}`)
|
|
}
|
|
} else { // same name, chack the date
|
|
if (entry.name[0].since > cdate) { // new date is older than old date
|
|
entry.name[0].since = cdate // so set new date
|
|
changed = true
|
|
logit(`New date for sensor ${item.sensor_id}`)
|
|
}
|
|
}
|
|
}
|
|
// push this entry to the new properties array if somethind was changed
|
|
if(changed) {
|
|
delete entry.values // delete values array
|
|
newProps.push({updateOne: {filter: {_id: entry._id}, update: {$set: entry}, upsert: true}})
|
|
}
|
|
}
|