Skip to content

Commit

Permalink
measurement stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
mpfeil committed Oct 8, 2024
1 parent f9458c7 commit 7718867
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 12 deletions.
22 changes: 13 additions & 9 deletions packages/api/lib/controllers/measurementsController.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const { findAccessToken, findById, saveMeasurement } = require('@sensebox/opensensemap-api-models/src/device');
const { findAccessToken, findById, saveMeasurement, saveMeasurements } = require('@sensebox/opensensemap-api-models/src/device');
const { hasDecoder, decodeMeasurements } = require('@sensebox/opensensemap-api-models/src/measurement');
const {
BadRequestError,
UnsupportedMediaTypeError,
Expand Down Expand Up @@ -363,7 +364,7 @@ const postNewMeasurement = async function postNewMeasurement (req, res) {
return Promise.reject(new UnauthorizedError('Device access token not valid!'));
}

const [measurement] = await Measurement.decodeMeasurements([{
const [measurement] = await decodeMeasurements([{
sensor_id: sensorId,
value,
createdAt,
Expand Down Expand Up @@ -457,7 +458,7 @@ const postNewMeasurement = async function postNewMeasurement (req, res) {
* }
*/
const postNewMeasurements = async function postNewMeasurements (req, res) {
const { boxId, luftdaten, hackair } = req._userParams;
const { boxId: deviceId, luftdaten, hackair } = req._userParams;
let contentType = req.getContentType();

if (hackair) {
Expand All @@ -466,21 +467,24 @@ const postNewMeasurements = async function postNewMeasurements (req, res) {
contentType = 'luftdaten';
}

if (Measurement.hasDecoder(contentType)) {
if (hasDecoder(contentType)) {
try {
const box = await Box.findBoxById(boxId, { populate: false, lean: false, projection: { sensors: 1, locations: 1, lastMeasurementAt: 1, currentLocation: 1, model: 1, access_token: 1, useAuth: 1 } });
const device = await findById(deviceId, { sensors: true });
const deviceAccessToken = await findAccessToken(deviceId);
// const box = await Box.findBoxById(boxId, { populate: false, lean: false, projection: { sensors: 1, locations: 1, lastMeasurementAt: 1, currentLocation: 1, model: 1, access_token: 1, useAuth: 1 } });

// if (contentType === 'hackair' && box.access_token !== req.headers.authorization) {
// throw new UnauthorizedError('Box access token not valid!');
// }

// authorization for all boxes that have not opt out
if ((box.useAuth || contentType === 'hackair') && box.access_token && box.access_token !== req.headers.authorization) {
return Promise.reject(new UnauthorizedError('Box access token not valid!'));
if ((device.useAuth || contentType === 'hackair') && deviceAccessToken.token && deviceAccessToken.token !== req.headers.authorization) {
return Promise.reject(new UnauthorizedError('Device access token not valid!'));
}

const measurements = await Measurement.decodeMeasurements(req.body, { contentType, sensors: box.sensors });
await box.saveMeasurementsArray(measurements);
const measurements = await decodeMeasurements(req.body, { contentType, sensors: device.sensors });
// await box.saveMeasurementsArray(measurements);
await saveMeasurements(device, measurements);
res.send(201, 'Measurements saved in box');
} catch (err) {
return handleError(err);
Expand Down
32 changes: 30 additions & 2 deletions packages/models/src/device/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const sensorLayouts = require('../box/sensorLayouts');
const { db } = require('../drizzle');
const ModelError = require('../modelError');
const { inArray, arrayContains, sql } = require('drizzle-orm');
const { insertMeasurement } = require('../measurement');
const { insertMeasurement, insertMeasurements } = require('../measurement');

const buildWhereClause = function buildWhereClause (opts = {}) {
const { phenomenon, fromDate, toDate, bbox, near, maxDistance, grouptag } = opts;
Expand Down Expand Up @@ -168,6 +168,33 @@ const saveMeasurement = async function saveMeasurement (device, measurement) {
await insertMeasurement(measurement);
};

const saveMeasurements = async function saveMeasurements (device, measurements) {

if (!Array.isArray(measurements)) {
return Promise.reject(new Error('Array expected'));
}

const sensorIds = this.sensorIds(),
lastMeasurements = {};

// TODO: refactor
// find new lastMeasurements
// check if all the measurements belong to this box
for (let i = measurements.length - 1; i >= 0; i--) {
if (!sensorIds.includes(measurements[i].sensor_id)) {
return Promise.reject(new ModelError(`Measurement for sensor with id ${measurements[i].sensor_id} does not belong to box`));
}

if (!lastMeasurements[measurements[i].sensor_id]) {
lastMeasurements[measurements[i].sensor_id] = measurements[i];
}
}

// TODO: check if we can merge this with `saveMeasurement`

await insertMeasurements(measurements);
};

module.exports = {
createDevice,
deleteDevice,
Expand All @@ -176,5 +203,6 @@ module.exports = {
findDevicesMinimal,
findTags,
findAccessToken,
saveMeasurement
saveMeasurement,
saveMeasurements
};
26 changes: 25 additions & 1 deletion packages/models/src/measurement/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@

const { measurementTable } = require('../../schema/schema');
const { db } = require('../drizzle');
const ModelError = require('../modelError');
const decodeHandlers = require('./decoding');

const hasDecoder = function hasDecoder (contentType) {
if (!decodeHandlers[contentType]) {
return false;
}

return true;
};

const decodeMeasurements = function decodeMeasurements (measurements, { contentType = 'json', sensors } = {}) {
return decodeHandlers[contentType].decodeMessage(measurements, { sensors })
.catch(function (err) {
throw new ModelError(err.message, { type: 'UnprocessableEntityError' });
});
};

const insertMeasurement = async function insertMeasurement (measurement) {
return db.insert(measurementTable).values({
Expand All @@ -11,6 +28,13 @@ const insertMeasurement = async function insertMeasurement (measurement) {
});
};

const insertMeasurements = async function insertMeasurements (measurements) {
return db.insert(measurementTable).values(measurements);
};

module.exports = {
insertMeasurement
decodeMeasurements,
hasDecoder,
insertMeasurement,
insertMeasurements
};

0 comments on commit 7718867

Please sign in to comment.