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 }; };