mirror of
https://github.com/sergeyyarkov/modbus-logger.git
synced 2026-10-11 10:28:51 +03:00
173 lines
5.1 KiB
JavaScript
173 lines
5.1 KiB
JavaScript
import express from "express";
|
|
import db from "#root/config/database.config.js";
|
|
import modbusClient from "#root/config/modbus-client.config.js";
|
|
|
|
/**
|
|
* Validators
|
|
*/
|
|
import { appConfigSchema } from "#root/validators/index.js";
|
|
|
|
/**
|
|
* Services
|
|
*/
|
|
import { appService } from "#root/services/index.js";
|
|
|
|
/**
|
|
* Middlewares
|
|
*/
|
|
import { validateBodyMiddleware } from "#root/middlewares/index.js";
|
|
|
|
const apiRouter = express.Router();
|
|
|
|
/**
|
|
* Get application config
|
|
*/
|
|
apiRouter.get("/app/config", async (req, res, next) => {
|
|
try {
|
|
const data = await appService.getConfig(db);
|
|
if (!data) return res.status(200).json({ config: null });
|
|
return res.status(200).json({ config: data });
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Update app configuration
|
|
*/
|
|
apiRouter.patch("/app/config", validateBodyMiddleware(appConfigSchema), async (req, res, next) => {
|
|
try {
|
|
const config = await appService.getConfig(db);
|
|
const payload = req.body;
|
|
|
|
if (!config) await db.run(`INSERT INTO "app_config" (id) VALUES (?)`, [0]);
|
|
|
|
/* Update TCP configuration */
|
|
if (payload.mb_connection_type === "TCP") {
|
|
const { mb_tcp_ip, mb_tcp_port } = payload;
|
|
await db.run(
|
|
`
|
|
UPDATE "app_config" SET id = 0, mb_connection_type = "TCP", mb_tcp_ip = ?, mb_tcp_port = ?, log_interval_ms = ?
|
|
`,
|
|
[mb_tcp_ip, mb_tcp_port, payload.log_interval_ms],
|
|
);
|
|
|
|
return res.status(200).json({ message: "Config Updated." });
|
|
}
|
|
|
|
/* Update RTU configuration */
|
|
if (payload.mb_connection_type === "RTU") {
|
|
const { mb_rtu_path, mb_rtu_baud, mb_rtu_parity, mb_rtu_data_bits, mb_rtu_stop_bits } = payload;
|
|
await db.run(
|
|
`
|
|
UPDATE "app_config" SET id = 0,
|
|
mb_connection_type = "RTU",
|
|
mb_rtu_path = ?,
|
|
mb_rtu_baud = ?,
|
|
mb_rtu_parity = ?,
|
|
mb_rtu_data_bits = ?,
|
|
mb_rtu_stop_bits = ?,
|
|
log_interval_ms = ?
|
|
`,
|
|
[mb_rtu_path, mb_rtu_baud, mb_rtu_parity, mb_rtu_data_bits, mb_rtu_stop_bits, payload.log_interval_ms],
|
|
);
|
|
return res.status(200).json({ message: "Config updated." });
|
|
}
|
|
|
|
return res.status(400).json({ message: "Undefined Modbus connection type." });
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Check whether the application is configured or not
|
|
*/
|
|
apiRouter.get("/app/is_configured", async (req, res, next) => {
|
|
try {
|
|
const config = await appService.getConfig(db);
|
|
let is_configured = false;
|
|
|
|
if (!config) return res.status(200).json({ is_configured });
|
|
|
|
const isValuesExists = (colPrefix) => {
|
|
const keys = Object.keys(config).filter((k) => k.includes(colPrefix));
|
|
for (const k of keys) if (!config[k]) return false;
|
|
return true;
|
|
};
|
|
|
|
if (config.mb_connection_type === "TCP") is_configured = isValuesExists("mb_tcp");
|
|
if (config.mb_connection_type === "RTU") is_configured = isValuesExists("mb_rtu");
|
|
|
|
return res.status(200).json({ is_configured });
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Connect to modbus network using configuration from database
|
|
*/
|
|
apiRouter.post("/modbus/connect", async (req, res, next) => {
|
|
try {
|
|
const config = await appService.getConfig(db);
|
|
if (!config) return res.status(400).json({ message: "Application is not configured" });
|
|
|
|
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." });
|
|
}
|
|
|
|
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) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
apiRouter.post("/modbus/close", (req, res, next) => {
|
|
try {
|
|
if (!modbusClient.isOpen) return res.status(400).json({ message: "Already closed." });
|
|
modbusClient.close(undefined);
|
|
modbusClient.destroy(undefined);
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
apiRouter.get("/modbus/data_stream", async (req, res, next) => {
|
|
try {
|
|
if (!modbusClient.isOpen) return res.status(503).json({ message: "Modbus connection closed." });
|
|
|
|
res.setHeader("Cache-Control", "no-cache");
|
|
res.setHeader("Content-Type", "text/event-stream");
|
|
res.setHeader("Connection", "keep-alive");
|
|
|
|
let interval = setInterval(async () => {
|
|
const { data } = await modbusClient.readHoldingRegisters(0, 1);
|
|
res.write("event: messsage\n");
|
|
res.write(`data: ${JSON.stringify({ data })}`);
|
|
res.write("\n\n");
|
|
}, 1000);
|
|
req.on("close", () => clearInterval(interval));
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
|
|
export { apiRouter };
|