using ServiceCenter.Logs; using ServiceCenter.Redis; using ServiceCenter.SqlSugars; using System; using System.ComponentModel; using WCS.Core; using WCS.Entity; using WCS.WorkEngineering.Extensions; using WCS.WorkEngineering.WebApi.Controllers; using WCS.WorkEngineering.Worlds; using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags; namespace WCS.WorkEngineering.Systems { /// /// 出库站台交互 /// [BelongTo(typeof(MainWorld))] [Description("一楼出库工位处理系统")] public class 一楼出库工位处理系统 : DeviceSystem { protected override bool ParallelDo => true; protected override bool SaveLogsToFile => true; public override void Do(Station obj) { var key = $"WCS:Lock:{obj.Entity.Code}"; try { if (RedisHub.Default.Get(key) != null) { throw new KnownException($"[{obj.Entity.Code}]--触发并发管控", LogLevelEnum.High); } RedisHub.Default.Set(key, obj.Entity.Code); if (!obj.Data3.Status.HasFlag(Entity.Protocol.Station.StatusEunm.PH_Status) && !obj.Data3.Status.HasFlag(Entity.Protocol.Station.StatusEunm.OT_Status)) { bool result = true; //是否需要申请出库任务,默认需要 SqlSugarHelper.Do(db => { //当前站台是否有任务在执行 var task = db.Default.Queryable().Where(v => v.AddrTo == obj.Entity.Code && v.Status < Entity.TaskStatus.AGVExecution).OrderByDescending(v => v.AddTime).First(); if (db.Default.Queryable().Where(v => v.AddrTo == obj.Entity.Code && v.Status == Entity.TaskStatus.WaitingToExecute).Count() > 1) return; if (task != null && (task.BusType == "一楼立库出空轮" || task.TaskGroupKey == "1")) //有任务 { if (task.AgvTaskID == 0) throw new KnownException($"WCS任务[{task.ID}],还没有下发给AGV", LogLevelEnum.Mid); else { //检查对应的AGV任务状态是否大于退出储位状态 var agv = db.Default.Queryable().SplitTable(v => v.Take(2)).First(v => v.ID == task.ID) ?? throw new KnownException($"未找到AGV中间表任务[{task.AgvTaskID}],请检查异常原因", LogLevelEnum.Mid); if (agv == null) { } else if (agv.AgvStatus >= AGVTaskStatus.Complete3) { result = true; } else { result = false; } } } else //无任务 { //判断有没有二楼分配过巷道的空轮任务 string tunnel = ""; switch (obj.Entity.Code) { case "1012": tunnel = "1"; break; case "1014": tunnel = "2"; break; case "1016": tunnel = "3"; break; case "1118" or "1131" or "1132" or "1133" or "1134" or "1135" or "1136" or "1137" or "1139": tunnel = "4"; break; } if (db.Default.Queryable().Where(v => v.Tunnel == tunnel && v.Type == TaskType.EnterDepot && v.BusType == "二楼湿拉空轮回立库").Any()) { result = false; } else { result = true; } } }); if (result) WmsApi.ApplyStockOutTask(obj.Entity.Code); } //下发满轮任务到agv else { SqlSugarHelper.Do(db => { var task = db.Default.Queryable().Where(v => v.ID == obj.Data.TaskNumber && v.Status == Entity.TaskStatus.ConveyorExecution).First(); if (task != null && (task.BusType == "一楼立库出空轮" || task.TaskGroupKey == "1")) //有任务 { if (task.AgvTaskID > 0 && task.BusType == "一楼立库出空轮") { //直接下发给agv SqlSugarHelper.Do(db => { //当前站台是否有任务在执行 var task = db.Default.Queryable().Where(v => v.ID == obj.Data.TaskNumber && v.Status == Entity.TaskStatus.ConveyorExecution).First(); if (task == null) throw new KnownException($"未找到空轮wcs任务{obj.Data.TaskNumber},请检查光电或任务状态", LogLevelEnum.Low); var agvTask = db.Default.Queryable().SplitTable(v => v.Take(2)).Where(v => v.ID == task.AgvTaskID).First(); if (agvTask == null) { throw new KnownException($"未找到AGV中间表任务[{task.AgvTaskID}],请检查异常原因", LogLevelEnum.Mid); } if (string.IsNullOrEmpty(agvTask.AgvID)) { var res = AgvApi.一楼空轮出库下发AGV(task.BarCode + "@", task.AddrTo, task.AddrTo, Guid.NewGuid().ToString().Replace("-", ""), "1"); agvTask.Status = AGVTaskStatus.Confirm; agvTask.AgvID = res.data; db.Default.Updateable(agvTask).SplitTable(x => x.Take(2)).ExecuteCommand(); //更新WCS数据 task.Status = Entity.TaskStatus.AGVExecution; db.Default.Updateable(task).ExecuteCommand(); task.AddWCS_TASK_DTL(db, task.Device, $"任务下发至AGV-AGV任务ID{agvTask.AgvID}"); } }); //throw new KnownException($"WCS任务[{task.ID}],等待AGV申请任务", LogLevelEnum.Mid); } else if (task.TaskGroupKey == "1" && !db.Default.Queryable().SplitTable(v => v.Take(2)).Where(v => v.ID == task.AgvTaskID && v.TaskType == AGVTaskType.CallForMaterial).Any()) { //直接下发给agv SqlSugarHelper.Do(db => { //当前站台是否有任务在执行 var task = db.Default.Queryable().Where(v => v.ID == obj.Data.TaskNumber && v.Status == Entity.TaskStatus.ConveyorExecution).First(); if (task == null) throw new KnownException($"未找到空轮wcs任务{obj.Data.TaskNumber},请检查光电或任务状态", LogLevelEnum.Low); var agvTask1 = db.Default.Queryable().SplitTable(v => v.Take(2)).Where(v => v.ID == task.AgvTaskID && v.Status < AGVTaskStatus.MissionCompleted).First(); if (agvTask1 != null) { throw new KnownException($"[{task.AgvTaskID}]已经存在AGV任务,不需要重复下发", LogLevelEnum.Mid); } var res = AgvApi.一楼空轮出库下发AGV(task.BarCode+"@", task.AddrTo, task.AddrTo, Guid.NewGuid().ToString().Replace("-", ""), "1"); //创建AGV任务 var agvTask = new WCS_AgvTaskInfo() { ID = db.GetAGVTaskId(), TaskType = AGVTaskType.CallForMaterial, Status = AGVTaskStatus.Confirm, Station = task.SrmStation, Position = task.AddrTo, AgvID = res.data, AddWho = "WCS" }; db.Default.Insertable(agvTask).SplitTable().ExecuteCommand(); task.AgvTaskID = agvTask.ID; //更新WCS数据 task.Status = Entity.TaskStatus.AGVExecution; db.Default.Updateable(task).ExecuteCommand(); task.AddWCS_TASK_DTL(db, task.Device, $"任务下发至AGV-AGV任务ID{agvTask.AgvID}"); }); } } else { //当前站台是否有任务在执行 if (task == null) throw new KnownException($"未找到wcs任务{obj.Data.TaskNumber},请检查光电或任务状态", LogLevelEnum.Low); if (task.BusType == "一楼出满轮" && task.AgvTaskID > 0) { var agvTask = db.Default.Queryable().SplitTable(v => v.Take(2)).Where(v => v.ID == task.AgvTaskID).First(); if (agvTask == null) { throw new KnownException($"未找到AGV中间表任务[{task.AgvTaskID}],请检查异常原因", LogLevelEnum.Mid); } var res = AgvApi.一楼满轮出库(task.BarCode, agvTask.Station, agvTask.Position, Guid.NewGuid().ToString().Replace("-", ""), "1"); agvTask.Status = AGVTaskStatus.Confirm; agvTask.AgvID = res.data; db.Default.Updateable(agvTask).SplitTable(x => x.Take(2)).ExecuteCommand(); //更新WCS数据 task.Status = Entity.TaskStatus.AGVExecution; db.Default.Updateable(task).ExecuteCommand(); task.AddWCS_TASK_DTL(db, task.Device, $"任务下发至AGV-AGV任务ID{agvTask.AgvID}"); } } }); } } finally { RedisHub.Default.Del(key); } } public override bool Select(Device dev) { return dev.HasFlag(DeviceFlags.一楼出库口); } } }