mirror of
https://github.com/sergeyyarkov/modbus-logger.git
synced 2026-10-11 10:28:51 +03:00
refactor
This commit is contained in:
parent
92d5449246
commit
d06edd791a
@ -1,6 +1,5 @@
|
|||||||
import db from "#root/config/database.config.js";
|
import db from "#root/config/database.config.js";
|
||||||
import modbusClient from "#root/config/modbus-client.config.js";
|
import modbusClient from "#root/config/modbus-client.config.js";
|
||||||
import * as utils from '#root/utils/index.js'
|
|
||||||
import { appService, modbusService } from "#root/services/index.js";
|
import { appService, modbusService } from "#root/services/index.js";
|
||||||
|
|
||||||
export const modbusController = {
|
export const modbusController = {
|
||||||
@ -12,30 +11,10 @@ export const modbusController = {
|
|||||||
*/
|
*/
|
||||||
async connect(req, res, next) {
|
async connect(req, res, next) {
|
||||||
try {
|
try {
|
||||||
const config = await appService.getConfig(db);
|
const appConfig = await appService.getConfig();
|
||||||
if (!config) return res.status(400).json({ message: "Application is not configured" });
|
if (!appConfig) return res.status(400).json({ message: "Application is not configured" });
|
||||||
|
await modbusService.connect(appConfig)
|
||||||
if (modbusClient.isOpen) {
|
|
||||||
modbusClient.close(undefined);
|
|
||||||
modbusClient.destroy(undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.mb_connection_type === "TCP") {
|
|
||||||
await modbusClient.connectTCP(config.mb_tcp_ip, { port: config.mb_tcp_port });
|
|
||||||
return res.status(200).json({ message: "Connected." });
|
return res.status(200).json({ message: "Connected." });
|
||||||
}
|
|
||||||
|
|
||||||
if (config.mb_connection_type === "RTU") {
|
|
||||||
await modbusClient.connectRTU(config.mb_rtu_path, {
|
|
||||||
baudRate: config.mb_rtu_baud,
|
|
||||||
dataBits: config.mb_rtu_data_bits,
|
|
||||||
parity: config.mb_rtu_parity,
|
|
||||||
stopBits: config.mb_rtu_stop_bits,
|
|
||||||
});
|
|
||||||
return res.status(200).json({ message: "Connected." });
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.status(400).json({ message: "Connection type is invalid." });
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@ -66,25 +45,8 @@ export const modbusController = {
|
|||||||
*/
|
*/
|
||||||
async list(req, res, next) {
|
async list(req, res, next) {
|
||||||
try {
|
try {
|
||||||
const slaves = await db.all(`
|
const devices = await modbusService.getDevices();
|
||||||
SELECT ms.id AS id, ms.name AS name, g_display_reg_addr, g_display_reg_format, g_display_reg_type, g_y_label, is_logging,
|
return res.status(200).json(devices);
|
||||||
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 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) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@ -218,6 +180,8 @@ export const modbusController = {
|
|||||||
if (!device)
|
if (!device)
|
||||||
return res.status(404).json({ error: { message: "Device not found." } });
|
return res.status(404).json({ error: { message: "Device not found." } });
|
||||||
|
|
||||||
|
// modbusService.createPollInterval(req, res, device).poll(1000);
|
||||||
|
|
||||||
res.setHeader("Cache-Control", "no-cache");
|
res.setHeader("Cache-Control", "no-cache");
|
||||||
res.setHeader("Content-Type", "text/event-stream");
|
res.setHeader("Content-Type", "text/event-stream");
|
||||||
res.setHeader("Connection", "keep-alive");
|
res.setHeader("Connection", "keep-alive");
|
||||||
|
|||||||
@ -774,6 +774,14 @@ video {
|
|||||||
max-width: 64rem;
|
max-width: 64rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.max-w-xl {
|
||||||
|
max-width: 36rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.max-w-md {
|
||||||
|
max-width: 28rem;
|
||||||
|
}
|
||||||
|
|
||||||
.flex-1 {
|
.flex-1 {
|
||||||
flex: 1 1 0%;
|
flex: 1 1 0%;
|
||||||
}
|
}
|
||||||
@ -956,6 +964,10 @@ video {
|
|||||||
padding: 20rem;
|
padding: 20rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-5 {
|
||||||
|
padding: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.px-2 {
|
.px-2 {
|
||||||
padding-left: 0.5rem;
|
padding-left: 0.5rem;
|
||||||
padding-right: 0.5rem;
|
padding-right: 0.5rem;
|
||||||
@ -971,6 +983,21 @@ video {
|
|||||||
padding-bottom: 0.75rem;
|
padding-bottom: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.px-6 {
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
padding-right: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.py-4 {
|
||||||
|
padding-top: 1rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.px-5 {
|
||||||
|
padding-left: 1.25rem;
|
||||||
|
padding-right: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
.pl-0 {
|
.pl-0 {
|
||||||
padding-left: 0px;
|
padding-left: 0px;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -264,7 +264,7 @@
|
|||||||
<!-- Configuration content -->
|
<!-- Configuration content -->
|
||||||
<template x-if="$store.app.currentPage === 'configuration'">
|
<template x-if="$store.app.currentPage === 'configuration'">
|
||||||
<main class="mt-6 mb-2" x-data="configAppPage" x-bind:hidden="$store.app.currentPage !== 'configuration'">
|
<main class="mt-6 mb-2" x-data="configAppPage" x-bind:hidden="$store.app.currentPage !== 'configuration'">
|
||||||
<div class="border rounded-sm p-4 max-w-2xl mx-auto">
|
<div class="border rounded-sm p-5 max-w-md mx-auto mb-2">
|
||||||
<h2 class="text-2xl font-bold">Setup configuration</h2>
|
<h2 class="text-2xl font-bold">Setup configuration</h2>
|
||||||
<p class="text-gray-700 italic">
|
<p class="text-gray-700 italic">
|
||||||
Fill in the required configuration settings to connect to the Modbus network.
|
Fill in the required configuration settings to connect to the Modbus network.
|
||||||
@ -273,7 +273,7 @@
|
|||||||
<form @submit.prevent="configurateApp()" action="#">
|
<form @submit.prevent="configurateApp()" action="#">
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block" for="connection_type">Network type</label>
|
<label class="block" for="connection_type"><span class="text-red-500">*</span>Network type</label>
|
||||||
<select
|
<select
|
||||||
x-model="$store.app.config.mb_connection_type"
|
x-model="$store.app.config.mb_connection_type"
|
||||||
name="mb_connection_type"
|
name="mb_connection_type"
|
||||||
@ -287,7 +287,7 @@
|
|||||||
|
|
||||||
<div x-show="$store.app.config.mb_connection_type === 'TCP'" class="flex flex-col space-y-3">
|
<div x-show="$store.app.config.mb_connection_type === 'TCP'" class="flex flex-col space-y-3">
|
||||||
<div>
|
<div>
|
||||||
<label for="tcp_ip">IP</label>
|
<label for="tcp_ip"><span class="text-red-500">*</span>IP</label>
|
||||||
<input
|
<input
|
||||||
x-model="$store.app.config.mb_tcp_ip"
|
x-model="$store.app.config.mb_tcp_ip"
|
||||||
id="tcp_ip"
|
id="tcp_ip"
|
||||||
@ -299,7 +299,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="rtu_port">Port</label>
|
<label for="rtu_port"><span class="text-red-500">*</span>Port</label>
|
||||||
<input
|
<input
|
||||||
x-model.number="$store.app.config.mb_tcp_port"
|
x-model.number="$store.app.config.mb_tcp_port"
|
||||||
id="rtu_port"
|
id="rtu_port"
|
||||||
@ -313,7 +313,7 @@
|
|||||||
|
|
||||||
<div x-show="$store.app.config.mb_connection_type === 'RTU'" class="flex flex-col space-y-3">
|
<div x-show="$store.app.config.mb_connection_type === 'RTU'" class="flex flex-col space-y-3">
|
||||||
<div>
|
<div>
|
||||||
<label for="rtu_path">Path</label>
|
<label for="rtu_path"><span class="text-red-500">*</span>Path</label>
|
||||||
<input
|
<input
|
||||||
id="rtu_path"
|
id="rtu_path"
|
||||||
name="mb_rtu_path"
|
name="mb_rtu_path"
|
||||||
@ -325,7 +325,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="rtu_baud">Baud</label>
|
<label for="rtu_baud"><span class="text-red-500">*</span>Baud</label>
|
||||||
<select
|
<select
|
||||||
name="mb_rtu_baud"
|
name="mb_rtu_baud"
|
||||||
id="rtu_baud"
|
id="rtu_baud"
|
||||||
@ -342,7 +342,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="rtu_parity">Parity</label>
|
<label for="rtu_parity"><span class="text-red-500">*</span>Parity</label>
|
||||||
<select
|
<select
|
||||||
name="mb_rtu_parity"
|
name="mb_rtu_parity"
|
||||||
id="rtu_parity"
|
id="rtu_parity"
|
||||||
@ -356,7 +356,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="rtu_data_bits">Data bits</label>
|
<label for="rtu_data_bits"><span class="text-red-500">*</span>Data bits</label>
|
||||||
<select
|
<select
|
||||||
name="mb_rtu_data_bits"
|
name="mb_rtu_data_bits"
|
||||||
id="rtu_data_bits"
|
id="rtu_data_bits"
|
||||||
@ -371,7 +371,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="rtu_stop_bits">Stop bits</label>
|
<label for="rtu_stop_bits"><span class="text-red-500">*</span>Stop bits</label>
|
||||||
<select
|
<select
|
||||||
name="mb_rtu_stop_bits"
|
name="mb_rtu_stop_bits"
|
||||||
id="rtu_stop_bits"
|
id="rtu_stop_bits"
|
||||||
@ -386,7 +386,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<label for="rtu_path">Log Interval (ms)</label>
|
<label for="rtu_path"><span class="text-red-500">*</span>Log Interval (ms)</label>
|
||||||
<input
|
<input
|
||||||
id="log_interval_ms"
|
id="log_interval_ms"
|
||||||
name="log_interval_ms"
|
name="log_interval_ms"
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
|
import db from "#root/config/database.config.js";
|
||||||
|
|
||||||
export const appService = {
|
export const appService = {
|
||||||
/**
|
/**
|
||||||
* Get configuration of app
|
* Get configuration of app
|
||||||
* @param {import('sqlite').Database} db
|
|
||||||
* @returns {Promise<import('../index').AppConfig | undefined>}
|
* @returns {Promise<import('../index').AppConfig | undefined>}
|
||||||
*/
|
*/
|
||||||
async getConfig(db) {
|
async getConfig() {
|
||||||
const data = await db.get(`
|
const data = await db.get(`
|
||||||
SELECT "mb_connection_type",
|
SELECT "mb_connection_type",
|
||||||
"mb_tcp_ip",
|
"mb_tcp_ip",
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import modbusClient from "#root/config/modbus-client.config.js";
|
import modbusClient from "#root/config/modbus-client.config.js";
|
||||||
|
import db from "#root/config/database.config.js";
|
||||||
import * as utils from '#root/utils/index.js'
|
import * as utils from '#root/utils/index.js'
|
||||||
|
|
||||||
export const modbusService = {
|
export const modbusService = {
|
||||||
@ -35,6 +36,48 @@ export const modbusService = {
|
|||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import("..").AppConfig} appConfig
|
||||||
|
* @return {Promise<void>}
|
||||||
|
*/
|
||||||
|
async connect(appConfig) {
|
||||||
|
const {
|
||||||
|
mb_connection_type,
|
||||||
|
mb_tcp_ip,
|
||||||
|
mb_tcp_port,
|
||||||
|
mb_rtu_path,
|
||||||
|
mb_rtu_baud,
|
||||||
|
mb_rtu_data_bits,
|
||||||
|
mb_rtu_parity,
|
||||||
|
mb_rtu_stop_bits
|
||||||
|
} = appConfig
|
||||||
|
|
||||||
|
if (modbusClient.isOpen) {
|
||||||
|
modbusClient.close(undefined);
|
||||||
|
modbusClient.destroy(undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mb_connection_type) {
|
||||||
|
case 'TCP':
|
||||||
|
{
|
||||||
|
await modbusClient.connectTCP(mb_tcp_ip, { port: mb_tcp_port });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "RTU":
|
||||||
|
{
|
||||||
|
await modbusClient.connectRTU(mb_rtu_path, {
|
||||||
|
baudRate: mb_rtu_baud,
|
||||||
|
dataBits: mb_rtu_data_bits,
|
||||||
|
parity: mb_rtu_parity,
|
||||||
|
stopBits: mb_rtu_stop_bits,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new Error('Unsupported connection type!')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} addr
|
* @param {number} addr
|
||||||
* @param {"HR" | "IR" | "DI"} type
|
* @param {"HR" | "IR" | "DI"} type
|
||||||
@ -70,5 +113,58 @@ export const modbusService = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return data.buffer;
|
return data.buffer;
|
||||||
}
|
},
|
||||||
|
|
||||||
|
async getDevices() {
|
||||||
|
/** @type {import("..").ModbusDevice[]} */
|
||||||
|
const devices = await db.all(`
|
||||||
|
SELECT ms.id AS id, ms.name AS name, g_display_reg_addr, g_display_reg_format, g_display_reg_type, 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,
|
||||||
|
'reg_type', dv.reg_type
|
||||||
|
), ', '
|
||||||
|
) || ']' 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;
|
||||||
|
`);
|
||||||
|
// @ts-ignore
|
||||||
|
devices.forEach((s) => (s.display_values = JSON.parse(s.display_values)));
|
||||||
|
return devices
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import('express').Request} req
|
||||||
|
* @param {import('express').Response} res
|
||||||
|
* @param {import("..").ModbusDevice} device
|
||||||
|
*/
|
||||||
|
// createPollInterval(req, res, device, pollIntervalMs) {
|
||||||
|
// let intervalId;
|
||||||
|
|
||||||
|
// res.setHeader("Cache-Control", "no-cache");
|
||||||
|
// res.setHeader("Content-Type", "text/event-stream");
|
||||||
|
// res.setHeader("Connection", "keep-alive");
|
||||||
|
|
||||||
|
// return {
|
||||||
|
// /**
|
||||||
|
// * @param {number} pollIntervalMs
|
||||||
|
// */
|
||||||
|
// poll(pollIntervalMs) {
|
||||||
|
// intervalId = setInterval(async () => {
|
||||||
|
// device.display_values = await db.all(`SELECT * FROM "display_values" WHERE slave_id = ?`, [device.id])
|
||||||
|
// const data = await modbusService.readDataFromDevice(device);
|
||||||
|
// res.write("event: message\n");
|
||||||
|
// res.wriste(`data: ${JSON.stringify(data)}\n\n`);
|
||||||
|
// }, pollIntervalMs)
|
||||||
|
|
||||||
|
// req.on("close", () => clearInterval(intervalId));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user