using CirculateTool.Attribute; using WcsMain.ApiClient.DataEntity.AGVEntity; using WcsMain.Business.AGV; using WcsMain.Business.CommonAction; using WcsMain.Business.Container; using WcsMain.Constant; using WcsMain.DataBase.Dao; using WcsMain.DataBase.TableEntity; using WcsMain.Enum.General; using WcsMain.Enum.Stacker; using WcsMain.EquipOperation.StackerConvey; namespace WcsMain.Business.CirculationTask.Stacker; /// /// 执行仓库任务 /// [Circulation] public class ExecuteWmsTask(AppWmsTaskDao wmsTaskDao, StackerConveyOperation stackerConveyOperation, AGVAction agvAction, ContainerAction containerAction, AppLiftInfoDao liftInfoDao) { /// /// 开始执行任务 /// /// [Circulation("执行任务", 1000)] public bool ExecuteWmsTaskStarter() { /* 执行任务列表任务 */ List? wmsTasks = wmsTaskDao.Select(new AppWmsTask() { TaskStatus = (int)WmsTaskStatusEnum.create }); if(wmsTasks == default) { ConsoleLog.Error("【异常】解析Wms任务时拉取任务列表失败,与数据库连接中断"); Thread.Sleep(5000); return true; } wmsTasks.ForEach(ExecuteTask); /* 出库站台发送AGV接续任务 */ ExecuteAGVOutTask(); return true; } /// /// 执行对应的任务 /// /// private void ExecuteTask(AppWmsTask wmsTask) { switch (wmsTask.TaskType) { case (int)WmsTaskTypeEnum.agv: // AGV 点对点搬运 ExecuteAGVTask(wmsTask); break; case (int)WmsTaskTypeEnum.outTask: ExecuteOutTask(wmsTask); break; case (int)WmsTaskTypeEnum.inTask: ExecuteInTask(wmsTask); break; case (int)WmsTaskTypeEnum.moveTask: ExecuteMoveTask(wmsTask); break; default: break; } } /// /// 执行 AGV 任务 /// /// private void ExecuteAGVTask(AppWmsTask wmsTask) { string errText = agvAction.Send_NO_VERIFY_BUCKET_MOVE(wmsTask); if(!string.IsNullOrEmpty(errText)) { ConsoleLog.Warning($"【警告】AGV点对点搬运请求AGV服务失败,任务号:{wmsTask.TaskId},异常信息:{errText}"); return; } ConsoleLog.Success($"AGV点对点搬运请求AGV服务成功,任务号:{wmsTask.TaskId}"); /* 更新任务状态为执行中 */ var updateResult = wmsTaskDao.Update(new() { TaskId = wmsTask.TaskId, TaskStatus = (int)WmsTaskStatusEnum.running, ModifyTime = DateTime.Now }); ConsoleLog.Success($"更新任务状态结果:{(updateResult > 0 ? "成功" : "失败")},任务号:{wmsTask.TaskId}"); } /// /// 执行入库任务 /// /// private void ExecuteInTask(AppWmsTask wmsTask) { string? midPoint = GetEmptyInLift(wmsTask.Destination); if (string.IsNullOrEmpty(midPoint)) return; // 没有可用的站台 /* 发送AGV 搬运任务 */ string errText = agvAction.Send_AGV_TASK(wmsTask.TaskId, wmsTask.Origin, midPoint); if (!string.IsNullOrEmpty(errText)) { ConsoleLog.Warning($"【警告】入库请求AGV搬运失败,任务号:{wmsTask.TaskId},异常信息:{errText}"); return; } ConsoleLog.Success($"入库搬运请求AGV成功,任务号:{wmsTask.TaskId}"); /* 更新任务状态为前往中间点,更新中间点 */ var updateResult = wmsTaskDao.Update(new() { TaskId = wmsTask.TaskId, MidPoint = midPoint, TaskStatus = (int)WmsTaskStatusEnum.toMid, ModifyTime = DateTime.Now }); ConsoleLog.Success($"更新任务状态结果:{(updateResult > 0 ? "成功" : "失败")},任务号:{wmsTask.TaskId}"); /* 四向车任务有接口返回给四向车 */ } /// /// 执行出库任务 /// /// private void ExecuteOutTask(AppWmsTask wmsTask) { string? midPoint = GetEmptyOutLift(wmsTask.Origin); if(string.IsNullOrEmpty(midPoint)) return; // 没有可用站台 /* 发送四向车搬运任务 */ string? errText = containerAction.ExecuteOutTask(wmsTask.TaskId, wmsTask.Origin, midPoint, wmsTask.VehicleNo); if (!string.IsNullOrEmpty(errText)) { ConsoleLog.Warning($"【警告】入库请求四向车搬运失败,任务号:{wmsTask.TaskId},异常信息:{errText}"); return; } ConsoleLog.Success($"入库搬运请求四向车成功,任务号:{wmsTask.TaskId}"); /* 更新任务状态为前往中间点,更新中间点 */ var updateResult = wmsTaskDao.Update(new() { TaskId = wmsTask.TaskId, MidPoint = midPoint, TaskStatus = (int)WmsTaskStatusEnum.toMid, ModifyTime = DateTime.Now }); ConsoleLog.Success($"更新任务状态结果:{(updateResult > 0 ? "成功" : "失败")},任务号:{wmsTask.TaskId}"); /* AGV接续任务由定时器触发 */ } /// /// 执行 四向车库移库任务 /// /// private void ExecuteMoveTask(AppWmsTask wmsTask) { string errText = containerAction.ExecuteMoveTask(wmsTask); if (!string.IsNullOrEmpty(errText)) { ConsoleLog.Warning($"四向车移库任务请求四向车服务失败,任务号:{wmsTask.TaskId},异常信息:{errText}"); return; } ConsoleLog.Success($"四向车移库任务请求四向车服务成功,任务号:{wmsTask.TaskId}"); /* 更新任务状态为执行中 */ var updateResult = wmsTaskDao.Update(new() { TaskId = wmsTask.TaskId, TaskStatus = (int)WmsTaskStatusEnum.running, ModifyTime = DateTime.Now }); ConsoleLog.Success($"更新任务状态结果:{(updateResult > 0 ? "成功" : "失败")},任务号:{wmsTask.TaskId}"); } /// /// 执行AGV出库任务 /// private void ExecuteAGVOutTask() { List? liftInfos = liftInfoDao.Query(new() { Status = (int)TrueFalseEnum.TRUE }); if (liftInfos == default || liftInfos.Count < 1) return; foreach (var liftInfo in liftInfos) { (string errText, short model, short allowAction, short errCode, string code) = stackerConveyOperation.GetLiftInfo(liftInfo.LiftId ?? ""); if (!string.IsNullOrEmpty(errText)) { ConsoleLog.Warning($"【警告】提升机站台信息获取失败,异常信息:{errText}"); continue; } if (model != 2 || allowAction != (short)TrueFalseEnum.TRUE || errCode != 0) continue; // 不满足执行条件 /* 查找出库任务 */ List? tasks = wmsTaskDao.Select(new() { VehicleNo = code, TaskStatus = (int)WmsTaskStatusEnum.arriveMid })?.OrderByDescending(o => o.CreateTime).ToList(); if(tasks == null || tasks.Count == 0) continue; var task = tasks.First(); /* 下发任务 */ string agvErrText = agvAction.Send_AGV_TASK(task.TaskId, task.MidPoint, task.Destination); if (!string.IsNullOrEmpty(agvErrText)) { ConsoleLog.Warning($"【警告】AGV出库任务请求AGV服务失败,任务号:{task.TaskId},异常信息:{agvErrText}"); return; } /* 更新任务状态为前往终点 */ var updateResult = wmsTaskDao.Update(new() { TaskId = task.TaskId, TaskStatus = (int)WmsTaskStatusEnum.toDestination, ModifyTime = DateTime.Now }); ConsoleLog.Success($"更新任务状态结果:{(updateResult > 0 ? "成功" : "失败")},任务号:{task.TaskId}"); } } /// /// 获取一个空闲的入库站台 /// /// /// private string? GetEmptyInLift(string? destination) { if (string.IsNullOrEmpty(destination)) return default; List? liftInfos = liftInfoDao.Query(new() { Status = (int)TrueFalseEnum.TRUE }); if (liftInfos == default || liftInfos.Count < 1) return default; foreach (var liftInfo in liftInfos) { (string errText, short model, short allowAction, short errCode, string code) = stackerConveyOperation.GetLiftInfo(liftInfo.LiftId ?? ""); if(!string.IsNullOrEmpty(errText)) { ConsoleLog.Warning($"【警告】提升机站台信息获取失败,异常信息:{errText}"); continue; } if (model != 1 || allowAction != (short)TrueFalseEnum.TRUE || errCode != 0) continue; /* 检验任务是否是第一层,若是不是第一层不能分配第一层出入口 */ if (destination.StartsWith("1")) // [TODO] { if (liftInfo.LiftMode != 2) continue; } /* 获取这个站台的任务.没有占用任务即可重新使用 */ List? tasks = wmsTaskDao.Select(new() { MidPoint = liftInfo.Tag, TaskStatus = (int)WmsTaskStatusEnum.toMid }); if (tasks == default || tasks.Count > 0) continue; return liftInfo.Tag; } return default; } /// /// 获取一个空闲的出库站台 /// /// /// private string? GetEmptyOutLift(string? origin) { if (string.IsNullOrEmpty(origin)) return default; Dictionary liftTaskCount = []; List? liftInfos = liftInfoDao.Query(new() { Status = (int)TrueFalseEnum.TRUE }); if (liftInfos == default || liftInfos.Count < 1) return default; foreach (var liftInfo in liftInfos) { (string errText, short model, short allowAction, short errCode, string code) = stackerConveyOperation.GetLiftInfo(liftInfo.LiftId ?? ""); if (!string.IsNullOrEmpty(errText)) { ConsoleLog.Warning($"【警告】提升机站台信息获取失败,异常信息:{errText}"); continue; } if (model != 2 || allowAction != (short)TrueFalseEnum.TRUE || errCode != 0) continue; /* 检验任务是否是第一层,若是不是第一层不能分配第一层出入口 */ if (origin.StartsWith("1")) // [TODO] { if (liftInfo.LiftMode != 2) continue; } /* 获取这个站台的任务.并计数 */ List? tasks = wmsTaskDao.Select(new() { MidPoint = liftInfo.Tag, TaskStatus = (int)WmsTaskStatusEnum.toMid }); if (tasks == default) continue; liftTaskCount.TryAdd(liftInfo.Tag ?? "", tasks.Count); } var sortLiftInfos = liftTaskCount.OrderBy(o => o.Value).ToDictionary(); if(sortLiftInfos.Count > 0) return sortLiftInfos.First().Key; return default; } }