big update
This commit is contained in:
@@ -2,5 +2,5 @@
|
|||||||
"development": false,
|
"development": false,
|
||||||
"defaultMinuteSpan": 60,
|
"defaultMinuteSpan": 60,
|
||||||
"reloadIntervalSec": 30,
|
"reloadIntervalSec": 30,
|
||||||
"dataEndpoint": "http://home.djledda.de:4040/climate/api"
|
"dataEndpoint": "http://home.djledda.de/climate/api"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {defineConfig} from "vite";
|
import {defineConfig} from "vite";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
base: "/climate/static",
|
base: "/climate",
|
||||||
build: {
|
build: {
|
||||||
outDir: "../dist",
|
outDir: "../dist",
|
||||||
},
|
},
|
||||||
|
|||||||
3074
package-lock.json
generated
3074
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
2593
server/package-lock.json
generated
2593
server/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "climate-server",
|
"name": "climate-server",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"child-process-promise": "^2.2.1",
|
"child-process-promise": "^2.2.1",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ try:
|
|||||||
humidity = dhtDevice.humidity
|
humidity = dhtDevice.humidity
|
||||||
co2 = None
|
co2 = None
|
||||||
try:
|
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:
|
if mhz19_reading is not None and mhz19_reading['co2'] is not None:
|
||||||
co2 = mhz19_reading['co2']
|
co2 = mhz19_reading['co2']
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
|
|||||||
@@ -1,16 +1,36 @@
|
|||||||
|
import { URL } from 'url';
|
||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
import express from "express";
|
import express from "express";
|
||||||
import {newMainRouter} from "./mainRouter";
|
import {newMainRouter} from "./mainRouter";
|
||||||
import {setupCollections} from "./Collections";
|
import {setupCollections} from "./Collections";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import {startSensorPinger} from "./pingSensors";
|
import {startSensorPinger} from "./pingSensors";
|
||||||
|
import { GenericPersistenceError, ClayPIError } from './errors';
|
||||||
|
|
||||||
|
const __dirname = new URL('.', import.meta.url).pathname;
|
||||||
|
|
||||||
const DOTENV_PATH = path.resolve(__dirname, "..", "./.env");
|
const DOTENV_PATH = path.resolve(__dirname, "..", "./.env");
|
||||||
dotenv.config({ path: DOTENV_PATH });
|
dotenv.config({ path: DOTENV_PATH });
|
||||||
const SERVER_ROOT = process.env.SERVER_ROOT ?? "/";
|
const SERVER_ROOT = process.env.SERVER_ROOT ?? "/";
|
||||||
|
|
||||||
console.log(DOTENV_PATH);
|
const topLevelErrorHandler: express.ErrorRequestHandler = (err, req, res, next) => {
|
||||||
console.log(process.env.SERVER_ROOT);
|
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() {
|
async function main() {
|
||||||
try {
|
try {
|
||||||
const collections = await setupCollections();
|
const collections = await setupCollections();
|
||||||
@@ -22,8 +42,12 @@ async function main() {
|
|||||||
app.locals = {
|
app.locals = {
|
||||||
rootUrl: SERVER_ROOT,
|
rootUrl: SERVER_ROOT,
|
||||||
};
|
};
|
||||||
app.use(SERVER_ROOT, express.static(path.resolve(__dirname + "/../dist/public")));
|
app.use(SERVER_ROOT + '/api', mainRouter);
|
||||||
app.use(SERVER_ROOT, 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"), () => {
|
app.listen(app.get("port"), () => {
|
||||||
console.log("ClayPI running on http://localhost:%d", app.get("port"));
|
console.log("ClayPI running on http://localhost:%d", app.get("port"));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,27 +7,9 @@ import newByteSeriesRouter from "./byteSeriesRouter";
|
|||||||
export function newMainRouter(collections: CollectionRegistry) {
|
export function newMainRouter(collections: CollectionRegistry) {
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
router.use("/api/snapshots", newSnapshotRouter(collections));
|
router.use("/snapshots", newSnapshotRouter(collections));
|
||||||
router.use("/api/timeseries", newByteSeriesRouter(collections));
|
router.use("/timeseries", newByteSeriesRouter(collections));
|
||||||
router.use(topLevelErrorHandler);
|
|
||||||
|
|
||||||
return router;
|
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);
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
|
import { URL } from 'url';
|
||||||
import {ISOSnapshot} from "./Snapshot";
|
import {ISOSnapshot} from "./Snapshot";
|
||||||
import {exec} from "child-process-promise";
|
import {exec} from "child-process-promise";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import {ClayPIError} from "./errors";
|
import {ClayPIError} from "./errors";
|
||||||
|
|
||||||
|
const __dirname = new URL('.', import.meta.url).pathname;
|
||||||
|
|
||||||
async function pingSensors(): Promise<Omit<ISOSnapshot, "id">> {
|
async function pingSensors(): Promise<Omit<ISOSnapshot, "id">> {
|
||||||
try {
|
try {
|
||||||
const process = await exec(`python3 ${path.resolve(__dirname + "/../scripts/climate-pinger.py")}`);
|
const process = await exec(`python3 ${path.resolve(__dirname + "/../scripts/climate-pinger.py")}`);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ function newSnapshotRouter(collections: CollectionRegistry) {
|
|||||||
|
|
||||||
router.use(unixTimeParamMiddleware);
|
router.use(unixTimeParamMiddleware);
|
||||||
|
|
||||||
router.get("", async (req, res) => {
|
router.get("/", async (req, res) => {
|
||||||
const query = req.query as Record<string, string>;
|
const query = req.query as Record<string, string>;
|
||||||
const isMinutesQuery = typeof query["last-minutes"] !== "undefined" && !query.from && !query.to;
|
const isMinutesQuery = typeof query["last-minutes"] !== "undefined" && !query.from && !query.to;
|
||||||
const isFromToQuery = typeof query.from !== "undefined";
|
const isFromToQuery = typeof query.from !== "undefined";
|
||||||
@@ -66,6 +66,7 @@ function newSnapshotRouter(collections: CollectionRegistry) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.post("/", async (req, res) => {
|
router.post("/", async (req, res) => {
|
||||||
|
console.log("New snapshot:", req.body);
|
||||||
const goodRequest = req.body.snapshots
|
const goodRequest = req.body.snapshots
|
||||||
&& req.body.snapshots.length === 1
|
&& req.body.snapshots.length === 1
|
||||||
&& SnapshotCollection.isSubmissibleSnapshot(req.body.snapshots[0]);
|
&& SnapshotCollection.isSubmissibleSnapshot(req.body.snapshots[0]);
|
||||||
@@ -80,4 +81,4 @@ function newSnapshotRouter(collections: CollectionRegistry) {
|
|||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default newSnapshotRouter;
|
export default newSnapshotRouter;
|
||||||
|
|||||||
@@ -34,4 +34,4 @@ export const unixTimeParamMiddleware: express.Handler = (req, res, next) => {
|
|||||||
res.locals.timeFormat = timeFormat;
|
res.locals.timeFormat = timeFormat;
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
"module": "commonjs",
|
"module": "ES2022",
|
||||||
"target": "ES6",
|
"target": "ES2022",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "Node",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"experimentalDecorators": true
|
"experimentalDecorators": true
|
||||||
},
|
},
|
||||||
@@ -17,6 +17,6 @@
|
|||||||
"lib": [
|
"lib": [
|
||||||
"dom",
|
"dom",
|
||||||
"dom.iterable",
|
"dom.iterable",
|
||||||
"esnext"
|
"ES2022"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user