一楼出库工位处理系统.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. using ServiceCenter.Logs;
  2. using ServiceCenter.Redis;
  3. using ServiceCenter.SqlSugars;
  4. using System;
  5. using System.ComponentModel;
  6. using WCS.Core;
  7. using WCS.Entity;
  8. using WCS.WorkEngineering.Extensions;
  9. using WCS.WorkEngineering.WebApi.Controllers;
  10. using WCS.WorkEngineering.Worlds;
  11. using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
  12. namespace WCS.WorkEngineering.Systems
  13. {
  14. /// <summary>
  15. /// 出库站台交互
  16. /// </summary>
  17. [BelongTo(typeof(MainWorld))]
  18. [Description("一楼出库工位处理系统")]
  19. public class 一楼出库工位处理系统 : DeviceSystem<Station>
  20. {
  21. protected override bool ParallelDo => true;
  22. protected override bool SaveLogsToFile => true;
  23. public override void Do(Station obj)
  24. {
  25. var key = $"WCS:Lock:{obj.Entity.Code}";
  26. try
  27. {
  28. if (RedisHub.Default.Get(key) != null)
  29. {
  30. throw new KnownException($"[{obj.Entity.Code}]--触发并发管控", LogLevelEnum.High);
  31. }
  32. RedisHub.Default.Set(key, obj.Entity.Code);
  33. if (!obj.Data3.Status.HasFlag(Entity.Protocol.Station.StatusEunm.PH_Status) && !obj.Data3.Status.HasFlag(Entity.Protocol.Station.StatusEunm.OT_Status))
  34. {
  35. bool result = true; //是否需要申请出库任务,默认需要
  36. SqlSugarHelper.Do(db =>
  37. {
  38. //当前站台是否有任务在执行
  39. var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.AddrTo == obj.Entity.Code && v.Status < Entity.TaskStatus.AGVExecution).OrderByDescending(v => v.AddTime).First();
  40. if (db.Default.Queryable<WCS_TaskInfo>().Where(v => v.AddrTo == obj.Entity.Code && v.Status == Entity.TaskStatus.WaitingToExecute).Count() > 1) return;
  41. if (task != null && (task.BusType == "一楼立库出空轮" || task.TaskGroupKey == "1")) //有任务
  42. {
  43. if (task.AgvTaskID == 0) throw new KnownException($"WCS任务[{task.ID}],还没有下发给AGV", LogLevelEnum.Mid);
  44. else
  45. {
  46. //检查对应的AGV任务状态是否大于退出储位状态
  47. var agv = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(2)).First(v => v.ID == task.ID) ?? throw new KnownException($"未找到AGV中间表任务[{task.AgvTaskID}],请检查异常原因", LogLevelEnum.Mid);
  48. if (agv == null)
  49. {
  50. }
  51. else if (agv.AgvStatus >= AGVTaskStatus.Complete3)
  52. {
  53. result = true;
  54. }
  55. else
  56. {
  57. result = false;
  58. }
  59. }
  60. }
  61. else //无任务
  62. {
  63. //判断有没有二楼分配过巷道的空轮任务
  64. string tunnel = "";
  65. switch (obj.Entity.Code)
  66. {
  67. case "1012":
  68. tunnel = "1";
  69. break;
  70. case "1014":
  71. tunnel = "2";
  72. break;
  73. case "1016":
  74. tunnel = "3";
  75. break;
  76. case "1118" or "1131" or "1132" or "1133" or "1134" or "1135" or "1136" or "1137" or "1139":
  77. tunnel = "4";
  78. break;
  79. }
  80. if (db.Default.Queryable<WCS_TaskInfo>().Where(v => v.Tunnel == tunnel && v.Type == TaskType.EnterDepot && v.BusType == "二楼湿拉空轮回立库").Any())
  81. {
  82. result = false;
  83. }
  84. else
  85. {
  86. result = true;
  87. }
  88. }
  89. });
  90. if (result) WmsApi.ApplyStockOutTask(obj.Entity.Code);
  91. }
  92. //下发满轮任务到agv
  93. else
  94. {
  95. SqlSugarHelper.Do(db =>
  96. {
  97. var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.ID == obj.Data.TaskNumber && v.Status == Entity.TaskStatus.ConveyorExecution).First();
  98. if (task != null && (task.BusType == "一楼立库出空轮" || task.TaskGroupKey == "1")) //有任务
  99. {
  100. if (task.AgvTaskID > 0 && task.BusType == "一楼立库出空轮")
  101. {
  102. //直接下发给agv
  103. SqlSugarHelper.Do(db =>
  104. {
  105. //当前站台是否有任务在执行
  106. var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.ID == obj.Data.TaskNumber && v.Status == Entity.TaskStatus.ConveyorExecution).First();
  107. if (task == null) throw new KnownException($"未找到空轮wcs任务{obj.Data.TaskNumber},请检查光电或任务状态", LogLevelEnum.Low);
  108. var agvTask = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(2)).Where(v => v.ID == task.AgvTaskID).First();
  109. if (agvTask == null)
  110. {
  111. throw new KnownException($"未找到AGV中间表任务[{task.AgvTaskID}],请检查异常原因", LogLevelEnum.Mid);
  112. }
  113. if (string.IsNullOrEmpty(agvTask.AgvID))
  114. {
  115. var res = AgvApi.一楼空轮出库下发AGV(task.BarCode + "@", task.AddrTo, task.AddrTo, Guid.NewGuid().ToString().Replace("-", ""), "1");
  116. agvTask.Status = AGVTaskStatus.Confirm;
  117. agvTask.AgvID = res.data;
  118. db.Default.Updateable(agvTask).SplitTable(x => x.Take(2)).ExecuteCommand();
  119. //更新WCS数据
  120. task.Status = Entity.TaskStatus.AGVExecution;
  121. db.Default.Updateable(task).ExecuteCommand();
  122. task.AddWCS_TASK_DTL(db, task.Device, $"任务下发至AGV-AGV任务ID{agvTask.AgvID}");
  123. }
  124. });
  125. //throw new KnownException($"WCS任务[{task.ID}],等待AGV申请任务", LogLevelEnum.Mid);
  126. }
  127. else if (task.TaskGroupKey == "1" && !db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(2)).Where(v => v.ID == task.AgvTaskID && v.TaskType == AGVTaskType.CallForMaterial).Any())
  128. {
  129. //直接下发给agv
  130. SqlSugarHelper.Do(db =>
  131. {
  132. //当前站台是否有任务在执行
  133. var task = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.ID == obj.Data.TaskNumber && v.Status == Entity.TaskStatus.ConveyorExecution).First();
  134. if (task == null) throw new KnownException($"未找到空轮wcs任务{obj.Data.TaskNumber},请检查光电或任务状态", LogLevelEnum.Low);
  135. var agvTask1 = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(2)).Where(v => v.ID == task.AgvTaskID && v.Status < AGVTaskStatus.MissionCompleted).First();
  136. if (agvTask1 != null)
  137. {
  138. throw new KnownException($"[{task.AgvTaskID}]已经存在AGV任务,不需要重复下发", LogLevelEnum.Mid);
  139. }
  140. var res = AgvApi.一楼空轮出库下发AGV(task.BarCode+"@", task.AddrTo, task.AddrTo, Guid.NewGuid().ToString().Replace("-", ""), "1");
  141. //创建AGV任务
  142. var agvTask = new WCS_AgvTaskInfo()
  143. {
  144. ID = db.GetAGVTaskId(),
  145. TaskType = AGVTaskType.CallForMaterial,
  146. Status = AGVTaskStatus.Confirm,
  147. Station = task.SrmStation,
  148. Position = task.AddrTo,
  149. AgvID = res.data,
  150. AddWho = "WCS"
  151. };
  152. db.Default.Insertable(agvTask).SplitTable().ExecuteCommand();
  153. task.AgvTaskID = agvTask.ID;
  154. //更新WCS数据
  155. task.Status = Entity.TaskStatus.AGVExecution;
  156. db.Default.Updateable(task).ExecuteCommand();
  157. task.AddWCS_TASK_DTL(db, task.Device, $"任务下发至AGV-AGV任务ID{agvTask.AgvID}");
  158. });
  159. }
  160. }
  161. else
  162. {
  163. //当前站台是否有任务在执行
  164. if (task == null) throw new KnownException($"未找到wcs任务{obj.Data.TaskNumber},请检查光电或任务状态", LogLevelEnum.Low);
  165. if (task.BusType == "一楼出满轮" && task.AgvTaskID > 0)
  166. {
  167. var agvTask = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(2)).Where(v => v.ID == task.AgvTaskID).First();
  168. if (agvTask == null)
  169. {
  170. throw new KnownException($"未找到AGV中间表任务[{task.AgvTaskID}],请检查异常原因", LogLevelEnum.Mid);
  171. }
  172. var res = AgvApi.一楼满轮出库(task.BarCode, agvTask.Station, agvTask.Position, Guid.NewGuid().ToString().Replace("-", ""), "1");
  173. agvTask.Status = AGVTaskStatus.Confirm;
  174. agvTask.AgvID = res.data;
  175. db.Default.Updateable(agvTask).SplitTable(x => x.Take(2)).ExecuteCommand();
  176. //更新WCS数据
  177. task.Status = Entity.TaskStatus.AGVExecution;
  178. db.Default.Updateable(task).ExecuteCommand();
  179. task.AddWCS_TASK_DTL(db, task.Device, $"任务下发至AGV-AGV任务ID{agvTask.AgvID}");
  180. }
  181. }
  182. });
  183. }
  184. }
  185. finally
  186. {
  187. RedisHub.Default.Del(key);
  188. }
  189. }
  190. public override bool Select(Device dev)
  191. {
  192. return dev.HasFlag(DeviceFlags.一楼出库口);
  193. }
  194. }
  195. }