using HH.WCS.Mobox3.SXJK.api; using HH.WCS.Mobox3.SXJK.device; using HH.WCS.Mobox3.SXJK.dispatch; using HH.WCS.Mobox3.SXJK.models; using HH.WCS.Mobox3.SXJK.process; using HH.WCS.Mobox3.SXJK.util; using HH.WCS.Mobox3.SXJK.wms; using Newtonsoft.Json; using NLog.Fluent; using System; using System.Collections; using System.Collections.Generic; using System.Data.Odbc; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; using static EasyModbus.ModbusServer; using static HH.WCS.Mobox3.SXJK.api.WmsController; using static HH.WCS.Mobox3.SXJK.dispatch.WMSDispatch; using static HH.WCS.Mobox3.SXJK.dispatch.WMSDispatch.TrayRequestInStockData; using static HH.WCS.Mobox3.SXJK.util.Settings; using static HH.WCS.Mobox3.SXJK.wms.WCSHelper; using static System.Runtime.CompilerServices.RuntimeHelpers; namespace HH.WCS.Mobox3.SXJK.core { /// /// 定时轮询任务 /// internal class Monitor { internal static void CheckThirdOutWork() { //第三方读中间表 //var db= new SqlHelper().GetInstance("中间表的sql连接字符串"); // db.Queryable //读到了出库单,插入到我们的表 } internal static void CheckOutWork() { //读自己的中间表,我们自己的表有表有个字段计数,计数小于最大值,继续出库,一次生成一条任务 } internal static void CheckDevice() { //检测输送线状态 S7Helper.ReadStr("plc1", 100, 1, 8); S7Helper.ReadBit("plc1", 101, 1, 2); S7Helper.ReadInt("plc1", 102, 1, 6); //1 设备plc的ip deviceNo 自动建立连接 //2 设备对应的通讯项和线体类型(输送线入口、输送线出口、提升机的入口。。。。)起始读的偏移地址,写的偏移地址 //{ "deviceNo":"5","code":"9001","location":"F1CJ-SSX1-01","writeAddr900":0,"writeAddr905":-1,"writeAddr710":0,"readAddr901":2,"readAddr902":0,"lineType":1}, //3 通讯项自动读plc,读到的数据根据lineType做处理,自动创建任务或者更新任务状态(创建一个设备动作或任务动作,如果是任务动作有个线程去读) } /// /// 监听输送线,入库同步单入库 /// /// internal static void MonitorDevice() { var lineDeviceInfos = Settings.lineDeviceInfos.ToList(); foreach (var line in lineDeviceInfos) { // 1.查询输送线信息,货位托盘码 PipelineSignalInfo pipelineSignalInfo = WCSHelper.readPipelineInfo(line); if (pipelineSignalInfo != null) { // agv任务反馈,取托完成 = 1 if (pipelineSignalInfo.agvTaskFeedback == 1 || pipelineSignalInfo.agvTaskFeedback == 2) { // 清除AGV任务反馈 S7Helper.WriteInt(line.deviceNo, 101, line.writeAddr + 14, 0); LogHelper.Info("清除输送线【" + line.code + "】的AGV任务反馈", "输送线"); } // 指令已读,清除指令 if (pipelineSignalInfo.receiveInstruction == 2) { issueCommand(line, 0, 0, 0); LogHelper.Info("入库指令已读,清除入库指令", "输送线"); } else if (pipelineSignalInfo.receiveInstruction == 3) { issueCommand(line, 0, 0, 0); LogHelper.Info("退回指令已读,清除退回指令", "输送线"); } // 2.输送线线体光电 = 1 有托盘 if ( pipelineSignalInfo.linePhotoelectric == 1 ) { // 当前输送线只返回下层托盘码 string downTrayCode = pipelineSignalInfo.downTrayCode; if (downTrayCode != null && downTrayCode != "") { // 3.查询任务托盘码 string taskTrayCode = downTrayCode; List trayCodes = new List() { downTrayCode }; /*string upTrayCode = ContainerHelper.GetUpTrayCode(downTrayCode); // 上层托盘*/ string upTrayCode = pipelineSignalInfo.upTrayCode; if (upTrayCode != null && upTrayCode != "") { taskTrayCode = taskTrayCode + "," + upTrayCode; trayCodes.Add(upTrayCode); } // 4.查询托盘作业任务 WMSTask wmsTask = WMSHelper.GetWmsTaskByCntr(taskTrayCode); // 判断 1.线体type = 1(输送线入口接驳线体) 2.线体请求去向 = 1 3.托盘没有执行中的任务 if (line.type == 1 && pipelineSignalInfo.requestReadCode == 1 && wmsTask == null) { bool isAllow = true; string asnNo = null; // 预期入库单号 string orientSign = null; // 定向标识 定向 JD,非定向是 F // 5.查询托盘码是否在入库同步单中 List inStocks = new List(); foreach (var tray in trayCodes) { var cntrItemRels = ContainerHelper.GetCntrItemRel(tray); if (cntrItemRels != null && cntrItemRels.Count() > 0) { isAllow = false; LogHelper.Info("托盘码:" + tray + ",托盘已入库使用中", "Mobox"); break; } var inStockListChilds = WMSHelper.getInstockListChild(tray); if (inStockListChilds == null || inStockListChilds.Count == 0) { // 6.如果不是则调用托盘请求入库接口,查询托盘的物料信息,再进行入库 inStockListChilds = getInStockTrayInfo(tray); } if (inStockListChilds != null && inStockListChilds.Count > 0) { foreach (var child in inStockListChilds) { float weight = pipelineSignalInfo.weight / trayCodes.Count; float furWeight = WMSHelper.getFurWeight(child.LOTATT10); // 毛皮重量 child.F_NET_WEIGHT = weight - furWeight; asnNo = child.S_ASN_NO; orientSign = child.LOTATT18; inStocks.Add(child); } } else { isAllow = false; LogHelper.Info("托盘码:" + tray + ",未找到该托盘相关的入库单和请求入库信息", "Mobox"); break; } } // 判断该托盘满足入库条件 if (isAllow) { // 6.创建入库任务 Location startLoc = LocationHelper.GetLoc(line.localtion); Location endLoc = new Location() { S_CODE = "虚拟货位", S_AREA_CODE = "虚拟库区" }; if (startLoc != null) { wmsTask = new WMSTask() { S_CNTR_CODE = taskTrayCode, S_CODE = WMSHelper.GenerateTaskNo(), S_START_LOC = startLoc.S_CODE, S_START_AREA = startLoc.S_AREA_CODE, S_END_LOC = endLoc.S_CODE, S_END_AREA = endLoc.S_AREA_CODE, S_TYPE = "入库任务", S_OP_DEF_CODE = asnNo, S_OP_DEF_NAME = "入库同步单", T_START_TIME = DateTime.Now, }; if (WMSHelper.CreateWmsTask(wmsTask)) { // 5.创建容器并绑定物料信息 foreach (var order in inStocks) { BindCntrItemRel(order); } LogHelper.Info("开始下发输送线指令,作业任务号:" + wmsTask.S_CODE + ",目标地址:" + line.descLine + ",指令入库 = 2", "输送线"); issueCommand(line, int.Parse(wmsTask.S_CODE.Substring(7)), (short)line.descLine, 2); LogHelper.Info("开始下发输送线指令成功", "输送线"); } } } else { LogHelper.Info("托盘入库条件不满足,开始下发输送线退回指令", "输送线"); issueCommand(line, 0, (short)line.descLine, 3); LogHelper.Info("托盘入库条件不满足,下发输送线退回指令成功", "输送线"); } } // 判断 1.线体type = 2(输送线出口接驳线体) 2.存在该托盘的作业任务且状态为等待 if (line.type == 2 && wmsTask != null && wmsTask.N_B_STATE == 0 && wmsTask.S_TYPE == "入库任务") { var cntrItemRel = ContainerHelper.GetCntrItemRel(trayCodes[0]).FirstOrDefault(); if (cntrItemRel != null) { string asnNo = cntrItemRel.S_ASN_NO; string orientSign = cntrItemRel.LOTATT18; Location endLoc = WMSHelper.getEndLocation(orientSign, asnNo, 2); //trayCodes.Count() if (endLoc != null) { WCSTask wcsTask = new WCSTask { S_OP_CODE = wmsTask.S_CODE, S_OP_NAME = wmsTask.S_OP_DEF_NAME, S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = wmsTask.S_TYPE, S_START_LOC = wmsTask.S_START_LOC, S_START_AREA = wmsTask.S_START_AREA, S_END_LOC = endLoc.S_CODE, S_END_AREA = endLoc.S_AREA_CODE, S_CNTR_CODE = taskTrayCode, N_CNTR_COUNT = trayCodes.Count, S_SCHEDULE_TYPE = "国自", T_START_TIME = DateTime.Now, }; if (WCSHelper.CreateTask(wcsTask)) { // 对终点货位进行加锁 LocationHelper.LockLoc(wcsTask.S_END_LOC, 1, asnNo); LocationHelper.LockLoc(wcsTask.S_START_LOC, 2, asnNo); ContainerHelper.deleteTrayRelation(downTrayCode); wmsTask.N_B_STATE = 1; wmsTask.S_END_LOC = endLoc.S_CODE; wmsTask.S_END_AREA = endLoc.S_AREA_CODE; WMSHelper.UpdateTaskEnd(wmsTask); } } else { LogHelper.Info("未找到入库任务:" + wmsTask.S_CODE + "的终点货位", "Mobox"); } } else { LogHelper.Info("未找到该任务:" + wmsTask.S_CODE + "的容器货品信息", "Mobox"); } } } } } } } /// /// 清除输送线命令 /// /// /// /// /// public static void issueCommand(LineDeviceInfo line, int taskId, short descLine, short command) { S7Helper.WriteDint(line.deviceNo, 101, line.writeAddr + 2, taskId); // 任务号 S7Helper.WriteInt(line.deviceNo, 101, line.writeAddr + 6, descLine); // 目标线体 S7Helper.WriteInt(line.deviceNo, 101, line.writeAddr + 8, command); // 下发指令(默认=0 入库=2 出库=1 不合格退回=3) } public static List getInStockTrayInfo(string trayCode) { List requestDatas = new List(); RequestData requestData = new RequestData() { organizationId = Settings.orgInfo.organizationId, warehouseId = Settings.orgInfo.warehouseId, customerId = Settings.orgInfo.customerId, traceId = trayCode, }; requestDatas.Add(requestData); WMSTrayRequestResponse response = WMSDispatch.TrayRequestInStock(requestDatas); if (response != null) { List inStockListChildren = new List(); foreach (var item in response.IT_DATA) { InStockListChild inStockListChild = new InStockListChild() { S_SKU = item.sku, S_SKU_DESCR = item.skuDescr, N_QTY = float.Parse(item.qty), S_TRACE_ID = item.traceId, S_SERIAL_NO = item.serialNo, LOTATT01 = item.lotAtt01, LOTATT02 = item.lotAtt02, LOTATT03 = item.lotAtt03, LOTATT04 = item.lotAtt04, LOTATT05 = item.lotAtt05, LOTATT06 = item.lotAtt06, LOTATT07 = item.lotAtt07, LOTATT08 = item.lotAtt08, LOTATT09 = item.lotAtt09, LOTATT10 = item.lotAtt10, LOTATT11 = item.lotAtt11, LOTATT12 = item.lotAtt12, LOTATT13 = item.lotAtt13, LOTATT14 = item.lotAtt14, LOTATT15 = item.lotAtt15, LOTATT16 = item.lotAtt16, LOTATT17 = item.lotAtt17, LOTATT18 = item.lotAtt18, LOTATT19 = item.lotAtt19, LOTATT20 = item.lotAtt20, LOTATT21 = item.lotAtt21, LOTATT22 = item.lotAtt22, LOTATT23 = item.lotAtt23, LOTATT24 = item.lotAtt24, }; inStockListChildren.Add(inStockListChild); }; return inStockListChildren; } return null; } public static bool BindCntrItemRel(InStockListChild inStockListChild) { bool result = false; try { CntrItemRel cntrItemRel = new CntrItemRel() { S_ITEM_CODE = inStockListChild.S_SKU, S_ITEM_NAME = inStockListChild.S_SKU_DESCR, F_QTY = inStockListChild.N_QTY, S_CNTR_CODE = inStockListChild.S_TRACE_ID, S_SERIAL_NO = inStockListChild.S_SERIAL_NO, F_GROSS_WEIGHT = inStockListChild.S_CONTAINER_WEIGHT, F_NET_WEIGHT = inStockListChild.F_NET_WEIGHT, S_ASN_NO = inStockListChild.S_ASN_NO, T_INBOUND_TIME = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), LOTATT01 = inStockListChild.LOTATT01, LOTATT02 = inStockListChild.LOTATT02, LOTATT03 = inStockListChild.LOTATT03 == null ? DateTime.Now.ToString("yyyy-MM-dd") : inStockListChild.LOTATT03, LOTATT04 = inStockListChild.LOTATT04, LOTATT05 = inStockListChild.LOTATT05, LOTATT06 = inStockListChild.LOTATT06, LOTATT07 = inStockListChild.LOTATT07, LOTATT08 = inStockListChild.LOTATT08, LOTATT09 = inStockListChild.LOTATT09, LOTATT10 = inStockListChild.LOTATT10, LOTATT11 = inStockListChild.LOTATT11, LOTATT12 = inStockListChild.LOTATT12, LOTATT13 = inStockListChild.LOTATT13, LOTATT14 = inStockListChild.LOTATT14, LOTATT15 = inStockListChild.LOTATT15, LOTATT16 = inStockListChild.LOTATT16, LOTATT17 = inStockListChild.LOTATT17, LOTATT18 = inStockListChild.LOTATT18, LOTATT19 = inStockListChild.LOTATT19, LOTATT20 = inStockListChild.LOTATT20, LOTATT21 = inStockListChild.LOTATT21, LOTATT22 = inStockListChild.LOTATT22, LOTATT23 = inStockListChild.LOTATT23, LOTATT24 = inStockListChild.LOTATT24 }; result = ContainerHelper.BindCntrItemSingle(inStockListChild.S_TRACE_ID, cntrItemRel); } catch (Exception ex) { LogHelper.Info("绑定容器物料信息失败,错误信息:"+ex.Message, "WMS"); } return result; } /// /// 监听出库同步单 /// internal static void Monitor0utStockOrder() { LogHelper.Info("1", "Mobox"); // 开关控制 var formControlSwitch = WCSHelper.GetFormControlSwitch("CKBD"); if (formControlSwitch != null && formControlSwitch.S_B_STATUS == "是") { LogHelper.Info("2", "Mobox"); // 集货区 var areaList = LocationHelper.GetAreaByCode(Settings.WHCode, 7); if (areaList != null) { string endAreaCode = areaList[0].S_CODE; LogHelper.Info("3", "Mobox"); // 1.查询是否有新建的出库同步单 List outStockLists = WMSHelper.getOutstockListByStatus("执行"); foreach (var item in outStockLists) { LogHelper.Info($"4.执行的出库单号:{item.S_ORDER_NO}", "Mobox"); // 2.有则根据同步单列表进行出库 List outStockListChilds = WMSHelper.getOutstockListChilds(item.S_ORDER_NO); foreach (var child in outStockListChilds) { if (child.PRE_COMPLETED_QTY < child.N_QTY) { string asnNo = ""; // 查询开始货位 LogHelper.Info("查询开始货位", "Mobox"); Location startLoc = WMSHelper.getStartLoc(child); LogHelper.Info("开始货位:"+ JsonConvert.SerializeObject(startLoc), "Mobox"); if (startLoc != null) { // 1.开始货位排是否有锁,有锁暂时不生成任务 if (LocationHelper.isLocRowLock(startLoc)) { LogHelper.Info(" 开始货位或终点货位排有锁,暂时不生成任务;开始货位:" + startLoc.S_CODE + ",ORDER_NO :" + child.S_ORDER_NO, "Mobox"); continue; }; List locCntrs = LocationHelper.GetLocCntr(startLoc.S_CODE); // 查询任务容器编码 string taskTrayCode = ""; if (locCntrs.Count > 0) { for (int i = 0; i < locCntrs.Count; i++) { var cntrItemRels = ContainerHelper.GetCntrItemRel(locCntrs[i].S_CNTR_CODE); if (cntrItemRels.Count > 0) { asnNo = cntrItemRels[0].S_ASN_NO; if (i == 0) { taskTrayCode = locCntrs[i].S_CNTR_CODE; } else { taskTrayCode = taskTrayCode + "," + locCntrs[i].S_CNTR_CODE; } } } // 查询集货区货位 Location endLoc = WMSHelper.getEndLocation(child.LOTATT18, asnNo, locCntrs.Count(), endAreaCode); if (endLoc != null) { var wmsTask = new WMSTask() { S_CNTR_CODE = taskTrayCode, S_CODE = WMSHelper.GenerateTaskNo(), S_START_LOC = startLoc.S_CODE, S_START_AREA = startLoc.S_AREA_CODE, S_END_LOC = endLoc.S_CODE, S_END_AREA = endLoc.S_AREA_CODE, S_TYPE = "出库任务", S_OP_DEF_CODE = child.S_ORDER_NO, S_OP_DEF_NAME = "出库同步单", T_START_TIME = DateTime.Now, }; if (WMSHelper.CreateWmsTask(wmsTask)) { WCSTask wcsTask = new WCSTask { S_OP_CODE = wmsTask.S_CODE, S_OP_NAME = wmsTask.S_OP_DEF_NAME, S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = wmsTask.S_TYPE, S_START_LOC = startLoc.S_CODE, S_START_AREA = startLoc.S_AREA_CODE, S_END_LOC = endLoc.S_CODE, S_END_AREA = endLoc.S_AREA_CODE, S_CNTR_CODE = taskTrayCode, N_CNTR_COUNT = locCntrs.Count, S_SCHEDULE_TYPE = "国自", T_START_TIME = DateTime.Now, S_DATA = child.S_SEQ_NO, }; if (WCSHelper.CreateTask(wcsTask)) { // 对终点货位进行加锁 LocationHelper.LockLoc(startLoc.S_CODE, 2); LocationHelper.LockLoc(endLoc.S_CODE, 1); wmsTask.N_B_STATE = 1; WMSHelper.UpdateTaskState(wmsTask); // 更新预出库数量 float qty = 0; for (int i = 0; i < locCntrs.Count; i++) { var cntrItemRels = ContainerHelper.GetCntrItemRel(locCntrs[i].S_CNTR_CODE); foreach (var cntrItemRel in cntrItemRels) { qty += cntrItemRel.F_QTY; } } child.PRE_COMPLETED_QTY = child.PRE_COMPLETED_QTY + qty; WMSHelper.updateOutStockListChild(child); } } } else { LogHelper.Info("出库单:" + JsonConvert.SerializeObject(child) + " 没有满足条件的终点货位","Mobox"); } } } else { LogHelper.Info("出库单:" + JsonConvert.SerializeObject(child) + " 没有满足条件的开始货位", "Mobox"); } } } } } } } /// /// agv 自动移库 /// 用途:用于取货过程中,前方有货位阻塞,进行的自动移库 /// /// /// /// /// public static void agvAutoShiftStock(string opCode, string opName ,Location shiftLoc , Location endLoc = null) { string shiftCntr = ""; List locCntrRels = LocationHelper.GetLocCntr(shiftLoc.S_CODE); if (locCntrRels != null && locCntrRels.Count > 0) { for (int i = 0; i < locCntrRels.Count; i++) { if (i == 0) { shiftCntr = locCntrRels[0].S_CNTR_CODE; } else { shiftCntr = shiftCntr + "," + locCntrRels[i].S_CNTR_CODE; } } var wcsTask = WCSHelper.GetTaskByCntrNo(shiftCntr); if (wcsTask == null) { var cntrItemRels = ContainerHelper.GetCntrItemRel(locCntrRels[0].S_CNTR_CODE); Location shiftEndLoc = null; if (endLoc != null) { shiftEndLoc = endLoc; } else { string araCode = null; var area = LocationHelper.getArea(shiftLoc.S_AREA_CODE); if (area.N_TYPE != 1) { araCode = area.S_CODE; } shiftEndLoc = WMSHelper.getEndLocation(cntrItemRels[0].LOTATT18, cntrItemRels[0].S_ASN_NO, locCntrRels.Count(), araCode ,shiftLoc.N_ROW); } if (shiftEndLoc != null) { wcsTask = new WCSTask { S_OP_CODE = opCode, S_OP_NAME = opName, S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = "移库任务", S_START_LOC = shiftLoc.S_CODE, S_START_AREA = shiftLoc.S_AREA_CODE, S_END_LOC = shiftEndLoc.S_CODE, S_END_AREA = shiftEndLoc.S_AREA_CODE, S_CNTR_CODE = shiftCntr, N_CNTR_COUNT = 1, S_SCHEDULE_TYPE = "国自", T_START_TIME = DateTime.Now, }; if (WCSHelper.CreateTask(wcsTask)) { // 对终点货位进行加锁 LocationHelper.LockLoc(shiftLoc.S_CODE, 2); LocationHelper.LockLoc(shiftEndLoc.S_CODE, 1); var wmsTask = WMSHelper.GetWmsTask(opCode); wmsTask.N_B_STATE = 1; WMSHelper.UpdateTaskState(wmsTask); } } else { LogHelper.Info("AGV自动移库失败,未获取到移库终点", "Mobox"); } } } } /// /// 监听移库同步单 /// internal static void MonitorShiftStockOrder() { // 1.查询是否有新建的移库同步单 List shiftStockLists = WMSHelper.getShiftstockListByStatus("执行"); foreach (var shiftStockList in shiftStockLists) { var shiftStockListChilds = WMSHelper.getShiftstockListChilds(shiftStockList.S_MDOC_NO); foreach (var child in shiftStockListChilds) { string taskTrayCode = ""; var locCntr = LocationHelper.GetLocCntrRelByCntr(child.S_TRACE_ID); if (locCntr != null) { List locCntrRels = LocationHelper.GetLocCntr(locCntr.S_LOC_CODE); if (locCntrRels != null && locCntrRels.Count > 0) { for (int i = 0; i < locCntrRels.Count; i++) { if (i == 0) { taskTrayCode = locCntrRels[0].S_CNTR_CODE; } else { taskTrayCode = taskTrayCode + "," + locCntrRels[i].S_CNTR_CODE; } } } var wmsTask = WMSHelper.GetWmsTaskByCntr(taskTrayCode); if (wmsTask == null) { Location startLoc = LocationHelper.GetLoc(locCntr.S_LOC_CODE); /*var fullerList = LocationHelper.getFullerByFullerCode(child.S_TO_LOCATION);*/ Location endLoc = LocationHelper.getShiftEndLoc(child.S_TO_LOCATION, locCntrRels.Count); if (startLoc != null && endLoc != null ) { // 1.开始货位\终点货位排是否有锁,有锁暂时不生成任务 if (LocationHelper.isLocRowLock(startLoc) || LocationHelper.isLocRowLock(endLoc)) { LogHelper.Info(" 开始货位或终点货位排有锁,暂时不生成任务;开始货位:" + startLoc.S_CODE + ",终点货位:" + endLoc.S_CODE + ",MDOC_NO:" + child.S_MDOC_NO, "Mobox"); continue; }; wmsTask = new WMSTask() { S_CNTR_CODE = taskTrayCode, S_CODE = WMSHelper.GenerateTaskNo(), S_START_LOC = startLoc.S_CODE, S_START_AREA = startLoc.S_AREA_CODE, S_END_LOC = endLoc.S_CODE, S_END_AREA = endLoc.S_AREA_CODE, S_TYPE = "移库任务", S_OP_DEF_CODE = child.S_MDOC_NO, S_OP_DEF_NAME = "移库同步单", T_START_TIME = DateTime.Now, }; if (WMSHelper.CreateWmsTask(wmsTask)) { WCSTask wcsTask = new WCSTask { S_OP_CODE = wmsTask.S_CODE, S_OP_NAME = wmsTask.S_OP_DEF_NAME, S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = wmsTask.S_TYPE, S_START_LOC = startLoc.S_CODE, S_START_AREA = startLoc.S_AREA_CODE, S_END_LOC = endLoc.S_CODE, S_END_AREA = endLoc.S_AREA_CODE, S_CNTR_CODE = taskTrayCode, N_CNTR_COUNT = locCntrRels.Count, S_SCHEDULE_TYPE = "国自", T_START_TIME = DateTime.Now, }; if (WCSHelper.CreateTask(wcsTask)) { // 对终点货位进行加锁 LocationHelper.LockLoc(startLoc.S_CODE, 2); LocationHelper.LockLoc(endLoc.S_CODE, 1); wmsTask.N_B_STATE = 1; WMSHelper.UpdateTaskState(wmsTask); } } } } } } } } /// /// 创建有抽检任务 /// /// /// /// /// public static void createCheckTask(string startLocCode, string orientSign, string asnNo, string taskTrayCode) { LogHelper.Info("开始创建抽检任务,参数:startLocCode="+ startLocCode+ ",orientSign="+ orientSign+ ",asnNo="+ asnNo+ ",taskTrayCode="+ taskTrayCode, "Mobox"); Location startLoc = LocationHelper.GetLoc(startLocCode); var area = LocationHelper.GetAreaByCode(Settings.WHCode, 3); var endLoc = WMSHelper.getEndLocation(orientSign, asnNo, 1, area[0].S_CODE); var locCntrRel = LocationHelper.GetLocCntrRelByCntr(taskTrayCode); if (endLoc != null && startLoc != null && startLoc.N_LOCK_STATE == 0) { var wmsTask = new WMSTask() { S_CNTR_CODE = taskTrayCode, S_CODE = WMSHelper.GenerateTaskNo(), S_START_LOC = startLoc.S_CODE, S_START_AREA = startLoc.S_AREA_CODE, S_END_LOC = endLoc.S_CODE, S_END_AREA = endLoc.S_AREA_CODE, S_TYPE = "抽检任务", S_OP_DEF_CODE = asnNo, S_OP_DEF_NAME = "入库抽检任务", T_START_TIME = DateTime.Now, }; if (WMSHelper.CreateWmsTask(wmsTask)) { var wcsTask = new WCSTask { S_OP_CODE = wmsTask.S_CODE, S_OP_NAME = wmsTask.S_OP_DEF_NAME, S_CODE = WCSHelper.GenerateTaskNo(), S_TYPE = wmsTask.S_TYPE, S_START_LOC = startLoc.S_CODE, S_START_AREA = startLoc.S_AREA_CODE, S_END_LOC = endLoc.S_CODE, S_END_AREA = endLoc.S_AREA_CODE, S_CNTR_CODE = taskTrayCode, N_CNTR_COUNT = 1, S_SCHEDULE_TYPE = "国自", T_START_TIME = DateTime.Now, }; if (WCSHelper.CreateTask(wcsTask)) { // 对终点货位进行加锁 LocationHelper.LockLoc(startLoc.S_CODE, 2); LocationHelper.LockLoc(endLoc.S_CODE, 1); wmsTask.N_B_STATE = 1; WMSHelper.UpdateTaskState(wmsTask); LogHelper.Info("创建抽检任务成功", "Mobox"); } } } else { LogHelper.Info("抽检区没有空余货位", "入库同步单"); } } /// /// 监听待出库的抽检单,并进行出库 /// internal static void MonitorOutStockSpotCheckOrder() { // 1.查询需要抽检的容器,并进行出库到抽检区 var outStockSpotCheckList = WMSHelper.GetShopCheckListByStatus("待出库"); if (outStockSpotCheckList != null && outStockSpotCheckList.Count() > 0) { foreach (var item in outStockSpotCheckList) { var wmsTask = WMSHelper.GetWmsTaskByAsnNo(item.S_ASN_NO); if (wmsTask == null) { createCheckTask(item.S_LOC_CODE, null, item.S_ASN_NO, item.S_TRACE_ID); } } } } /// /// 监听已检验的抽检单,并进行回库 /// internal static void MonitorInspectedSpotCheckOrder() { // 2.查询已检验的抽检单 var asnNoList = WMSHelper.getFinishSpotCheckList(); if (asnNoList != null && asnNoList.Count > 0) { foreach (var asnNo in asnNoList) { WMSTask wmsTask = WMSHelper.GetWmsTaskByAsnNo(asnNo); if (wmsTask == null) { var spotCheckList = WMSHelper.GetShopCheckListByAsnNo(asnNo); foreach (var item in spotCheckList) { // 质量状态为 N 合格,进行入库,为 Y 不合格,入库不合格区 if (item.S_QUALITY_STATUS == "Y") { // 更改同批次的入库货物质量状态 WMSHelper.updateCntrItemStatusByAsnNO(item.S_ASN_NO, item.S_QUALITY_STATUS); } } foreach (var item in spotCheckList) { if (item.N_STATUS == 3) { var locCntrRel = LocationHelper.GetLocCntrRelByCntr(item.S_TRACE_ID); if (locCntrRel != null) { var startLoc = LocationHelper.GetLoc(locCntrRel.S_LOC_CODE); var endLoc = LocationHelper.GetLoc(item.S_LOC_CODE); if (endLoc.N_LOCK_STATE == 0 && endLoc.N_CURRENT_NUM < endLoc.N_CAPACITY) { LogHelper.Info("创建抽检品回库任务", "Mobox"); wmsTask = WMSHelper.GetWmsTaskByAsnNo(item.S_ASN_NO); if (wmsTask == null) { wmsTask = new WMSTask() { S_CNTR_CODE = item.S_TRACE_ID, S_CODE = WMSHelper.GenerateTaskNo(), S_START_LOC = startLoc.S_CODE, S_START_AREA = startLoc.S_AREA_CODE, S_END_LOC = endLoc.S_CODE, S_END_AREA = endLoc.S_AREA_CODE, S_TYPE = "移库任务", S_OP_DEF_CODE = asnNo, S_OP_DEF_NAME = "创建抽检品回库任务", T_START_TIME = DateTime.Now, }; if (WMSHelper.CreateWmsTask(wmsTask)) { agvAutoShiftStock(wmsTask.S_CODE, wmsTask.S_OP_DEF_NAME, startLoc, endLoc); } } } } } } } } } } /// /// 扫描库区内的不合格物料,将其移到不合格区 /// internal static void scanAreaUnacceptedProduct() { // 不合格区 var areaCodes = LocationHelper.GetAreaByCode(Settings.WHCode, 5); if (areaCodes == null) { return; } string areaCode = areaCodes[0].S_CODE; // 查询抽检区完成回库的批次列表(抽检区整个批次全部回库后,才触发库区不合格品移库) var spotCheckList = WMSHelper.getBackStockSpotCheckList(); var locList = WMSHelper.getUnacceptedLocList(); if (locList != null && locList.Count > 0) { foreach (var item in locList) { string asnNo = ""; string taskTrayCode = ""; string lotatt18 = null; // 查询开始货位 Location startLoc = item; List locCntrs = LocationHelper.GetLocCntr(startLoc.S_CODE); if (locCntrs == null || locCntrs.Count() == 0) { continue; } for (int i = 0; i < locCntrs.Count; i++) { var cntrItemRels = ContainerHelper.GetCntrItemRel(locCntrs[i].S_CNTR_CODE); asnNo = cntrItemRels[0].S_ASN_NO; lotatt18 = cntrItemRels[0].LOTATT18; if (i == 0) { taskTrayCode = locCntrs[i].S_CNTR_CODE; } else { taskTrayCode = taskTrayCode + "," + locCntrs[i].S_CNTR_CODE; } } if (spotCheckList.Contains(asnNo)) { var locCntrRel = LocationHelper.GetLocCntr(item.S_CODE); Location endLoc = WMSHelper.getEndLocation(lotatt18, asnNo, locCntrs.Count(), areaCode); if (startLoc != null && endLoc != null) { // 1.开始货位排是否有锁,有锁暂时不生成任务 if (LocationHelper.isLocRowLock(startLoc)) { LogHelper.Info(" 开始货位排有锁,暂时不生成任务;开始货位:" + startLoc.S_CODE + ", asnNo:" + asnNo, "Mobox"); continue; }; var wmsTask = WMSHelper.GetWmsTaskByCntr(taskTrayCode); if (wmsTask == null) { LogHelper.Info("库区不合格品移库不合格区", "Mobox"); wmsTask = new WMSTask() { S_CNTR_CODE = taskTrayCode, S_CODE = WMSHelper.GenerateTaskNo(), S_START_LOC = startLoc.S_CODE, S_START_AREA = startLoc.S_AREA_CODE, S_END_LOC = endLoc.S_CODE, S_END_AREA = endLoc.S_AREA_CODE, S_TYPE = "移库任务", S_OP_DEF_CODE = asnNo, S_OP_DEF_NAME = "库区不合格品移库不合格区", T_START_TIME = DateTime.Now, }; if (WMSHelper.CreateWmsTask(wmsTask)) { var wcsTask = WCSHelper.GetTaskByStart(startLoc.S_CODE); if (wcsTask == null) { // agv 自动移库 LogHelper.Info("扫描库区内的不合格物料,移库到不合格区", "Mobox"); agvAutoShiftStock(wmsTask.S_CODE, wmsTask.S_OP_DEF_NAME, startLoc, endLoc); } } } } } } } } public static Dictionary, int> keyValuePairs1 = new Dictionary, int>(); public static Dictionary, int> keyValuePairs2 = new Dictionary, int>(); public static Dictionary, int> keyValuePairs3 = new Dictionary, int>(); /// /// 对反馈上游失败的数据,进行重复反馈 /// public static void feedbackUpstreamSystem() { // 1.物料入库反馈 var inStockFeedbackDatas = WCSCore.inStockFeedbackDatas; if (inStockFeedbackDatas.Count > 0) { for (int i = 0; i < inStockFeedbackDatas.Count; i++) { var feedbackResult = WMSDispatch.ReceiveGoodsFeedback(inStockFeedbackDatas[i]); if (feedbackResult) { WCSCore.inStockFeedbackDatas.Remove(inStockFeedbackDatas[i]); } else { keyValuePairs1.TryGetValue(inStockFeedbackDatas[i], out int num); keyValuePairs1[inStockFeedbackDatas[i]] = num + 1; if (num > 3) { WCSCore.inStockFeedbackDatas.Remove(inStockFeedbackDatas[i]); } } } } // 2.物料出库反馈 var outStockFeedbackDatas = WCSCore.outStockFeedbackDatas; if (outStockFeedbackDatas.Count > 0) { for (int i = 0; i < outStockFeedbackDatas.Count; i++) { var feedbackResult = WMSDispatch.ShipmentsTrayFeedback(outStockFeedbackDatas[i]); if (feedbackResult) { WCSCore.outStockFeedbackDatas.Remove(outStockFeedbackDatas[i]); } else { keyValuePairs2.TryGetValue(outStockFeedbackDatas[i], out int num); keyValuePairs2[outStockFeedbackDatas[i]] = num + 1; if (num > 3) { WCSCore.outStockFeedbackDatas.Remove(outStockFeedbackDatas[i]); } } } } // 3.物料移库反馈 var shiftFeedbackDatas = WCSCore.shiftFeedbackDatas; if (shiftFeedbackDatas.Count > 0) { for (int i = 0; i < shiftFeedbackDatas.Count; i++) { var feedbackResult = WMSDispatch.ShiftingStockOrderFeedback(shiftFeedbackDatas[i]); if (feedbackResult) { WCSCore.shiftFeedbackDatas.Remove(shiftFeedbackDatas[i]); } else { keyValuePairs3.TryGetValue(shiftFeedbackDatas[i], out int num); keyValuePairs3[shiftFeedbackDatas[i]] = num + 1; if (num > 3) { WCSCore.shiftFeedbackDatas.Remove(shiftFeedbackDatas[i]); } } } } } // 每十分钟对未连接的pic,尝试进行重新连接 public static void PlcAgainLink() { foreach (var item in S7Helper.plcDic) { S7Helper.Link(item.Value); } } } }