feat(ocp): create and book in plus dyco controller implemented

This commit is contained in:
2025-03-26 22:07:19 -05:00
parent 878e650e62
commit 7a1a4773e7
23 changed files with 1233 additions and 40 deletions

View File

@@ -17,8 +17,9 @@ export const prodlabels = pgTable(
line: integer("line"),
runningNr: integer("runningNr").notNull(),
status: text("status"),
add_date: timestamp("add_date"),
upd_date: timestamp("upd_date"),
add_user: text("add_user").default("lst"),
add_date: timestamp("add_date").defaultNow(),
upd_date: timestamp("upd_date").defaultNow(),
},
(table) => [
//uniqueIndex("emailUniqueIndex").on(sql`lower(${table.email})`),

View File

@@ -73,7 +73,7 @@ export default function LabelLog() {
</div>
);
}
const labelData = data ? data : [];
return (
<LstCard className="m-2 p-2 min-h-2/5">
<p className="text-center">Labels for the last 2 hours</p>
@@ -113,7 +113,7 @@ export default function LabelLog() {
</>
) : (
<TableBody>
{data?.map((label: any) => (
{labelData.map((label: any) => (
<TableRow key={label.runningNr}>
<TableCell className="font-medium">
{label.line}

View File

@@ -0,0 +1,89 @@
import axios from "axios";
import { prodEndpointCreation } from "../../../../globalUtils/createUrl.js";
import { lstAuth } from "../../../../index.js";
import { createLog } from "../../../logger/logger.js";
import { db } from "../../../../../database/dbclient.js";
import { prodlabels } from "../../../../../database/schema/prodLabels.js";
import { eq, sql } from "drizzle-orm";
export const bookInLabel = async (data: any) => {
// update sscc so we can book in
const SSCC = data.SSCC.slice(2);
// api url
const url = await prodEndpointCreation("public/v1.0/Warehousing/BookIn");
// create bookin
const newBookin = {
scannerId: 777,
sscc: SSCC,
};
try {
const res = await axios.post(url, newBookin, {
headers: {
Authorization: `Basic ${lstAuth}`,
accept: "text/plain",
},
});
if (res.data.Result !== 0) {
createLog(
"error",
"labeling",
"ocp",
`${data.printer.name}, Error:${res.data.Message}`
);
//printerUpdate(data.printer, 7, "Error while booking in.");
return {
success: false,
message: "There was an error booking in the label.",
data: res.data,
};
}
// update the label.
try {
await db
.update(prodlabels)
.set({
status: "Booked in",
upd_date: sql`NOW()`,
})
.where(
eq(prodlabels.runningNr, parseInt(data.SSCC.slice(10, -1)))
);
} catch (error) {
createLog(
"error",
"labeling",
"ocp",
`Error creating new runningNumber in the DB.`
);
}
// label was booked in
createLog(
"info",
"labeling",
"ocp",
`${parseInt(data.SSCC.slice(10, -1))}, was just booked in`
);
return {
success: true,
message: `${parseInt(data.SSCC.slice(10, -1))}, was just booked in`,
};
} catch (error) {
createLog(
"error",
"labeling",
"ocp",
`${data.printer.name}, "Error: ${error}`
);
return {
success: false,
message: "There was an error booking in the label.",
data: error,
};
}
};

View File

@@ -0,0 +1,158 @@
import { eq, gte, sql } from "drizzle-orm";
import { db } from "../../../../../database/dbclient.js";
import { printers } from "../../../../../database/schema/printers.js";
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
import { createLog } from "../../../logger/logger.js";
import { prodEndpointCreation } from "../../../../globalUtils/createUrl.js";
import { settings } from "../../../../../database/schema/settings.js";
import { lstAuth } from "../../../../index.js";
import axios from "axios";
import { prodlabels } from "../../../../../database/schema/prodLabels.js";
export const createLabel = async (data: any, userPrinted: any) => {
createLog("info", "labeling", "ocp", `Label being created`);
const { data: printer, error: printerError } = await tryCatch(
db
.select()
.from(printers)
.where(eq(printers.humanReadableId, data.printerID))
);
const { data: settingsData, error: settingsError } = await tryCatch(
db.select().from(settings)
);
if (printerError) {
return {
success: false,
message: "There was an error getting the printer.",
printerError,
};
}
if (settingsError) {
return {
success: false,
message: "There was an error getting the printer.",
settingsError,
};
}
const url = await prodEndpointCreation(
"/public/v1.0/Warehousing/GenerateAndPrintLabelExtended"
);
const plantToken = settingsData.filter((n) => n.name === "plantToken");
const newLabel = {
scannerId: 99,
lotNr: data.LOT,
machineId: data.machineID,
printerId: data.printerID,
//layoutId: cartonCustomers.includes(data.CustomerId.toString()) ? data.cartonLabel : data.palletLabel,
layoutId:
plantToken[0].value === "usksc1"
? data.cartonLabel
: data.palletLabel,
//numberOfCopies: cartonCustomers.includes(data.CustomerId.toString()) ? data.cartonCopies : data.pallerCopies,
numberOfCopies:
plantToken[0].value === "usksc1"
? data.cartonCopies
: data.pallerCopies,
};
// create the label
// create the label with the data we have
try {
const res = await axios.post(url, newLabel, {
headers: {
Authorization: `Basic ${lstAuth}`,
"Content-Type": "application/json",
},
});
// error handling
if (res.data.Result != 0) {
createLog(
"error",
"labeling",
"ocp",
`${data.MachineDescription}, has an error while printing: Error: ${res.data.Message}.`
);
return {
success: false,
mesasge: `${data.MachineDescription}, has an error while printing`,
data: res.data,
};
}
// save the data to lst db (only saved for x time see the db clean up functions)
let newlabel = res.data;
try {
await db.insert(prodlabels).values({
printerID: parseInt(printer[0]?.humanReadableId!, 10),
runningNr: parseInt(newlabel.SSCC.slice(10, -1)),
printerName: printer[0].name.toLowerCase(),
line: data.MachineLocation,
status: "printed",
add_user: userPrinted || "LST_System",
});
} catch (error) {
createLog(
"error",
"labeling",
"ocp",
`Error creating new runningNumber in the DB.`
);
}
createLog(
"info",
"labeling",
"ocp",
`New label was created for: ${
data.MachineDescription
}, Running number: ${parseInt(newlabel.SSCC.slice(10, -1))}`
);
const returnData = {
...newlabel,
printer,
};
// check if we can remove labels or not
deleteLabels();
return { sucess: true, message: "Label created", data: returnData }; // returning label data to be able to book in if active
} catch (error) {
createLog(
"info",
"labeling",
"ocp",
`${printer[0].name}, "Error: ${error}`
);
return {
success: false,
message: "There was an error creating the label",
data: error,
};
}
};
// run the label delete process we want to delate them older than 90 days right now
const deleteLabels = async () => {
/**
* Deletes labels older than 90 days from lst... all label data can be found in alpla prod.
*/
try {
await db
.delete(prodlabels)
.where(
gte(prodlabels.upd_date, sql.raw(`NOW() - INTERVAL '90 days'`))
);
} catch (error) {
createLog(
"error",
"labeling",
"ocp",
`Error deleting labels older than 90 days`
);
}
};

View File

@@ -20,7 +20,7 @@ export const getLabels = async (hours: string) => {
return {
success: false,
message: "There was an error getting the labels",
data: labelError,
data: [labelError],
};
}

View File

@@ -0,0 +1,236 @@
import { eq } from "drizzle-orm";
import { db } from "../../../../../database/dbclient.js";
import { printers } from "../../../../../database/schema/printers.js";
import { settings } from "../../../../../database/schema/settings.js";
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
import { createLog } from "../../../logger/logger.js";
import { getLots } from "../lots/lots.js";
import { getMac } from "../specialProcesses/utils/getMachineId.js";
import { billingCheck } from "../specialProcesses/billingCheck/billingCheck.js";
import { isMainMatStaged } from "../materials/mainMaterial.js";
import { firstLotLabel } from "../specialProcesses/lotChangeLabel/lotCHangeLabel.js";
import { prolinkCheck } from "../lots/prolinkCheck.js";
import { createLabel } from "./createLabel.js";
import { bookInLabel } from "./bookIn.js";
import { delieryInhouse } from "../specialProcesses/inhouse/inhouseDelivery.js";
interface Printer {
name: string;
// Add any other expected properties
}
export const labelingProcess = async ({
line = null as string | null,
printer = null as Printer | null,
userPrinted = null,
rfidTag = null,
} = {}) => {
/**
* Creates a label once all logic is passed
*/
let filteredLot: any = [];
createLog("debug", "labeling", "ocp", `Starting labeling process`);
const { data: settingData, error: settingError } = await tryCatch(
db.select().from(settings)
);
if (settingError) {
return {
success: false,
message: "There was an error getting the settings.",
settingError,
};
}
// get the plantToken
const plantToken = settingData.filter((n) => n.name === "plantToken");
// get the current lots
const lots = await getLots();
// if we got a line passed over we need to get the machine id from this.
if (line) {
const macId = await getMac(line);
// filter out the lot for the line
filteredLot = lots.data.filter((l: any) => l.machineId === macId);
if (filteredLot.length === 0) {
createLog(
"error",
"labeling",
"ocp",
`There is not a lot assigned to ${macId[0].Name}.`
);
return {
success: false,
message: `There is not a lot assigned to ${macId[0].Name}.`,
};
}
}
// if we came from a printer
if (printer) {
// filter the lot based on the printerID
// console.log(printer);
filteredLot = lots.data.filter((l: any) => l.printerID === printer);
if (filteredLot.length === 0) {
// console.log(`There is not a lot assigned to ${printer.name}`);
createLog(
"error",
"labeling",
"ocp",
`There is not a lot assigned to ${printer.name}`
);
//printerUpdate(printer, 7, `There is no lot assigned to this printer.`);
return {
success: false,
message: `There is not a lot assigned to ${printer.name}.`,
};
}
}
/**
*
* The checks we do before we can actually print a label will take place meow.
*
*/
// if the plant does not want to have dual printing and we have >2 assigned well return and send error.
let dualPrinting = settingData.filter((d) => d.name === "dualPrinting")[0]
?.value;
if (filteredLot.length > 1 && dualPrinting === "0") {
createLog(
"error",
"labeling",
"ocp",
`${printer?.name}, has more than one lot assigned to it, and dual printing shut off.`
);
return {
success: false,
message: `${printer?.name}, has more than one lot assigned to it, and dual printing shut off.`,
};
}
if (filteredLot.length > 1 && dualPrinting === "1") {
// send over for dual printing processing
createLog(
"info",
"labeling",
"ocp",
`${printer?.name}, being sent over for dual printing processing.`
);
// process what line to print the label for and return the lot info and change filteredLot to returned one.
//filteredLot = await dualPrintingProcess(filteredLot);
}
// if there are more than 2 lots it might be an auto labeler, autolabeler will be defined by its id for now only dayton
if (filteredLot.length > 2 && plantToken[0].value !== "usday1") {
createLog(
"error",
"labeling",
"ocp",
`${printer?.name}, has more than 2 lot assigned to it, and not in ${plantToken[0].value}`
);
return {
success: false,
message: `${printer?.name}, has more than 2 lot assigned to it, and not in ${plantToken[0].value}`,
};
}
// special process for florence
const isBillingTime = await billingCheck();
if (isBillingTime) {
// billing is inside the window we dont want to bill now.
return {
success: false,
message: "Billing time cant print.",
};
}
// check mm is good
const mmStaged = await isMainMatStaged(filteredLot[0]);
if (!mmStaged) {
createLog(
"error",
"labeling",
"ocp",
`Main material is not prepaired for lot ${filteredLot[0].lot}`
);
return;
}
// comment only but will check for color
createLog(
"info",
"labeling",
"ocp",
`Remaining pallets for: ${filteredLot[0].MachineDescription} is ${filteredLot[0].Remaining}`
);
// do we want to over run
if (filteredLot[0].overPrinting === "no" && filteredLot[0].Remaining <= 0) {
createLog(
"error",
"labeling",
"ocp",
`Over Printing on ${filteredLot[0].MachineDescription} is not allowed please change the lot`
);
// for slc we want to run the first label for henkel
firstLotLabel(filteredLot[0]);
return {
success: false,
message: `Over Printing on ${filteredLot[0].MachineDescription} is not allowed please change the lot`,
};
}
// prolink check by lot
const prolink = await prolinkCheck(filteredLot[0].lot);
if (!prolink) {
//console.error(`Prolink does not match for ${filteredLot[0].MachineDescription}`);
createLog(
"error",
"labeling",
"ocp",
`Prolink does not match for ${filteredLot[0].MachineDescription}`
);
return;
}
createLog("info", "labeling", "ocp", `Is prolink good? ${prolink}`);
// create the label
const label = await createLabel(filteredLot[0], userPrinted);
if (!label.success) {
return { sucess: false, message: label.message, data: label.data };
}
// send over to be booked in if we can do it.
const bookin = settingData.filter((s) => s.name === "bookin");
if (bookin[0].value === "1") {
const book = await bookInLabel(label.data);
} else {
createLog("info", "labeling", "ocp", "Bookin is turned off.");
// will add later!!! :P
}
// inhouse - if the inhouse funtion is turned on we will deliver to inhouse as long as we did not hit an error state
const inhouseDelivery = settingData.filter(
(s) => s.name === "inhouseDelivery"
);
if (inhouseDelivery[0].value === "1") {
const deliverPallet = await delieryInhouse(label);
}
return {
success: true,
message: "Label fully processed.",
data: label.data,
};
};

View File

@@ -0,0 +1,38 @@
import { createLog } from "../../../logger/logger.js";
import { query } from "../../../sqlServer/prodSqlServer.js";
import { mmQuery } from "../../../sqlServer/querys/ocp/mainMaterial.js";
export const isMainMatStaged = async (lot: any) => {
// make staged false by deefault and error logged if theres an issue
let isStaged = false;
// strangly the lot is not always sending over in slc so adding this in for now to see what line is cauing this issue
if (!lot) {
return isStaged;
}
const updateQuery = mmQuery.replaceAll("[lotNumber]", lot.lot);
try {
const res = await query(updateQuery, "Main Material Check");
createLog(
"info",
"mainMaterial",
"ocp",
`MainMaterial results: ${JSON.stringify(res)}`
);
if (res[0].Staged >= 1) {
isStaged = true;
}
} catch (err) {
createLog(
"error",
"mainMaterial",
"ocp",
`Error from running the Main Material query: ${err}`
);
}
return isStaged;
};

View File

@@ -73,7 +73,7 @@ export const updatePrinters = async () => {
);
}
createLog(
"info",
"debug",
"lst",
"ocp",
`${prodPrinterInfo[i].name} were just added/updated.`

View File

@@ -0,0 +1,54 @@
import { eq } from "drizzle-orm";
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";
const st = 5;
const sm = 55;
const et = 6;
const em = 5;
export const billingCheck = async () => {
const now = new Date();
const startTime = new Date();
const endTime = new Date();
let isOutsideBilling = false;
const { data, error } = await tryCatch(db.select().from(settings));
if (error) {
return { success: false, message: "Error in getting settings." };
}
const plant = data.filter((n) => n.name === "plantToken");
// set everything up
startTime.setHours(st, sm, 0, 0);
endTime.setHours(et, em, 0, 0);
if (plant[0].value === "usflo1") {
if (now >= startTime && now <= endTime) {
createLog(
"warn",
"specialProcess",
"ocp",
`You are inside the billing window no labels will print! please wait`
);
isOutsideBilling = true;
} else {
createLog(
"info",
"specialProcess",
"ocp",
"Out side billing window ok to print"
);
}
} else {
createLog(
"debug",
"specialProcess",
"ocp",
"This plant dose not check for billing"
);
}
return isOutsideBilling;
};

View File

@@ -0,0 +1,76 @@
import { Controller, Tag } from "st-ethernet-ip";
import { createLog } from "../../../../logger/logger.js";
import { labelerTagRead } from "./plcTags/labelerTag.js";
import { palletSendTag } from "./plcTags/palletSendTag.js";
let PLC = new Controller();
let isDycoRunning = false;
// PLC address
let plcAddress = "10.44.5.4";
// Initialize the interval variable outside the function
let plcCycle: any;
let plcInterval = 500;
// Create Tag Instances
const labelerTag: any = new Tag("labeler.line_info");
const palletSend = new Tag("Zone_6.Ready_to_Send");
const strapperError = new Tag("Zone_3.Strapper_Faulted");
export const dycoConnect = async () => {
// if we crash or start over reset the timers so we dont get duplicates
clearInterval(plcCycle);
if (isDycoRunning)
return { success: false, message: "Dyco is already connected." };
// Remove all listeners before adding a new one to prevent memory leaks
PLC.removeAllListeners("error");
try {
await PLC.connect(plcAddress, 0).then(async () => {
createLog("info", "dyco", "ocp", `We are connected to the dyco.`);
isDycoRunning = true;
let buffer = "";
plcCycle = setInterval(async () => {
await PLC.readTag(labelerTag);
await PLC.readTag(palletSend);
// send the labeler tag data over
labelerTagRead(labelerTag);
// send the end of line check over.
palletSendTag(palletSend);
}, 500);
});
} catch (error) {
createLog(
"error",
"dyco",
"ocp",
`There was an error in the dyco: ${error}`
);
isDycoRunning = false;
}
};
export const closeDyco = async () => {
if (!isDycoRunning)
return { success: false, message: "Dyco is not connected." };
console.log(`Closing the connection`);
try {
await PLC.disconnect();
isDycoRunning = false;
return {
success: true,
message: "Dyco Connection is now closed.",
};
} catch (error) {
console.log(error);
return {
success: false,
message: "There was an error closing the dyco connection.",
};
}
};

View File

@@ -0,0 +1,66 @@
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 { readTags } from "../../../../../rfid/controller/readTags.js";
import { labelingProcess } from "../../../labeling/labelProcess.js";
let lastProcessedTimestamp = 0;
export const labelerTagRead = async (tagData: any) => {
/**
* Reads the tag data from the Dyco PLC and processes it based on the feedback.
*/
// Convert tag data buffer to a string and extract numeric values
const buffer = Buffer.from(tagData.value);
const numericString = buffer.toString("utf8").replace(/[^0-9#]/g, "");
// Ignore empty or invalid tag data
if (numericString === "#") {
return;
}
const tagTime = new Date(tagData.state.timestamp).getTime();
// get the settings
const { data: settingData, error: settingError } = await tryCatch(
db.select().from(settings)
);
if (settingError) {
createLog(
"error",
"dyco",
"ocp",
"There was an error getting the settings"
);
return;
}
// check the dyco settings
const dycoPrint = settingData.filter((n) => n.name === "dycoPrint");
// Only process if this is a new timestamp within the last 5 seconds
if (tagTime !== lastProcessedTimestamp && Date.now() - tagTime <= 5000) {
lastProcessedTimestamp = tagTime;
//console.log(numericString, tagData.state.timestamp);
if (dycoPrint[0].value === "1") {
createLog("info", "dyco", "ocp", "Dyco will be printing the label");
// send over to print.
labelingProcess({ line: numericString });
}
if (dycoPrint[0].value === "0") {
createLog(
"info",
"dyco",
"ocp",
"Rfid system is contorlling the printing"
);
// trigger the reader so we can get the label from the tag readers.
await readTags("wrapper1");
}
}
};
/**
* setting to switch between rfid and dyco labeling
*/

View File

@@ -0,0 +1,54 @@
import { createLog } from "../../../../../logger/logger.js";
import { pickedup } from "../../../../../ocme/controller/pickedup.js";
import { triggerScanner } from "../../../../../ocme/controller/triggerCamera.js";
let lastProcessedTimestamp = 0;
export const palletSendTag = async (tagData: any) => {
/**
* Reads the tag data from the Dyco PLC and processes it based on the feedback.
* We will only trigger the camera and removal of pending tags
*/
const tagTime = new Date(tagData.state.timestamp).getTime();
// Only process if this is a new timestamp within the last 5 seconds
if (
tagTime !== lastProcessedTimestamp &&
Date.now() - tagTime <= 5000 &&
tagData.value
) {
lastProcessedTimestamp = tagTime;
//console.log(tagData.state.timestamp);
createLog(
"info",
"dyco",
"ocp",
`Station 6 is ${tagData.value ? "full" : "empty"}`
);
// take the picture
setTimeout(async () => {
const scan: any = await triggerScanner();
if (!scan.success) {
createLog(
"error",
"dyco",
"ocp",
`Scanner failed to take a picture trying one more time in 10 seconds`
);
setTimeout(async () => {
await triggerScanner();
}, 10 * 1000);
}
}, 15 * 1000);
}
if (
tagTime !== lastProcessedTimestamp &&
Date.now() - tagTime <= 5000 &&
!tagData.value
) {
await pickedup({ runningNr: 1234, all: true });
}
};

View File

@@ -0,0 +1,91 @@
import axios from "axios";
import { prodEndpointCreation } from "../../../../../globalUtils/createUrl.js";
import { lstAuth } from "../../../../../index.js";
import { createLog } from "../../../../logger/logger.js";
import { db } from "../../../../../../database/dbclient.js";
import { prodlabels } from "../../../../../../database/schema/prodLabels.js";
import { eq, sql } from "drizzle-orm";
export const delieryInhouse = async (data: any) => {
// update sscc so we can book in
const SSCC = data.SSCC.slice(2);
// api url
const url = await prodEndpointCreation(
"/public/v1.0/Warehousing/InhouseDelivery"
);
// create bookin
const newDelivery = {
scannerId: 99,
sscc: SSCC,
};
try {
const res = await axios.post(url, newDelivery, {
headers: {
Authorization: `Basic ${lstAuth}`,
accept: "text/plain",
},
});
if (res.data.Result !== 0) {
createLog(
"error",
"labeling",
"ocp",
`${data.printer.name}, Error:${res.data.Message}`
);
//printerUpdate(data.printer, 7, "Error while deliverying inhouse.");
return {
success: true,
message: `${data.printer.name} had an error while trying to deliver.`,
data: res.data,
};
} // label was just delivered
createLog(
"info",
"labeling",
"ocp",
`${parseInt(data.SSCC.slice(10, -1))}, was just delivered`
);
try {
await db
.update(prodlabels)
.set({
status: "Delivered",
upd_date: sql`NOW()`,
})
.where(
eq(prodlabels.runningNr, parseInt(data.SSCC.slice(10, -1)))
);
} catch (error) {
createLog(
"error",
"labeling",
"ocp",
`Error updating ${parseInt(data.SSCC.slice(10, -1))} in the DB.`
);
return {
success: true,
message: `Error updating ${parseInt(
data.SSCC.slice(10, -1)
)} in the DB.`,
data: error,
};
}
} catch (error) {
createLog(
"error",
"labeling",
"ocp",
`${data.printer.name}, "Error: ${error}`
);
return {
success: true,
message: `Error deliverying ${parseInt(data.SSCC.slice(10, -1))}.`,
data: error,
};
}
};

View File

@@ -0,0 +1,72 @@
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";
export const firstLotLabel = async (lot: any) => {
/*
currently this is only requested by slc
when a lot is finished and not set to over run we will trigger this function to insert data into the custom T_firstLotLabel table.
in nice label we look for unique id to run the process and then if the add date is older than 7 days we delete it for tracablility purpose.
we will also only do this for specific customers currently henkel is the requested.
*/
/* work on the server side
new table created in the _cus db
CREATE TABLE T_firstLotLabel
(
ID INT IDENTITY(1,1) PRIMARY KEY,
printerName varchar(max),
add_date datetime
-- Add other columns here as needed
);
the nicelabel trigger to be activated.
*/
const { data: settingData, error: settingError } = await tryCatch(
db.select().from(settings)
);
if (settingError) {
return {
success: false,
message: "There was an error getting the settings.",
settingError,
};
}
// get the plantToken
const plantToken = settingData.filter((n) => n.name === "plantToken");
createLog(
"info",
"ocp",
"ocp",
`Checking if we can create the first label lot.`
);
if (plantToken[0].value === "usslc1") {
const newLabel = `insert into T_firstLotLabel (printerName, add_date) VALUES('${lot.PrinterName}', getdate())`;
// if (lot.CustomerId === 40) {
createLog(
"info",
"ocp",
"ocp",
`Creating first lot label for ${lot.MachineDescription}`
);
await query(newLabel, "newLotLabel");
createLog(
"info",
"ocp",
"ocp",
`Was created for ${lot.MachineDescription}`
);
//}
} else {
return;
}
};

View File

@@ -0,0 +1,27 @@
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 { machineCheck } from "../../../../sqlServer/querys/ocp/machineId.js";
export const getMac = async (machine: string) => {
let updateQuery = machineCheck.replaceAll("[loc]", machine);
// create blank lots in case there is an error and dose not work
let mac = [];
try {
mac = await query(updateQuery, "Machine id check");
// console.log("Machine data", mac); // removed due to swr being activated
} catch (err) {
createLog(
"error",
"lst",
"ocp",
`Error with Machine id Check query: ${err}`
);
}
return mac;
};

View File

@@ -9,6 +9,9 @@ import updateprinters from "./routes/printers/updatePrinters.js";
import { updatePrinters } from "./controller/printers/updatePrinters.js";
import getLots from "./routes/lots/getLots.js";
import getLabels from "./routes/labeling/getLabels.js";
import { dycoConnect } from "./controller/specialProcesses/dyco/plcConnection.js";
import dycoCon from "./routes/specialProcesses/dyco/connection.js";
import dycoClose from "./routes/specialProcesses/dyco/closeConnection.js";
const app = new OpenAPIHono();
@@ -21,6 +24,9 @@ const routes = [
getLots,
// labeling
getLabels,
//dyco
dycoCon,
dycoClose,
] as const;
const setting = await db.select().from(settings);
@@ -40,4 +46,9 @@ setTimeout(() => {
updatePrinters();
}, 3 * 1000);
// do the intnal connection to the dyco
setTimeout(() => {
dycoConnect();
}, 3 * 1000);
export default app;

View File

@@ -0,0 +1,56 @@
// an external way to creating logs
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
import { responses } from "../../../../../globalUtils/routeDefs/responses.js";
import { authMiddleware } from "../../../../auth/middleware/authMiddleware.js";
import { tryCatch } from "../../../../../globalUtils/tryCatch.js";
import { closeDyco } from "../../../controller/specialProcesses/dyco/plcConnection.js";
const app = new OpenAPIHono({ strict: false });
app.openapi(
createRoute({
tags: ["ocp:dyco"],
summary: "Disconnect to the dyco.",
method: "get",
path: "/dycodisconnect",
middleware: authMiddleware,
description:
"Use this when you just want to stop the entire thing due to an error or what not.",
// request: {
// body: {content: {"application/json": {schema: CreateLog}}},
// },
responses: responses(),
}),
async (c) => {
//const body = await c.req.json();
//apiHit(c, {endpoint: `api/logger/logs/id`});
// const authHeader = c.req.header("Authorization");
// const token = authHeader?.split("Bearer ")[1] || "";
// let user: User;
// try {
// const payload = await verify(token, process.env.JWT_SECRET!);
// user = payload.user as User;
// } catch (error) {
// console.log(error);
// return c.json({message: "Unauthorized"}, 401);
// }
const { data, error } = await tryCatch(closeDyco());
if (error) {
return c.json({
success: false,
message: "Error in connecting to dyco",
data: error,
});
}
const getData: any = data;
return c.json({
success: getData?.success,
message: getData?.message,
});
}
);
export default app;

View File

@@ -0,0 +1,56 @@
// an external way to creating logs
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
import { responses } from "../../../../../globalUtils/routeDefs/responses.js";
import { authMiddleware } from "../../../../auth/middleware/authMiddleware.js";
import { tryCatch } from "../../../../../globalUtils/tryCatch.js";
import { dycoConnect } from "../../../controller/specialProcesses/dyco/plcConnection.js";
const app = new OpenAPIHono({ strict: false });
app.openapi(
createRoute({
tags: ["ocp:dyco"],
summary: "Connects to the dyco.",
method: "get",
path: "/dycoconnect",
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 body = await c.req.json();
//apiHit(c, {endpoint: `api/logger/logs/id`});
// const authHeader = c.req.header("Authorization");
// const token = authHeader?.split("Bearer ")[1] || "";
// let user: User;
// try {
// const payload = await verify(token, process.env.JWT_SECRET!);
// user = payload.user as User;
// } catch (error) {
// console.log(error);
// return c.json({message: "Unauthorized"}, 401);
// }
const { data, error } = await tryCatch(dycoConnect());
const dataError: any = error;
if (error) {
return c.json({
success: false,
message: "Error in connecting to dyco",
data: dataError?.data,
});
}
const getData: any = data;
return c.json({
success: getData?.success,
message: getData?.message,
data: getData.data ?? [],
});
}
);
export default app;

View File

@@ -1,8 +1,8 @@
import axios from "axios";
import {createLog} from "../../logger/logger.js";
import {db} from "../../../../database/dbclient.js";
import {rfidReaders} from "../../../../database/schema/rfidReaders.js";
import {eq} from "drizzle-orm";
import { createLog } from "../../logger/logger.js";
import { db } from "../../../../database/dbclient.js";
import { rfidReaders } from "../../../../database/schema/rfidReaders.js";
import { eq } from "drizzle-orm";
const authData = btoa("admin:Zebra123!");
let token: string;
@@ -12,10 +12,18 @@ export const readTags = async (reader: string) => {
/**
* Start the read for x seconds then auto stop it
*/
const readers = await db.select().from(rfidReaders).where(eq(rfidReaders.active, true));
createLog("info", "rfid", "rfid", `Read was just triggered from ${reader}`);
const readers = await db
.select()
.from(rfidReaders)
.where(eq(rfidReaders.active, true));
if (readers.length === 0) {
createLog("error", "rfid", "rfid", `There are no active readers right now maybe one forgot to be activated`);
createLog(
"error",
"rfid",
"rfid",
`There are no active readers right now maybe one forgot to be activated`
);
return;
}
// get the auth token
@@ -23,7 +31,7 @@ export const readTags = async (reader: string) => {
try {
const res = await axios.get(`https://${ip}/cloud/localRestLogin`, {
headers: {Authorization: `Basic ${authData}`},
headers: { Authorization: `Basic ${authData}` },
});
token = res.data.message;
// start the read
@@ -47,7 +55,7 @@ const startRead = async () => {
`https://${ip}/cloud/start`,
{},
{
headers: {Authorization: `Bearer ${token}`},
headers: { Authorization: `Bearer ${token}` },
}
);
@@ -67,7 +75,12 @@ const startRead = async () => {
startRead();
}, 1000);
}
createLog("error", "rfid", "rfid", `There was an error Starting the read: ${error.response.data.message}`);
createLog(
"error",
"rfid",
"rfid",
`There was an error Starting the read: ${error.response.data.message}`
);
}
};
const stopRead = async () => {
@@ -76,10 +89,15 @@ const stopRead = async () => {
`https://${ip}/cloud/stop`,
{},
{
headers: {Authorization: `Bearer ${token}`},
headers: { Authorization: `Bearer ${token}` },
}
);
} catch (error: any) {
createLog("error", "rfid", "rfid", `There was an error Stopping the read: ${error.response.data.message}`);
createLog(
"error",
"rfid",
"rfid",
`There was an error Stopping the read: ${error.response.data.message}`
);
}
};

View File

@@ -1,5 +1,5 @@
import {station3Tags} from "./stations/station3.js";
import {wrapperStuff} from "./stations/wrappers.js";
import { station3Tags } from "./stations/station3.js";
import { wrapperStuff } from "./stations/wrappers.js";
export type TagData = {
tagHex: string;
@@ -8,6 +8,7 @@ export type TagData = {
timeStamp: Date;
antenna: number;
tagStrength: number;
lastareaIn?: string;
};
export const tagData = async (data: TagData[]) => {
/**

View File

@@ -3,20 +3,41 @@
* this will only run on a server start up
*/
import {db} from "../../../../database/dbclient.js";
import {settings} from "../../../../database/schema/settings.js";
import { db } from "../../../../database/dbclient.js";
import { settings } from "../../../../database/schema/settings.js";
import {createLog} from "../../logger/logger.js";
import { createLog } from "../../logger/logger.js";
// "view", "technician", "supervisor","manager", "admin", "systemAdmin"
const newSettings = [
{name: "server", value: "localhost", description: "Where the app runs at", moduleName: "server"},
{name: "serverPort", value: "4400", description: "What are we listening on", moduleName: "server"},
{name: "dbUser", value: "alplaprod", description: "What is the db username", moduleName: "server"},
{name: "dbPass", value: "b2JlbGl4", description: "What is the db password", moduleName: "server"},
{
name: "server",
value: "localhost",
description: "Where the app runs at",
moduleName: "server",
},
{
name: "serverPort",
value: "4400",
description: "What are we listening on",
moduleName: "server",
},
{
name: "dbUser",
value: "alplaprod",
description: "What is the db username",
moduleName: "server",
},
{
name: "dbPass",
value: "b2JlbGl4",
description: "What is the db password",
moduleName: "server",
},
{
name: "tcpPort",
value: "2222",
description: "TCP port for printers to connect send data and the zedra cameras",
description:
"TCP port for printers to connect send data and the zedra cameras",
moduleName: "server",
},
{
@@ -59,13 +80,15 @@ const newSettings = [
{
name: "ocmeService",
value: "0",
description: "Is the ocme service enabled. this is gernerally only for Dayton.",
description:
"Is the ocme service enabled. this is gernerally only for Dayton.",
moduleName: "ocme",
},
{
name: "fifoCheck",
value: "45",
description: "How far back do we want to check for fifo default 45, putting 0 will ignore.",
description:
"How far back do we want to check for fifo default 45, putting 0 will ignore.",
moduleName: "ocme",
},
{
@@ -83,7 +106,8 @@ const newSettings = [
{
name: "monitorAddress",
value: "8",
description: "What address is monitored to be limited to the amount of lots that can be added to a truck.",
description:
"What address is monitored to be limited to the amount of lots that can be added to a truck.",
moduleName: "ocme",
},
{
@@ -96,7 +120,8 @@ const newSettings = [
{
name: "devDir",
value: "C:\\Users\\matthes01\\Documents\\lstv2",
description: "This is the dev dir and strictly only for updating the servers.",
description:
"This is the dev dir and strictly only for updating the servers.",
moduleName: "server",
},
{
@@ -116,7 +141,30 @@ const newSettings = [
{
name: "ocpLogsCheck",
value: "4",
description: "How long do we want to allow logs to show that have not been cleared?",
description:
"How long do we want to allow logs to show that have not been cleared?",
roles: "admin",
module: "ocp",
},
{
name: "inhouseDelivery",
value: "0",
description: "Are we doing auto inhouse delivery?",
roles: "admin",
module: "ocp",
},
// dyco settings
{
name: "dycoConnect",
value: "0",
description: "Are we running the dyco system?",
roles: "admin",
module: "ocp",
},
{
name: "dycoPrint",
value: "0",
description: "Are we using the dyco to get the labels or the rfid?",
roles: "admin",
module: "ocp",
},
@@ -129,16 +177,31 @@ export const areSettingsIn = async () => {
if (settingsCheck.length !== newSettings.length) {
try {
const newRole = await db
.insert(settings)
.values(newSettings)
.onConflictDoNothing() // this will only update the ones that are new :D
.returning({name: settings.name});
createLog("info", "lst", "server", "Settingss were just added due to missing them on server startup");
.insert(settings)
.values(newSettings)
.onConflictDoNothing() // this will only update the ones that are new :D
.returning({ name: settings.name });
createLog(
"info",
"lst",
"server",
"Settingss were just added due to missing them on server startup"
);
} catch (error) {
createLog("error", "lst", "server", "There was an error adding new roles to the db");
createLog(
"error",
"lst",
"server",
"There was an error adding new roles to the db"
);
}
}
} catch (error) {
createLog("error", "lst", "server", "There was an error getting or adding new Settingss");
createLog(
"error",
"lst",
"server",
"There was an error getting or adding new Settingss"
);
}
};

View File

@@ -0,0 +1,9 @@
export const machineCheck = `
SELECT [HumanReadableId]
,[Name]
,[Location]
,[Active]
,[ImportSource]
,[StagingMainMaterialMandatory]
FROM [test1_AlplaPROD2.0_Read].[masterData].[Machine] (nolock)
where Active = 1 and [Location] = [loc]`;

View File

@@ -0,0 +1,17 @@
export const mmQuery = `
SELECT lot.ProductionLotHumanReadableId,
case when SourcingState in (1, 2) then 1
when x.ProvidedAmount > 0 then 1
when x.EffectiveConsumption > 0 then 1
else 0 end as Staged,
x.ProvidedAmount as Provided,
x.EffectiveConsumption as consumption,
x.IsManualProcess as isManual,
MaterialHumanReadableId
FROM [test1_AlplaPROD2.0_Read].[issueMaterial].[MaterialDemand] x (nolock)
left join
[test1_AlplaPROD2.0_Read].[issueMaterial].[ProductionLot] as lot on
x.ProductionLotId = lot.Id
where lot.ProductionLotHumanReadableId = [lotNumber]
and IsMainMaterial = 1
`;