diff --git a/frontend/src/components/production/ocp/LabelLog.tsx b/frontend/src/components/production/ocp/LabelLog.tsx index f8efbc1..d38e3e2 100644 --- a/frontend/src/components/production/ocp/LabelLog.tsx +++ b/frontend/src/components/production/ocp/LabelLog.tsx @@ -5,6 +5,7 @@ import { Table, TableBody, TableCell, + TableFooter, TableHead, TableHeader, TableRow, @@ -137,6 +138,16 @@ export default function LabelLog() { ))} )} + + + {labelData.length === 0 && ( +
+

+ No labels have been printed in the last 2 hours +

+
+ )} +
); diff --git a/frontend/src/components/production/ocp/Lots.tsx b/frontend/src/components/production/ocp/Lots.tsx index 72b9b6d..010e3b3 100644 --- a/frontend/src/components/production/ocp/Lots.tsx +++ b/frontend/src/components/production/ocp/Lots.tsx @@ -71,6 +71,7 @@ export default function Lots() { const server = settings.filter((n) => n.name === "server")[0]?.value || ""; const roles = ["admin", "manager", "operator"]; + const lotdata = data ? data : []; if (user && roles.includes(user.role)) { //width = 1280; @@ -144,7 +145,6 @@ export default function Lots() { ); } - return ( @@ -197,7 +197,7 @@ export default function Lots() { ) : ( - {data?.map((lot: LotType) => ( + {lotdata.map((lot: LotType) => ( {lot.MachineLocation} diff --git a/frontend/src/components/production/ocp/OcpPage.tsx b/frontend/src/components/production/ocp/OcpPage.tsx index 6f85d4a..5e2aee7 100644 --- a/frontend/src/components/production/ocp/OcpPage.tsx +++ b/frontend/src/components/production/ocp/OcpPage.tsx @@ -10,6 +10,7 @@ export default function OCPPage() { const { settings } = useSettingStore(); const server = settings.filter((n) => n.plantToken === "usday1"); + console.log(server); return (
@@ -40,7 +41,7 @@ export default function OCPPage() {
- {server && ( + {server.length >= 1 && (
diff --git a/frontend/src/components/production/ocp/PrinterStatus.tsx b/frontend/src/components/production/ocp/PrinterStatus.tsx index d724f41..f55bdaf 100644 --- a/frontend/src/components/production/ocp/PrinterStatus.tsx +++ b/frontend/src/components/production/ocp/PrinterStatus.tsx @@ -9,12 +9,10 @@ import { TableHeader, TableRow, } from "@/components/ui/table"; +import { getPrinters } from "@/utils/querys/production/printers"; +import { useQuery } from "@tanstack/react-query"; let printerCols = [ - { - key: "status", - label: "Status", - }, { key: "printer", label: "Printer", @@ -25,10 +23,12 @@ let printerCols = [ }, ]; export default function PrinterStatus() { - return ( - - -

Printer Status

+ const { data, isError, isLoading } = useQuery(getPrinters()); + + if (isError) { + return ( + +

Printer Staus error

@@ -50,14 +50,65 @@ export default function PrinterStatus() { - - - ))}
+ ); + } + + /** + * only show the assigned printers + */ + + const assigned = data?.filter((a: any) => a.assigned) || []; + return ( + + +

+ {isLoading ? ( + Printers status loading... + ) : ( + Printer Status + )} +

+ + + + + {printerCols.map((l) => ( + {l.label} + ))} + + {" "} + {isLoading ? ( + + {Array(5) + .fill(0) + .map((_, i) => ( + + + + + + + + + ))} + + ) : ( + + {assigned?.map((p: any) => ( + + {p.name} + {p.statusText} + + ))} + + )} +
+
); } diff --git a/frontend/src/utils/querys/production/printers.tsx b/frontend/src/utils/querys/production/printers.tsx new file mode 100644 index 0000000..b04e036 --- /dev/null +++ b/frontend/src/utils/querys/production/printers.tsx @@ -0,0 +1,20 @@ +import { queryOptions } from "@tanstack/react-query"; +import axios from "axios"; + +export function getPrinters() { + return queryOptions({ + queryKey: ["printers"], + queryFn: () => fetchSettings(), + + staleTime: 1000, + refetchInterval: 2 * 2000, + refetchOnWindowFocus: true, + }); +} + +const fetchSettings = async () => { + const { data } = await axios.get(`/api/ocp/getprinters`); + // if we are not localhost ignore the devDir setting. + //const url: string = window.location.host.split(":")[0]; + return data.data ?? []; +}; diff --git a/server/services/ocp/controller/printers/printerCycle.ts b/server/services/ocp/controller/printers/printerCycle.ts index 4559f2d..2a75cdc 100644 --- a/server/services/ocp/controller/printers/printerCycle.ts +++ b/server/services/ocp/controller/printers/printerCycle.ts @@ -4,13 +4,23 @@ import { settings } from "../../../../../database/schema/settings.js"; import { tryCatch } from "../../../../globalUtils/tryCatch.js"; import { createLog } from "../../../logger/logger.js"; import { getPrinters } from "./getPrinters.js"; -import { printerStatus } from "./printerStatus.js"; +import { autoLabelingStats, printerStatus } from "./printerStatus.js"; + +let isPrinterCycling = false; +let actualPrinterCycle: any; export const printerCycle = async () => { /** * We will cycle through the printers to check there states. */ + if (isPrinterCycling) + return { + success: false, + message: "Printers are already being cycled.", + }; + + createLog("info", "ocp", "ocp", "Printer cycle has started."); // get the printers const { data: s, error: se } = await tryCatch( db.select().from(settings).where(eq(settings.name, "ocpCycleDelay")) @@ -29,9 +39,9 @@ export const printerCycle = async () => { } const ocpDelay: any = s; - + isPrinterCycling = true; // start the actual printer cycle - const actualPrinterCycle = setInterval(async () => { + actualPrinterCycle = setInterval(async () => { const { data, error } = await tryCatch(getPrinters()); if (error) { @@ -51,10 +61,8 @@ export const printerCycle = async () => { // only keep the assigned ones printers = printers.filter((p: any) => p.assigned === true); - // for autolabelers like dayton and MCD we want to ignore them from the loop as well. - printers = printers.filter( - (p: any) => p.name != "Autolabeler" && !p.remark.includes("ignore") - ); + // for printers we want to ignore there must be a remark stateing to ignore. + printers = printers.filter((p: any) => !p.remark.includes("ignore")); printers.forEach(async (p: any) => { /** @@ -75,7 +83,31 @@ export const printerCycle = async () => { return; } + if (p.name === "Autolabeler") { + await autoLabelingStats(p); + return; + } + + // for all other printers await printerStatus(p); }); }, parseInt(ocpDelay[0]?.value) * 1000); + + return { success: true, message: "Printer cycle has been started." }; +}; + +export const stopPrinterCycle = async () => { + /** + * We will stop the print cylce this is more an emergancy thing. + */ + if (actualPrinterCycle && !actualPrinterCycle._destroyed) { + createLog("info", "ocp", "ocp", "Printer cycle is being stopped."); + clearInterval(actualPrinterCycle); + isPrinterCycling = false; + return { success: true, message: "Printer cycle has been stopped." }; + } else { + createLog("info", "ocp", "ocp", "Printer cycle is already stopped."); + isPrinterCycling = false; + return { success: true, message: "Printer cycle is already Stopped." }; + } }; diff --git a/server/services/ocp/controller/printers/printerStatUpdate.ts b/server/services/ocp/controller/printers/printerStatUpdate.ts index 117b013..2389b2b 100644 --- a/server/services/ocp/controller/printers/printerStatUpdate.ts +++ b/server/services/ocp/controller/printers/printerStatUpdate.ts @@ -8,6 +8,7 @@ export const printStatus = [ { code: 2, text: "Pending labels" }, { code: 3, text: "Printing to fast" }, { code: 4, text: "Creating label" }, + { code: 5, text: "Waiting" }, { code: 6, text: "Printer Paused" }, { code: 7, text: "Printer error" }, { diff --git a/server/services/ocp/controller/printers/printerStatus.ts b/server/services/ocp/controller/printers/printerStatus.ts index 041ced9..b92bbb4 100644 --- a/server/services/ocp/controller/printers/printerStatus.ts +++ b/server/services/ocp/controller/printers/printerStatus.ts @@ -68,9 +68,9 @@ export const printerStatus = async (p: any) => { "debug", "ocp", "ocp", - `${p.name}: timeBetween: ${timeBetween}, delay ${ - p.printDelay || 90 - }, ${currentTime}... ${lastTime}` + `${p.name}: timeBetween: ${timeBetween}, delay ${parseInt( + p.printDelay + )}, ${currentTime}... ${lastTime}` ); if (tmp[2] === "0" && tmp[4] !== "000") { @@ -80,7 +80,7 @@ export const printerStatus = async (p: any) => { "ocp", "ocp", `Unpaused and printing labels, time remaing ${differenceInSeconds( - p.printDelay || 90, + parseInt(p.printDelay), timeBetween )}` ); @@ -96,7 +96,7 @@ export const printerStatus = async (p: any) => { `${ p.name } paused to soon, unpausing, remaining time: ${differenceInSeconds( - p.printDelay || 90, + parseInt(p.printDelay), timeBetween )}` ); @@ -105,20 +105,20 @@ export const printerStatus = async (p: any) => { printerUpdate(p, 2); unPausePrinter(p); - } else if ((tmp[2] === "0" && timeBetween < p.printDelay) || 90) { + } else if (tmp[2] === "0" && timeBetween < parseInt(p.printDelay)) { // was unpaused to soon so repause it createLog( "debug", "ocp", "ocp", `${p.name} Unpaused before the time allowed, time left ${ - differenceInSeconds(p.printDelay || 90, timeBetween) //seconds + differenceInSeconds(parseInt(p.printDelay), timeBetween) //seconds }` ); printerUpdate(p, 3); pausePrinter(p); - } else if ((tmp[2] === "0" && timeBetween > p.printDelay) || 90) { + } else if (tmp[2] === "0" && timeBetween > parseInt(p.printDelay)) { // its been long enough we can print a label createLog( "debug", @@ -188,3 +188,68 @@ export const printerStatus = async (p: any) => { }); }); }; + +export const autoLabelingStats = async (p: any) => { + /** + * Checks autolabeling printers just to see what they are doing. + */ + createLog("debug", "ocp", "ocp", `Printer cycling`); + + const printer = new net.Socket(); + + return new Promise((resolve) => { + // connect to the printer, and check its status + printer.connect(p.port, p.ipAddress, async () => { + // write the message to the printer below gives us a feedback of the printer + printer.write("~HS"); + }); + + // read the data from the printer + printer.on("data", async (data) => { + const res = data.toString(); + + // turn the data into an array to make it more easy to deal with + const tmp = res.split(","); + + if (tmp[4] !== "000") { + // unpaused and printing labels - reset timer + createLog("debug", "ocp", "ocp", `Printing Labels`); + + // update last time printed in the array + printerUpdate(p, 1); + } + + if (tmp[4] === "000") { + // unpaused and printing labels - reset timer + createLog("debug", "ocp", "ocp", `Printing Labels`); + + // update last time printed in the array + printerUpdate(p, 5); + } + }); + + printer.on("error", async (error) => { + // just going to say theres an error with the printer + + if (!errorCheck) { + createLog( + "error", + "ocp", + "ocp", + `${p.name} encountered an error: ${error}` + ); + } + + await printerUpdate(p, 7); + errorCheck = true; + + // send log data + // fake line + printer.end(); + resolve({ + success: false, + message: "There was an error with the printer.", + }); + }); + }); +}; diff --git a/server/services/ocp/controller/printers/updatePrinters.ts b/server/services/ocp/controller/printers/updatePrinters.ts index 4869275..48f4811 100644 --- a/server/services/ocp/controller/printers/updatePrinters.ts +++ b/server/services/ocp/controller/printers/updatePrinters.ts @@ -57,6 +57,7 @@ export const updatePrinters = async () => { port: prodPrinterInfo[i].port, remark: prodPrinterInfo[i].remark, upd_date: sql`NOW()`, + printDelay: "90", // need to remove in a couple weeks }, }) ); diff --git a/server/services/ocp/ocpService.ts b/server/services/ocp/ocpService.ts index ea781fd..791d91a 100644 --- a/server/services/ocp/ocpService.ts +++ b/server/services/ocp/ocpService.ts @@ -15,7 +15,8 @@ import dycoClose from "./routes/specialProcesses/dyco/closeConnection.js"; import manualprint from "./routes/labeling/manualPrint.js"; import { assignedPrinters } from "./utils/checkAssignments.js"; import { printerCycle } from "./controller/printers/printerCycle.js"; -import { tryCatch } from "../../globalUtils/tryCatch.js"; +import stopPrinterCycle from "./routes/printers/stopCycle.js"; +import startPrinterCycle from "./routes/printers/startCycle.js"; const app = new OpenAPIHono(); @@ -24,6 +25,8 @@ const routes = [ //printer getPrinters, updateprinters, + startPrinterCycle, + stopPrinterCycle, // lots getLots, // labeling @@ -55,21 +58,21 @@ const ocpActive = setting.filter((n) => n.name === "ocpActive"); // do the intnal connection to the dyco setTimeout(() => { - if (dycoActive[0].value === "1") { + if (dycoActive[0]?.value === "1") { dycoConnect(); } }, 3 * 1000); // check for printers being assigned setInterval(() => { - if (ocpActive[0].value === "1") { + if (ocpActive[0]?.value === "1") { assignedPrinters(); } }, 60 * 1000); // start the printer process after everything else is up ad running setTimeout(async () => { - if (ocpActive[0].value === "1") { + if (ocpActive[0]?.value === "1") { await updatePrinters(); await assignedPrinters(); printerCycle(); diff --git a/server/services/ocp/routes/printers/startCycle.ts b/server/services/ocp/routes/printers/startCycle.ts new file mode 100644 index 0000000..9967c6e --- /dev/null +++ b/server/services/ocp/routes/printers/startCycle.ts @@ -0,0 +1,41 @@ +// an external way to creating logs +import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi"; +import { authMiddleware } from "../../../auth/middleware/authMiddleware.js"; +import { responses } from "../../../../globalUtils/routeDefs/responses.js"; +import { tryCatch } from "../../../../globalUtils/tryCatch.js"; +import { printerCycle } from "../../controller/printers/printerCycle.js"; + +const app = new OpenAPIHono({ strict: false }); + +app.openapi( + createRoute({ + tags: ["ocp:printers"], + summary: "starts the printers cycling.", + method: "get", + path: "/startsprintercycle", + middleware: authMiddleware, + //description: "This might be a temp soltuin during the transtion between versions", + // request: { + // body: {content: {"application/json": {schema: CreateLog}}}, + // }, + responses: responses(), + }), + async (c) => { + const { data, error } = await tryCatch(printerCycle()); + const dataError: any = error; + if (error) { + return c.json({ + success: false, + message: "Error in stopping the printer cycle", + data: dataError?.data, + }); + } + const getData: any = data; + return c.json({ + success: getData?.success, + message: getData?.message, + data: getData.data ?? [], + }); + } +); +export default app; diff --git a/server/services/ocp/routes/printers/stopCycle.ts b/server/services/ocp/routes/printers/stopCycle.ts new file mode 100644 index 0000000..f651d0e --- /dev/null +++ b/server/services/ocp/routes/printers/stopCycle.ts @@ -0,0 +1,41 @@ +// an external way to creating logs +import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi"; +import { authMiddleware } from "../../../auth/middleware/authMiddleware.js"; +import { responses } from "../../../../globalUtils/routeDefs/responses.js"; +import { tryCatch } from "../../../../globalUtils/tryCatch.js"; +import { stopPrinterCycle } from "../../controller/printers/printerCycle.js"; + +const app = new OpenAPIHono({ strict: false }); + +app.openapi( + createRoute({ + tags: ["ocp:printers"], + summary: "Stops the printers cycling.", + method: "get", + path: "/stopprintercycle", + middleware: authMiddleware, + //description: "This might be a temp soltuin during the transtion between versions", + // request: { + // body: {content: {"application/json": {schema: CreateLog}}}, + // }, + responses: responses(), + }), + async (c) => { + const { data, error } = await tryCatch(stopPrinterCycle()); + const dataError: any = error; + if (error) { + return c.json({ + success: false, + message: "Error in stopping the printer cycle", + data: dataError?.data, + }); + } + const getData: any = data; + return c.json({ + success: getData?.success, + message: getData?.message, + data: getData.data ?? [], + }); + } +); +export default app; diff --git a/server/services/ocp/utils/checkAssignments.ts b/server/services/ocp/utils/checkAssignments.ts index 27b0b10..cc51f3c 100644 --- a/server/services/ocp/utils/checkAssignments.ts +++ b/server/services/ocp/utils/checkAssignments.ts @@ -8,7 +8,7 @@ import { getPrinters } from "../controller/printers/getPrinters.js"; import { createLog } from "../../logger/logger.js"; export const assignedPrinters = async () => { - createLog("info", "ocp", "ocp", "Lot assignment check"); + createLog("debug", "ocp", "ocp", "Lot assignment check"); const { data: l, error: lotError } = await tryCatch(getLots()); if (lotError) { diff --git a/server/services/server/utils/settingsCheck.ts b/server/services/server/utils/settingsCheck.ts index 52c65ee..4a06ca4 100644 --- a/server/services/server/utils/settingsCheck.ts +++ b/server/services/server/utils/settingsCheck.ts @@ -194,7 +194,7 @@ const newSettings = [ // ocp { - name: "acpActive", + name: "ocpActive", value: `1`, description: "Are we pritning on demand?", serviceBelowsTo: "ocp",