New file |
| | |
| | | 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; |
| | | using HH.WCS.Mobox3.FJJT.util; |
| | | |
| | | namespace HH.WCS.Mobox3.FJJT.core { |
| | | internal class WCSCore { |
| | | |
| | | /// <summary> |
| | | /// AGV任务回报 |
| | | /// 1.根据回报AGV任务状态,更新货位信息和任务状态 |
| | | /// 2.判断WMSTask是否是出库任务,是,如果工装内有物料,则判断物料是否合格,不合格,则生成不合格品入库任务 |
| | | /// 3.如果合格,则触发余料/空托回库任务 |
| | | /// </summary> |
| | | /// <param name="model"></param> |
| | | 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, "取货完成"); |
| | | LocationHelper.UnLockLoc(cst.S_START_LOC); |
| | | TaskProcess.OperateStatus(cst, 4); |
| | | break; |
| | | case 5: |
| | | WCSHelper.UpdateStatus(cst, "开始卸货"); |
| | | break; |
| | | case 6: |
| | | WCSHelper.UpdateStatus(cst, "卸货完成"); |
| | | LocationHelper.UnLockLoc(cst.S_END_LOC); |
| | | 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"); |
| | | ContainerHelper.UpdateCntrState(cst.S_CNTR_CODE, 1); |
| | | WMSHelper.addRfidAnomalyRecord(cst.S_CNTR_CODE, 2, cst.S_START_LOC, null); |
| | | // 查询扫描的RFID |
| | | // 发送 00 04 71 02到扫码器 ,接受返回数据并解析 |
| | | /* byte[] bytes = new byte[] { 00, 04, 71, 02 }; |
| | | var plc = Settings.carDeviceInfos.Where(a => a.deviceNo == model.ForkliftNo && a.enable == 1).FirstOrDefault(); |
| | | TcpServer.TcpServerSend(plc.address, bytes);*/ |
| | | } |
| | | 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) |
| | | { |
| | | // 激活预创建任务 |
| | | // 场景:1.读码位激活预创建任务 2.空工装出库激活满料下线任务(非直连) |
| | | 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"); |
| | | } |
| | | |
| | | // 检测物料是否合格,如不合格, |
| | | // 判断物料是否是环带库物料,是则回环带库,并让环带下发新的物料 |
| | | // 非环带库物料,则退出立库,同时下发新的物料出库任务 |
| | | if (cst.S_TYPE.Contains("叫料出库任务")) |
| | | { |
| | | var bo = int.TryParse(mst.S_OP_DEF_CODE, out int mesId); |
| | | if (bo) |
| | | { |
| | | var mesTask = WMSHelper.GetLjMesTaskById(mesId); |
| | | var cntrItemRels = ContainerHelper.GetCntrItemRel(cst.S_CNTR_CODE); |
| | | if (cntrItemRels != null && cntrItemRels.Count > 0) |
| | | { |
| | | if (cntrItemRels[0].S_ITEM_STATE == "2") |
| | | { |
| | | mesTask.AWAIT_MSG = "物料检验状态为不合格,重新叫料中"; |
| | | WMSHelper.updateLjMesTask(mesTask); |
| | | |
| | | // 不合格品回库 |
| | | ApiHelper.rejectReturnStock(mst, cst); |
| | | } |
| | | else |
| | | { |
| | | // 如果作业名称为成型机叫料出库任务,则触发余料/空托搬运任务 |
| | | var sideLocConfig = WMSHelper.getReturnMaterialLocCode(mst.S_END_LOC); |
| | | ApiHelper.returnMaterialOrEmptyTray(sideLocConfig.S_RETURN_LOC_CODE, sideLocConfig.EQP); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | 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"); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 任务分发,根据调度类型发给不同的调度系统 |
| | | /// </summary> |
| | | internal static void Dispatch() { |
| | | //查询任务 |
| | | //获取所有等待的任务 |
| | | var list = WCSHelper.GetWaitingTaskList(); |
| | | if (list.Count > 0) { |
| | | list.ForEach(task => { |
| | | |
| | | if (!TaskProcess.Intercept(task)) { |
| | | //使用自定义任务推送 |
| | | TaskProcess.SendTask(task); |
| | | } |
| | | |
| | | }); |
| | | |
| | | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 杭奥堆垛机信号反馈 |
| | | /// </summary> |
| | | /// <param name="model"></param> |
| | | 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<string> { wcsTask.S_CNTR_CODE })) { |
| | | //修改托盘状态为可用,增加库存量表,后面分拣出可以计算到 |
| | | |
| | | |
| | | } |
| | | } |
| | | else if (wcsTask.S_TYPE == "堆垛机出库") { |
| | | //起点托盘解绑 |
| | | LocationHelper.UnBindingLoc(wcsTask.S_START_LOC, new List<string> { 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); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |