Files
climate-server/server/src/byteSeriesRouter.ts
2021-03-21 16:19:52 +01:00

52 lines
2.5 KiB
TypeScript

import {Router} from "express";
import {CollectionRegistry} from "./Collections";
import {ClayPIError} from "./errors";
import {ClimateDataType, SnapshotAttrTimeseries} from "./Snapshot";
function newByteSeriesRouter(collections: CollectionRegistry) {
const router = Router();
router.get("/:dataType", async (req, res) => {
const query = req.query as Record<string, string>;
const isMinutesQuery = typeof query["last-minutes"] !== "undefined" && !query.from && !query.to;
const isFromToQuery = typeof query.from !== "undefined";
const dataType = req.params.dataType;
if (!isValidDataType(dataType)) {
throw new ClayPIError(`The parameter 'data-type' must be one of the following: 'temp', 'humidity', 'co2'. Got: ${dataType}`);
}
let timeseries: SnapshotAttrTimeseries;
if (!isMinutesQuery && !isFromToQuery) {
if (query.to) {
throw new ClayPIError("The parameter 'to' must always be accompanied by a 'from'.");
}
timeseries = await collections.snapshots.getTimeseriesBytestreamSince(dataType, new Date().getTime() - 60 * 60000);
} else if (isMinutesQuery) {
const lastMinutes = Math.floor(Number(query["last-minutes"]));
if (isNaN(lastMinutes)) {
throw new ClayPIError("The parameter 'last-minutes' must be a number.");
} else {
timeseries = await collections.snapshots.getTimeseriesBytestreamSince(dataType, new Date().getTime() - lastMinutes * 60000);
}
} else if (isFromToQuery) {
const timeFrom = isNaN(Number(query.from)) ? query.from : Number(query.from);
const timeTo = isNaN(Number(query.to)) ? query.to : Number(query.to);
if (timeTo) {
timeseries = await collections.snapshots.getTimeseriesBytestreamInRange(dataType, timeFrom, timeTo);
} else {
timeseries = await collections.snapshots.getTimeseriesBytestreamSince(dataType, timeFrom);
}
} else {
throw new ClayPIError("Malformed request.");
}
res.type("application/octet-stream");
res.end(Buffer.from(timeseries.buffer), "binary");
});
return router;
}
function isValidDataType(dataType: string | undefined): dataType is ClimateDataType {
return typeof dataType !== "undefined" && (dataType === "temp" || dataType === "humidity" || dataType === "co2");
}
export default newByteSeriesRouter;