diff --git a/data.db b/data.db index 7e6c153..c7fe9ac 100644 Binary files a/data.db and b/data.db differ diff --git a/middlewares/validate-body.middleware.js b/middlewares/validate-body.middleware.js index 46641ba..8828363 100644 --- a/middlewares/validate-body.middleware.js +++ b/middlewares/validate-body.middleware.js @@ -13,9 +13,12 @@ export function validateBodyMiddleware(schema) { await schema.validate(req.body); next(); } catch (error) { - return res.status(400).json({ error: { - message: error.errors[0] - }}); + return res.status(400).json({ + error: { + status: 400, + message: error.errors[0], + }, + }); } }; } diff --git a/migrations/001-init.sql b/migrations/001-init.sql index 363eac8..beee752 100644 --- a/migrations/001-init.sql +++ b/migrations/001-init.sql @@ -21,8 +21,8 @@ CREATE TABLE IF NOT EXISTS "app_config" ( CREATE TABLE IF NOT EXISTS "modbus_slaves" ( "id" INTEGER CHECK (id >= 1 AND id <= 255), "name" VARCHAR(256) NOT NULL, - "display_addr" INTEGER CHECK(display_addr >= 0 AND display_addr <= 65534), - -- "display_val_format" INTEGER CHECK IN(16, 32) NOT NULL, + "display_reg_addr" INTEGER CHECK(display_reg_addr >= 0 AND display_reg_addr <= 65534), + "display_reg_format" INTEGER CHECK(display_reg_format IN(16, 32)), "is_logging" BOOLEAN NOT NULL, PRIMARY KEY("id") ); diff --git a/public/css/dist.css b/public/css/dist.css index 7ce2c2f..9b6b569 100644 --- a/public/css/dist.css +++ b/public/css/dist.css @@ -603,15 +603,21 @@ video { position: relative; } -.m-2 { - margin: 0.5rem; -} - .mx-auto { margin-left: auto; margin-right: auto; } +.my-4 { + margin-top: 1rem; + margin-bottom: 1rem; +} + +.my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; +} + .ml-auto { margin-left: auto; } @@ -640,6 +646,10 @@ video { margin-top: 1rem; } +.mt-10 { + margin-top: 2.5rem; +} + .block { display: block; } @@ -664,10 +674,18 @@ video { height: 5rem; } +.h-full { + height: 100%; +} + .h-screen { height: 100vh; } +.max-h-\[520px\] { + max-height: 520px; +} + .w-1 { width: 0.25rem; } @@ -676,32 +694,12 @@ video { width: 5rem; } -.w-48 { - width: 12rem; -} - -.w-72 { - width: 18rem; -} - .w-full { width: 100%; } -.w-24 { - width: 6rem; -} - -.w-16 { - width: 4rem; -} - -.w-12 { - width: 3rem; -} - -.w-64 { - width: 16rem; +.min-w-\[256px\] { + min-width: 256px; } .max-w-2xl { @@ -712,6 +710,14 @@ video { max-width: 72rem; } +.max-w-5xl { + max-width: 64rem; +} + +.flex-1 { + flex: 1 1 0%; +} + .flex-auto { flex: 1 1 auto; } @@ -730,6 +736,16 @@ video { animation: spin 1s linear infinite; } +.cursor-pointer { + cursor: pointer; +} + +.select-none { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + .resize { resize: both; } @@ -756,12 +772,22 @@ video { margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); } +.space-y-2 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); +} + .space-y-3 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); } +.overflow-y-auto { + overflow-y: auto; +} + .rounded-sm { border-radius: 0.125rem; } @@ -770,6 +796,14 @@ video { border-width: 1px; } +.border-2 { + border-width: 2px; +} + +.border-b { + border-bottom-width: 1px; +} + .border-l { border-left-width: 1px; } @@ -778,6 +812,10 @@ video { border-right-width: 1px; } +.border-dashed { + border-style: dashed; +} + .fill-blue-600 { fill: #2563eb; } @@ -786,6 +824,14 @@ video { padding: 2.5rem; } +.p-2 { + padding: 0.5rem; +} + +.p-2\.5 { + padding: 0.625rem; +} + .p-20 { padding: 5rem; } @@ -816,19 +862,13 @@ video { padding-right: 0.625rem; } -.py-1 { - padding-top: 0.25rem; - padding-bottom: 0.25rem; +.py-3 { + padding-top: 0.75rem; + padding-bottom: 0.75rem; } -.py-1\.5 { - padding-top: 0.375rem; - padding-bottom: 0.375rem; -} - -.py-8 { - padding-top: 2rem; - padding-bottom: 2rem; +.pt-5 { + padding-top: 1.25rem; } .text-center { @@ -845,6 +885,11 @@ video { line-height: 2.25rem; } +.text-5xl { + font-size: 3rem; + line-height: 1; +} + .text-sm { font-size: 0.875rem; line-height: 1.25rem; @@ -863,6 +908,11 @@ video { color: rgb(229 231 235 / var(--tw-text-opacity)); } +.text-gray-400 { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity)); +} + .text-gray-700 { --tw-text-opacity: 1; color: rgb(55 65 81 / var(--tw-text-opacity)); @@ -921,6 +971,11 @@ button:disabled { pointer-events: all !important; } +.hover\:bg-gray-50:hover { + --tw-bg-opacity: 1; + background-color: rgb(249 250 251 / var(--tw-bg-opacity)); +} + @media (prefers-color-scheme: dark) { .dark\:text-gray-600 { --tw-text-opacity: 1; diff --git a/public/index.html b/public/index.html index 53bad3d..f7909db 100644 --- a/public/index.html +++ b/public/index.html @@ -5,34 +5,55 @@ Modbus Logger App + - + - + -
+
-
+
-
-
-
-

Modbus slave #1

+
+
+
+ Devices list: +
+
+

Device #1

+
+
+

Device #2

+
+
+

Device #3

+
+
+
+ + +
+
+
Connection:
-
- graph... -
-
- +
+
+

Device #1

+
+
+
+
+
+
@@ -222,8 +243,7 @@

Refresh page to try again.


-
-            
+

           
diff --git a/public/js/app.js b/public/js/app.js index 474cb10..9ce0a32 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -1,9 +1,33 @@ // @ts-nocheck import "./alpine.js"; import api from "./api.js"; -import * as utils from './utils/index.js' +import * as utils from "./utils/index.js"; -const pages = ['loading', 'monitoring', 'configuration', '404'] +const pages = ["loading", "monitoring", "configuration", "404"]; + +var data = []; +var t = new Date(); + +for (var i = 10; i >= 0; i--) { + var x = new Date(t.getTime() - i * 1000); + data.push([x, Math.random()]); +} + +document.addEventListener("DOMContentLoaded", () => { + var g = new Dygraph(document.getElementById("div_g"), data, { + drawPoints: false, + showRoller: false, + // valueRange: [0.0, 6.8], + labels: ["Time", "Random"], + }); + + window.intervalId = setInterval(function () { + var x = new Date(); // current time + var y = Math.random(); + data.push([x, y]); + g.updateOptions({ file: data }); + }, 1000); +}); document.addEventListener("alpine:init", async () => { Alpine.store("app", { @@ -31,7 +55,7 @@ document.addEventListener("alpine:init", async () => { if (config) this.config = config; if (is_configured) { - const devices = await api.get('/modbus/devices'); + const devices = await api.get("/modbus/devices"); this.devices = devices; this.currentPage = "monitoring"; return; @@ -39,19 +63,19 @@ document.addEventListener("alpine:init", async () => { this.currentPage = "configuration"; } catch (error) { - this.currentPage = 'error' + this.currentPage = "error"; this.error = error; } }, setPage(page) { if (!pages.includes(page)) { - this.currentPage = '404' + this.currentPage = "404"; return; } this.currentPage = page; - } + }, }); Alpine.data("configAppPage", () => ({ @@ -64,11 +88,17 @@ document.addEventListener("alpine:init", async () => { this.errorMessage = ""; const data = { ...this.$store.app.config }; const body = { - RTU: utils.objKeysExclude(data, ['mb_tcp_ip', 'mb_tcp_port']), - TCP: utils.objKeysExclude(data, ['mb_rtu_path', 'mb_rtu_baud', 'mb_rtu_parity', 'mb_rtu_data_bits', 'mb_rtu_stop_bits']) - } + RTU: utils.objKeysExclude(data, ["mb_tcp_ip", "mb_tcp_port"]), + TCP: utils.objKeysExclude(data, [ + "mb_rtu_path", + "mb_rtu_baud", + "mb_rtu_parity", + "mb_rtu_data_bits", + "mb_rtu_stop_bits", + ]), + }; await api.patch("/app/config", body[data.mb_connection_type]); - await api.post("/modbus/connect"); + await api.post("/modbus/connect"); this.$store.app.currentPage = "monitoring"; } catch (error) { this.errorMessage = `${error.message}`; diff --git a/routes/api.router.js b/routes/api.router.js index 36222bf..de6e288 100644 --- a/routes/api.router.js +++ b/routes/api.router.js @@ -1,5 +1,4 @@ import express from "express"; -import modbusClient from "#root/config/modbus-client.config.js"; /** * Validators @@ -9,7 +8,7 @@ import { appConfigSchema } from "#root/validators/index.js"; /** * Controllers */ -import { appController, modbusController } from '#root/controllers/index.js' +import { appController, modbusController } from "#root/controllers/index.js"; /** * Middlewares @@ -22,7 +21,7 @@ apiRouter.get("/app/config", appController.getConfig); apiRouter.patch("/app/config", validateBodyMiddleware(appConfigSchema), appController.updateConfig); apiRouter.get("/app/is_configured", appController.isConfigured); -apiRouter.get('/modbus/devices', modbusController.list); +apiRouter.get("/modbus/devices", modbusController.list); apiRouter.post("/modbus/connect", modbusController.connect); apiRouter.post("/modbus/close", modbusController.close); apiRouter.get("/modbus/data_stream", modbusController.streamData); diff --git a/scripts/db-init.script.js b/scripts/db-init.script.js index 9335721..0e47190 100644 --- a/scripts/db-init.script.js +++ b/scripts/db-init.script.js @@ -1,11 +1,11 @@ -import db from '#root/config/database.config.js' +import db from "#root/config/database.config.js"; async function run() { try { - await db.migrate({ force: false }) - console.log('Database initialized.'); + await db.migrate({ force: false }); + console.log("Database initialized."); } catch (error) { - throw error; + console.error(error); } }