diff --git a/controllers/modbus.controller.js b/controllers/modbus.controller.js index 3305220..2fb1df8 100644 --- a/controllers/modbus.controller.js +++ b/controllers/modbus.controller.js @@ -75,7 +75,8 @@ export const modbusController = { 'id', dv.id, 'name', dv.name, 'reg_addr', dv.reg_addr, - 'reg_format', dv.reg_format + 'reg_format', dv.reg_format, + 'reg_type', dv.reg_type ), ', ' ) || ']' END AS display_values FROM modbus_slaves AS ms diff --git a/data.db b/data.db index 76368a9..73f3c09 100644 Binary files a/data.db and b/data.db differ diff --git a/index.d.ts b/index.d.ts index f5b8b77..c114aae 100644 --- a/index.d.ts +++ b/index.d.ts @@ -10,6 +10,7 @@ export type AppConfig = { log_interval_ms: number; }; +export type RegisterType = "HR" | "IR" export type NumberType = 'UI16' | 'I16' | 'UI32' | 'I32' | 'FP32' export type DisplayValue = { @@ -18,7 +19,8 @@ export type DisplayValue = { name: string; slave_id: number; reg_addr: number; - reg_format: number; + reg_format: NumberType; + reg_type: RegisterType; } export type ModbusDevice = { diff --git a/migrations/001-init.sql b/migrations/001-init.sql index 073ba83..bb9ad93 100644 --- a/migrations/001-init.sql +++ b/migrations/001-init.sql @@ -34,8 +34,8 @@ CREATE TABLE IF NOT EXISTS "display_values" ( "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_type" VARCHAR(3) CHECK(reg_type IN("HR", "IR", "DI", "DO")) DEFAULT "IR", - "reg_format" INTEGER NOT NULL CHECK(reg_format IN(16, 32)) DEFAULT 16, + "reg_type" VARCHAR(3) NOT NULL CHECK(reg_type IN("HR", "IR")) DEFAULT "IR", + "reg_format" VARCHAR(5) NOT NULL CHECK(reg_format IN("UI16", "I16", "UI32", "I32", "FP32")) DEFAULT "UI16", PRIMARY KEY("id"), FOREIGN KEY("slave_id") REFERENCES modbus_slaves("id") ON DELETE CASCADE ); @@ -64,16 +64,17 @@ INSERT INTO "modbus_slaves" ( (4, "Device #4", NULL, NULL, NULL, "Label 4", 0); INSERT INTO "display_values" ( - "id", "name", "slave_id", "reg_addr", "reg_format" + "id", "name", "slave_id", "reg_addr", "reg_format", "reg_type" ) VALUES - (1, "CV1", 1, 10, 16), - (2, "CV2", 1, 11, 16), - (3, "SP", 1, 12, 16), - (4, "CV1", 2, 13, 16), - (5, "CV2", 2, 14, 16), - (6, "SP", 2, 15, 16), - (7, "CV1", 3, 16, 16), - (8, "SP", 3, 17, 16); + (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"); -------------------------------------------------------------------------------- -- Down -------------------------------------------------------------------------------- diff --git a/public/index.html b/public/index.html index 20e279d..8bae9e4 100644 --- a/public/index.html +++ b/public/index.html @@ -238,6 +238,7 @@
Value: Reg Addr: + Reg Type: Format:
diff --git a/public/js/app.js b/public/js/app.js index 0142c7a..c98f0c5 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -32,10 +32,10 @@ document.addEventListener("alpine:init", async () => { const { is_configured } = await api.get("/app/is_configured"); this.is_configured = is_configured; + connStatusEventSource.onmessage = (e) => (this.is_opened = e.data === "true"); if (config) this.config = config; if (is_configured) { - connStatusEventSource.onmessage = (e) => (this.is_opened = e.data === "true"); await utils.wait(500); this.currentPage = "monitoring"; return; diff --git a/services/modbus.service.js b/services/modbus.service.js index f66c419..d8022a4 100644 --- a/services/modbus.service.js +++ b/services/modbus.service.js @@ -7,7 +7,7 @@ export const modbusService = { * @return {Promise} */ async readDataFromDevice(device) { - const { g_display_reg_format, g_display_reg_addr, g_display_reg_type } = device; + const { g_display_reg_format, g_display_reg_addr, g_display_reg_type, display_values } = device; /** @type {import("..").EventDataStream} */ const data = { graph: null, displayValues: [] }; @@ -16,22 +16,22 @@ export const modbusService = { /* Read data for graph */ if (g_display_reg_addr !== null) { - const graphValue = await this.readModbusRegisters(g_display_reg_addr, g_display_reg_type, g_display_reg_format); + const graphValueBuf = await this.readModbusRegisters(g_display_reg_addr, g_display_reg_type, g_display_reg_format); data.graph = { - value: utils.readNumberFromBuf(graphValue, device.g_display_reg_format, 'BE'), + value: utils.readNumberFromBuf(graphValueBuf, device.g_display_reg_format, 'BE'), format: g_display_reg_format } } /* Read data for display values */ - if (device.display_values) { - for (const value of device.display_values) { - value.data = Buffer.from((await this.readModbusRegisters(value.reg_addr, 'HR', 'UI16'))).readUInt16BE(); + if (display_values) { + for (const v of device.display_values) { + const displayValueBuf = await this.readModbusRegisters(v.reg_addr, v.reg_type, v.reg_format) + v.data = utils.readNumberFromBuf(displayValueBuf, v.reg_format, 'BE') + data.displayValues.push(v); } } - data.displayValues = device.display_values; - return data; }, @@ -44,10 +44,16 @@ export const modbusService = { async readModbusRegisters(addr, type, format) { let data; let len = 1; - - if (format.includes('32')) len = 2; - if (format.includes('64')) len = 4; - if (format.includes('128')) len = 8; + + switch (format) { + case 'UI32': + case 'I32': + case 'FP32': + len = 2; + break; + default: + break; + } switch (type) { case 'HR': diff --git a/utils/number.js b/utils/number.js index d0bc699..97484e9 100644 --- a/utils/number.js +++ b/utils/number.js @@ -9,11 +9,13 @@ export function readNumberFromBuf(buf, type, order) { if (type === 'UI16' && order === 'BE') return Buffer.from(buf).readUInt16BE(); if (type === 'I16' && order === 'BE') return Buffer.from(buf).readInt16BE(); if (type === 'UI32' && order === 'BE') return Buffer.from(buf).readUint32BE(); + if (type === 'I32' && order === 'BE') return Buffer.from(buf).readInt32BE(); if (type === 'FP32' && order === 'BE') return Buffer.from(buf).readFloatBE(); /* Little-Endian */ if (type === 'UI16' && order === 'LE') return Buffer.from(buf).readUInt16LE(); if (type === 'I16' && order === 'LE') return Buffer.from(buf).readInt16LE(); if (type === 'UI32' && order === 'LE') return Buffer.from(buf).readUint32LE(); + if (type === 'I32' && order === 'LE') return Buffer.from(buf).readInt32LE(); if (type === 'FP32' && order === 'LE') return Buffer.from(buf).readFloatLE(); } \ No newline at end of file diff --git a/validators/display-value.schema.js b/validators/display-value.schema.js index e4d4ae7..3e3259c 100644 --- a/validators/display-value.schema.js +++ b/validators/display-value.schema.js @@ -5,7 +5,8 @@ export const displayValueSchema = object({ name: string().required(), slave_id: number().required(), reg_addr: number().min(0).max(65534).required(), - reg_format: number().oneOf([16, 32]).required() + reg_format: string().oneOf(["UI16", "I16", "UI32", "I32", "FP32"]).required(), + reg_type: string().oneOf(["HR", "IR"]).required() }) export const removeDisplayValueSchema = displayValueSchema.pick(['id']); \ No newline at end of file