diff --git a/.gitignore b/.gitignore index 2bc24d0..431f969 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ .idea -node_modules +node_modules/ app-dist/server climate-server diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..209e3ef --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20 diff --git a/README.md b/README.md index 62abf52..6492552 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,10 @@ The setup script installs these for you. 1. Pull the repository. 1. Fill out your specific config options in `./server/.env` -1. Ensure `./app-dist/scripts/climate-pinger.py` has the correct pin for your adafruit-dht22 device and/or edit the script for your specific setup. +1. Ensure `./server/scripts/climate-pinger.py` has the correct pin for your adafruit-dht22 device and/or edit the script for your specific setup. 1. Run `./setup.sh` as administrator 1. Start the server: - > node ./app-dist/main.js + > npm start ## Usage @@ -122,4 +122,4 @@ Temp: Humidity: CO2: ``` -with label and data separated by tabs. \ No newline at end of file +with the labels and corresponding data separated by tabs. diff --git a/app-dist/static/index.ejs b/app-dist/static/index.ejs deleted file mode 100644 index 42403a1..0000000 --- a/app-dist/static/index.ejs +++ /dev/null @@ -1,13 +0,0 @@ - - - - - Ledda's Room Climate - - - - - -
- - diff --git a/app-dist/static/index.html b/app-dist/static/index.html deleted file mode 100644 index e10c39b..0000000 --- a/app-dist/static/index.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - Ledda's Room Climate - - - - - - - -
- - diff --git a/dashboard/package.json b/dashboard/package.json index b88c5d7..fd090bc 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -6,7 +6,7 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "vite build", - "dev": "vite", + "dev": "vite" }, "author": "", "license": "ISC", diff --git a/app-dist/static/favicon16.png b/dashboard/public/favicon16.png similarity index 100% rename from app-dist/static/favicon16.png rename to dashboard/public/favicon16.png diff --git a/app-dist/static/favicon32.png b/dashboard/public/favicon32.png similarity index 100% rename from app-dist/static/favicon32.png rename to dashboard/public/favicon32.png diff --git a/app-dist/static/favicon64.png b/dashboard/public/favicon64.png similarity index 100% rename from app-dist/static/favicon64.png rename to dashboard/public/favicon64.png diff --git a/dashboard/vite.config.ts b/dashboard/vite.config.ts index 95925d0..1a4dff6 100644 --- a/dashboard/vite.config.ts +++ b/dashboard/vite.config.ts @@ -1,7 +1,8 @@ import {defineConfig} from "vite"; export default defineConfig({ + base: "/climate/static", build: { - outDir: '../app-dist/static', + outDir: "../dist", }, }); diff --git a/dashboard/webpack.config.js b/dashboard/webpack.config.js deleted file mode 100644 index abc09b4..0000000 --- a/dashboard/webpack.config.js +++ /dev/null @@ -1,81 +0,0 @@ -const path = require("path"); -const webpack = require("webpack"); -const config = require("./src/config.json"); - -const TerserWebpackPlugin = require("terser-webpack-plugin"); - -const webpackConfig = { - mode: "development", - entry: "./src/main.ts", - plugins: [new webpack.ProgressPlugin()], - - module: { - rules: [ - { - test: /\.(ts|tsx)$/, - loader: "ts-loader", - include: [path.resolve(__dirname, "src")], - exclude: [/node_modules/] - }, - { - test: /.css$/, - - use: [{ - loader: "style-loader" - }, { - loader: "css-loader", - options: { - sourceMap: true - } - }] - }, - { - test: /\.(png|jpe?g|gif|ttf|woff2?|eot|svg)$/i, - use: [ - { - loader: "file-loader", - }, - ], - }] - }, - - resolve: { - extensions: [".tsx", ".ts", ".js"] - }, - - output: { - filename: "dashboard.js", - path: path.resolve(__dirname, "../app-dist/static/"), - }, - - devServer: { - contentBase: path.join(__dirname, "../app-dist/static/"), - contentBasePublicPath: "/", - port: 3000, - publicPath: "http://localhost:3000/", - hotOnly: true - }, -}; - -if (!config.development) { - webpackConfig.optimization = { - minimizer: [new TerserWebpackPlugin()], - - splitChunks: { - cacheGroups: { - vendors: { - priority: -10, - test: /[\\/]node_modules[\\/]/ - } - }, - - chunks: "async", - minChunks: 1, - minSize: 30000, - name: false - } - }; - webpackConfig.mode = "production"; -} - -module.exports = {...webpackConfig}; \ No newline at end of file diff --git a/package.json b/package.json index eacae80..f703021 100644 --- a/package.json +++ b/package.json @@ -3,26 +3,10 @@ "version": "0.0.1", "description": "Server API and frontend dashboard for monitoring climate stats with the Raspberry Pi", "scripts": { - "start": "concurrently -p \"[{name}]\" -n \"server,dashboard\" -c \"bgBlue.gray.bold,bgMagenta.gray.bold\" \"npm:server\" \"npm:dashboard-static\"", - "build": "sh ./setup.sh", - "server": "cd ./server && npm run dev", - "dashboard-static": "cd ./dashboard && npm run build-watch", - "dashboard-serve": "cd ./dashboard && npm run dev" - }, - "dependencies": { - "child-process-promise": "^2.2.1", - "cors": "^2.8.5", - "dotenv": "^8.2.0", - "ejs": "^3.1.6", - "express": "^5.0.0-alpha.8", - "mysql2": "^2.2.5", - "node-fetch": "^2.6.1" + "start": "cd ./server && ts-node ./src/main.ts", + "build": "sh ./setup.sh" }, "devDependencies": { - "@types/child-process-promise": "^2.2.1", - "@typescript-eslint/eslint-plugin": "^4.17.0", - "@typescript-eslint/parser": "^4.17.0", - "concurrently": "^6.0.0", "eslint": "^7.21.0", "prettier": "^2.1.2", "typescript": "^5.1.0" diff --git a/server/package-lock.json b/server/package-lock.json index cf0c84d..4ee5dfe 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -1,161 +1,355 @@ { "name": "climate-server", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@types/body-parser": { + "packages": { + "": { + "name": "climate-server", + "version": "1.0.0", + "dependencies": { + "ts-node": "^10.9.1" + }, + "devDependencies": { + "@types/cors": "^2.8.10", + "@types/dotenv": "^8.2.0", + "@types/express": "^4.17.11", + "@types/node-fetch": "^2.5.8" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + }, + "node_modules/@types/body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", "dev": true, - "requires": { + "dependencies": { "@types/connect": "*", "@types/node": "*" } }, - "@types/connect": { + "node_modules/@types/connect": { "version": "3.4.34", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", "dev": true, - "requires": { + "dependencies": { "@types/node": "*" } }, - "@types/cors": { + "node_modules/@types/cors": { "version": "2.8.10", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz", "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==", "dev": true }, - "@types/dotenv": { + "node_modules/@types/dotenv": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-8.2.0.tgz", "integrity": "sha512-ylSC9GhfRH7m1EUXBXofhgx4lUWmFeQDINW5oLuS+gxWdfUeW4zJdeVTYVkexEW+e2VUvlZR2kGnGGipAWR7kw==", + "deprecated": "This is a stub types definition. dotenv provides its own type definitions, so you do not need this installed.", "dev": true, - "requires": { + "dependencies": { "dotenv": "*" } }, - "@types/express": { + "node_modules/@types/express": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", "dev": true, - "requires": { + "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.18", "@types/qs": "*", "@types/serve-static": "*" } }, - "@types/express-serve-static-core": { + "node_modules/@types/express-serve-static-core": { "version": "4.17.18", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz", "integrity": "sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA==", "dev": true, - "requires": { + "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*" } }, - "@types/mime": { + "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", "dev": true }, - "@types/node": { + "node_modules/@types/node": { "version": "14.14.31", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", - "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==", - "dev": true + "integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==" }, - "@types/node-fetch": { + "node_modules/@types/node-fetch": { "version": "2.5.8", "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.8.tgz", "integrity": "sha512-fbjI6ja0N5ZA8TV53RUqzsKNkl9fv8Oj3T7zxW7FGv1GSH7gwJaNF8dzCjrqKaxKeUpTz4yT1DaJFq/omNpGfw==", "dev": true, - "requires": { + "dependencies": { "@types/node": "*", "form-data": "^3.0.0" } }, - "@types/qs": { + "node_modules/@types/qs": { "version": "6.9.5", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==", "dev": true }, - "@types/range-parser": { + "node_modules/@types/range-parser": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", "dev": true }, - "@types/serve-static": { + "node_modules/@types/serve-static": { "version": "1.13.9", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", "dev": true, - "requires": { + "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, - "asynckit": { + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, - "combined-stream": { + "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, - "requires": { + "dependencies": { "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "delayed-stream": { + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.4.0" + } }, - "dotenv": { + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "form-data": { + "node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dev": true, - "requires": { + "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" } }, - "mime-db": { + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/mime-db": { "version": "1.46.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.6" + } }, - "mime-types": { + "node_modules/mime-types": { "version": "2.1.29", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", "dev": true, - "requires": { + "dependencies": { "mime-db": "1.46.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" } } } diff --git a/server/package.json b/server/package.json index b6b5496..de9b549 100644 --- a/server/package.json +++ b/server/package.json @@ -1,13 +1,21 @@ { "name": "climate-server", "version": "1.0.0", + "dependencies": { + "ts-node": "^10.9.1", + "child-process-promise": "^2.2.1", + "cors": "^2.8.5", + "dotenv": "^8.2.0", + "ejs": "^3.1.6", + "express": "^5.0.0-alpha.8", + "mysql2": "^2.2.5" + }, "devDependencies": { - "@types/node-fetch": "^2.5.8", + "@types/cors": "^2.8.10", "@types/dotenv": "^8.2.0", "@types/express": "^4.17.11", - "@types/cors": "^2.8.10" - }, - "scripts": { - "dev": "concurrently -n \"typescript,nodemon\" -c \"bgGreen.gray.bold,bgYellow.gray.bold\" \"tsc -w\" \"nodemon ../app-dist/server/main.js\"" + "@types/child-process-promise": "^2.2.1", + "@typescript-eslint/eslint-plugin": "^4.17.0", + "@typescript-eslint/parser": "^4.17.0" } } diff --git a/app-dist/scripts/climate-pinger.py b/server/scripts/climate-pinger.py similarity index 64% rename from app-dist/scripts/climate-pinger.py rename to server/scripts/climate-pinger.py index 470c27a..aa77f0e 100755 --- a/app-dist/scripts/climate-pinger.py +++ b/server/scripts/climate-pinger.py @@ -10,16 +10,18 @@ try: dhtDevice = adafruit_dht.DHT22(D4) temp = dhtDevice.temperature humidity = dhtDevice.humidity - co2 = mh_z19.read() - if co2 is not None: - co2 = co2['co2'] - else: - raise RuntimeError() + co2 = None + try: + mhz19_reading = mh_z19.read() + if mhz19_reading is not None and mhz19_reading['co2'] is not None: + co2 = mhz19_reading['co2'] + except Exception as error: + co2 = 0 print( 'Time:', str(datetime.isoformat(datetime.now())), '\nTemp:', temp, '\nHumidity:', humidity, - '\nCO2:', co2, + '\nCO2:', co2 if co2 is not None else 0, sep='\t', ) except Exception as error: diff --git a/app-dist/scripts/pinger-test.py b/server/scripts/pinger-test.py similarity index 100% rename from app-dist/scripts/pinger-test.py rename to server/scripts/pinger-test.py diff --git a/server/src/database.ts b/server/src/database.ts index 1a2e580..9dd1f68 100644 --- a/server/src/database.ts +++ b/server/src/database.ts @@ -22,7 +22,7 @@ export async function establishDatabaseConnection() { \`time\` DATETIME NOT NULL);` ); } catch (e) { - throw new Error(`Error setting up the database: ${e.message}`); + throw new Error(`Error setting up the database: ${(e as Error).message}`); } return dbConnection; } @@ -31,6 +31,6 @@ export async function tryQuery(cb: () => Promise): Promise { try { return await cb(); } catch (err) { - throw new GenericPersistenceError(err.message, "There was an error querying the database."); + throw new GenericPersistenceError((err as Error).message, "There was an error querying the database."); } -} \ No newline at end of file +} diff --git a/server/src/main.ts b/server/src/main.ts index d4169a1..9632474 100644 --- a/server/src/main.ts +++ b/server/src/main.ts @@ -5,9 +5,12 @@ import {setupCollections} from "./Collections"; import path from "path"; import {startSensorPinger} from "./pingSensors"; -dotenv.config({ path: path.resolve(__dirname + "/.env") }); +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); async function main() { try { const collections = await setupCollections(); @@ -19,16 +22,14 @@ async function main() { app.locals = { rootUrl: SERVER_ROOT, }; - app.set("view-engine", "ejs"); - app.set("views", path.resolve(__dirname + "/../static")); - app.use(SERVER_ROOT + "/static", express.static(path.resolve(__dirname + "/../static"))); + app.use(SERVER_ROOT, express.static(path.resolve(__dirname + "/../dist/public"))); app.use(SERVER_ROOT, mainRouter); app.listen(app.get("port"), () => { console.log("ClayPI running on http://localhost:%d", app.get("port")); }); startSensorPinger(); } catch (e) { - throw new Error(`Problem setting up the server: ${e.message}`); + throw new Error(`Problem setting up the server: ${(e as Error).message}`); } } diff --git a/server/src/mainRouter.ts b/server/src/mainRouter.ts index 094a2d5..c2f2a5c 100644 --- a/server/src/mainRouter.ts +++ b/server/src/mainRouter.ts @@ -7,9 +7,6 @@ import newByteSeriesRouter from "./byteSeriesRouter"; export function newMainRouter(collections: CollectionRegistry) { const router = express.Router(); - router.get("/dashboard", (req, res) => { - res.render("index.ejs", { rootUrl: req.app.locals.rootUrl }); - }); router.use("/api/snapshots", newSnapshotRouter(collections)); router.use("/api/timeseries", newByteSeriesRouter(collections)); router.use(topLevelErrorHandler); diff --git a/server/src/pingSensors.ts b/server/src/pingSensors.ts index f8b9717..ad09ef0 100644 --- a/server/src/pingSensors.ts +++ b/server/src/pingSensors.ts @@ -1,7 +1,6 @@ import {ISOSnapshot} from "./Snapshot"; import {exec} from "child-process-promise"; import path from "path"; -import fetch from "node-fetch"; import {ClayPIError} from "./errors"; async function pingSensors(): Promise> { @@ -43,4 +42,4 @@ export function startSensorPinger() { }; createAndSubmitNewSnapshot(); setInterval(createAndSubmitNewSnapshot, (Number(process.env.SENSOR_PING_INTERVAL) ?? 30) * 1000); -} \ No newline at end of file +} diff --git a/server/tsconfig.json b/server/tsconfig.json index cfa762d..ce8b7d3 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "outDir": "../app-dist/server", "noImplicitAny": true, "module": "commonjs", "target": "ES6", @@ -20,4 +19,4 @@ "dom.iterable", "esnext" ] -} \ No newline at end of file +} diff --git a/setup.sh b/setup.sh index ee7a5e3..0fdd16c 100644 --- a/setup.sh +++ b/setup.sh @@ -3,4 +3,4 @@ apt-get install python3 libgpiod2 npm mariadb-server pip3 install adafruit-circuitpython-dht mh-z19 npm install -(cd ./server && npm install && tsc) & (cd ./dashboard && npm install && npm run build) +(cd ./server && npm install) & (cd ./dashboard && npm install && npm run build)