Files
lst/lstV2/server/services/ocp/utils/plcController.ts

156 lines
5.0 KiB
TypeScript

import { ControllerManager } from "st-ethernet-ip";
import { getMac } from "./getMachineId.js";
import { format } from "date-fns-tz";
import { tryCatch } from "../../../globalUtils/tryCatch.js";
import { getCurrentLabel } from "../../sqlServer/querys/ocp/getLabel.js";
import { query } from "../../sqlServer/prodSqlServer.js";
import { createLog } from "../../logger/logger.js";
export const createPlcMonitor = (config: any) => {
let cm: any;
let controllers: any = {};
let stats: any = {};
let isRunning = false;
const nowISO = () => {
return new Date().toISOString();
};
const start = () => {
if (isRunning) return;
cm = new ControllerManager();
config.controllers.forEach((cfg: any) => {
const plc: any = cm.addController(
cfg.ip,
cfg.slot,
cfg.rpi,
true,
cfg.retrySP || 3000
);
plc.connect();
controllers[cfg.id] = plc;
// initialize stats
stats[cfg.id] = {
id: cfg.id,
ip: cfg.ip,
slot: cfg.slot,
scanRate: cfg.rpi,
connected: false,
lastConnectedAt: null,
lastDisconnectedAt: null,
reconnectCount: 0,
};
// Add tags
cfg.tags.forEach((tag: any) => plc.addTag(tag));
// Events
plc.on("Connected", () => {
const s = stats[cfg.id];
s.connected = true;
s.lastConnectedAt = nowISO();
if (s.lastDisconnectedAt) {
s.reconnectCount++;
}
console.log(`[${cfg.id}] Connected @ ${cfg.ip}:${cfg.slot}`);
});
plc.on("Disconnected", () => {
const s = stats[cfg.id];
s.connected = false;
s.lastDisconnectedAt = nowISO();
console.log(`[${cfg.id}] Disconnected`);
});
plc.on("error", (err: any) => {
console.error(`[${cfg.id}] Error:`, err.message);
});
plc.on("TagChanged", async (tag: any, prevVal: any) => {
if (tag.value !== 0) {
const time = nowISO();
if (tag.value === 0) return;
setTimeout(async () => {
if (tag.value === 0) return;
const macId = await getMac(tag.value);
console.log(macId);
const { data, error } = (await tryCatch(
query(
getCurrentLabel
.replace(
"[macId]",
macId[0]?.HumanReadableId
)
.replace(
"[time]",
format(time, "yyyy-MM-dd HH:mm")
),
"Current label data"
)
)) as any;
createLog(
"info",
"zechettii",
"zechettii",
`${format(time, "yyyy-MM-dd HH:mm")} [${cfg.id}] ${
tag.name
}: ${prevVal} -> ${
tag.value
}, the running number is ${
error ? null : data.data[0]?.LfdNr
}}`
);
}, 1000);
}
});
});
isRunning = true;
};
const stop = () => {
if (!isRunning) return;
Object.values(controllers).forEach((plc: any) => {
try {
plc.disconnect();
} catch {}
});
controllers = {};
cm = null;
isRunning = false;
console.log("Monitor stopped");
};
const restart = () => {
console.log("Restarting the plc(s)");
stop();
new Promise((resolve) => setTimeout(resolve, 1500));
start();
};
const status = () => {
const result: any = {};
for (const [id, s] of Object.entries(stats)) {
let s: any;
let uptimeMs = null,
downtimeMs = null;
if (s.connected && s.lastConnectedAt) {
uptimeMs = Date.now() - new Date(s.lastConnectedAt).getTime();
} else if (!s.connected && s.lastDisconnectedAt) {
downtimeMs =
Date.now() - new Date(s.lastDisconnectedAt).getTime();
}
result[id] = { ...s, uptimeMs, downtimeMs };
}
return result;
};
return { start, stop, restart, status };
};