TaskExtension.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using WCS.Core;
  5. using WCS.Core.BaseExtensions;
  6. using WCS.Core.DataTrans;
  7. using WCS.Core.DbHelper;
  8. using WCS.Core.Log;
  9. using WCS.Entity;
  10. using WCS.Entity.Protocol;
  11. using WCS.Service.Helpers;
  12. namespace WCS.Service.Extensions
  13. {
  14. /// <summary>
  15. /// 任务扩展
  16. /// </summary>
  17. public static class TaskExtension
  18. {
  19. public static T Create<T>(this WCS_TASK source)
  20. {
  21. return (T)Activator.CreateInstance(typeof(T), source);
  22. }
  23. /// <summary>
  24. /// 获取可用的出库任务
  25. /// </summary>
  26. /// <param name="tasks"></param>
  27. /// <returns></returns>
  28. public static Task[] GetOutTask(this List<WCS_TASK> tasks)
  29. {
  30. var tasklist = tasks.Select(v => v.Create<Task>());
  31. var task = tasklist.FirstOrDefault() ?? throw new WarnException("无可用出库任务--GetOutTask");
  32. //AGV任务ID不为零表示为车间叫料任务
  33. if (task.AGVTASKID != 0)
  34. {
  35. //按照AGV任务ID分一次组
  36. tasklist = tasklist.OrderByDescending(v => v.Priority)
  37. .ThenBy(v => v.CREATETIME)
  38. .GroupBy(v => v.AGVTASKID)
  39. .FirstOrDefault() ?? throw new WarnException("无可用叫料任务--GetOutTask");
  40. //无论这个AGV任务绑定的货物相隔多远都必须要一起出出去
  41. return tasklist.OrderBy(v => v.Col).ToArray();
  42. }
  43. return tasklist.OrderByDescending(v => v.Priority)
  44. .GroupBy(v => v.MaterialCode)
  45. .OrderBy(v => v.Key).FirstOrDefault()
  46. .OrderByDescending(v => v.Priority)
  47. .ThenBy(v => v.Line)
  48. .ThenBy(v => v.Layer)
  49. .ThenBy(v => v.Col)
  50. .Take(2)
  51. .OrderBy(v => v.Col)
  52. .ToArray();
  53. }
  54. /// <summary>
  55. /// 获取出库任务的站台号及下一个地址
  56. /// </summary>
  57. /// <param name="task">任务</param>
  58. /// <param name="srmFork">货叉</param>
  59. public static void GetSrmStationAndaddNext(this WCS_TASK task, SrmFork srmFork)
  60. {
  61. //取任务巷道到达目标地址的下一个地址,即任务堆垛机的站台对应的设备组
  62. var stations = Device.Where(v => v.DEVICEGROUP.Any(p => p.MEMBER == Device.Find(task.TUNNEL).GetPath(task.ADDRTO.Replace("G", ""))))
  63. .Select(v => v.Create<StationDeviceGroup>())
  64. .FirstOrDefault()?.Items
  65. .OrderByDescending(v => v.Entity.CODE)
  66. .ToArray();
  67. //一工位放较大的站台号
  68. switch (srmFork)
  69. {
  70. case SrmFork.货叉1:
  71. task.SRMSTATION = stations?[0].Entity.CODE;
  72. task.ADDRNEXT = stations?[0].Entity.GetPath(task.ADDRTO).CODE;
  73. break;
  74. case SrmFork.货叉2:
  75. task.SRMSTATION = stations?[1].Entity.CODE;
  76. task.ADDRNEXT = stations?[1].Entity.GetPath(task.ADDRTO).CODE;
  77. break;
  78. }
  79. }
  80. /// <summary>
  81. /// 有效任务数是否符合任务组任务数
  82. /// </summary>
  83. /// <param name="tasks"></param>
  84. /// <param name="executable"></param>
  85. /// <param name="db"></param>
  86. public static void ValidTaskCheck(this List<WCS_TASK> tasks, int executable, Db db)
  87. {
  88. var task = tasks.FirstOrDefault();
  89. var taskCount = db.Default.Queryable<WCS_TASK>().Count(v => v.TaskGroupKey == task.TaskGroupKey && v.TYPE == TaskType.入库);
  90. //开始检查任务数是否匹配
  91. if (executable != taskCount) throw new WarnException($"可执行数{executable},任务组任务数{taskCount},数量不匹配,{task.ID}-{task.TaskGroupKey}");
  92. }
  93. /// <summary>
  94. /// 有效任务数是否符合任务组任务数 临时
  95. /// </summary>
  96. /// <param name="tasks"></param>
  97. /// <param name="executable"></param>
  98. /// <param name="db"></param>
  99. public static List<WCS_TASK> ValidTaskCheck(this List<FinishTaskList<string>> devs, Db db)
  100. {
  101. var taskIds = devs.Select(v => v.Station.Data2.Tasknum).ToList();
  102. var taskList = db.Default.Queryable<WCS_TASK>().Where(v => taskIds.Contains(v.ID)).ToList();
  103. var task = taskList.FirstOrDefault() ?? throw new WarnException($"ValidTaskCheck 无任务"); ;
  104. var taskCount = db.Default.Queryable<WCS_TASK>().Count(v => v.TaskGroupKey == task.TaskGroupKey && v.TYPE == TaskType.入库);
  105. //开始检查任务数是否匹配
  106. if (devs.Count != taskCount) throw new WarnException($"可执行数{devs.Count},任务组任务数{taskCount},数量不匹配,{task.ID}-{task.TaskGroupKey}");
  107. return taskList;
  108. }
  109. /// <summary>
  110. /// 用于任务创建时获取放货站台
  111. /// </summary>
  112. /// <param name="task"></param>
  113. public static void TaskGetSrmStation(this WCS_TASK task)
  114. {
  115. task.GetSrmStationAndaddNext(SrmFork.货叉1);
  116. task.SRMSTATION = Device.Where(v => v.IsDevGroup()).FirstOrDefault(v => v.DEVICEGROUP.Any(b => b.MEMBER.CODE == task.SRMSTATION))?.CODE;
  117. task.ADDRNEXT = string.Empty;
  118. }
  119. public static void AGVStatusChange(this WCS_AGVTask task, AGVTaskStatus status, string type = "同步")
  120. {
  121. InfoLog.INFO_AGV($"AGV状态更新Status:{task.Status},AGVStatus:{status},{type}");
  122. }
  123. }
  124. public enum SrmIndex
  125. {
  126. 工位一 = 0,
  127. 工位二 = 1,
  128. }
  129. public class Task : WCS_TASK
  130. {
  131. /// <summary>
  132. /// 行
  133. /// </summary>
  134. public short Line { get; set; }
  135. /// <summary>
  136. /// 列
  137. /// </summary>
  138. public short Col { get; set; }
  139. /// <summary>
  140. /// 层
  141. /// </summary>
  142. public short Layer { get; set; }
  143. public Task(WCS_TASK task)
  144. {
  145. var addrFrom = task.ADDRFROM.Split("-");
  146. ADDRTO = task.ADDRTO;
  147. TUNNEL = task.TUNNEL;
  148. DEVICE = task.DEVICE;
  149. Priority = task.Priority;
  150. AGVTASKID = task.AGVTASKID;
  151. CREATETIME = task.CREATETIME;
  152. MaterialCode = task.MaterialCode;
  153. SRMSTATION = task.SRMSTATION;
  154. ID = task.ID;
  155. Line = addrFrom[0].ToShort();
  156. Col = addrFrom[1].ToShort();
  157. Layer = addrFrom[2].ToShort();
  158. }
  159. }
  160. }