Compare commits

...

12 Commits

20 changed files with 2966 additions and 126 deletions

View File

@@ -0,0 +1,4 @@
CREATE TABLE "prodlabels" (
"label_id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"runningNr" integer NOT NULL
);

View File

@@ -0,0 +1,7 @@
ALTER TABLE "prodlabels" ADD COLUMN "printerID" integer;--> statement-breakpoint
ALTER TABLE "prodlabels" ADD COLUMN "printerName" text;--> statement-breakpoint
ALTER TABLE "prodlabels" ADD COLUMN "line" integer;--> statement-breakpoint
ALTER TABLE "prodlabels" ADD COLUMN "status" text;--> statement-breakpoint
ALTER TABLE "prodlabels" ADD COLUMN "add_date" timestamp;--> statement-breakpoint
ALTER TABLE "prodlabels" ADD COLUMN "upd_date" timestamp;--> statement-breakpoint
CREATE UNIQUE INDEX "runningNr" ON "prodlabels" USING btree ("runningNr");

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -211,6 +211,20 @@
"when": 1742917978318, "when": 1742917978318,
"tag": "0029_giant_blue_blade", "tag": "0029_giant_blue_blade",
"breakpoints": true "breakpoints": true
},
{
"idx": 30,
"version": "7",
"when": 1742938986653,
"tag": "0030_conscious_cable",
"breakpoints": true
},
{
"idx": 31,
"version": "7",
"when": 1742939306614,
"tag": "0031_loud_alex_power",
"breakpoints": true
} }
] ]
} }

View File

@@ -0,0 +1,29 @@
import {
integer,
pgTable,
uuid,
uniqueIndex,
text,
timestamp,
} from "drizzle-orm/pg-core";
import { createSelectSchema } from "drizzle-zod";
export const prodlabels = pgTable(
"prodlabels",
{
label_id: uuid("label_id").defaultRandom().primaryKey(),
printerID: integer("printerID"),
printerName: text("printerName"),
line: integer("line"),
runningNr: integer("runningNr").notNull(),
status: text("status"),
add_date: timestamp("add_date"),
upd_date: timestamp("upd_date"),
},
(table) => [
//uniqueIndex("emailUniqueIndex").on(sql`lower(${table.email})`),
uniqueIndex("runningNr").on(table.runningNr),
]
);
export const prodlabelsSchema = createSelectSchema(prodlabels);

View File

@@ -0,0 +1,131 @@
import axios from "axios";
import { LstCard } from "../extendedUI/LstCard";
import { Button } from "../ui/button";
import { ScrollArea } from "../ui/scroll-area";
import { Skeleton } from "../ui/skeleton";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "../ui/table";
import { toast } from "sonner";
const currentPallets = [
{ key: "line", label: "Line" },
{ key: "runningNr", label: "Running #" },
{ key: "upd_date", label: "Date Scanned" },
{ key: "waitingfor", label: "Waiting For" },
{ key: "clear", label: "Clear" },
];
const currentTags = [
{ key: "line", label: "Line" },
{ key: "printerName", label: "Printer" },
{ key: "runningNr", label: "Running #" },
{ key: "upd_date", label: "Label date" },
{ key: "status", label: "Label Status" },
];
export default function WrapperManualTrigger() {
const cameraTrigger = async () => {
try {
const res = await axios.get("/ocme/api/v1/manualCameraTrigger");
if (res.data.success) {
toast.success(res.data.message);
return;
}
if (!res.data.success) {
toast.error(res.data.message);
}
} catch (error) {
console.log(error);
//stoast.success(error.data.message);
}
};
return (
<LstCard className="m-2 p-2">
<ScrollArea className="max-h-[200px]">
<span>Wrapper Pallet Info</span>
<Table>
<TableHeader>
<TableRow>
{currentPallets.map((l) => (
<TableHead key={l.key}>{l.label}</TableHead>
))}
</TableRow>
</TableHeader>
<TableBody>
{Array(3)
.fill(0)
.map((_, i) => (
<TableRow key={i}>
<TableCell className="font-medium">
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</ScrollArea>
<ScrollArea className="max-h-[200px]">
<Table>
<TableHeader>
<TableRow>
{currentTags.map((l) => (
<TableHead key={l.key}>{l.label}</TableHead>
))}
</TableRow>
</TableHeader>
<TableBody>
{Array(3)
.fill(0)
.map((_, i) => (
<TableRow key={i}>
<TableCell className="font-medium">
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
<TableCell>
<Skeleton className="h-4" />
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</ScrollArea>
<div>
<hr />
<p className="text-center mb-3">Manual Triggers</p>
<div className="flex flex-row justify-between">
<Button onClick={cameraTrigger}>Camera</Button>
<Button>Rfid</Button>
</div>
</div>
</LstCard>
);
}

View File

@@ -1,7 +1,14 @@
import { LstCard } from "@/components/extendedUI/LstCard"; import { LstCard } from "@/components/extendedUI/LstCard";
import { Skeleton } from "@/components/ui/skeleton"; import { Skeleton } from "@/components/ui/skeleton";
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table"; import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
// import {useSessionStore} from "@/lib/store/sessionStore"; // import {useSessionStore} from "@/lib/store/sessionStore";
// import {useSettingStore} from "@/lib/store/useSettings"; // import {useSettingStore} from "@/lib/store/useSettings";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
@@ -108,13 +115,21 @@ export default function LabelLog() {
<TableBody> <TableBody>
{data?.map((label: any) => ( {data?.map((label: any) => (
<TableRow key={label.runningNr}> <TableRow key={label.runningNr}>
<TableCell className="font-medium">{label.line}</TableCell> <TableCell className="font-medium">
<TableCell className="font-medium">{label.printerName}</TableCell> {label.line}
<TableCell className="font-medium">{label.runningNr}</TableCell> </TableCell>
<TableCell className="font-medium">
{label.printerName}
</TableCell>
<TableCell className="font-medium">
{label.runningNr}
</TableCell>
<TableCell className="font-medium"> <TableCell className="font-medium">
{format(label.upd_date, "M/d/yyyy hh:mm")} {format(label.upd_date, "M/d/yyyy hh:mm")}
</TableCell> </TableCell>
<TableCell className="font-medium">{label.status}</TableCell> <TableCell className="font-medium">
{label.status}
</TableCell>
</TableRow> </TableRow>
))} ))}
</TableBody> </TableBody>

View File

@@ -1,9 +1,14 @@
import WrapperManualTrigger from "@/components/ocme/WrapperCard";
import LabelLog from "./LabelLog"; import LabelLog from "./LabelLog";
import Lots from "./Lots"; import Lots from "./Lots";
import OcpLogs from "./OcpLogs"; import OcpLogs from "./OcpLogs";
import PrinterStatus from "./PrinterStatus"; import PrinterStatus from "./PrinterStatus";
import { useSettingStore } from "@/lib/store/useSettings";
export default function OCPPage() { export default function OCPPage() {
const { settings } = useSettingStore();
const server = settings.filter((n) => n.plantToken === "usday1");
return ( return (
<div className="h-dvh w-full overflow-hidden"> <div className="h-dvh w-full overflow-hidden">
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
@@ -21,10 +26,17 @@ export default function OCPPage() {
</div> </div>
</div> </div>
</div> </div>
<div className="w-1/6"> <div className="w-1/6 flex flex-col">
{server && (
<div>
<WrapperManualTrigger />
</div>
)}
<div>
<PrinterStatus /> <PrinterStatus />
</div> </div>
</div> </div>
</div> </div>
</div>
); );
} }

View File

@@ -1,6 +1,14 @@
import { LstCard } from "@/components/extendedUI/LstCard"; import { LstCard } from "@/components/extendedUI/LstCard";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Skeleton } from "@/components/ui/skeleton"; import { Skeleton } from "@/components/ui/skeleton";
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table"; import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
let printerCols = [ let printerCols = [
{ {
@@ -19,7 +27,9 @@ let printerCols = [
export default function PrinterStatus() { export default function PrinterStatus() {
return ( return (
<LstCard className="m-2 p-2"> <LstCard className="m-2 p-2">
<ScrollArea className="max-h-[300px]">
<p className="text-center">Printer Status</p> <p className="text-center">Printer Status</p>
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow> <TableRow>
@@ -30,7 +40,7 @@ export default function PrinterStatus() {
</TableHeader> </TableHeader>
<TableBody> <TableBody>
{Array(10) {Array(5)
.fill(0) .fill(0)
.map((_, i) => ( .map((_, i) => (
<TableRow key={i}> <TableRow key={i}>
@@ -47,6 +57,7 @@ export default function PrinterStatus() {
))} ))}
</TableBody> </TableBody>
</Table> </Table>
</ScrollArea>
</LstCard> </LstCard>
); );
} }

View File

@@ -13,7 +13,7 @@ export function getlabels(hours: string) {
} }
const fetchSettings = async (hours: string) => { const fetchSettings = async (hours: string) => {
const {data} = await axios.get(`/api/v1/ocp/labels?hours=${hours}`); const { data } = await axios.get(`/api/ocp/getlabels?hours=${hours}`);
// if we are not localhost ignore the devDir setting. // if we are not localhost ignore the devDir setting.
//const url: string = window.location.host.split(":")[0]; //const url: string = window.location.host.split(":")[0];
return data.data ?? []; return data.data ?? [];

View File

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

View File

@@ -18,8 +18,15 @@ export const triggerScanner = async () => {
} }
const scannerData = JSON.parse(setting[0]?.value); const scannerData = JSON.parse(setting[0]?.value);
let data = scannerData.filter((n: any) => n.name === "wrapper1"); let data = scannerData.filter((n: any) => n.name === "wrapper1");
let port = data[0].port;
console.log(data); if (data.length === 0) {
return {
success: false,
message: "Looks like the scanner is missing.",
};
}
let port = data[0]?.port;
createLog( createLog(
"info", "info",
"wrapperScanner", "wrapperScanner",

View File

@@ -17,9 +17,12 @@ app.openapi(
async (c) => { async (c) => {
// make sure we have a vaid user being accessed thats really logged in // make sure we have a vaid user being accessed thats really logged in
apiHit(c, { endpoint: "api/auth/register" }); apiHit(c, { endpoint: "api/auth/register" });
const manualTrigger = await triggerScanner(); const manualTrigger: any = await triggerScanner();
console.log(manualTrigger); console.log(manualTrigger);
return c.json({ success: true, message: "Manual triggered" }); return c.json({
success: manualTrigger.success,
message: manualTrigger.message,
});
} }
); );
export default app; export default app;

View File

@@ -0,0 +1,32 @@
import { desc, lte, sql } from "drizzle-orm";
import { db } from "../../../../../database/dbclient.js";
import { prodlabels } from "../../../../../database/schema/prodLabels.js";
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
export const getLabels = async (hours: string) => {
const { data: labelInfo, error: labelError } = await tryCatch(
db
.select()
.from(prodlabels)
.where(
lte(
prodlabels.upd_date,
sql.raw(`NOW() - INTERVAL '${hours} hours'`)
)
)
.orderBy(desc(prodlabels.upd_date))
);
if (labelError) {
return {
success: false,
message: "There was an error getting the labels",
data: labelError,
};
}
return {
success: true,
message: "Current labels order by upd_Date.",
data: labelInfo,
};
};

View File

@@ -0,0 +1,68 @@
import { db } from "../../../../../database/dbclient.js";
import { settings } from "../../../../../database/schema/settings.js";
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
import { createLog } from "../../../logger/logger.js";
import { query } from "../../../sqlServer/prodSqlServer.js";
import { prolinkQuery } from "../../../sqlServer/querys/ocp/prolinkCheck.js";
// check the if the lot matches
export const prolinkCheck = async (lot: any) => {
const { data, error: settingError } = await tryCatch(
db.select().from(settings)
);
if (settingError) {
createLog(
"error",
"ocp",
"ocp",
`There was an error getting the settings.`
);
return;
}
const settingData: any = data;
const plantToken = settingData.filter(
(s: any) => s.name === "plantToken"
)[0].value;
const prolinkCheck = settingData.filter(
(s: any) => s.name === "prolinkCheck"
)[0].value;
// if we want to ignore prolink check it will be disabled and then just return a pass as true
if (prolinkCheck === "0") {
createLog(
"info",
"ocp",
"ocp",
`Prolink Check is disabled skipping check.`
);
return true;
}
// run the query
try {
const prolink = await query(prolinkQuery, "Prolink Checks");
//console.log(lot);
// filter out the lot
const filterdLot = prolink.filter(
(p: any) => p.AlplaLabelOnline === lot
);
//console.log(filterdLot);
if (filterdLot[0].LotCheck === "Good") {
return true;
} else {
return false;
}
} catch (err) {
createLog(
"error",
"ocp",
"ocp",
`Error from running the Prolink Check query: ${err}`
);
return false;
}
};

View File

@@ -8,6 +8,7 @@ import { settings } from "../../../database/schema/settings.js";
import updateprinters from "./routes/printers/updatePrinters.js"; import updateprinters from "./routes/printers/updatePrinters.js";
import { updatePrinters } from "./controller/printers/updatePrinters.js"; import { updatePrinters } from "./controller/printers/updatePrinters.js";
import getLots from "./routes/lots/getLots.js"; import getLots from "./routes/lots/getLots.js";
import getLabels from "./routes/labeling/getLabels.js";
const app = new OpenAPIHono(); const app = new OpenAPIHono();
@@ -18,6 +19,8 @@ const routes = [
updateprinters, updateprinters,
// lots // lots
getLots, getLots,
// labeling
getLabels,
] as const; ] as const;
const setting = await db.select().from(settings); const setting = await db.select().from(settings);
@@ -33,6 +36,8 @@ app.all("/ocp/*", (c) => {
}); });
// run the printer update on restart just to keep everything good // run the printer update on restart just to keep everything good
setTimeout(() => {
updatePrinters(); updatePrinters();
}, 3 * 1000);
export default app; export default app;

View File

@@ -0,0 +1,37 @@
// an external way to creating logs
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
import { responses } from "../../../../globalUtils/routeDefs/responses.js";
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
import { getLabels } from "../../controller/labeling/getLabels.js";
const app = new OpenAPIHono({ strict: false });
app.openapi(
createRoute({
tags: ["ocp"],
summary: "Returns current active lots that are tech released",
method: "get",
path: "/getlabels",
responses: responses(),
}),
async (c) => {
const hours = c.req.query("hours");
const { data: labelData, error: labelError } = await tryCatch(
getLabels(hours ?? "2")
);
if (labelError) {
return c.json({
success: false,
message: "There was an error getting the printers",
});
}
return c.json({
success: labelData.success,
message: labelData.message,
data: labelData.data,
});
}
);
export default app;

View File

@@ -0,0 +1,25 @@
export const prolinkQuery = `
select * from (
select *
From(select
V_Maschinen_ProdPlanungen.MaschinenStandort as Machine,
V_Maschinen_ProdPlanungen.IdProdPlanung as AlplaLabelOnline,
prolink.lot Prolink,
case when AlplaPROD_test1.dbo.V_Maschinen_ProdPlanungen.IdProdPlanung <> prolink.lot
Then 'IncorrectLot'
Else 'Good' end as LotCheck
from AlplaPROD_test1.dbo.V_Maschinen_ProdPlanungen (nolock)
left join
(
SELECT *
FROM (SELECT IdMaschine,
Produktionslos as lot,
Startzeit as StartTime,
Upd_Date,
ROW_NUMBER() OVER (PARTITION BY IdMaschine ORDER BY Upd_Date DESC) RN_Prolink
FROM AlplaPROD_test1.dbo.T_HistoryProduktionsdaten (nolock)
WHERE Upd_Date BETWEEN DATEADD(DD, - 10, getdate()) AND DATEADD(DD, 1, getdate())) a
WHERE RN_Prolink = 1
) as prolink on AlplaPROD_test1.dbo.V_Maschinen_ProdPlanungen.IdMaschine=prolink.IdMaschine) a
) a
`;