using HH.WCS.Mobox3.FJJF.models; using HH.WCS.Mobox3.FJJT.api; using HH.WCS.Mobox3.FJJT.device; using HH.WCS.Mobox3.FJJT.dispatch; using HH.WCS.Mobox3.FJJT.process; using HH.WCS.Mobox3.FJJT.wms; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Web.Http; using static HH.WCS.Mobox3.FJJT.api.ApiHelper; using static HH.WCS.Mobox3.FJJT.api.ApiModel; namespace HH.WCS.Mobox3.FJJT.core { internal class WCSCore { /// /// AGV任务回报 /// 1.根据回报AGV任务状态,更新货位信息和任务状态 /// 2.判断WMSTask是否是出库任务,是,如果工装内有物料,则判断物料是否合格,不合格,则生成不合格品入库任务 /// 3.如果合格,则触发余料/空托回库任务 /// /// public static void OperateAgvTaskStatus(AgvTaskState model) { try { if (string.IsNullOrEmpty(model.No)) { //无任务号请求(交管) //DeviceProcess.Traffic(model.ForkliftNo, model.LockNo, model.State==1023); } else { var cst = WCSHelper.GetTask(model.No); if (cst != null) { var mst = WMSHelper.GetWmsTask(cst.S_OP_CODE); if (mst != null) { WCSHelper.AddActionRecord(model.No, model.State, model.ForkliftNo, model.ExtData); if (model.State <= 7) { //有任务号请求 switch (model.State) { case 1: WCSHelper.Begin(cst); WMSHelper.updateMesTaskStatus(mst.S_CODE, "2"); // 更新MES任务状态 break; #region MyRegion case 3: WCSHelper.UpdateStatus(cst, "开始取货"); var locCntrRels = LocationHelper.GetLocCntr(cst.S_START_LOC); if (locCntrRels.Count > 0) { cst.S_CNTR_CODE = locCntrRels[0].S_CNTR_CODE; WCSHelper.UpdateWcsTask(cst); } break; case 4: WCSHelper.UpdateStatus(cst, "取货完成"); TaskProcess.OperateStatus(cst, 4); break; case 5: WCSHelper.UpdateStatus(cst, "开始卸货"); break; case 6: WCSHelper.UpdateStatus(cst, "卸货完成"); TaskProcess.OperateStatus(cst, 6); break; #endregion case 2: WCSHelper.End(cst); break; case 7: TaskProcess.OperateStatus(cst, 7); WCSHelper.Fail(cst); break; } } else if (model.State == 1012) { LogHelper.Info("开始进行RFID扫描", "AGV"); // 查询扫描的RFID // 发送 00 04 71 02到扫码器 ,接受返回数据并解析 /* string hexString = TcpClient.SendHexOnce("127.0.0.1", 8080, "00 04 71 02"); var rfid = hexString.Substring(6, 8);*/ string rfid = ""; LogHelper.Info($"扫描结束,RFID:{rfid}", "AGV"); if (rfid == cst.S_CNTR_CODE) { LogHelper.Info($"扫描RFID:{rfid}与任务RFID一致", "AGV"); // 修改1012的参数6为1 /* NDCApi.ChangeOrderParam(cst.S_CODE, 6, "1");*/ } else { WMSHelper.addAlarmRecord("流程异常", "低", $"扫描RFID:{rfid}与任务RFID:{cst.S_CNTR_CODE}不一致", "AGV"); // 修改参数6为3 /* NDCApi.ChangeOrderParam(cst.S_CODE, 6, "3");*/ // 修改容器异常状态 ContainerHelper.UpdateCntrState(cst.S_CNTR_CODE, 4); } } else if (model.State == 1002) { LogHelper.Info("开始获取AGV终点", "AGV"); // 更新AGV终点 // 判断容器是否异常,修改1002的终点参数 ,并将参数6修改为1 Container container = ContainerHelper.GetCntr(cst.S_CNTR_CODE); if (container != null) { LogHelper.Info($"容器的异常状态为:{container.N_E_STATE}", "AGV"); string agvEndLoc = null; if (container.N_E_STATE == 0) { agvEndLoc = ApiHelper.AGVApplyDest(model.No, cst.S_START_LOC, cst.S_CNTR_CODE, "1"); } else { agvEndLoc = ApiHelper.AGVApplyDest(model.No, cst.S_START_LOC, cst.S_CNTR_CODE, "2"); } ChangeParamModel paramModel = new ChangeParamModel() { task_no = model.No, param_no = 0, param = $"{model.No};{cst.S_START_LOC};{cst.S_END_LOC};4;512;0;1" }; NDCApi.ChangeOrderParam(paramModel); LogHelper.Info($"获取AGV终点:{agvEndLoc}", "AGV"); } else { WMSHelper.addAlarmRecord("流程异常", "中", $"AGV任务回报,任务容器编码:{cst.S_CNTR_CODE}的容器没有录入到WMS系统","AGV"); } } else { //安全请求等 TaskProcess.OperateReq(model.No, model.State, model.ForkliftNo, model.ExtData); } // AGV任务完成 if (model.State == 2) { // 检测物料是否合格,如不合格, // 判断物料是否是环带库物料,是则回环带库,并让环带下发新的物料 // 非环带库物料,则退出立库,同时下发新的物料出库任务 if (cst.S_TYPE.Contains("叫料出库任务")) { var cntrItemRels = ContainerHelper.GetCntrItemRel(cst.S_CNTR_CODE); if (cntrItemRels != null && cntrItemRels.Count > 0) { if (cntrItemRels[0].S_ITEM_STATE == "2") { // 不合格品回库 ApiHelper.rejectReturnStock(mst, cst); } } } // 检测是否是读码位,非读码位,可以激活预创建任务 var transfe = WMSHelper.GetTransfeRelevance(cst.S_END_LOC); // 接驳位属性 if ((transfe == null || transfe.N_READ_LOC == 0)) { if (cst.S_TYPE.Contains("【异常】")) { WCSHelper.ActivatePreCreateTask(mst.S_CODE,1); } else { WCSHelper.ActivatePreCreateTask(mst.S_CODE); } } // 查询是否有未完成的任务 if (WMSHelper.isFinishTask(mst.S_CODE)) { // 更新作业任务状态 mst.N_B_STATE = 2; mst.T_END_TIME = DateTime.Now; WMSHelper.UpdateTaskState(mst); // 更新任务中间表状态 WMSHelper.updateMesTaskStatus(mst.S_CODE, "3"); // 如果作业名称为成型机叫料出库任务,则触发余料/空托搬运任务 string locCode = WMSHelper.getReturnMaterialLocCode(mst.S_END_LOC); ApiHelper.returnMaterialOrEmptyTray(locCode); } } } else { WMSHelper.addAlarmRecord("系统错误", "高", $"AGV任务状态回报,作业号:{cst.S_OP_CODE},未查询到作业","AGV"); } } else { WMSHelper.addAlarmRecord("系统错误", "高", $"AGV任务状态回报,任务号:{model.No},未查询到任务","AGV"); } } } catch (Exception ex) { WMSHelper.addAlarmRecord("系统错误","高", $"WMS内部错误:agv任务状态回报错误,错误原因:{ex.Message}","AGV"); } } /// /// 任务分发,根据调度类型发给不同的调度系统 /// internal static void Dispatch() { //查询任务 //获取所有等待的任务 var list = WCSHelper.GetWaitingTaskList(); if (list.Count > 0) { list.ForEach(task => { if (!TaskProcess.Intercept(task)) { //使用自定义任务推送 TaskProcess.SendTask(task); } }); } } /// /// 杭奥堆垛机信号反馈 /// /// internal static void OperateHATaskStatus(HanAo.TaskStateInfoModel model) { var wcsTask = WCSHelper.GetTask(model.requestPk); if (wcsTask != null) { if (model.code == "0") { // if (wcsTask.S_TYPE == "堆垛机入库") { //终点托盘绑定 if (LocationHelper.BindingLoc(wcsTask.S_END_LOC, new List { wcsTask.S_CNTR_CODE })) { //修改托盘状态为可用,增加库存量表,后面分拣出可以计算到 } } else if (wcsTask.S_TYPE == "堆垛机出库") { //起点托盘解绑 LocationHelper.UnBindingLoc(wcsTask.S_START_LOC, new List { wcsTask.S_CNTR_CODE }); } //标记任务完成 //标记作业完成 wcsTask.N_B_STATE = 3; WCSHelper.UpdateStatus(wcsTask); var wmsTask = WMSHelper.GetWmsTask(wcsTask.S_OP_CODE); if (wmsTask != null) { wmsTask.N_B_STATE = 2; WMSHelper.UpdateTaskState(wmsTask); } } } } } }