big update

This commit is contained in:
2023-07-30 17:52:18 +02:00
parent 4ec3c5ab2f
commit 65f8d8567e
12 changed files with 2631 additions and 3115 deletions

2593
server/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,7 @@
{
"name": "climate-server",
"version": "1.0.0",
"type": "module",
"dependencies": {
"ts-node": "^10.9.1",
"child-process-promise": "^2.2.1",

View File

@@ -12,7 +12,7 @@ try:
humidity = dhtDevice.humidity
co2 = None
try:
mhz19_reading = mh_z19.read()
mhz19_reading = mh_z19.read(serial_console_untouched=True)
if mhz19_reading is not None and mhz19_reading['co2'] is not None:
co2 = mhz19_reading['co2']
except Exception as error:

View File

@@ -1,16 +1,36 @@
import { URL } from 'url';
import dotenv from "dotenv";
import express from "express";
import {newMainRouter} from "./mainRouter";
import {setupCollections} from "./Collections";
import path from "path";
import {startSensorPinger} from "./pingSensors";
import { GenericPersistenceError, ClayPIError } from './errors';
const __dirname = new URL('.', import.meta.url).pathname;
const DOTENV_PATH = path.resolve(__dirname, "..", "./.env");
dotenv.config({ path: DOTENV_PATH });
const SERVER_ROOT = process.env.SERVER_ROOT ?? "/";
console.log(DOTENV_PATH);
console.log(process.env.SERVER_ROOT);
const topLevelErrorHandler: express.ErrorRequestHandler = (err, req, res, next) => {
const errOutput = {
error: true,
message: "",
};
if (err instanceof GenericPersistenceError) {
errOutput.message = `An error occurred accessing the database: ${err.displayMessage}`;
}
else if (err instanceof ClayPIError) {
errOutput.message = `An error occurred: ${err.displayMessage}`;
}
else {
errOutput.message = "An unknown error occurred!";
}
console.log({...errOutput, internalMessage: err.message});
res.status(500).send(errOutput);
};
async function main() {
try {
const collections = await setupCollections();
@@ -22,8 +42,12 @@ async function main() {
app.locals = {
rootUrl: SERVER_ROOT,
};
app.use(SERVER_ROOT, express.static(path.resolve(__dirname + "/../dist/public")));
app.use(SERVER_ROOT, mainRouter);
app.use(SERVER_ROOT + '/api', mainRouter);
app.get(SERVER_ROOT + '/dashboard', (req, res) => {
res.sendFile(path.resolve(__dirname, '../../dist/index.html'));
});
app.use(SERVER_ROOT, express.static(path.resolve(__dirname, "../../dist")));
app.use(topLevelErrorHandler);
app.listen(app.get("port"), () => {
console.log("ClayPI running on http://localhost:%d", app.get("port"));
});

View File

@@ -7,27 +7,9 @@ import newByteSeriesRouter from "./byteSeriesRouter";
export function newMainRouter(collections: CollectionRegistry) {
const router = express.Router();
router.use("/api/snapshots", newSnapshotRouter(collections));
router.use("/api/timeseries", newByteSeriesRouter(collections));
router.use(topLevelErrorHandler);
router.use("/snapshots", newSnapshotRouter(collections));
router.use("/timeseries", newByteSeriesRouter(collections));
return router;
}
const topLevelErrorHandler: express.ErrorRequestHandler = (err, req, res, next) => {
const errOutput = {
error: true,
message: "",
};
if (err instanceof GenericPersistenceError) {
errOutput.message = `An error occurred accessing the database: ${err.displayMessage}`;
}
else if (err instanceof ClayPIError) {
errOutput.message = `An error occurred: ${err.displayMessage}`;
}
else {
errOutput.message = "An unknown error occurred!";
}
console.log({...errOutput, internalMessage: err.message});
res.status(500).send(errOutput);
};

View File

@@ -1,8 +1,11 @@
import { URL } from 'url';
import {ISOSnapshot} from "./Snapshot";
import {exec} from "child-process-promise";
import path from "path";
import {ClayPIError} from "./errors";
const __dirname = new URL('.', import.meta.url).pathname;
async function pingSensors(): Promise<Omit<ISOSnapshot, "id">> {
try {
const process = await exec(`python3 ${path.resolve(__dirname + "/../scripts/climate-pinger.py")}`);

View File

@@ -10,7 +10,7 @@ function newSnapshotRouter(collections: CollectionRegistry) {
router.use(unixTimeParamMiddleware);
router.get("", async (req, res) => {
router.get("/", 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";
@@ -66,6 +66,7 @@ function newSnapshotRouter(collections: CollectionRegistry) {
});
router.post("/", async (req, res) => {
console.log("New snapshot:", req.body);
const goodRequest = req.body.snapshots
&& req.body.snapshots.length === 1
&& SnapshotCollection.isSubmissibleSnapshot(req.body.snapshots[0]);
@@ -80,4 +81,4 @@ function newSnapshotRouter(collections: CollectionRegistry) {
return router;
}
export default newSnapshotRouter;
export default newSnapshotRouter;

View File

@@ -34,4 +34,4 @@ export const unixTimeParamMiddleware: express.Handler = (req, res, next) => {
res.locals.timeFormat = timeFormat;
next();
}
};
};

View File

@@ -1,15 +1,15 @@
{
"compilerOptions": {
"noImplicitAny": true,
"module": "commonjs",
"target": "ES6",
"module": "ES2022",
"target": "ES2022",
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"moduleResolution": "Node",
"resolveJsonModule": true,
"experimentalDecorators": true
},
@@ -17,6 +17,6 @@
"lib": [
"dom",
"dom.iterable",
"esnext"
"ES2022"
]
}