mirror of
https://github.com/sergeyyarkov/modbus-logger.git
synced 2026-10-11 02:18:51 +03:00
progress
This commit is contained in:
parent
ffcfe6767d
commit
4edb0f3a9d
@ -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
|
||||
|
||||
@ -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
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
55
models/base.model.js
Normal file
55
models/base.model.js
Normal file
@ -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<any>}
|
||||
*/
|
||||
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<void>}
|
||||
*/
|
||||
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<any>}
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
7
models/display-value.model.js
Normal file
7
models/display-value.model.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { BaseModel } from './base.model.js'
|
||||
|
||||
export class DisplayValueModel extends BaseModel {
|
||||
constructor() {
|
||||
super('display_values')
|
||||
}
|
||||
}
|
||||
@ -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<any>}
|
||||
*/
|
||||
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<void>}
|
||||
*/
|
||||
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<import('..').ModbusDevice[]>}
|
||||
*/
|
||||
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');
|
||||
export const modbusDeviceModel = new ModbusDeviceModel();
|
||||
export const displayValueModel = new DisplayValueModel();
|
||||
33
models/modbus-device.model.js
Normal file
33
models/modbus-device.model.js
Normal file
@ -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<import('..').ModbusDevice[]>}
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -326,9 +326,10 @@
|
||||
<span x-show="value?.reg_format === 'BOOL'"><input :value="Boolean(value?.data)" type="checkbox" onclick="return false;" /></span>
|
||||
<span x-show="value?.reg_format !== 'BOOL'" x-text="Number.isInteger(value?.data) ? value?.data : value?.data?.toFixed(3)"></span>
|
||||
</span>
|
||||
<span>Reg Addr: <span x-text="value?.reg_addr"></span></span>
|
||||
<span>Reg Type: <span x-text="value?.reg_type"></span></span>
|
||||
<span>Addr: <span x-text="value?.reg_addr"></span></span>
|
||||
<span>Type: <span x-text="$store.app.registersTypesMap[value?.reg_type]"></span></span>
|
||||
<span>Format: <span x-text="value?.reg_format"></span></span>
|
||||
<span x-show="value.desc" x-text="value?.desc" class="text-sm text-gray-500 italic"></span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -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();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user