using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using HH.WCS.Mobox3.DSZSH.api; using HH.WCS.Mobox3.DSZSH.device; using HH.WCS.Mobox3.DSZSH.models; using HH.WCS.Mobox3.DSZSH.process; using HH.WCS.Mobox3.DSZSH.util; using HH.WCS.Mobox3.DSZSH.wms; using Newtonsoft.Json; using static HH.WCS.Mobox3.DSZSH.api.ApiModel; namespace HH.WCS.Mobox3.DSZSH.core { public class WCSCore { public static ReturnResult OperateAgvTaskStatus(AgvTaskState model) { var result = new ReturnResult(); try { switch (model.state) { case 1023: break; case 1025: break; case 1012: break; case 1004: break; case 1103: break; default: // AGV 执行任务的逻辑处理 if (!AgvTaskProcessOk(model)) { // 执行不OK,说明没有找到任务 result.ResultCode = 1; result.ResultMsg = $"根据Model.No未找到对应的任务,{model.task_no}"; LogHelper.Info(result.ResultMsg, "API"); return result; } break; } result.ResultCode = 0; result.ResultMsg = "success"; LogHelper.Info(result.ResultMsg, "API"); return result; } catch (Exception ex) { result.ResultCode = -1; result.ResultMsg = $"发生了异常:+{ex.Message}"; LogHelper.Info(result.ResultMsg, "Error"); return result; } } /// /// 执行 AGV 任务,查询不到任务返回 /// /// /// private static bool AgvTaskProcessOk(AgvTaskState model) { var TN_Task = WCSHelper.GetTask(model.task_no); // 根据当前model编号查询任务 if (TN_Task == null) { return false; } if (model.state > 7) { //安全请求等 TaskProcess.OperateReq(model.task_no, model.state, model.forklift_no, model.ext_data); return true; } // AGV 任务 134562(7) 状态处理 switch (model.state) { case 1: // 执行 WCSHelper.Begin(TN_Task, model.forklift_no); // 已推送的任务的状态改成执行 break; case 3: // 开始取货 WCSHelper.UpdateStatus(TN_Task, "开始取货"); // 任务状态改成开始取货 break; case 4: // 取货完成 WCSHelper.UpdateStatus(TN_Task, "取货完成"); // 任务状态改成取货完成 TaskProcess.OperateStatus(TN_Task, 4); // 起点容器货位解绑,解锁起点 if (TN_Task.S_TYPE == TaskName.C成品胶出库) { var nextOutboundTask = Task.Run(() => { UpdateOutboundTaskState(3); }); //var pickUpReturnErpTask = Task.Run(() => { // PickUpReturnErp(TN_Task); //}); } break; case 5: // 开始卸货 WCSHelper.UpdateStatus(TN_Task, "开始卸货"); // 任务状态改成开始卸货 break; case 6: // 卸货完成 WCSHelper.UpdateStatus(TN_Task, "卸货完成"); // 任务状态改成卸货完成 TaskProcess.OperateStatus(TN_Task, 6); // 终点容器货位绑定,解锁终点 break; case 2: // 完成 WCSHelper.End(TN_Task); // 任务状态改成结束 //if (TN_Task.S_TYPE == TaskName.抽检_出库) { // var checkCompleteTask = Task.Run(() => { // UpdateCheckTaskState(3); // }); //} var recordTask = Task.Run(() => { RecordTaskTable(TN_Task); }); break; case 7: // 异常 TaskProcess.OperateStatus(TN_Task, 7); // 异常处理 WCSHelper.Fail(TN_Task); // 任务状态改成错误 break; } // 将AGV执行状态,加入TN_Task_Action表中 WCSHelper.AddActionRecord(model.task_no, model.state, model.forklift_no, model.ext_data); //调用第三方接口(如果有)TaskProcess.ReportStatus,添加任务动作关系表 return true; } private static void RecordTaskTable(TN_Task task) { var db = new SqlHelper().GetInstance(); var info = ""; try { var cgDetail = new TN_CG_Detail(); var emptyTask = false; if (task.S_TYPE != TaskName.H好运箱_空箱上线 && task.S_TYPE != TaskName.H好运箱_空箱入库 && task.S_TYPE != TaskName.T托盘_空托上线 && task.S_TYPE != TaskName.T托盘_空托入库) { // 非空托任务(空托任务无法在CGDetail查到物料信息) emptyTask= true; cgDetail = db.Queryable() .Where(d => d.S_CNTR_CODE == task.S_CNTR_CODE) .First(); if (cgDetail == null) { info = $"任务{task.S_CODE}完成,记录出入库失败:无法在容器货品明细表中找到托盘{task.S_CNTR_CODE}对应的物料"; LogHelper.Info(info); return; } } var isInbound = false; var inboundTasks = new List { TaskName.H好运箱_满箱下线入库, TaskName.H好运箱_空箱入库, TaskName.T托盘_满托下线入库, TaskName.T托盘_空托入库, TaskName.C抽检_合格回库, TaskName.C抽检_不合格移库, TaskName.Y移库 }; if (inboundTasks.Contains(task.S_TYPE)) { isInbound= true; } var record = new TN_Record_Table { S_ITEM_CODE = cgDetail.S_ITEM_CODE, S_BATCH_NO = cgDetail.S_BATCH_NO, S_ITEM_NAME = cgDetail.S_ITEM_NAME, S_LOC_CODE = isInbound ? task.S_END_LOC : task.S_START_LOC, // 入库记录终点货位,出库记录起点货位 S_CNTR_CODE = task.S_CNTR_CODE, S_ITEM_SPEC = cgDetail.S_ITEM_SPEC, S_NET_WEIGHT = cgDetail.S_NET_WEIGHT, S_QUALITY_GRADE = cgDetail.S_QUALITY_GRADE, S_STANDARD = cgDetail.S_STANDARD, S_TASK_NO = task.S_CODE, T_RECORD_TIME = DateTime.Now, S_TYPE = task.S_TYPE, S_BS_CODE = task.S_BS_TYPE, N_QTY = cgDetail.N_ITEM_NUM, }; if (db.Insertable(record).ExecuteCommand() <= 0) { info = "插入出入库记录表失败:" + JsonConvert.SerializeObject(record); LogHelper.Info(info); return; } info = "插入出入库记录表成功"; LogHelper.Info(info); } catch (Exception ex) { LogHelper.InfoEx(ex); } } public static ReturnResult SafetyInteraction(SafetyInteractionInfo model) { var db = new SqlHelper().GetInstance(); var info = ""; try { ModbusHelper.Relink(); //var loc = db.Queryable() // .Where(l => l.S_AGV_SITE == model.station_name && Settings.AreaMap[AreaName.包装区].Contains(l.S_AREA_CODE)) // .First(); if (!Settings.AgvSite_ProdLineCodeMap.TryGetValue(model.station_name, out int prodIndex)) { info = $"AGV 站点{model.station_name}不是合法的产线接驳位站点"; LogHelper.Info(info); return NewReturnResult(1, info); } var prodLineInfo = Settings.ProductionLines[prodIndex]; var prodLineDevice = new ProductionLineDevice(prodLineInfo); if (!prodLineDevice.LoadDeviceStateOk()) { info = "与产线设备通讯失败"; LogHelper.Info(info); return NewReturnResult(2, info); } //var tn_task = db.Queryable().First(a => a.S_CODE == model.task_no); //if (tn_task == null) { // LogHelper.Info($"任务号 '{model.task_no}' 不存在"); //} //if (prodLineDevice.SystemState == 1) { // if (prodLineDevice.FullOffline == 1 && tn_task.S_TYPE == TaskName.托盘_满托下线入库) { // prodLineDevice.AgvPicking = 1; // } // if (prodLineDevice.AllowAgvPlacePallet == 1 && tn_task.S_TYPE == TaskName.托盘_空托上线) { // prodLineDevice.AgvPlacingPallet = 1; // } //} if (prodLineDevice.SystemState != 1) { info = $"当前产线无法与AGV联动:状态{prodLineDevice.SystemState}"; LogHelper.Info(info); return NewReturnResult(3, info); } if (model.apply_code == "5") { // 请求取货 if (prodLineDevice.FullOffline != 1) { info = $"当前输送线满料下线信号不为1,无法取货"; LogHelper.Info(info); return NewReturnResult(4, info); } if (!prodLineDevice.SetAgvPicking(1)) { info = $"向输送线写入允许取货信号失败"; LogHelper.Info(info); return NewReturnResult(5, info); } info = $"向输送线写入允许取货信号成功"; LogHelper.Info(info); return NewReturnResult(0, info); } else if (model.apply_code == "1") { // 请求卸货 if (prodLineDevice.AllowAgvPlacePallet != 1) { info = $"当前输送线允许放托盘信号不为1,无法放货"; LogHelper.Info(info); return NewReturnResult(6, info); } if (!prodLineDevice.SetAgvPlacingPallet(1)) { info = $"向输送线写入允许放货信号失败"; LogHelper.Info(info); return NewReturnResult(7, info); } info = $"向输送线写入允许放货信号成功"; LogHelper.Info(info); return NewReturnResult(0, info); } else { info = $"当前AGV请求码不为 5取货 或 1卸货"; LogHelper.Info(info); return NewReturnResult(8, info); } } catch (Exception ex) { info = $"发生了异常:{ex.Message}"; LogHelper.InfoEx(ex); return NewReturnResult(1, info); } } public static void UpdateOutboundTaskState(int spotStateCode) { var taskName = TaskName.C成品胶出库; var db = new SqlHelper().GetInstance(); var detail = db.Queryable() .First(d => d.N_B_STATE == 2); if (detail == null) { LogHelper.Info($"{taskName}--AGV取货--查询明细单:当前没有执行中的明细单"); return; } using (var tran = db.Ado.UseTran()) { detail.N_B_STATE = spotStateCode; if (db.Updateable(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand() <= 0) { tran.RollbackTran(); LogHelper.Info($"{taskName}--AGV取货:修改明细单状态为3任务执行完成--失败!"); return; } var finishedCount = db.Queryable().Count(d => d.S_OO_NO == detail.S_OO_NO && d.N_B_STATE == 3); var allCount = db.Queryable().Count(d => d.S_OO_NO == detail.S_OO_NO); LogHelper.Info($"{taskName}--AGV取货--统计任务已完成:{finishedCount}/{allCount}"); if (finishedCount == allCount) { // 当前出库单下的所有明细单,任务都已经完成 if (db.Updateable().SetColumns(it => it.N_B_STATE == 3) .Where(it => it.S_NO == detail.S_OO_NO) .ExecuteCommand() <= 0) { tran.RollbackTran(); LogHelper.Info($"{taskName}--AGV取货--所有任务完成时:修改单据状态为3任务执行完成--失败!"); return; } } tran.CommitTran(); } } public static void PickUpReturnErp(TN_Task task) { var httpH = new HttpHelper(); var model = new OtherModel.PickUpReturnErpInfo(); model.LocCode = task.S_START_LOC; try { var jsonInfo = JsonConvert.SerializeObject(model); var result = httpH.WebPost(Settings.ErpApiUrl + "PickUpReturn", jsonInfo); // TODO } catch (Exception ex) { LogHelper.InfoEx(ex); } } /// /// 任务分发,根据调度类型发给不同的调度系统 /// internal static void Dispatch() { //查询任务 //获取所有等待的任务 var list = WCSHelper.GetWaitingTaskList(); LogHelper.Info("等待任务信息" + JsonConvert.SerializeObject(list), "API"); if (list.Count > 0) { list.ForEach(task => { //使用自定义任务推送 TaskProcess.SendTask(task);//调度NDC或杭奥或国自设备 //TaskProcess.SendGZTask(task);///调度国自设备 }); } else { LogHelper.Info("暂无任务"); } } } }