From 4edb0f3a9dc6eb1ebc60b09e6895042b3fd46886 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Fri, 10 Nov 2023 16:31:47 +0300 Subject: [PATCH] progress --- controllers/modbus.controller.js | 35 +++++++------ data.db | Bin 20480 -> 20480 bytes migrations/001-init.sql | 33 +++++++------ models/base.model.js | 55 +++++++++++++++++++++ models/display-value.model.js | 7 +++ models/index.js | 82 ++----------------------------- models/modbus-device.model.js | 33 +++++++++++++ public/index.html | 5 +- public/js/app.js | 8 ++- 9 files changed, 142 insertions(+), 116 deletions(-) create mode 100644 models/base.model.js create mode 100644 models/display-value.model.js create mode 100644 models/modbus-device.model.js diff --git a/controllers/modbus.controller.js b/controllers/modbus.controller.js index d4d1e89..43ffdb4 100644 --- a/controllers/modbus.controller.js +++ b/controllers/modbus.controller.js @@ -3,7 +3,7 @@ import modbusClient from "#root/config/modbus-client.config.js"; import * as utils from '#root/utils/index.js' import { RowNotFoundError } from '#root/errors/index.js' import { appService, modbusService } from "#root/services/index.js"; -import { modbusDeviceModel } from "#root/models/index.js"; +import { modbusDeviceModel, displayValueModel } from "#root/models/index.js"; export const modbusController = { /** @@ -63,19 +63,14 @@ export const modbusController = { */ async createDevice(req, res, next) { try { - const { id, name, g_display_reg_addr, g_display_reg_format, g_display_reg_type, g_y_label } = - req.body; - await db.run( - `INSERT INTO "modbus_slaves" ( - "id", - "name", - "g_display_reg_addr", - "g_display_reg_format", - "g_display_reg_type", - "g_y_label") - VALUES (?, ?, ?, ?, ?, ?)`, - [id, name, g_display_reg_addr, g_display_reg_format, g_display_reg_type, g_y_label], - ); + await modbusDeviceModel.create({ + id: req.body.id, + name: req.body.name, + g_display_reg_addr: req.body.g_display_reg_addr, + g_display_reg_format: req.body.g_display_reg_format, + g_display_reg_type: req.body.g_display_reg_type, + g_y_label: req.body.g_y_label + }) return res.status(200).json({ message: "Device created." }); } catch (error) { next(error); @@ -124,9 +119,10 @@ export const modbusController = { */ async removeDevice(req, res, next) { try { - const device = await db.get(`SELECT id FROM "modbus_slaves" WHERE id = ?`, [req.body.id]); + const { id } = req.body; + const device = await modbusDeviceModel.getById(id) if (!device) throw new RowNotFoundError(); - await db.run(`DELETE FROM "modbus_slaves" WHERE id = ?`, [req.body.id]); + await modbusDeviceModel.delById(id); return res.status(200).json({ message: "Device removed." }); } catch (error) { next(error); @@ -167,7 +163,10 @@ export const modbusController = { */ async removeDisplayValue(req, res, next) { try { - await db.run(`DELETE FROM "display_values" WHERE id = ?`, req.body.id); + const { id } = req.body; + const value = await displayValueModel.getById(id); + if (!value) throw new RowNotFoundError(); + await displayValueModel.delById(id); return res.status(200).json({ message: "Display value removed." }); } catch (error) { next(error); @@ -199,7 +198,7 @@ export const modbusController = { }, /** - * Creates event stream aboud modbus connection status + * Creates event stream about modbus connection status * @param {import('express').Request} req * @param {import('express').Response} res * @param {import('express').NextFunction} next diff --git a/data.db b/data.db index 45ad0eed07cf5224c8bd7ab4671548a1404686b8..97fe14e1856d8e22cc50d570a25a59cca7226d12 100644 GIT binary patch delta 1120 zcmZux!E4h{7=KB+CE3=zWnCt-wZ;tH3S~BVZPy(Hokf<}(bBoW1jV`bFdW^mnIJoK z6G3nwZegI{Vc=DeQO~=J2mJ?j+0BC&58ed7FRxqaFc6aOm*4mOe&6@r%hrLgbs)Tr z>N|vxF1TBlFteLv!p`BNpRy2Y&L}rSg4EpU+mu3kMA|#tekG}W@16)UF+TS;zeg67 z8?$#y=7?=2O`ADM)0!^Bt2OW1S$vkcHZ?7U zrn$J>2AL@F{DE!`MnK3BMYjwt^)AE|9Wfgr<`^NF46CAU@NFRW^OBY%6Nd1E|7wB|veH@#Ta2k1OuGwR+l$&3O;>54)N=47Ef|TFwt^-`6N)i0 z#!DMw)PqU2_nO+ovtDex_hR}7s0R~IdiA~Cfe_;cvds6s_r3SNnPGj4Ti@a~2BbMc z2oGQOaO0cF6gRhf{fEFg_b$6HxH#9|GyempYo9pxcUw=Ke*YR#-bs&g)mpXDej}e2 zUmBc1l${|4N%8#lFWEhjsobkBRn+5JBB_oh)r47qABhE1Gw_`)EmoFQEpaLt@On<_ zfOPnJ`%HA$(^;k3i#@A!`$hD*Z@P$@8hl3Eo3U^cv!{zX!vIgPB2d!SPXRWcX9T1# zm?`9AQ#KDU(nQy_Q%1nHr`c2 z3>la5b~`hjb|yMX$Ur3}f*ww<)EakImetZyqqYsZlAbwbJbhi$$TiVQY>adv)HC$)T~$ z0T^hQ^T3!rVU4$=L(o(Tb^o(%Jai8NcQ}S(dEU@(z|O@yrIub%d diff --git a/migrations/001-init.sql b/migrations/001-init.sql index 0feed69..a1adddb 100644 --- a/migrations/001-init.sql +++ b/migrations/001-init.sql @@ -57,26 +57,27 @@ CREATE TABLE IF NOT EXISTS "display_values" ( INSERT INTO "modbus_slaves" ( "id", "name", "g_display_reg_addr", "g_display_reg_type", "g_display_reg_format", "g_y_label" ) VALUES - (1, "Device #1", 0, "IR", "UI16", "Label 1"), - (2, "Device #2", 1, "IR", "UI32", "Label 2"), - (3, "Device #3", 3, "IR", "UI16", "Label 3"), - (4, "Device #4", NULL, NULL, NULL, "Label 4"); + (1, "MKP #1", 132, "HR", "UI16", "PID Out"), + (2, "Test Device #1", 1, "IR", "UI32", "Label 2"), + (3, "Test Device #2", 3, "IR", "UI16", "Label 3"), + (4, "Test Device #3", NULL, NULL, NULL, "Label 4"); INSERT INTO "display_values" ( "id", "name", "slave_id", "reg_addr", "reg_format", "reg_type" ) VALUES - (1, "CV1", 1, 10, "UI16", "IR"), - (2, "CV2", 1, 11, "I16", "IR"), - (3, "SP", 1, 12, "UI32", "IR"), - (4, "CV1", 2, 13, "I32", "IR"), - (5, "CV2", 2, 14, "I16", "IR"), - (6, "SP", 2, 15, "UI16", "IR"), - (7, "CV1", 3, 16, "UI16", "HR"), - (8, "CV2", 3, 17, "FP32", "HR"), - (9, "SP", 3, 15, "UI16", "IR"), - (10, "Control action type", 3, 0, "BOOL", "DI"), - (11, "Status ALARM1", 3, 1, "BOOL", "DO"), - (12, "Status ALARM2", 3, 2, "BOOL", "DO"); + (1, "SP", 1, 138, "UI32", "HR"), + (2, "Status Device", 1, 89, "UI16", "HR"), + (3, "Control action type", 1, 2301, "BOOL", "DI"), + (4, "S.L.Bd", 1, 528, "UI16", "HR"), + (5, "VAL1", 2, 0, "I32", "IR"), + (6, "VAL2", 2, 2, "I16", "IR"), + (7, "VAL3", 2, 3, "UI16", "IR"), + (8, "VAL4", 3, 4, "UI16", "HR"), + (9, "VAL5", 3, 5, "FP32", "HR"), + (10, "VAL6", 3, 7, "UI16", "IR"), + (11, "VAL7", 3, 0, "BOOL", "DI"), + (12, "VAL8", 3, 1, "BOOL", "DO"), + (13, "VAL9", 3, 2, "BOOL", "DO"); -------------------------------------------------------------------------------- -- Down -------------------------------------------------------------------------------- diff --git a/models/base.model.js b/models/base.model.js new file mode 100644 index 0000000..4b678c0 --- /dev/null +++ b/models/base.model.js @@ -0,0 +1,55 @@ +import db from '#root/config/database.config.js' + +export class BaseModel { + /** + * @param {string} table + */ + constructor(table) { + this.table = table; + } + + /** + * @param {number | string} id + * @param {string[]} keys + * @return {Promise} + */ + async getById(id, keys = ['*']) { + const query = `SELECT ${keys.join(',')} FROM ${this.table} WHERE id = ?`; + const params = [id]; + const res = await db.get(query, params); + return res; + } + + /** + * @param {number | string} id + * @return {Promise} + */ + async delById(id) { + const query = `DELETE FROM ${this.table} WHERE id = ?`; + await db.run(query, [id]); + } + + /** + * @param {string[]} keys + */ + async getList(keys = ['*']) { + const query = `SELECT ${keys.join(',')} FROM ${this.table}`; + const res = await db.all(query); + return res; + } + + /** + * @param {{ [key: string]: any }} data + * @returns {Promise} + */ + async create(data) { + const fields = Object.keys(data); + const values = Object.values(data); + const query = ` + INSERT INTO ${this.table} + (${fields.join(', ')}) + VALUES (${values.map(() => '?').join(',')})`; + await db.run(query, values); + return data; + } +} \ No newline at end of file diff --git a/models/display-value.model.js b/models/display-value.model.js new file mode 100644 index 0000000..8aa3b10 --- /dev/null +++ b/models/display-value.model.js @@ -0,0 +1,7 @@ +import { BaseModel } from './base.model.js' + +export class DisplayValueModel extends BaseModel { + constructor() { + super('display_values') + } +} \ No newline at end of file diff --git a/models/index.js b/models/index.js index e024dba..e81ad5b 100644 --- a/models/index.js +++ b/models/index.js @@ -1,79 +1,5 @@ -import db from '#root/config/database.config.js' +import { ModbusDeviceModel } from './modbus-device.model.js'; +import { DisplayValueModel } from './display-value.model.js'; -class BaseModel { - /** - * @param {string} table - */ - constructor(table) { - this.table = table; - } - - /** - * @param {number | string} id - * @param {string[]} keys - * @return {Promise} - */ - async getById(id, keys = ['*']) { - const query = `SELECT ${keys.join(',')} FROM ${this.table} WHERE id = ?`; - const params = [id]; - const res = await db.get(query, params); - return res; - } - - /** - * @param {number | string} id - * @return {Promise} - */ - async delById(id) { - const query = `DELETE FROM ${this.table} WHERE id = ?`; - await db.run(query, [id]); - } - - async getList(keys = ['*']) { - const query = `SELECT ${keys.join(',')} FROM ${this.table}`; - const res = await db.all(query); - return res; - } - - async create(fields, values) { - const query = ` - INSERT INTO ${this.table} - (${fields.join(',')}) - VALUES (${values.map(() => '?').join(',')})`; - await db.run(query, values); - return this; - } -} - -class ModbusDeviceModel extends BaseModel { - constructor(table) { - super(table); - } - - /** - * @return {Promise} - */ - async getListWithDisplayValues() { - const query = ` - SELECT ms.id AS id, ms.name AS name, g_display_reg_addr, g_display_reg_format, g_display_reg_type, g_y_label, - 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, - 'reg_type', dv.reg_type - ), ', ' - ) || ']' END AS display_values - FROM ${this.table} AS ms - LEFT JOIN display_values AS dv ON dv.slave_id = ms.id - GROUP BY ms.id, ms.name;`; - const devices = await db.all(query); - devices.forEach((s) => (s.display_values = JSON.parse(s.display_values))); - return devices; - } -} - -export const modbusDeviceModel = new ModbusDeviceModel('modbus_slaves'); \ No newline at end of file +export const modbusDeviceModel = new ModbusDeviceModel(); +export const displayValueModel = new DisplayValueModel(); \ No newline at end of file diff --git a/models/modbus-device.model.js b/models/modbus-device.model.js new file mode 100644 index 0000000..6fa82b2 --- /dev/null +++ b/models/modbus-device.model.js @@ -0,0 +1,33 @@ +import { BaseModel } from './base.model.js' +import db from '#root/config/database.config.js' + +export class ModbusDeviceModel extends BaseModel { + constructor() { + super('modbus_slaves'); + } + + /** + * @return {Promise} + */ + async getListWithDisplayValues() { + const query = ` + SELECT ms.id AS id, ms.name AS name, g_display_reg_addr, g_display_reg_format, g_display_reg_type, g_y_label, + 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, + 'reg_type', dv.reg_type + ), ', ' + ) || ']' END AS display_values + FROM ${this.table} AS ms + LEFT JOIN display_values AS dv ON dv.slave_id = ms.id + GROUP BY ms.id, ms.name;`; + const devices = await db.all(query); + devices.forEach((s) => (s.display_values = JSON.parse(s.display_values))); + return devices; + } +} \ No newline at end of file diff --git a/public/index.html b/public/index.html index 32f59cf..e1fd011 100644 --- a/public/index.html +++ b/public/index.html @@ -326,9 +326,10 @@ - Reg Addr: - Reg Type: + Addr: + Type: Format: + diff --git a/public/js/app.js b/public/js/app.js index f62a3a4..7e3a7f1 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -25,6 +25,12 @@ document.addEventListener("alpine:init", async () => { }, currentPage: "loading", error: null, + registersTypesMap: { + 'IR': 'Input Registers', + 'HR': 'Holding Registers', + "DI": "Discrete Input", + "DO": "Coils" + }, async init() { try { const connStatusEventSource = new EventSource("/api/modbus/status"); @@ -266,8 +272,6 @@ document.addEventListener("alpine:init", async () => { this.error = null; this.selectedDevice = device; this.resetGraph(); - - // if (device.g_display_reg_addr !== null) this.isLoading = true; dataStreamSource?.close();