From 90271dc45f94587689defcfdad835f5ddf8ea0dc Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Mon, 30 Oct 2023 16:26:56 +0300 Subject: [PATCH] progress --- controllers/modbus.controller.js | 32 +++++- data.db | Bin 20480 -> 20480 bytes getslaves.sql | 19 ++++ migrations/001-init.sql | 22 ++++- public/css/dist.css | 152 +++++------------------------ public/css/main.css | 4 + public/index.html | 115 ++++++++++++++-------- public/js/app.js | 65 +++++++++--- public/js/utils/object.js | 6 ++ routes/api/app.router.js | 18 ++++ routes/api/index.js | 9 +- routes/api/modbus.router.js | 3 +- validators/display-value.schema.js | 11 +++ validators/index.js | 3 +- validators/modbus-device.schema.js | 2 +- 15 files changed, 265 insertions(+), 196 deletions(-) create mode 100644 getslaves.sql create mode 100644 routes/api/app.router.js create mode 100644 validators/display-value.schema.js diff --git a/controllers/modbus.controller.js b/controllers/modbus.controller.js index 9ab78df..2847907 100644 --- a/controllers/modbus.controller.js +++ b/controllers/modbus.controller.js @@ -65,7 +65,23 @@ export const modbusController = { */ async list(req, res, next) { try { - const slaves = await db.all('SELECT * from modbus_slaves'); + const slaves = await db.all(` + SELECT ms.id AS id, ms.name AS name, g_display_reg_addr, g_display_reg_format, g_y_label, is_logging, + CASE + WHEN COUNT(dv.id) = 0 THEN '[]' + ELSE '[' || GROUP_CONCAT( + JSON_OBJECT( + 'id', dv.id, + 'name', dv.name, + 'reg_addr', dv.reg_addr, + 'reg_format', dv.reg_format + ), ', ' + ) || ']' END AS display_values + FROM modbus_slaves AS ms + LEFT JOIN display_values AS dv ON dv.slave_id = ms.id + GROUP BY ms.id, ms.name; + `); + slaves.forEach(s => (s.display_values = JSON.parse(s.display_values))) return res.status(200).json(slaves); } catch (error) { next(error) @@ -80,6 +96,7 @@ export const modbusController = { */ async createDevice(req, res, next) { try { + const { id, name, g_display_reg_addr, g_display_reg_format, g_y_label, is_logging } = req.body; await db.run(`INSERT INTO "modbus_slaves" ( "id", "name", @@ -88,8 +105,8 @@ export const modbusController = { "g_y_label", "is_logging") VALUES (?, ?, ?, ?, ?, ?)`, - [...req.body]); - return res.send(200).json({ message: 'Device created.', data: req.body }); + [id, name, g_display_reg_addr, g_display_reg_format, g_y_label, is_logging]); + return res.status(200).json({ message: 'Device created.' }); } catch (error) { next(error) } @@ -140,7 +157,14 @@ export const modbusController = { * @param {import('express').Response} res * @param {import('express').NextFunction} next */ - async removeDisplayValue(req, res, next) {}, + async removeDisplayValue(req, res, next) { + try { + await db.run(`DELETE FROM "display_values" WHERE id = ?`, req.body.id); + return res.status(200).json({ message: 'Display value removed.' }); + } catch (error) { + next(error); + } + }, /** * Get latest data log from modbus slave device diff --git a/data.db b/data.db index 3beddde9a450cd1c1fc0f631a13e5dfc460abb9f..607d474b58f96415b6a3ccfafcb93af475787175 100644 GIT binary patch delta 951 zcmb`GU2D@&7{||PlIEqUC&kuoYirYrY=utN7ppKtitVHl+Oocg?4nkij$t>klX@Z8 zjv;~|IF7Jg4n#qQur0fm-3!7l2lZCeYd?TbS`+*LJ9&Ga-}BEuInPN3yLhmR-v&H; z2q6v*YaDOIQ@%ZPrTxndh!su|xhJ=!u5fy=p$pRH1(x^6V)*4UeI!OOL*IxwQ7x9L zYO$ti^hA8-jdu0rM*DGhwfQuv7K+vU?ffEDByVWU0L>&aaW$2U#nfDWAzRa`Y9d3I zLM>_Y3B&uRr}3-E`$Gx4?efU`d*HsyCUC=zU_i0+sMdU-ccOGwj-0dMLRPEfX;GfX ztnpfY&TyQ8IOAaB6DPd8gL&lpSTGv?7wnlmXoCKpiqOMg=1f{*EQOA+t5B@u7prC? zOLRXt)sL&uwdSfGh3k5!+0z>^hDUUH|Ox!p1Y1;=Vh%Eh8+Xpy^EDp;(_5lnU3tzKszymZE zzi!C^g9h-tTbdmYIuYKcpTl>(0@*?25BW)keV5=w9*l9N%niw2$M_q=-HKmfnL+Dc9T0&bsbr dc@#z{AmsGk%0peflpcN7YI>645j`qte*w5i)t>+W delta 337 zcmZozz}T>Wae}mmg$$2RE7pS8K^eo<>#exFuwr#jzIwIYmoPufhL{ipM2Y1jh}x5 z0~7yr2L5OK(?Jj@(atX`&ce= 1 AND id <= 255), "name" VARCHAR(256) NOT NULL, -- Holding register - "g_display_reg_addr" INTEGER CHECK(g_display_reg_addr >= 0 AND g_display_reg_addr <= 65534), + "g_display_reg_addr" INTEGER CHECK(g_display_reg_addr >= 0 AND g_display_reg_addr <= 65534) DEFAULT NULL, -- Use 1 or 2 bytes - "g_display_reg_format" INTEGER CHECK(g_display_reg_format IN(16, 32)), - "g_y_label" VARCHAR(40), - "is_logging" BOOLEAN NOT NULL, + "g_display_reg_format" INTEGER CHECK(g_display_reg_format IN(16, 32)) DEFAULT 16, + "g_y_label" VARCHAR(40) DEFAULT "Label", + "is_logging" BOOLEAN NOT NULL DEFAULT FALSE, PRIMARY KEY("id") ); CREATE TABLE IF NOT EXISTS "display_values" ( "id" INTEGER, - "name" VARCHAR(32), + "name" VARCHAR(32) NOT NULL, "slave_id" INTEGER NOT NULL, "reg_addr" INTEGER DEFAULT 0 NOT NULL CHECK(reg_addr >= 0 AND reg_addr <= 65534), + "reg_format" INTEGER NOT NULL CHECK(reg_format IN(16, 32)) DEFAULT 16, PRIMARY KEY("id"), FOREIGN KEY("slave_id") REFERENCES modbus_slaves("id") ON DELETE CASCADE ); @@ -62,6 +63,17 @@ INSERT INTO "modbus_slaves" ( (3, "Device #3", 8, 16, "Label 3", 0), (4, "Device #4", NULL, NULL, "Label 4", 0); +INSERT INTO "display_values" ( + "id", "name", "slave_id", "reg_addr", "reg_format" +) VALUES + (1, "CV1", 1, 0, 16), + (2, "CV2", 1, 1, 16), + (3, "SP", 1, 2, 16), + (4, "CV1", 2, 3, 16), + (5, "CV2", 2, 4, 16), + (6, "SP", 2, 5, 16), + (7, "CV1", 3, 6, 16), + (8, "SP", 3, 7, 16); -------------------------------------------------------------------------------- -- Down -------------------------------------------------------------------------------- diff --git a/public/css/dist.css b/public/css/dist.css index 6432749..c43c182 100644 --- a/public/css/dist.css +++ b/public/css/dist.css @@ -632,16 +632,16 @@ video { margin-bottom: 0.5rem; } -.my-4 { - margin-top: 1rem; - margin-bottom: 1rem; -} - .my-3 { margin-top: 0.75rem; margin-bottom: 0.75rem; } +.my-4 { + margin-top: 1rem; + margin-bottom: 1rem; +} + .mb-2 { margin-bottom: 0.5rem; } @@ -662,10 +662,6 @@ video { margin-right: 0.5rem; } -.mr-auto { - margin-right: auto; -} - .mt-1 { margin-top: 0.25rem; } @@ -686,10 +682,6 @@ video { margin-top: 0.5rem; } -.mt-20 { - margin-top: 5rem; -} - .mt-3 { margin-top: 0.75rem; } @@ -706,10 +698,6 @@ video { margin-top: 1.5rem; } -.mt-auto { - margin-top: auto; -} - .block { display: block; } @@ -750,6 +738,10 @@ video { max-height: 400px; } +.min-h-\[140px\] { + min-height: 140px; +} + .min-h-\[50px\] { min-height: 50px; } @@ -766,31 +758,10 @@ video { width: 100%; } -.w-16 { - width: 4rem; -} - -.w-24 { - width: 6rem; -} - -.w-52 { - width: 13rem; -} - .min-w-\[256px\] { min-width: 256px; } -.min-w-fit { - min-width: -moz-fit-content; - min-width: fit-content; -} - -.min-w-\[100px\] { - min-width: 100px; -} - .max-w-2xl { max-width: 42rem; } @@ -799,10 +770,6 @@ video { max-width: 64rem; } -.max-w-md { - max-width: 28rem; -} - .flex-1 { flex: 1 1 0%; } @@ -811,10 +778,6 @@ video { flex: 1 1 auto; } -.basis-52 { - flex-basis: 13rem; -} - .transform { transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } @@ -843,42 +806,10 @@ video { resize: both; } -.grid-flow-col { - grid-auto-flow: column; -} - -.grid-cols-4 { - grid-template-columns: repeat(4, minmax(0, 1fr)); -} - -.grid-cols-3 { - grid-template-columns: repeat(3, minmax(0, 1fr)); -} - -.grid-cols-\[200px_minmax\(900px\2c _1fr\)_100px\] { - grid-template-columns: 200px minmax(900px, 1fr) 100px; -} - .grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); } -.grid-rows-3 { - grid-template-rows: repeat(3, minmax(0, 1fr)); -} - -.grid-rows-4 { - grid-template-rows: repeat(4, minmax(0, 1fr)); -} - -.grid-rows-1 { - grid-template-rows: repeat(1, minmax(0, 1fr)); -} - -.grid-rows-2 { - grid-template-rows: repeat(2, minmax(0, 1fr)); -} - .flex-row { flex-direction: row; } @@ -891,6 +822,10 @@ video { flex-wrap: wrap; } +.items-start { + align-items: flex-start; +} + .items-center { align-items: center; } @@ -907,10 +842,6 @@ video { justify-content: space-between; } -.gap-3 { - gap: 0.75rem; -} - .gap-2 { gap: 0.5rem; } @@ -939,10 +870,6 @@ video { margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); } -.overflow-auto { - overflow: auto; -} - .overflow-y-auto { overflow-y: auto; } @@ -951,10 +878,6 @@ video { border-radius: 0.125rem; } -.rounded-md { - border-radius: 0.375rem; -} - .border { border-width: 1px; } @@ -993,11 +916,6 @@ video { background-color: rgb(239 68 68 / var(--tw-bg-opacity)); } -.bg-white { - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - .fill-blue-600 { fill: #2563eb; } @@ -1044,19 +962,13 @@ video { padding-right: 0.625rem; } -.px-4 { - padding-left: 1rem; - padding-right: 1rem; -} - .py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; } -.py-3\.5 { - padding-top: 0.875rem; - padding-bottom: 0.875rem; +.pl-0 { + padding-left: 0px; } .pl-2 { @@ -1071,10 +983,6 @@ video { padding-top: 1.25rem; } -.pl-0 { - padding-left: 0px; -} - .text-left { text-align: left; } @@ -1098,6 +1006,11 @@ video { line-height: 2.5rem; } +.text-5xl { + font-size: 3rem; + line-height: 1; +} + .text-lg { font-size: 1.125rem; line-height: 1.75rem; @@ -1113,11 +1026,6 @@ video { line-height: 1.75rem; } -.text-5xl { - font-size: 3rem; - line-height: 1; -} - .font-bold { font-weight: 700; } @@ -1221,6 +1129,12 @@ select { padding-bottom: 0.25rem; } +input[type="checkbox"] { + margin: 0px; + width: auto; + vertical-align: middle; +} + input { padding-left: 0.375rem; padding-right: 0.375rem; @@ -1253,22 +1167,12 @@ button:disabled { } } -@media (min-width: 640px) { - .sm\:grid-cols-1 { - grid-template-columns: repeat(1, minmax(0, 1fr)); - } -} - @media (min-width: 768px) { @media (min-width: 640px) { .md\:sm\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } } - - .md\:grid-cols-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } } @media (min-width: 1024px) { @@ -1277,8 +1181,4 @@ button:disabled { grid-template-columns: repeat(3, minmax(0, 1fr)); } } - - .lg\:grid-cols-3 { - grid-template-columns: repeat(3, minmax(0, 1fr)); - } } diff --git a/public/css/main.css b/public/css/main.css index f4c39a2..e86e7f2 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -29,6 +29,10 @@ select { @apply w-full border py-1 rounded-sm my-0.5 bg-white; } +input[type="checkbox"] { + @apply w-auto m-0 align-middle; +} + input { @apply px-1.5; } diff --git a/public/index.html b/public/index.html index 38bbaab..20842c2 100644 --- a/public/index.html +++ b/public/index.html @@ -20,10 +20,6 @@