using DBHelper; using System; using System.Collections.Generic; using System.Linq; using WCS.Core; using WCS.Entity; using WCS.Entity.Protocol; using WCS.Service.Helpers; using WCS.Service.Log; namespace WCS.Service.Extensions { /// /// 任务扩展 /// public static class TaskExtension { public static T Create(this WCS_TASK source) { return (T)Activator.CreateInstance(typeof(T), source); } /// /// 获取可用的出库任务 /// /// /// public static Task[] GetOutTask(this List tasks) { var tasklist = tasks.Select(v => v.Create()); var task = tasklist.FirstOrDefault() ?? throw new WarnException("无可用出库任务--GetOutTask"); //AGV任务ID不为零表示为车间叫料任务 if (task.AgvTask != 0) { //按照AGV任务ID分一次组 tasklist = tasklist.OrderByDescending(v => v.Priority) .ThenBy(v => v.CREATETIME) .GroupBy(v => v.AgvTask) .FirstOrDefault() ?? throw new WarnException("无可用叫料任务--GetOutTask"); //无论这个AGV任务绑定的货物相隔多远都必须要一起出出去 return tasklist.OrderBy(v => v.Col).ToArray(); } return tasklist.OrderByDescending(v => v.Priority) .GroupBy(v => v.MaterialCode) .OrderBy(v => v.Key).FirstOrDefault() .OrderByDescending(v => v.Priority) .ThenBy(v => v.Line) .ThenBy(v => v.Layer) .ThenBy(v => v.Col) .Take(2) .DistinctBy(v => v.Col) .OrderBy(v => v.Col) .ToArray(); } /// /// 获取出库任务的站台号及下一个地址 /// /// 任务 /// 货叉 public static void GetSrmStationAndaddNext(this WCS_TASK task, SrmFork srmFork) { //取任务巷道到达目标地址的下一个地址,即任务堆垛机的站台对应的设备组 var stations = Device.Where(v => v.DEVICEGROUP.Any(p => p.MEMBER == Device.Find(task.TUNNEL).GetPath(task.ADDRTO.Replace("G", "")))) .Select(v => v.Create()) .FirstOrDefault().Items .OrderByDescending(v => v.Entity.CODE) .ToArray(); //一工位放较大的站台号 switch (srmFork) { case SrmFork.货叉1: task.SRMSTATION = stations[0].Entity.CODE; task.ADDRNEXT = stations[0].Entity.GetPath(task.ADDRTO).CODE; break; case SrmFork.货叉2: task.SRMSTATION = stations[1].Entity.CODE; task.ADDRNEXT = stations[1].Entity.GetPath(task.ADDRTO).CODE; break; } } /// /// 有效任务数是否符合任务组任务数 /// /// /// /// public static void ValidTaskCheck(this List tasks, int executable, DB db) { var task = tasks.FirstOrDefault(); var taskCount = db.Default.Set().Count(v => v.TaskGroupKey == task.TaskGroupKey && v.TYPE == TaskType.入库); //开始检查任务数是否匹配 if (executable != taskCount) throw new WarnException($"可执行数{executable},任务组任务数{taskCount},数量不匹配,{task.ID}-{task.TaskGroupKey}"); } /// /// 有效任务数是否符合任务组任务数 临时 /// /// /// /// public static List ValidTaskCheck(this List> devs, DB db) { var taskIds = devs.Select(v => v.Station.Data2.Tasknum).ToList(); var taskList = db.Default.Set().Where(v => taskIds.Contains(v.ID)).ToList(); var task = taskList.FirstOrDefault() ?? throw new WarnException($"ValidTaskCheck 无任务"); ; var taskCount = db.Default.Set().Count(v => v.TaskGroupKey == task.TaskGroupKey && v.TYPE == TaskType.入库); //开始检查任务数是否匹配 if (devs.Count != taskCount) throw new WarnException($"可执行数{devs.Count},任务组任务数{taskCount},数量不匹配,{task.ID}-{task.TaskGroupKey}"); return taskList; } public static void AGVStatusChange(this WCS_AGVTask task, AGVTaskStatus status, string type = "同步") { InfoLog.INFO_AGV($"AGV状态更新Status:{task.Status},AGVStatus:{status},{type}"); } } public enum SrmIndex { 工位一 = 0, 工位二 = 1, } public class Task : WCS_TASK { /// /// 行 /// public short Line { get; set; } /// /// 列 /// public short Col { get; set; } /// /// 层 /// public short Layer { get; set; } public Task(WCS_TASK task) { var addrFrom = task.ADDRFROM.Split("-"); ADDRTO = task.ADDRTO; TUNNEL = task.TUNNEL; DEVICE = task.DEVICE; Priority = task.Priority; AgvTask = task.AgvTask; CREATETIME = task.CREATETIME; MaterialCode = task.MaterialCode; SRMSTATION = task.SRMSTATION; ID = task.ID; Line = addrFrom[0].ToShort(); Col = addrFrom[1].ToShort(); Layer = addrFrom[2].ToShort(); } } }