Compare commits

..

32 Commits

Author SHA1 Message Date
04eb2e3e14 refactor(tcpserver): just the tcp server doing something 2025-03-25 07:58:37 -05:00
90fb0d364d Merge branch 'main' of https://git.tuffraid.net/cowch/lstV2 2025-03-25 07:57:55 -05:00
e6e1cecce3 refactor(ocme): corrections to endpoints to work with ocnme as intneeded 2025-03-25 07:54:58 -05:00
73aa95a693 refactor(ocme): cleaup on pickedup 2025-03-25 07:54:22 -05:00
b9f19095cb refactor(ocme): clean up on the getInfo endpoint 2025-03-25 07:54:00 -05:00
dcb56d4274 fix(ocme): corrections to posting data for the response was added 2025-03-25 07:53:30 -05:00
bc1821132e feat(ocme): manual camera trigger for the wrapper added 2025-03-25 07:52:40 -05:00
2551d6c907 refactor(updateserver): removed ocme from starting back up as it was migrated 2025-03-25 07:41:10 -05:00
adf0880659 refactor(server): changed to log only when in dev, and removed the redirect of the url 2025-03-25 07:40:15 -05:00
5149de3199 ci(lst): changes made to the settings file to work across all pvs 2025-03-25 07:39:32 -05:00
c71b514d9a refactor(frontend): prettier change to formatting 2025-03-25 07:27:45 -05:00
9254e52808 chore(release): bump build number to 76 2025-03-25 06:17:31 -05:00
b8c028a6c1 chore(release): bump build number to 75 2025-03-24 20:20:55 -05:00
529e922485 chore(release): bump build number to 74 2025-03-24 20:13:07 -05:00
5201012235 chore(release): bump build number to 73 2025-03-24 20:08:59 -05:00
abe53b8f5d chore(release): bump build number to 72 2025-03-24 20:06:15 -05:00
836f3e294b chore(release): bump build number to 71 2025-03-24 19:56:03 -05:00
96abef762b chore(release): bump build number to 70 2025-03-24 19:40:39 -05:00
2c227f9428 chore(release): bump build number to 69 2025-03-24 18:33:12 -05:00
46647687dc chore(release): bump build number to 68 2025-03-24 18:23:24 -05:00
cb01ef1af1 chore(release): bump build number to 67 2025-03-24 17:16:23 -05:00
b3b5fcec65 chore(release): bump build number to 66 2025-03-24 17:14:25 -05:00
3a4dc47a36 chore(release): bump build number to 65 2025-03-24 17:06:23 -05:00
63177b523e chore(release): bump build number to 64 2025-03-24 17:00:20 -05:00
e1cad027d2 chore(release): bump build number to 63 2025-03-24 16:42:53 -05:00
c1cc355f4f chore(release): bump build number to 62 2025-03-24 16:40:50 -05:00
5ed67f3fc0 chore(release): bump build number to 61 2025-03-24 16:28:32 -05:00
57e82d2360 chore(release): bump build number to 60 2025-03-24 16:26:04 -05:00
9395ec6cd4 chore(release): bump build number to 59 2025-03-24 15:50:29 -05:00
0475bb30f9 chore(release): bump build number to 58 2025-03-24 15:49:37 -05:00
6843368c36 chore(release): bump build number to 57 2025-03-24 15:47:16 -05:00
335ea2deca chore(release): bump build number to 56 2025-03-24 15:39:33 -05:00
15 changed files with 914 additions and 640 deletions

50
.vscode/settings.json vendored
View File

@@ -1,26 +1,28 @@
{ {
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "esbenp.prettier-vscode",
"workbench.colorTheme": "Default Dark+",
"editor.formatOnSave": true, "prettier.tabWidth": 4,
"[javascript]": { "terminal.integrated.env.windows": {},
"editor.formatOnSave": true "editor.formatOnSave": true,
}, "[javascript]": {
"[javascriptreact]": { "editor.formatOnSave": true
"editor.formatOnSave": true },
}, "[javascriptreact]": {
"[typescript]": { "editor.formatOnSave": true
"editor.formatOnSave": true },
}, "[typescript]": {
"[typescriptreact]": { "editor.formatOnSave": true
"editor.formatOnSave": true },
}, "[typescriptreact]": {
"[json]": { "editor.formatOnSave": true
"editor.formatOnSave": true },
}, "[json]": {
"[graphql]": { "editor.formatOnSave": true
"editor.formatOnSave": true },
}, "[graphql]": {
"[handlebars]": { "editor.formatOnSave": true
"editor.formatOnSave": true },
} "[handlebars]": {
"editor.formatOnSave": true
}
} }

View File

@@ -3,210 +3,239 @@ import { LstCard } from "../extendedUI/LstCard";
import { Button } from "../ui/button"; import { Button } from "../ui/button";
import { Input } from "../ui/input"; import { Input } from "../ui/input";
import { import {
Table, Table,
TableBody, TableBody,
TableCell, TableCell,
TableHead, TableHead,
TableHeader, TableHeader,
TableRow, TableRow,
} from "../ui/table"; } from "../ui/table";
import { Skeleton } from "../ui/skeleton"; import { Skeleton } from "../ui/skeleton";
//import CycleCountLog from "./CycleCountLog"; //import CycleCountLog from "./CycleCountLog";
import { import {
Select, Select,
SelectContent, SelectContent,
SelectItem, SelectItem,
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "../ui/select"; } from "../ui/select";
import { Controller, useForm } from "react-hook-form"; import { Controller, useForm } from "react-hook-form";
import axios from "axios"; import axios from "axios";
import { useState } from "react"; import { useState } from "react";
export default function OcmeCycleCount() { export default function OcmeCycleCount() {
const token = localStorage.getItem("auth_token"); const token = localStorage.getItem("auth_token");
const [data, setData] = useState([]); const [data, setData] = useState([]);
const [counting, setCounting] = useState(false); const [counting, setCounting] = useState(false);
const { const {
register, register,
handleSubmit, handleSubmit,
//watch, //watch,
formState: { errors }, formState: { errors },
reset, reset,
control, control,
} = useForm(); } = useForm();
const onSubmit = async (data: any) => { const onSubmit = async (data: any) => {
setData([]); setData([]);
setCounting(true); setCounting(true);
toast.success(`Cycle count started`); toast.success(`Cycle count started`);
try { try {
const res = await axios.post("/ocme/api/v1/cycleCount", data, { const res = await axios.post("/ocme/api/v1/cyclecount", data, {
headers: { Authorization: `Bearer ${token}` }, headers: { Authorization: `Bearer ${token}` },
}); });
console.log(data); toast.success(res.data.message);
toast.success(res.data.message); setData(res.data.data);
setData(res.data.data); setCounting(false);
setCounting(false); reset();
reset(); } catch (error) {
} catch (error) { toast.error("There was an error cycle counting");
toast.error("There was an error cycle counting"); setCounting(false);
setCounting(false); reset();
reset(); }
} };
}; return (
<div className="flex flex-row w-screen">
return ( <div className="m-2 w-5/6">
<div className="flex flex-row w-screen"> <LstCard>
<div className="m-2 w-5/6"> <p className="ml-2">
<LstCard> Please enter the name or laneID you want to cycle count.
<p className="ml-2"> </p>
Please enter the name or laneID you want to cycle count. <div>
</p> <form onSubmit={handleSubmit(onSubmit)}>
<div> <div className="flex justify-between">
<form onSubmit={handleSubmit(onSubmit)}> <div className="m-2 flex flex-row">
<div className="flex justify-between"> <Input
<div className="m-2 flex flex-row"> placeholder="enter lane: L064"
<Input className={
placeholder="enter lane: L064" errors.lane ? "border-red-500" : ""
className={errors.lane ? "border-red-500" : ""} }
aria-invalid={!!errors.lane} aria-invalid={!!errors.lane}
{...register("lane", { {...register("lane", {
required: true, required: true,
minLength: { minLength: {
value: 3, value: 3,
message: "The lane is too short!", message:
}, "The lane is too short!",
})} },
/> })}
<div className="ml-2"> />
<Controller <div className="ml-2">
control={control} <Controller
name="laneType" control={control}
defaultValue={""} name="laneType"
render={({ defaultValue={""}
field: { onChange }, render={({
fieldState: {}, field: { onChange },
//formState, fieldState: {},
}) => ( //formState,
<Select onValueChange={onChange}> }) => (
<SelectTrigger className="w-[180px]"> <Select
<SelectValue placeholder="Select name or id" /> onValueChange={onChange}
</SelectTrigger> >
<SelectContent> <SelectTrigger className="w-[180px]">
<SelectItem value="name">Name</SelectItem> <SelectValue placeholder="Select name or id" />
<SelectItem value="laneId">Lane ID</SelectItem> </SelectTrigger>
</SelectContent> <SelectContent>
</Select> <SelectItem value="name">
)} Name
/> </SelectItem>
</div> <SelectItem value="laneId">
</div> Lane ID
<Button className="m-2" type="submit" disabled={counting}> </SelectItem>
{counting ? ( </SelectContent>
<span>Counting...</span> </Select>
) : ( )}
<span>CycleCount</span> />
)} </div>
</Button> </div>
</div> <Button
</form> className="m-2"
</div> type="submit"
<div> disabled={counting}
<Table> >
<TableHeader> {counting ? (
<TableRow> <span>Counting...</span>
<TableHead>LaneID</TableHead> ) : (
<TableHead>Lane</TableHead> <span>CycleCount</span>
<TableHead>AV</TableHead> )}
<TableHead>Description</TableHead> </Button>
<TableHead>Running Number</TableHead> </div>
<TableHead>In Ocme</TableHead> </form>
<TableHead>In Stock</TableHead> </div>
<TableHead>Result</TableHead> <div>
</TableRow> <Table>
</TableHeader> <TableHeader>
{data?.length === 0 ? ( <TableRow>
<TableBody> <TableHead>LaneID</TableHead>
{Array(10) <TableHead>Lane</TableHead>
.fill(0) <TableHead>AV</TableHead>
.map((_, i) => ( <TableHead>Description</TableHead>
<TableRow key={i}> <TableHead>Running Number</TableHead>
<TableCell className="font-medium"> <TableHead>In Ocme</TableHead>
<Skeleton className="h-4" /> <TableHead>In Stock</TableHead>
</TableCell> <TableHead>Result</TableHead>
<TableCell> </TableRow>
<Skeleton className="h-4" /> </TableHeader>
</TableCell> {data.length === 0 ? (
<TableCell> <TableBody>
<Skeleton className="h-4" /> {Array(10)
</TableCell> .fill(0)
<TableCell> .map((_, i) => (
<Skeleton className="h-4" /> <TableRow key={i}>
</TableCell> <TableCell className="font-medium">
<TableCell> <Skeleton className="h-4" />
<Skeleton className="h-4" /> </TableCell>
</TableCell> <TableCell>
<TableCell> <Skeleton className="h-4" />
<Skeleton className="h-4" /> </TableCell>
</TableCell> <TableCell>
<TableCell> <Skeleton className="h-4" />
<Skeleton className="h-4" /> </TableCell>
</TableCell> <TableCell>
<TableCell> <Skeleton className="h-4" />
<Skeleton className="h-4" /> </TableCell>
</TableCell> <TableCell>
</TableRow> <Skeleton className="h-4" />
))} </TableCell>
</TableBody> <TableCell>
) : ( <Skeleton className="h-4" />
<> </TableCell>
{data?.map((i: any) => { <TableCell>
let classname = ``; <Skeleton className="h-4" />
if (i.info === "Quality Check Required") { </TableCell>
classname = `bg-red-500`; <TableCell>
} <Skeleton className="h-4" />
if (i.info === "Sent to Inv") { </TableCell>
classname = `bg-amber-700`; </TableRow>
} ))}
return ( </TableBody>
<TableRow key={i.runningNumber}> ) : (
<TableCell className={`font-medium ${classname}`}> <>
{i.alpla_laneID} {data.map((i: any) => {
</TableCell> let classname = ``;
<TableCell className={`font-medium ${classname}`}> if (
{i.alpla_laneDescription} i.info === "Quality Check Required"
</TableCell> ) {
<TableCell className={`font-medium ${classname}`}> classname = `bg-red-500`;
{i.Article} }
</TableCell> if (i.info === "Sent to Inv") {
<TableCell className={`font-medium ${classname}`}> classname = `bg-amber-700`;
{i.alpla_laneDescription} }
</TableCell> return (
<TableCell className={`font-medium ${classname}`}> <TableRow key={i.runningNumber}>
{i.runningNumber} <TableCell
</TableCell> className={`font-medium ${classname}`}
<TableCell className={`font-medium ${classname}`}> >
{i.ocme} {i.alpla_laneID}
</TableCell> </TableCell>
<TableCell className={`font-medium ${classname}`}> <TableCell
{i.stock} className={`font-medium ${classname}`}
</TableCell> >
<TableCell className={`font-medium ${classname}`}> {i.alpla_laneDescription}
{i.info} </TableCell>
</TableCell> <TableCell
</TableRow> className={`font-medium ${classname}`}
); >
})} {i.Article}
</> </TableCell>
)} <TableCell
</Table> className={`font-medium ${classname}`}
</div> >
</LstCard> {i.alpla_laneDescription}
</div> </TableCell>
{/* <div className="m-2"> <TableCell
className={`font-medium ${classname}`}
>
{i.runningNumber}
</TableCell>
<TableCell
className={`font-medium ${classname}`}
>
{i.ocme}
</TableCell>
<TableCell
className={`font-medium ${classname}`}
>
{i.stock}
</TableCell>
<TableCell
className={`font-medium ${classname}`}
>
{i.info}
</TableCell>
</TableRow>
);
})}
</>
)}
</Table>
</div>
</LstCard>
</div>
{/* <div className="m-2">
<CycleCountLog /> <CycleCountLog />
</div> */} </div> */}
</div> </div>
); );
} }

View File

@@ -32,7 +32,7 @@
} }
}, },
"admConfig": { "admConfig": {
"build": 54, "build": 76,
"oldBuild": "backend-0.1.3.zip" "oldBuild": "backend-0.1.3.zip"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -31,64 +31,67 @@ export const lstAuth = btoa(`${username}:${password}`);
// checking to make sure we have the settings intialized // checking to make sure we have the settings intialized
const serverIntialized = await db.select({ count: count() }).from(settings); const serverIntialized = await db.select({ count: count() }).from(settings);
export const installed = export const installed =
serverIntialized[0].count === 0 && process.env.NODE_ENV !== "development" serverIntialized[0].count === 0 && process.env.NODE_ENV !== "development"
? false ? false
: true; : true;
createLog("info", "LST", "server", `Server is installed: ${installed}`); createLog("info", "LST", "server", `Server is installed: ${installed}`);
const app = new OpenAPIHono({ strict: false }); const app = new OpenAPIHono({ strict: false });
// middle ware // middle ware
app.use("*", logger()); if (process.env.NODE_ENV === "development") {
app.use("*", logger());
}
app.use( app.use(
"*", "*",
cors({ cors({
origin: "*", // Allow all origins origin: "*", // Allow all origins
allowHeaders: ["Content-Type", "Authorization", "X-Requested-With"], allowHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"], allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"],
//exposeHeaders: ["Content-Length", "X-Kuma-Revision"], //exposeHeaders: ["Content-Length", "X-Kuma-Revision"],
credentials: true, // Allow credentials if needed credentials: true, // Allow credentials if needed
maxAge: 600, maxAge: 600,
}) })
); );
// Middleware to normalize route case // Middleware to normalize route case
// app.use("*", async (c, next) => { // app.use("*", async (c, next) => {
// const lowercasedUrl = c.req.url.toLowerCase(); // // const lowercasedUrl = c.req.url.toLowerCase();
// //console.log("Incoming Request:", c.req.url, c.req.method); // console.log("Incoming Request:", c.req.url, c.req.method);
// // If the URL is already lowercase, continue as usual // // // If the URL is already lowercase, continue as usual
// if (c.req.url === lowercasedUrl) { // // if (c.req.url === lowercasedUrl) {
// await next(); // await next();
// } // // }
// // Otherwise, re-route internally // // // Otherwise, re-route internally
// return c.redirect(lowercasedUrl, 308); // 308 preserves the HTTP method // // return c.redirect(lowercasedUrl, 308); // 308 preserves the HTTP method
// }); // });
app.doc("/api/ref", { app.doc("/api/ref", {
openapi: "3.0.0", openapi: "3.0.0",
info: { info: {
version: "2.0.0", version: "2.0.0",
title: "LST API", title: "LST API",
}, },
}); });
const routes = [ const routes = [
scalar, scalar,
auth, auth,
// apiHits, // apiHits,
system, system,
tcpServer, tcpServer,
sqlService, sqlService,
logistics, logistics,
rfid, rfid,
printers, printers,
loggerService, loggerService,
ocpService, ocpService,
] as const; ] as const;
const appRoutes = routes.forEach((route) => { const appRoutes = routes.forEach((route) => {
app.route("/api/", route); app.route("/api/", route);
}); });
app.route("/ocme/", ocme); app.route("/ocme/", ocme);
@@ -129,48 +132,48 @@ app.use("*", serveStatic({ path: "./frontend/dist/index.html" }));
// Handle app exit signals // Handle app exit signals
process.on("SIGINT", async () => { process.on("SIGINT", async () => {
console.log("\nGracefully shutting down..."); console.log("\nGracefully shutting down...");
//await closePool(); //await closePool();
process.exit(0); process.exit(0);
}); });
process.on("SIGTERM", async () => { process.on("SIGTERM", async () => {
console.log("Received termination signal, closing database..."); console.log("Received termination signal, closing database...");
//await closePool(); //await closePool();
process.exit(0); process.exit(0);
}); });
process.on("uncaughtException", async (err) => { process.on("uncaughtException", async (err) => {
console.log("Uncaught Exception:", err); console.log("Uncaught Exception:", err);
//await closePool(); //await closePool();
process.exit(1); process.exit(1);
}); });
process.on("beforeExit", async () => { process.on("beforeExit", async () => {
console.log("Process is about to exit..."); console.log("Process is about to exit...");
//await closePool(); //await closePool();
process.exit(0); process.exit(0);
}); });
const port = const port =
process.env.NODE_ENV === "development" process.env.NODE_ENV === "development"
? process.env.VITE_SERVER_PORT ? process.env.VITE_SERVER_PORT
: process.env.PROD_PORT; : process.env.PROD_PORT;
serve( serve(
{ {
fetch: app.fetch, fetch: app.fetch,
port: Number(port), port: Number(port),
hostname: "0.0.0.0", hostname: "0.0.0.0",
}, },
(info) => { (info) => {
createLog( createLog(
"info", "info",
"LST", "LST",
"server", "server",
`Server is running on http://${info.address}:${info.port}` `Server is running on http://${info.address}:${info.port}`
); );
} }
); );
export type AppRoutes = typeof appRoutes; export type AppRoutes = typeof appRoutes;

View File

@@ -4,12 +4,26 @@ import { db } from "../../database/dbclient.js";
import { serverData } from "../../database/schema/serverData.js"; import { serverData } from "../../database/schema/serverData.js";
import { eq, sql } from "drizzle-orm"; import { eq, sql } from "drizzle-orm";
import { createLog } from "../services/logger/logger.js"; import { createLog } from "../services/logger/logger.js";
import { spawn } from "child_process";
import { getAppInfo } from "../globalUtils/appInfo.js";
import { db } from "../../database/dbclient.js";
import { serverData } from "../../database/schema/serverData.js";
import { eq, sql } from "drizzle-orm";
import { createLog } from "../services/logger/logger.js";
type UpdateServerResponse = { type UpdateServerResponse = {
success: boolean; success: boolean;
message: string; message: string;
success: boolean;
message: string;
}; };
export const updateServer = async (
devApp: string,
server: string | null
): Promise<UpdateServerResponse> => {
const app = await getAppInfo(devApp);
const serverInfo = await db
export const updateServer = async ( export const updateServer = async (
devApp: string, devApp: string,
server: string | null server: string | null
@@ -33,7 +47,32 @@ export const updateServer = async (
"Looks like you are missing the plant token or have entered an incorrect one please try again.", "Looks like you are missing the plant token or have entered an incorrect one please try again.",
}; };
} }
if (serverInfo.length === 0) {
createLog(
"error",
"lst",
"serverUpdater",
`Looks like you are missing the plant token or have entered an incorrect one please try again.`
);
return {
success: false,
message:
"Looks like you are missing the plant token or have entered an incorrect one please try again.",
};
}
if (serverInfo[0].isUpgrading) {
createLog(
"error",
"lst",
"serverUpdater",
`Looks like ${serverInfo[0].plantToken} is upgrading already you cant do this again.`
);
return {
success: false,
message: `Looks like ${serverInfo[0].plantToken} is upgrading already you cant do this again.`,
};
}
if (serverInfo[0].isUpgrading) { if (serverInfo[0].isUpgrading) {
createLog( createLog(
"error", "error",
@@ -77,8 +116,15 @@ export const updateServer = async (
, ,
]; ];
console.log(args); return new Promise(async (resolve, reject) => {
const process = spawn("powershell", args);
// change the server to upgradeing
await db
.update(serverData)
.set({ isUpgrading: true })
.where(eq(serverData.plantToken, server?.toLowerCase() ?? ""));
//let stdout = "";
//let stderr = "";
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
const process = spawn("powershell", args); const process = spawn("powershell", args);
// change the server to upgradeing // change the server to upgradeing
@@ -89,6 +135,12 @@ export const updateServer = async (
//let stdout = ""; //let stdout = "";
//let stderr = ""; //let stderr = "";
// Collect stdout data
process.stdout.on("data", (data) => {
const output = data.toString().trim();
createLog("info", "lst", "serverUpdater", `${output}`);
//onData(output);
});
// Collect stdout data // Collect stdout data
process.stdout.on("data", (data) => { process.stdout.on("data", (data) => {
const output = data.toString().trim(); const output = data.toString().trim();
@@ -96,6 +148,12 @@ export const updateServer = async (
//onData(output); //onData(output);
}); });
// Collect stderr data
process.stderr.on("data", (data) => {
const output = data.toString().trim();
createLog("info", "lst", "serverUpdater", `${output}`);
//onData(output);
});
// Collect stderr data // Collect stderr data
process.stderr.on("data", (data) => { process.stderr.on("data", (data) => {
const output = data.toString().trim(); const output = data.toString().trim();
@@ -103,6 +161,13 @@ export const updateServer = async (
//onData(output); //onData(output);
}); });
// Handle process close
process.on("close", async (code) => {
if (code === 0) {
// if (count >= servers) {
// //onClose(`Server completed with code: ${code}`);
// }
createLog("info", "lst", "serverUpdater", `${server}`);
// Handle process close // Handle process close
process.on("close", async (code) => { process.on("close", async (code) => {
if (code === 0) { if (code === 0) {
@@ -111,6 +176,26 @@ export const updateServer = async (
// } // }
createLog("info", "lst", "serverUpdater", `${server}`); createLog("info", "lst", "serverUpdater", `${server}`);
//update the last build.
try {
await db
.update(serverData)
.set({ lastUpdated: sql`NOW()`, isUpgrading: false })
.where(eq(serverData.plantToken, server?.toLowerCase() ?? ""));
createLog(
"info",
"lst",
"serverUpdater",
`${server?.toLowerCase()}, has been updated and can now be used again.`
);
} catch (error) {
createLog(
"error",
"lst",
"serverUpdater",
`There was an error updating the last time the server was updated: ${error}`
);
}
//update the last build. //update the last build.
try { try {
await db await db
@@ -132,6 +217,12 @@ export const updateServer = async (
); );
} }
resolve({
success: true,
message: `${server?.toLowerCase()}, has been updated and can now be used again.`,
});
} else {
const errorMessage = `Process exited with code ${code}`;
resolve({ resolve({
success: true, success: true,
message: `${server?.toLowerCase()}, has been updated and can now be used again.`, message: `${server?.toLowerCase()}, has been updated and can now be used again.`,
@@ -139,6 +230,9 @@ export const updateServer = async (
} else { } else {
const errorMessage = `Process exited with code ${code}`; const errorMessage = `Process exited with code ${code}`;
// if (count >= servers) {
// //onClose(code);
// }
// if (count >= servers) { // if (count >= servers) {
// //onClose(code); // //onClose(code);
// } // }
@@ -149,6 +243,12 @@ export const updateServer = async (
}); });
} }
}); });
reject({
success: false,
message: `${server?.toLowerCase()}, Has encounted an error while updating.`,
});
}
});
// Handle errors with the process itself // Handle errors with the process itself
process.on("error", (error) => { process.on("error", (error) => {
@@ -157,11 +257,31 @@ export const updateServer = async (
reject(error); reject(error);
}); });
}); });
// Handle errors with the process itself
process.on("error", (error) => {
//onError(err.message);
createLog("error", "lst", "serverUpdater", `${error}`);
reject(error);
});
});
}; };
export async function processAllServers(devApp: string) { export async function processAllServers(devApp: string) {
const servers = await db.select().from(serverData); const servers = await db.select().from(serverData);
const servers = await db.select().from(serverData);
createLog(
"info",
"lst",
"serverUpdater",
`Running the update on all servers`
);
let count = 1;
for (const server of servers) {
try {
const updateToServer = await updateServer(devApp, server.plantToken);
createLog("info", "lst", "serverUpdater", `${server.sName} was updated.`);
count = count + 1;
createLog( createLog(
"info", "info",
"lst", "lst",
@@ -186,4 +306,15 @@ export async function processAllServers(devApp: string) {
//return {success: false, message: `Error updating ${server.sName}: ${error.message}`}; //return {success: false, message: `Error updating ${server.sName}: ${error.message}`};
} }
} }
//return {success: true, message: `${server.sName} was updated.`, data: updateToServer};
} catch (error: any) {
createLog(
"info",
"lst",
"serverUpdater",
`Error updating ${server.sName}: ${error.message}`
);
//return {success: false, message: `Error updating ${server.sName}: ${error.message}`};
}
}
} }

View File

@@ -1,21 +1,21 @@
import axios from "axios"; import axios from "axios";
export const ocmeInv = async (data: any) => { export const ocmeInv = async (data: any) => {
try { try {
const res = await axios.post( const res = await axios.post(
"http://usday1vms010:3250/api/v1/getlanedata", "http://usday1vms010:3250/api/v1/getlanedata",
{ lane: data.lane, laneType: data.laneType }, { lane: data.lane, laneType: data.laneType },
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
Connection: "keep-alive", Connection: "keep-alive",
}, },
} }
); );
// console.log(res.data.data); // console.log(res.data.data);
return res.data.data; return res.data.data;
} catch (error: any) { } catch (error: any) {
console.log(error.code); console.log(error.code);
} }
}; };

View File

@@ -1,25 +1,39 @@
import {db} from "../../../../database/dbclient.js"; import { db } from "../../../../database/dbclient.js";
import {ocmeData} from "../../../../database/schema/ocme.js"; import { ocmeData } from "../../../../database/schema/ocme.js";
import {differenceInMinutes} from "date-fns"; import { differenceInMinutes } from "date-fns";
import {createLog} from "../../logger/logger.js"; import { createLog } from "../../logger/logger.js";
import {eq} from "drizzle-orm"; import { eq } from "drizzle-orm";
export const getInfo = async () => { export const getInfo = async () => {
let ocmeInfo: any = []; let ocmeInfo: any = [];
try { try {
ocmeInfo = await db.select().from(ocmeData).where(eq(ocmeData.pickedUp, false)); ocmeInfo = await db
.select()
.from(ocmeData)
.where(eq(ocmeData.pickedUp, false));
// add in the time difference // add in the time difference
ocmeInfo = ocmeInfo.map((o: any) => { ocmeInfo = ocmeInfo.map((o: any) => {
const now = new Date(Date.now()); const now = new Date(Date.now());
const diff = differenceInMinutes(now, o.add_Date!); //const strippedDate = o.add_Date.replace("Z", "");
return {...o, waitingFor: diff}; const diff = differenceInMinutes(now, o.add_Date);
}); return { ...o, waitingFor: diff };
createLog("info", "ocme", "ocme", `There are ${ocmeInfo.length} pallet(s) to be picked up.`); });
} catch (error) { createLog(
createLog("error", "ocme", "ocme", "There was an error trying to retrive the ocmeInfo."); "info",
throw Error("There was an error trying to retrive the."); "ocme",
} "ocme",
`There are ${ocmeInfo.length} pallet(s) to be picked up.`
);
} catch (error) {
createLog(
"error",
"ocme",
"ocme",
"There was an error trying to retrive the ocmeInfo."
);
throw Error("There was an error trying to retrive the.");
}
return ocmeInfo; return ocmeInfo;
}; };

View File

@@ -4,64 +4,79 @@ import { createSSCC } from "../../../globalUtils/createSSCC.js";
import { createLog } from "../../logger/logger.js"; import { createLog } from "../../logger/logger.js";
import { query } from "../../sqlServer/prodSqlServer.js"; import { query } from "../../sqlServer/prodSqlServer.js";
import { labelData } from "../../sqlServer/querys/materialHelpers/labelInfo.js"; import { labelData } from "../../sqlServer/querys/materialHelpers/labelInfo.js";
import { db } from "../../../../database/dbclient.js";
import { ocmeData } from "../../../../database/schema/ocme.js";
import { createSSCC } from "../../../globalUtils/createSSCC.js";
import { createLog } from "../../logger/logger.js";
import { query } from "../../sqlServer/prodSqlServer.js";
import { labelData } from "../../sqlServer/querys/materialHelpers/labelInfo.js";
export const postLabelData = async (data: any) => { export const postLabelData = async (data: any) => {
console.log(data); console.log(data);
let newData = data; let newData = data;
if (Array.isArray(data)) { if (Array.isArray(data)) {
newData = { newData = {
sscc: data[1], sscc: data[1],
areaFrom: data[0], areaFrom: data[0],
completed: true, completed: true,
}; };
} }
if (newData.sscc && !newData.runningNr) { if (newData.sscc && !newData.runningNr) {
newData.runningNr = newData.sscc.slice(10, -1); newData.runningNr = newData.sscc.slice(10, -1);
} }
if (!newData.sscc && !newData.runningNr) { if (!newData.sscc && !newData.runningNr) {
return { return {
success: false, success: false,
message: "Missing data please try again", message: "Missing data please try again",
data: [], data: [],
};
}
let label;
const filterQuery = labelData.replaceAll("[rn]", newData.runningNr);
try {
label = await query(filterQuery, "Label data");
} catch (error) {
createLog(
"error",
"ocme",
"ocme",
"There was an error getting the labelData"
);
}
const newPost = {
sscc: newData.sscc ? newData.sscc : await createSSCC(newData.runningNr),
runningNr: newData.runningNr,
completed: newData.completed ? newData.completed : true,
lineNum: label[0]?.machineLocation,
areaFrom: newData.areaFrom,
pickedUp: false,
}; };
} try {
let label; const enterNewData = await db
const filterQuery = labelData.replaceAll("[rn]", newData.runningNr); .insert(ocmeData)
try { .values(newPost)
label = await query(filterQuery, "Label data"); .returning({
} catch (error) { sscc: ocmeData.sscc,
createLog( runningNr: ocmeData.runningNr,
"error", areaFrom: ocmeData.areaFrom,
"ocme", lineNum: ocmeData.lineNum,
"ocme", completed: ocmeData.completed,
"There was an error getting the labelData" pickedUp: ocmeData.pickedUp,
); });
}
const newPost = { //console.log(enterNewData);
sscc: newData.sscc ? newData.sscc : await createSSCC(newData.runningNr), return {
runningNr: newData.runningNr, success: true,
completed: newData.completed, message: "Data was posted to ocme info",
lineNum: label[0].machineLocation, data: enterNewData,
areaFrom: newData.areaFrom, };
pickedUp: false, } catch (error) {
}; //console.log(error);
try { return {
const enterNewData = await db success: false,
.insert(ocmeData) message: "Data was posted to ocme info",
.values(newPost) data: [],
.returning({ sscc: ocmeData.sscc }); };
return { }
success: true,
message: "Data was posted to ocme info",
data: enterNewData,
};
} catch (error) {
console.log(error);
return {
success: false,
message: "Data was posted to ocme info",
data: newPost,
};
}
}; };

View File

@@ -0,0 +1,49 @@
import net from "net";
import { db } from "../../../../database/dbclient.js";
import { settings } from "../../../../database/schema/settings.js";
import { eq } from "drizzle-orm";
import { createLog } from "../../logger/logger.js";
export const triggerScanner = async () => {
const camera = new net.Socket();
let setting = await db
.select()
.from(settings)
.where(eq(settings.name, "zebraScanners"));
if (setting.length === 0) {
return {
success: false,
message: "Looks like the setting is missing.",
};
}
const scannerData = JSON.parse(setting[0]?.value);
let data = scannerData.filter((n: any) => n.name === "wrapper1");
let port = data[0].port;
console.log(data);
createLog(
"info",
"wrapperScanner",
"ocme",
`End of line Camera was triggered`
);
return new Promise((resolve, reject) => {
camera.connect(port, data[0].ip, async () => {
createLog("info", "wrapperScanner", "ocme", `Triggered`);
camera.write("TRIGGER", "utf8");
camera.end();
resolve({ success: true, message: "Camera was triggered." });
});
camera.on("error", (error) => {
createLog("error", "wrapperScanner", "ocme", `${error}`);
resolve({
success: false,
message: `There was an error triggering the camera: ${JSON.stringify(
error
)}`,
});
});
resolve({ success: true, message: "Camera was triggered." });
});
};

View File

@@ -1,4 +1,4 @@
import {OpenAPIHono} from "@hono/zod-openapi"; import { OpenAPIHono } from "@hono/zod-openapi";
// routes // routes
import getInfo from "./route/getInfo.js"; import getInfo from "./route/getInfo.js";
@@ -7,35 +7,52 @@ import pickedup from "./route/pickedUp.js";
import postsscc from "./route/postSSCC.js"; import postsscc from "./route/postSSCC.js";
import getShipments from "./route/getShipmentPallets.js"; import getShipments from "./route/getShipmentPallets.js";
import cycleCount from "./route/cycleCount.js"; import cycleCount from "./route/cycleCount.js";
import {serve} from "@hono/node-server"; import { serve } from "@hono/node-server";
import {createLog} from "../logger/logger.js"; import { createLog } from "../logger/logger.js";
import {db} from "../../../database/dbclient.js"; import { db } from "../../../database/dbclient.js";
import {settings} from "../../../database/schema/settings.js"; import { settings } from "../../../database/schema/settings.js";
import manualTrigger from "./route/triggerCamera.js";
const app = new OpenAPIHono(); const app = new OpenAPIHono();
const port = process.env.OCME_PORT; const port = process.env.OCME_PORT;
const routes = [getInfo, postRunningNr, postsscc, pickedup, getShipments, cycleCount] as const; const routes = [
getInfo,
postRunningNr,
postsscc,
pickedup,
getShipments,
cycleCount,
manualTrigger,
] as const;
const setting = await db.select().from(settings); const setting = await db.select().from(settings);
const isActive = setting.filter((n) => n.name === "ocmeService"); const isActive = setting.filter((n) => n.name === "ocmeService");
const appRoutes = routes.forEach((route) => { const appRoutes = routes.forEach((route) => {
app.route("/api/v1", route); app.route("/api/v1", route);
}); });
app.all("/api/v1/*", (c) => { app.all("/api/v1/*", (c) => {
return c.json({success: false, message: "you have encounted an ocme route that dose not exist."}); return c.json({
success: false,
message: "you have encounted an ocme route that dose not exist.",
});
}); });
if (port && isActive[0]?.value === "1") { if (port && isActive[0]?.value === "1") {
serve( serve(
{ {
fetch: app.fetch, fetch: app.fetch,
port: Number(port), port: Number(port),
hostname: "0.0.0.0", hostname: "0.0.0.0",
}, },
(info) => { (info) => {
createLog("info", "LST", "server", `Ocme section is listening on http://${info.address}:${info.port}`); createLog(
} "info",
); "LST",
"server",
`Ocme section is listening on http://${info.address}:${info.port}`
);
}
);
} }
export default app; export default app;

View File

@@ -1,96 +1,37 @@
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi"; import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
import { getInfo } from "../controller/getInfo.js"; import { getInfo } from "../controller/getInfo.js";
import { apiHit } from "../../../globalUtils/apiHits.js"; import { apiHit } from "../../../globalUtils/apiHits.js";
import { responses } from "../../../globalUtils/routeDefs/responses.js";
const app = new OpenAPIHono({ strict: false }); const app = new OpenAPIHono({ strict: false });
const AddSetting = z.object({
name: z.string().openapi({ example: "server" }),
value: z.string().openapi({ example: "localhost" }),
description: z
.string()
.openapi({ example: "The server we are going to connect to" }),
roles: z.string().openapi({ example: "admin" }),
module: z.string().openapi({ example: "production" }),
});
app.openapi( app.openapi(
createRoute({ createRoute({
tags: ["ocme"], tags: ["ocme"],
summary: "Get all current info", summary: "Get all current info",
method: "get", method: "get",
path: "/getInfo", path: "/getInfo",
request: {
body: { responses: responses(),
content: { }),
"application/json": { schema: AddSetting }, async (c) => {
}, // make sure we have a vaid user being accessed thats really logged in
}, apiHit(c, { endpoint: "api/auth/register" });
}, try {
responses: { return c.json(
200: { { success: true, message: "Ocme Info", data: await getInfo() },
content: { 200
"application/json": { );
schema: z.object({ } catch (error) {
success: z.boolean().openapi({ example: true }), return c.json(
message: z.string().openapi({ example: "Starter" }), {
data: z.array(z.object({})).optional().openapi({ example: [] }), success: false,
}), message: "There was an error getting ocmeInfo data",
}, data: error,
}, },
description: "Response message", 400
}, );
400: { }
content: {
"application/json": {
schema: z.object({
success: z.boolean().openapi({ example: false }),
message: z
.string()
.optional()
.openapi({ example: "Internal Server error" }),
data: z.array(z.object({})).optional().openapi({ example: [] }),
}),
},
},
description: "Internal Server Error",
},
// 401: {
// content: {
// "application/json": {
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
// },
// },
// description: "Unauthorized",
// },
// 500: {
// content: {
// "application/json": {
// schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
// },
// },
// description: "Internal Server Error",
// },
},
}),
async (c) => {
// make sure we have a vaid user being accessed thats really logged in
apiHit(c, { endpoint: "api/auth/register" });
try {
return c.json(
{ success: true, message: "Ocme Info", data: await getInfo() },
200
);
} catch (error) {
return c.json(
{
success: false,
message: "There was an error getting ocmeInfo data",
data: error,
},
400
);
} }
}
); );
export default app; export default app;

View File

@@ -1,86 +1,106 @@
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi"; import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
import {getInfo} from "../controller/getInfo.js"; import { getInfo } from "../controller/getInfo.js";
import {postLabelData} from "../controller/postRunningNr.js"; import { postLabelData } from "../controller/postRunningNr.js";
import {apiHit} from "../../../globalUtils/apiHits.js"; import { apiHit } from "../../../globalUtils/apiHits.js";
const app = new OpenAPIHono(); const app = new OpenAPIHono();
const PostRunningNr = z.object({ const PostRunningNr = z.object({
sscc: z.string().optional().openapi({example: "00090103830005710997"}), sscc: z.string().optional().openapi({ example: "00090103830005710997" }),
runningNr: z.string().optional().openapi({example: "localhost"}), runningNr: z.string().optional().openapi({ example: "localhost" }),
areaFrom: z.string().optional().openapi({example: "The server we are going to connect to"}), areaFrom: z
completed: z.boolean().optional().openapi({example: true}), .string()
.optional()
.openapi({ example: "The server we are going to connect to" }),
completed: z.boolean().optional().openapi({ example: true }),
}); });
app.openapi( app.openapi(
createRoute({ createRoute({
tags: ["ocme"], tags: ["ocme"],
summary: "Post New running number to be picked up.", summary: "Post New running number to be picked up.",
method: "post", method: "post",
path: "/postsscc", path: "/postSSCC",
request: { request: {
body: { body: {
content: { content: {
"application/json": {schema: PostRunningNr}, "application/json": { schema: PostRunningNr },
},
},
}, },
responses: { },
200: { },
content: { responses: {
"application/json": { 200: {
schema: z.object({ content: {
success: z.boolean().openapi({example: true}), "application/json": {
message: z.string().openapi({example: "Starter"}), schema: z.object({
// data: z success: z.boolean().openapi({ example: true }),
// .array(z.object({sscc: z.string().optional()})) message: z.string().openapi({ example: "Starter" }),
// .optional() // data: z
// .openapi({example: []}), // .array(z.object({sscc: z.string().optional()}))
}), // .optional()
}, // .openapi({example: []}),
}, }),
description: "Response message", },
},
400: {
content: {
"application/json": {
schema: z.object({
success: z.boolean().openapi({example: false}),
message: z.string().optional().openapi({example: "Internal Server error"}),
data: z.array(z.object({})).optional().openapi({example: []}),
}),
},
},
description: "Internal Server Error",
},
// 401: {
// content: {
// "application/json": {
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
// },
// },
// description: "Unauthorized",
// },
// 500: {
// content: {
// "application/json": {
// schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
// },
// },
// description: "Internal Server Error",
// },
}, },
}), description: "Response message",
async (c) => { },
// make sure we have a vaid user being accessed thats really logged in 400: {
try { content: {
const data = await c.req.json(); "application/json": {
apiHit(c, {endpoint: "api/ocme/postRunningNumber", lastBody: data}); schema: z.object({
const postPallet = await postLabelData(data); success: z.boolean().openapi({ example: false }),
return c.json({success: postPallet.success, message: postPallet.message, data: postPallet.data ?? []}, 200); message: z
} catch (error) { .string()
return c.json({success: false, message: "There was an error getting ocmeInfo data", data: error}, 400); .optional()
} .openapi({ example: "Internal Server error" }),
data: z.array(z.object({})).optional().openapi({ example: [] }),
}),
},
},
description: "Internal Server Error",
},
// 401: {
// content: {
// "application/json": {
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
// },
// },
// description: "Unauthorized",
// },
// 500: {
// content: {
// "application/json": {
// schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
// },
// },
// description: "Internal Server Error",
// },
},
}),
async (c) => {
// make sure we have a vaid user being accessed thats really logged in
try {
const data = await c.req.json();
apiHit(c, { endpoint: "api/ocme/postRunningNumber", lastBody: data });
const postPallet = await postLabelData(data);
return c.json(
{
success: postPallet.success,
message: postPallet.message,
data: postPallet.data ?? [],
},
200
);
} catch (error) {
return c.json(
{
success: false,
message: "There was an error getting ocmeInfo data",
data: error,
},
400
);
} }
}
); );
export default app; export default app;

View File

@@ -0,0 +1,25 @@
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
import { getInfo } from "../controller/getInfo.js";
import { apiHit } from "../../../globalUtils/apiHits.js";
import { responses } from "../../../globalUtils/routeDefs/responses.js";
import { triggerScanner } from "../controller/triggerCamera.js";
const app = new OpenAPIHono({ strict: false });
app.openapi(
createRoute({
tags: ["ocme"],
summary: "Triggers the camera at the end of the dyco.",
method: "get",
path: "/manualCameraTrigger",
responses: responses(),
}),
async (c) => {
// make sure we have a vaid user being accessed thats really logged in
apiHit(c, { endpoint: "api/auth/register" });
const manualTrigger = await triggerScanner();
console.log(manualTrigger);
return c.json({ success: true, message: "Manual triggered" });
}
);
export default app;

View File

@@ -3,44 +3,64 @@
* Phase 2 we will just reprint the tag that was generated at the line * Phase 2 we will just reprint the tag that was generated at the line
*/ */
import {createLog} from "../../../logger/logger.js"; import { createLog } from "../../../logger/logger.js";
import type {TagData} from "../tagData.js"; import type { TagData } from "../tagData.js";
import {tagStuff} from "../tags/crudTag.js"; import { tagStuff } from "../tags/crudTag.js";
export const wrapperStuff = async (tagData: TagData[]) => { export const wrapperStuff = async (tagData: TagData[]) => {
if (tagData.length != 1) { if (tagData.length != 1) {
createLog( createLog(
"error", "error",
"rfid", "rfid",
"rfid", "rfid",
`There are ${tagData.length} tags and this ${tagData[0].reader} only allows 1 tag to create a label.` `There are ${tagData.length} tags and this ${tagData[0].reader} only allows 1 tag to create a label.`
); );
tagStuff(tagData); tagStuff(tagData);
} else { } else {
const tagdata = await tagStuff(tagData); const tagdata = await tagStuff(tagData);
if (!tagData) {
/** createLog("error", "rfid", "rfid", `No tagData was grabbed.`);
* we want to make sure this pallet came from a line as its last spot if not we need to have a manual check.
*/
const station3 = tagdata.some((n: any) => n.lastareaIn.includes("line3"));
if (!station3) {
createLog(
"error",
"rfid",
"rfid",
`${tagdata.tag}, Did not come from a line please check the pallet and manually print the label.`
);
// when we manually run again we want to make sure we read from the 3rd antenna this way we do not get the wrong info.
// more testing will need to be done on this.
}
// check if a running number exists
if (station3.runningNumber) {
createLog("info", "rfid", "rfid", `Reprint label ${station3.runningNumber}`);
} else {
createLog("info", "rfid", "rfid", `A new labels will be created and linked to this ${tagdata.tag} tag`);
}
} }
/**
* we want to make sure this pallet came from a line as its last spot if not we need to have a manual check.
*/
if (
!Array.isArray(tagdata) &&
tagdata?.some((n: any) => n.lastareaIn.includes("line3"))
) {
createLog("error", "rfid", "rfid", `Data passed over is not an array.`);
return;
}
const station3 = tagdata; //?.some((n: any) => n.lastareaIn.includes("line3"));
if (!station3) {
createLog(
"error",
"rfid",
"rfid",
`${tagdata[0].tag}, Did not come from a line please check the pallet and manually print the label.`
);
// when we manually run again we want to make sure we read from the 3rd antenna this way we do not get the wrong info.
// more testing will need to be done on this.
}
// check if a running number exists
if (station3.runningNumber) {
createLog(
"info",
"rfid",
"rfid",
`Reprint label ${station3.runningNumber}`
);
} else {
createLog(
"info",
"rfid",
"rfid",
`A new labels will be created and linked to this ${tagdata.tag} tag`
);
}
}
}; };

View File

@@ -15,65 +15,73 @@ let tcpSockets: Set<net.Socket> = new Set();
let isServerRunning = false; let isServerRunning = false;
const tcpPort = await db const tcpPort = await db
.select() .select()
.from(settings) .from(settings)
.where(eq(settings.name, "tcpPort")); .where(eq(settings.name, "tcpPort"));
const app = new OpenAPIHono(); const app = new OpenAPIHono();
export const startTCPServer = () => { export const startTCPServer = () => {
if (isServerRunning) if (isServerRunning)
return { success: false, message: "Server is already running" }; return { success: false, message: "Server is already running" };
tcpServer = net.createServer((socket) => { tcpServer = net.createServer((socket) => {
console.log("Client connected"); console.log("Client connected");
tcpSockets.add(socket); tcpSockets.add(socket);
socket.on("data", (data: Buffer) => { socket.on("data", (data: Buffer) => {
console.log("Received:", data.toString()); console.log("Received:", data.toString());
const parseData = data.toString("utf-8").trimEnd().split(" "); const parseData = data.toString("utf-8").trimEnd().split(" ");
if (parseData[0] === "HB") { // hb from the scanners
return; if (parseData[0] === "HB") {
} return;
postLabelData(parseData); }
// alert from the printers
if (parseData[0] === "ALERT:" || parseData[0] === "ALERT") {
return;
}
// from the wrapper send the data
postLabelData(parseData);
});
socket.on("end", () => {
console.log("Client disconnected");
tcpSockets.delete(socket);
});
socket.on("error", (err: Error) => {
console.error("Socket error:", err);
tcpSockets.delete(socket);
});
}); });
socket.on("end", () => { tcpServer.listen(tcpPort[0]?.value ?? 2222, () => {
console.log("Client disconnected"); createLog(
tcpSockets.delete(socket); "info",
"lst",
"tcp",
`TCP Server listening on port ${tcpPort[0]?.value ?? 2222}`
);
}); });
socket.on("error", (err: Error) => { isServerRunning = true;
console.error("Socket error:", err); return { success: true, message: "TCP Server started" };
tcpSockets.delete(socket);
});
});
tcpServer.listen(tcpPort[0]?.value ?? 2222, () => {
createLog(
"info",
"lst",
"tcp",
`TCP Server listening on port ${tcpPort[0]?.value ?? 2222}`
);
});
isServerRunning = true;
return { success: true, message: "TCP Server started" };
}; };
// Function to stop the TCP server // Function to stop the TCP server
export const stopTCPServer = () => { export const stopTCPServer = () => {
if (!isServerRunning) if (!isServerRunning)
return { success: false, message: "Server is not running" }; return { success: false, message: "Server is not running" };
for (const socket of tcpSockets) { for (const socket of tcpSockets) {
socket.destroy(); socket.destroy();
} }
tcpSockets.clear(); tcpSockets.clear();
tcpServer.close(() => { tcpServer.close(() => {
console.log("TCP Server stopped"); console.log("TCP Server stopped");
}); });
isServerRunning = false; isServerRunning = false;
return { success: true, message: "TCP Server stopped" }; return { success: true, message: "TCP Server stopped" };
}; };
app.route("/tcpserver/start", startTCP); app.route("/tcpserver/start", startTCP);
@@ -82,7 +90,7 @@ app.route("/tcpserver/restart", restartTCP);
// start the server after on system start up // start the server after on system start up
setTimeout(() => { setTimeout(() => {
startTCPServer(); startTCPServer();
}, 5000); }, 5000);
export default app; export default app;