using PlcSiemens.Core.Extension; using ServiceCenter.Extensions; using ServiceCenter.Logs; using ServiceCenter.SqlSugars; using SqlSugar; using System.ComponentModel; using WCS.Core; using WCS.Entity; using WCS.Entity.Protocol.Station; using WCS.WorkEngineering.Extensions; using WCS.WorkEngineering.Worlds; using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags; using TaskStatus = WCS.Entity.TaskStatus; namespace WCS.WorkEngineering.Systems { /// /// 无交互系统 /// [BelongTo(typeof(NoInteractionWorld))] [Description("无交互系统")] public class NoInteractionSystems : DeviceSystem> { protected override bool ParallelDo => true; public override void Do(Device obj) { var taskInfos = new List(); var sqlSugar = new SqlSugarHelper(); SqlSugarHelper.Do(db => { //获取所有的新建任务,组盘任务不需要 taskInfos = db.Default.Queryable().ReadPastUpdLock().Where(x => x.Status == 0).ToList() .Where(x => x.Type != TaskType.SetPlate || (x.Type == TaskType.SetPlate && x.AddrFrom != "Robot")).Where(x => x.BusType != "人工满托入库").Select(x => x.ID).ToList(); var time = DateTime.Now.AddMinutes(-20); var time1 = DateTime.Now.AddMinutes(-40); var timeOut = db.Default.Queryable().NoLock().Count(x => x.BusType == "车间叫料" && x.Status < TaskStatus.StackerExecution && x.AddTime < time); if (timeOut > 0) World.Log($"共有{timeOut}个车间叫料任务超过二十分钟未执行,请检查相关相关任务对应的堆垛机是否正常、堆垛机放货点是否卡任务等", LogLevelEnum.High); var timeOut1 = db.Default.Queryable().NoLock().Count(x => x.BusType == "车间叫料" && x.Status < TaskStatus.StackerExecution && x.AddTime < time1); if (timeOut1 > 0) World.Log($"共有{timeOut1}个车间叫料任务超过四十分钟未执行,请检查相关相关任务对应的堆垛机是否正常、堆垛机放货点是否卡任务等", LogLevelEnum.High); var timeOut2 = db.Default.Queryable().NoLock().Count(x => x.BusType == "皮盘入库" && x.Status < TaskStatus.StackerExecution && x.AddTime < time); if (timeOut2 > 0) World.Log($"共有{timeOut2}个皮盘入库任务超过二十分钟未执行,请检查相关相关任务及对应agv设备", LogLevelEnum.High); var timeOut3 = db.Default.Queryable().NoLock().Count(x => x.BusType == "皮盘入库" && x.Status < TaskStatus.StackerExecution && x.AddTime < time1); if (timeOut3 > 0) World.Log($"共有{timeOut3}个皮盘入库任务超过四十分钟未执行,请检查相关相关任务及对应agv设备", LogLevelEnum.High); var time3 = DateTime.Now.AddHours(-24); var timeOut4 = db.Default.Queryable().NoLock().Count(x => x.AddTime < time3); if (timeOut4 > 0) World.Log($"共有{timeOut4}个库存信息超过24小时未执行,请检查相关库存信息并处理", LogLevelEnum.High); }); if (!taskInfos.Any()) { return; } var isEnd = false; //每个周期只处理一个任务 foreach (var item in taskInfos) { if (isEnd) return; try { SqlSugarHelper.Do(db => { var task = db.Default.Queryable().Where(t => t.ID == item).First(); switch (task.Type) { case TaskType.SetPlate: if (task.AddrFrom != "Robot") { //更新任务状态 task.Status = TaskStatus.WaitingToExecute; db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化入库任务信息"); isEnd = true; } break; case TaskType.EnterDepot: if (task.LastInteractionPoint == "2") { var sta = GetAgvStation(task, db); var agv = new WCS_AgvTaskInfo() { ID = db.GetAgvTaskId(), TaskType = AGVTaskType.EnterDepot, Status = AGVTaskStatus.NewBuild, TaskId = task.ID, Position = task.WorkBench, Station = sta, AddWho = "WCS", AddTime = DateTime.Now }; db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand(); task.AgvTaskID = agv.ID; task.Status = Entity.TaskStatus.WaitingToExecute; db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.AgvTaskID }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化单独返皮盘任务"); } else { //更新任务状态 task.Status = Entity.TaskStatus.WaitingToExecute; task.Device = task.WarehouseCode switch { "1N" => "SRM1", "1S" => "SRM2", "2N" => "SRM3", "2S" => "SRM4", "3N" => "SRM5", "3S" => "SRM6", _ => task.Device }; task.Device = task.AddrFrom switch { "1666" or "1661" => "SRM1", "1681" or "1676" => "SRM2", "1696" or "1691" => "SRM3", "1711" or "1706" => "SRM4", "1726" or "1721" => "SRM5", "1741" or "1736" => "SRM6", _ => task.Device }; //计算下一个地址 var path1 = DevicePath.GetPath(task.AddrFrom, task.Device); task.AddrNext = path1.Points[1].Code; task.SrmStation = task.BarCode.Contains("TPA") || task.BarCode.Contains("TPB") ? task.AddrFrom : path1.Points[2].Code; db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.Device, x.AddrNext, x.SrmStation }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化入库任务信息"); } isEnd = true; break; case TaskType.OutDepot: { if (task.Device.Contains("Robot")) { var lastTask = db.Default.Queryable().NoLock().First(x => x.Type == TaskType.OutDepot && x.AddrTo == task.AddrTo && x.Status > TaskStatus.WaitingToExecute && x.Status < TaskStatus.Finish); if (lastTask != null) { World.Log($"等待任务结束:{task.AddrTo}上一组码垛任务未结束,等待{lastTask.ID}任务完成后开始初始化当前任务{task.ID}"); return; } var pos = task.AddrFrom.Split("-"); task.Status = Entity.TaskStatus.WaitingToExecute; task.Line = pos[0].ToShort(); task.Col = pos[1].ToShort(); task.Layer = pos[2].ToShort(); task.Depth = pos[3].ToShort(); db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.Line, x.Col, x.Layer, x.Depth }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化出库任务信息,放货站台:{task.SrmStation}"); isEnd = true; } else { if (task.SrmStation == "1") { var srmStation = new string[2]; switch (task.Device) { case "SRM1": srmStation[0] = "2534"; srmStation[1] = "2533"; break; case "SRM2": srmStation[0] = "2734"; srmStation[1] = "2733"; break; case "SRM3": srmStation[0] = "2934"; srmStation[1] = "2933"; break; case "SRM4": srmStation[0] = "3134"; srmStation[1] = "3133"; break; case "SRM5": srmStation[0] = "3334"; srmStation[1] = "3333"; break; case "SRM6": srmStation[0] = "3534"; srmStation[1] = "3533"; break; } //开始计算当前这个任务要从哪个站台出 //计算两个站台小于取货完成数量的AGV任务 var agv1 = db.Default.Queryable().NoLock().Where(x => x.Status <= TaskStatus.StackerExecution && x.AddrTo == srmStation[0]).Count(); var agv2 = db.Default.Queryable().NoLock().Where(x => x.Status <= TaskStatus.StackerExecution && x.AddrTo == srmStation[1]).Count(); task.SrmStation = ""; task.AddrTo = agv1 > agv2 ? srmStation[1] : srmStation[0]; } if (task.SrmStation.IsNullOrEmpty()) //如果没有指定放货站台 { if (task.Device.IsNullOrEmpty()) { task.Device = "SRM" + task.Tunnel.GetLastDigit(); } //获取堆垛机到目标地址的路径信息 var path = DevicePath.GetPath(task.Device, task.AddrTo); task.SrmStation = path.Points[1].Code; } var devs = Device.All.Where(x => x.HasFlag(DeviceFlags.AGV取货站台口)).Select(x => x.Code); if (devs.Contains(task.SrmStation) && task.LastInteractionPoint != "3") //车间叫料任务,此值为3时是单独取满任务 { var sta = GetAgvStation(task, db); var agv = new WCS_AgvTaskInfo() { ID = db.GetAgvTaskId(), TaskType = AGVTaskType.EnterDepot, Status = AGVTaskStatus.NewBuild, TaskId = task.ID, Position = task.WorkBench, Station = sta, AddWho = "WCS", AddTime = DateTime.Now }; db.Default.InsertableRowLock(agv).SplitTable().ExecuteCommand(); } //更新任务状态 task.Status = Entity.TaskStatus.WaitingToExecute; db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.SrmStation, x.AddrTo, x.Status }).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, task.Device, $"初始化出库任务信息,放货站台:{task.SrmStation}"); isEnd = true; } break; } case TaskType.Delivery: break; case TaskType.EmptyInit: break; } }); } catch (Exception ex) { if (ex.Message.Contains("Index")) World.Log($"{ex.Message}:{ex.StackTrace}"); if (ex.Message.Contains("SqlTransaction")) World.Log($"{ex.Message}:{ex.StackTrace}"); World.Log(ex.Message, LogLevelEnum.Mid); } } } public override bool Select(Device dev) { return dev.Code == nameof(NoInteractionSystems); } /// /// 获取AGV的目标站台 /// /// /// /// public string GetAgvStation(WCS_TaskInfo task, SqlSugarHelper db) { string sta = ""; var n = 0; var s = 0; //同侧之间均分 if (task.WarehouseCode.Contains("1")) { n = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station.Contains("25")) .SplitTable(v => v.Take(2)).Count(); s = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station.Contains("27")) .SplitTable(v => v.Take(2)).Count(); sta = n > s ? "2701" : "2501"; } else if (task.WarehouseCode.Contains("2")) { n = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station.Contains("29")) .SplitTable(v => v.Take(2)).Count(); s = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station.Contains("31")) .SplitTable(v => v.Take(2)).Count(); sta = n > s ? "3101" : "2901"; } else if (task.WarehouseCode.Contains("3")) { n = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station.Contains("33")) .SplitTable(v => v.Take(2)).Count(); s = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station.Contains("35")) .SplitTable(v => v.Take(2)).Count(); sta = n > s ? "3501" : "3301"; } else { return default; } n = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot && v.Station == sta) .SplitTable(v => v.Take(2)).Count(); if (n > 5) { sta = db.Default.Queryable().NoLock().Where(v => v.Status >= AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.Complete1 && v.TaskType == AGVTaskType.EnterDepot) .SplitTable(v => v.Take(2)).ToList().GroupBy(x => x.Station).Select(x => new { x.Key, Count = x.Count() }).MinBy(x => x.Count).Key; } return sta; } } }