mirror of
https://github.com/sergeyyarkov/modbus-logger.git
synced 2026-10-11 10:28:51 +03:00
progress
This commit is contained in:
parent
90271dc45f
commit
6b9b15970d
@ -51,7 +51,7 @@ export const modbusController = {
|
|||||||
if (!modbusClient.isOpen) return res.status(400).json({ message: "Already closed." });
|
if (!modbusClient.isOpen) return res.status(400).json({ message: "Already closed." });
|
||||||
modbusClient.close(undefined);
|
modbusClient.close(undefined);
|
||||||
modbusClient.destroy(undefined);
|
modbusClient.destroy(undefined);
|
||||||
return res.status(200).json({ message: 'Closed.' });
|
return res.status(200).json({ message: "Closed." });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@ -81,10 +81,10 @@ export const modbusController = {
|
|||||||
LEFT JOIN display_values AS dv ON dv.slave_id = ms.id
|
LEFT JOIN display_values AS dv ON dv.slave_id = ms.id
|
||||||
GROUP BY ms.id, ms.name;
|
GROUP BY ms.id, ms.name;
|
||||||
`);
|
`);
|
||||||
slaves.forEach(s => (s.display_values = JSON.parse(s.display_values)))
|
slaves.forEach((s) => (s.display_values = JSON.parse(s.display_values)));
|
||||||
return res.status(200).json(slaves);
|
return res.status(200).json(slaves);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error)
|
next(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -97,7 +97,8 @@ export const modbusController = {
|
|||||||
async createDevice(req, res, next) {
|
async createDevice(req, res, next) {
|
||||||
try {
|
try {
|
||||||
const { id, name, g_display_reg_addr, g_display_reg_format, g_y_label, is_logging } = req.body;
|
const { id, name, g_display_reg_addr, g_display_reg_format, g_y_label, is_logging } = req.body;
|
||||||
await db.run(`INSERT INTO "modbus_slaves" (
|
await db.run(
|
||||||
|
`INSERT INTO "modbus_slaves" (
|
||||||
"id",
|
"id",
|
||||||
"name",
|
"name",
|
||||||
"g_display_reg_addr",
|
"g_display_reg_addr",
|
||||||
@ -105,10 +106,11 @@ export const modbusController = {
|
|||||||
"g_y_label",
|
"g_y_label",
|
||||||
"is_logging")
|
"is_logging")
|
||||||
VALUES (?, ?, ?, ?, ?, ?)`,
|
VALUES (?, ?, ?, ?, ?, ?)`,
|
||||||
[id, name, g_display_reg_addr, g_display_reg_format, g_y_label, is_logging]);
|
[id, name, g_display_reg_addr, g_display_reg_format, g_y_label, is_logging],
|
||||||
return res.status(200).json({ message: 'Device created.' });
|
);
|
||||||
|
return res.status(200).json({ message: "Device created." });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error)
|
next(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -120,7 +122,6 @@ export const modbusController = {
|
|||||||
*/
|
*/
|
||||||
async updateDevice(req, res, next) {
|
async updateDevice(req, res, next) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@ -135,9 +136,9 @@ export const modbusController = {
|
|||||||
async removeDevice(req, res, next) {
|
async removeDevice(req, res, next) {
|
||||||
try {
|
try {
|
||||||
const device = await db.get(`SELECT id FROM "modbus_slaves" WHERE id = ?`, [req.body.id]);
|
const device = await db.get(`SELECT id FROM "modbus_slaves" WHERE id = ?`, [req.body.id]);
|
||||||
if (!device) return res.status(404).json({ message: 'Device not found.' });
|
if (!device) return res.status(404).json({ message: "Device not found." });
|
||||||
await db.run(`DELETE FROM "modbus_slaves" WHERE id = ?`, [req.body.id]);
|
await db.run(`DELETE FROM "modbus_slaves" WHERE id = ?`, [req.body.id]);
|
||||||
return res.status(200).json({ message: 'Device removed.' });
|
return res.status(200).json({ message: "Device removed." });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@ -160,7 +161,7 @@ export const modbusController = {
|
|||||||
async removeDisplayValue(req, res, next) {
|
async removeDisplayValue(req, res, next) {
|
||||||
try {
|
try {
|
||||||
await db.run(`DELETE FROM "display_values" WHERE id = ?`, req.body.id);
|
await db.run(`DELETE FROM "display_values" WHERE id = ?`, req.body.id);
|
||||||
return res.status(200).json({ message: 'Display value removed.' });
|
return res.status(200).json({ message: "Display value removed." });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@ -188,7 +189,7 @@ export const modbusController = {
|
|||||||
let intervalId = setInterval(() => {
|
let intervalId = setInterval(() => {
|
||||||
res.write(`event: message\ndata: ${JSON.stringify(modbusClient.isOpen)}\n\n`);
|
res.write(`event: message\ndata: ${JSON.stringify(modbusClient.isOpen)}\n\n`);
|
||||||
}, 500);
|
}, 500);
|
||||||
req.on('close', () => clearInterval(intervalId));
|
req.on("close", () => clearInterval(intervalId));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@ -202,21 +203,44 @@ export const modbusController = {
|
|||||||
*/
|
*/
|
||||||
async streamData(req, res, next) {
|
async streamData(req, res, next) {
|
||||||
try {
|
try {
|
||||||
if (!modbusClient.isOpen) return res.status(503).json({ message: "Modbus connection closed." });
|
if (!modbusClient.isOpen) return res.status(503).json({ error: { message: "Modbus connection closed." } });
|
||||||
|
|
||||||
|
if (!req.query.slave_id) return res.status(400).json({ error: { message: "'slave_id' parameter is required." } });
|
||||||
|
|
||||||
|
const device = await db.get(`SELECT * FROM "modbus_slaves" WHERE id = ?`, [req.query.slave_id]);
|
||||||
|
|
||||||
|
if (!device) return res.status(404).json({ error: { message: "Device not found." } });
|
||||||
|
|
||||||
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");
|
||||||
|
|
||||||
let interval = setInterval(async () => {
|
let interval = setInterval(async () => {
|
||||||
const { data } = await modbusClient.readHoldingRegisters(0, 1);
|
let value = 0;
|
||||||
res.write("event: messsage\n");
|
let len = 1; // 16 bits default
|
||||||
res.write(`data: ${JSON.stringify({ data })}`);
|
|
||||||
res.write("\n\n");
|
if (device.g_display_reg_format === 32) len = 2;
|
||||||
|
// ...64, 128, 256...
|
||||||
|
|
||||||
|
const result = await modbusClient.readHoldingRegisters(device.g_display_reg_addr, len);
|
||||||
|
|
||||||
|
switch (device.g_display_reg_format) {
|
||||||
|
case 32:
|
||||||
|
value = Buffer.from(result.buffer).readUInt32BE();
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
value = Buffer.from(result.buffer).readUint16BE();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.write("event: message\n");
|
||||||
|
res.write(`data: ${JSON.stringify({ graph: { value, format: device.g_display_reg_format } })}\n\n`);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
req.on("close", () => clearInterval(interval));
|
req.on("close", () => clearInterval(interval));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|||||||
@ -3,8 +3,10 @@ import "./alpine.js";
|
|||||||
import api from "./api.js";
|
import api from "./api.js";
|
||||||
import * as utils from "./utils/index.js";
|
import * as utils from "./utils/index.js";
|
||||||
|
|
||||||
const pages = ["loading", "monitoring", "configuration", "404"];
|
var pages = ["loading", "monitoring", "configuration", "404"];
|
||||||
let graphData = [[0, 0]];
|
var dataStreamSource;
|
||||||
|
var graphData = [[0, 0]];
|
||||||
|
var g;
|
||||||
|
|
||||||
document.addEventListener("alpine:init", async () => {
|
document.addEventListener("alpine:init", async () => {
|
||||||
Alpine.store("app", {
|
Alpine.store("app", {
|
||||||
@ -56,38 +58,38 @@ document.addEventListener("alpine:init", async () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Alpine.data('deviceModal', () => ({
|
Alpine.data("deviceModal", () => ({
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
error: null,
|
error: null,
|
||||||
data: {
|
data: {
|
||||||
id: null,
|
id: null,
|
||||||
name: '',
|
name: "",
|
||||||
g_display_reg_addr: null,
|
g_display_reg_addr: null,
|
||||||
g_display_reg_format: 16,
|
g_display_reg_format: 16,
|
||||||
g_y_label: '',
|
g_y_label: "",
|
||||||
is_logging: false
|
is_logging: false,
|
||||||
},
|
},
|
||||||
resetDataFields() {
|
resetDataFields() {
|
||||||
this.data.id = null;
|
this.data.id = null;
|
||||||
this.data.name = '';
|
this.data.name = "";
|
||||||
this.data.g_display_reg_addr = null;
|
this.data.g_display_reg_addr = null;
|
||||||
this.data.g_display_reg_format = 16;
|
this.data.g_display_reg_format = 16;
|
||||||
this.data.g_y_label = '';
|
this.data.g_y_label = "";
|
||||||
this.data.is_logging = false;
|
this.data.is_logging = false;
|
||||||
},
|
},
|
||||||
async create(cb) {
|
async create(cb) {
|
||||||
try {
|
try {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
await api.post('/modbus/create_device', utils.dellNullableKeys({...this.data}));
|
await api.post("/modbus/create_device", utils.dellNullableKeys({ ...this.data }));
|
||||||
graphData = [] // todo: update graph data
|
graphData = []; // todo: update graph data
|
||||||
this.$dispatch('add-device', {...this.data}); // add device to state
|
this.$dispatch("add-device", { ...this.data }); // add device to state
|
||||||
this.resetDataFields();
|
this.resetDataFields();
|
||||||
this.close();
|
this.close();
|
||||||
cb && cb();
|
cb && cb();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.error = error
|
this.error = error;
|
||||||
console.error(error);
|
console.error(error);
|
||||||
} finally {
|
} finally {
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
@ -99,7 +101,7 @@ document.addEventListener("alpine:init", async () => {
|
|||||||
close() {
|
close() {
|
||||||
this.isOpen = false;
|
this.isOpen = false;
|
||||||
},
|
},
|
||||||
}))
|
}));
|
||||||
|
|
||||||
Alpine.data("monitoringPage", () => ({
|
Alpine.data("monitoringPage", () => ({
|
||||||
selectedDevice: null,
|
selectedDevice: null,
|
||||||
@ -107,18 +109,11 @@ document.addEventListener("alpine:init", async () => {
|
|||||||
async init() {
|
async init() {
|
||||||
try {
|
try {
|
||||||
this.$store.app.currentPage = "loading";
|
this.$store.app.currentPage = "loading";
|
||||||
var g = new Dygraph(document.getElementById("div_g"), graphData, {
|
|
||||||
drawPoints: false,
|
|
||||||
showRoller: false,
|
|
||||||
ylabel: "Y Label",
|
|
||||||
valueRange: [0.0, 1.8],
|
|
||||||
// labels: ["Time", "Random"],
|
|
||||||
});
|
|
||||||
this.devices = await api.get("/modbus/devices");
|
this.devices = await api.get("/modbus/devices");
|
||||||
window.intervalId = setInterval(() => {
|
// window.intervalId = setInterval(() => {
|
||||||
graphData.push([new Date(), Math.random()]);
|
// graphData.push([new Date(), Math.random()]);
|
||||||
g.updateOptions({ file: graphData });
|
// g.updateOptions({ file: graphData });
|
||||||
}, 500);
|
// }, 500);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$store.app.error = error;
|
this.$store.app.error = error;
|
||||||
} finally {
|
} finally {
|
||||||
@ -126,6 +121,21 @@ document.addEventListener("alpine:init", async () => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
selectDevice(device) {
|
selectDevice(device) {
|
||||||
|
dataStreamSource?.close();
|
||||||
|
dataStreamSource = new EventSource(`/api/modbus/data_stream?slave_id=${device.id}`);
|
||||||
|
g = new Dygraph(document.getElementById("div_g"), graphData, {
|
||||||
|
drawPoints: false,
|
||||||
|
showRoller: false,
|
||||||
|
ylabel: device.g_y_label,
|
||||||
|
// valueRange: [0, 1000],
|
||||||
|
// labels: ["Time", "Random"],
|
||||||
|
});
|
||||||
|
dataStreamSource.onmessage = (e) => {
|
||||||
|
const data = JSON.parse(e.data);
|
||||||
|
console.log(data);
|
||||||
|
graphData.push([new Date(), data.graph.value]);
|
||||||
|
g.updateOptions({ file: graphData });
|
||||||
|
};
|
||||||
if (device.id === this.selectedDevice?.id) return;
|
if (device.id === this.selectedDevice?.id) return;
|
||||||
graphData = []; // todo: reset graph
|
graphData = []; // todo: reset graph
|
||||||
this.selectedDevice = device;
|
this.selectedDevice = device;
|
||||||
@ -141,12 +151,12 @@ document.addEventListener("alpine:init", async () => {
|
|||||||
},
|
},
|
||||||
async removeDisplayValue(id) {
|
async removeDisplayValue(id) {
|
||||||
try {
|
try {
|
||||||
await api.post('/modbus/remove_display-value', { id });
|
await api.post("/modbus/remove_display-value", { id });
|
||||||
this.selectedDevice.display_values = this.selectedDevice.display_values.filter(v => v.id != id);
|
this.selectedDevice.display_values = this.selectedDevice.display_values.filter((v) => v.id != id);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error while removing display value", error);
|
console.error("Error while removing display value", error);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Alpine.data("configAppPage", () => ({
|
Alpine.data("configAppPage", () => ({
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user