一楼入库巷道分配处理系统.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. using ServiceCenter.Extensions;
  2. using ServiceCenter.Logs;
  3. using ServiceCenter.SqlSugars;
  4. using System.ComponentModel;
  5. using WCS.Core;
  6. using WCS.Entity;
  7. using WCS.WorkEngineering.Extensions;
  8. using WCS.WorkEngineering.Protocol.BCR;
  9. using WCS.WorkEngineering.Protocol.SRM;
  10. using WCS.WorkEngineering.Protocol.Station;
  11. using WCS.WorkEngineering.WebApi.Controllers;
  12. using WCS.WorkEngineering.Worlds;
  13. using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
  14. namespace WCS.WorkEngineering.Systems
  15. {
  16. /// <summary>
  17. /// 一楼入库巷道分配处理系统
  18. /// </summary>
  19. [BelongTo(typeof(MainWorld))]
  20. [Description("一楼入库巷道分配处理系统")]
  21. public class 一楼入库巷道分配处理系统 : DeviceSystem<Station>
  22. {
  23. protected override bool ParallelDo => true;
  24. protected override bool SaveLogsToFile => true;
  25. private List<Device<IBCR81>> BCRS = new List<Device<IBCR81>>();
  26. private List<Station> devs = new List<Station>();
  27. private List<Station> sta = new List<Station>();
  28. private List<SRM> srms = new List<SRM>();
  29. public 一楼入库巷道分配处理系统()
  30. {
  31. BCRS = Device.All.Where(v => v.HasProtocol<IBCR81>()).Select(x=>new Device<IBCR81>(x,World)).ToList();
  32. devs = Device.All.Where(v => v.HasFlag(DeviceFlags.入库, DeviceFlags.巷道口)).Select(v => new Station(v, this.World)).ToList();
  33. sta = Device.All.Where(v => v.HasFlag(DeviceFlags.检测门)).Select(v => new Station(v, this.World)).ToList();
  34. srms = Device.All.Where(v => v.HasProtocol(typeof(ISRM520))).Select(v => new SRM(v, this.World)).ToList();
  35. }
  36. public override void Do(Station obj)
  37. {
  38. obj.入库站点是否被禁止();
  39. obj.入库站点是否满足执行条件();
  40. WCS_TaskInfo task = null;//处理完成的任务
  41. WCS_TaskInfo taskInfo = null;
  42. try
  43. {
  44. SqlSugarHelper.Do(_db =>
  45. {
  46. var db = _db.Default;
  47. //扫码信号交互
  48. var agvTaskCur = db.Queryable<WCS_AgvTaskInfo>().SplitTable().First(v => v.AgvStatus == AGVTaskStatus.RequestOrPermission1 && v.Status != AGVTaskStatus.Complete1 && v.Position == obj.Entity.Code);
  49. if (agvTaskCur != null)
  50. {
  51. var dev = sta.Find(v => v.Entity.Code == obj.Entity.Code);
  52. var taskCur = db.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agvTaskCur.ID);
  53. if (taskCur != null && dev.Data2.GoodsStart == 0)
  54. {
  55. obj.Data.GoodsStart = obj.Entity.Code.ToShort();
  56. }
  57. }
  58. else
  59. {
  60. return;
  61. }
  62. //获取RFID
  63. var barentity = BCRS.Where(p => p.Entity.Code == "BCR" + obj.Entity.Code).First();
  64. var bardata = barentity.Data;
  65. var barcode = bardata.Content.Trim().Split('\0')[0];
  66. if(string.IsNullOrEmpty(barcode)) throw new KnownException($"条码为空,请检查", LogLevelEnum.High);
  67. if (!barcode.StartsWith("PT") && !barcode.StartsWith("Test")) throw new KnownException($"条码{barcode}无法识别", LogLevelEnum.High);
  68. //根据agv任务找到对应wcs任务并赋值
  69. if (db.Queryable<WCS_AgvTaskInfo>().SplitTable().Count(v => v.AgvStatus == AGVTaskStatus.RequestOrPermission1 && v.Status != AGVTaskStatus.Complete1 && v.Position == obj.Entity.Code) > 1)
  70. {
  71. throw new KnownException($"未分配巷道任务数异常,请检查现场情况", LogLevelEnum.High);
  72. }
  73. var agvTask = db.Queryable<WCS_AgvTaskInfo>().SplitTable().First(v => v.AgvStatus == AGVTaskStatus.RequestOrPermission1 && v.Status != AGVTaskStatus.Complete1 && v.Position == obj.Entity.Code);
  74. if (agvTask == null) throw new KnownException($"未找到对应agv任务,条码{barcode}", LogLevelEnum.High);
  75. taskInfo = db.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agvTask.ID) ?? throw new KnownException($"未找到agv任务{agvTask.ID}对应WCS任务", LogLevelEnum.High);
  76. if (taskInfo.BarCode.StartsWith("PT") && taskInfo.BarCode != barcode) throw new KnownException($"条码读取有误,请检查条码", LogLevelEnum.High);
  77. taskInfo.BarCode = barcode;
  78. //分配巷道,agv目标站台
  79. if (agvTaskCur.WorkShop == 1)
  80. {
  81. barcode = "";
  82. }
  83. var res = WmsApi.GetTunnelPriorityList(taskInfo.ID,barcode);
  84. var tunnelNo = res.ResData.Split(",").Select(v => "TY" + v).ToList();
  85. //开始获取堆垛机与可用站台信息
  86. var agvs = db.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status < AGVTaskStatus.MissionCompleted && v.TaskType == AGVTaskType.EnterDepot).SplitTable(v => v.Take(2)).ToList();
  87. var stations = devs.Where(v => v.Entity.Code is "1001" or "1003" or "1005" or "1007").ToList();
  88. //筛选出可用站台
  89. if (agvs == null)
  90. {
  91. stations = stations.Where(v => v.Data.VoucherNo == v.Data2.VoucherNo && v.Data3.Status.HasFlag(StationStatus.Auto))
  92. .Where(v => !v.Data3.Status.HasFlag(StationStatus.PH_Status) && !v.Data3.Status.HasFlag(StationStatus.OT_Status))
  93. .Where(v => !v.Data3.Status.HasFlag(StationStatus.Run))
  94. .ToList(); // 筛选出可用站台
  95. }
  96. else
  97. {
  98. stations = stations.Where(v => v.Data.VoucherNo == v.Data2.VoucherNo && v.Data3.Status.HasFlag(StationStatus.Auto))
  99. .Where(v => !v.Data3.Status.HasFlag(StationStatus.PH_Status) && !v.Data3.Status.HasFlag(StationStatus.OT_Status))
  100. .Where(v => !v.Data3.Status.HasFlag(StationStatus.Run))
  101. .Where(v => !agvs.Select(a => a.Position).Contains(v.Entity.Code)).ToList(); // 筛选出可用站台
  102. }
  103. if (!stations.Any())
  104. {
  105. World.Log($"无可用站台", LogLevelEnum.Mid);
  106. return;
  107. }
  108. //可用堆垛机
  109. var tunnelList = stations.Select(v => v.Entity.Sources).SelectMany(v => v).Where(v => v.IsTunnel()).ToList();//上一个地址是巷道的
  110. var tunnel = stations.Select(v => v.Entity.Sources).SelectMany(v => v).Where(v => v.IsTunnel())//上一个地址是巷道的
  111. .Select(v => v.Sources).SelectMany(v => v).Where(v => v.HasProtocol(typeof(ISRM520))) //筛选出堆垛机
  112. .Select(v => new SRM(v, this.World)) //转换为SRM
  113. .Where(v => !v.Data2.Status.HasFlag(SrmStatus.Alarm) && v.Data2.AutoStatus == SrmAutoStatus.Automatic)//筛选出可用堆垛机
  114. .Select(v => v.Entity.Sources).SelectMany(v => v).Where(v => v.IsTunnel())
  115. .Where(v => tunnelList.Select(s => s.Code).Contains(v.Code))
  116. .Where(v => tunnelNo.Contains(v.Code))
  117. .MinBy(v => tunnelNo.IndexOf(v.Code));//按照巷道优先级排序
  118. if (tunnel == null)
  119. {
  120. World.Log($"无可用巷道", LogLevelEnum.Mid);
  121. return;
  122. };
  123. //筛选出堆垛机的放货站台
  124. var nextPos = stations.FirstOrDefault(v => v.Entity.Sources.Where(t => t.IsTunnel()).Where(t => t.Code== tunnel.Code).Any());
  125. if (nextPos == null)
  126. {
  127. World.Log($"无可用放货站台,请检查", LogLevelEnum.Mid);
  128. return;
  129. };
  130. agvTask.Status = AGVTaskStatus.Complete1;
  131. agvTask.Position = nextPos.Entity.Code;
  132. agvTask.EditTime = DateTime.Now;
  133. db.Updateable(agvTask).SplitTable().ExecuteCommand();
  134. AgvApi.ContinueTask(agvTask.AgvID, nextPos.Entity.Code);
  135. taskInfo.Status = Entity.TaskStatus.AGVExecution;
  136. taskInfo.Tunnel = tunnel.Code.GetLastDigit().ToString();
  137. string srm = "";
  138. if (tunnel.Code.GetLastDigit() > 2)
  139. {
  140. srm = "SRM2";
  141. }
  142. else
  143. {
  144. srm = "SRM1";
  145. }
  146. taskInfo.Device = srm; ;
  147. taskInfo.SrmStation = nextPos.Entity.Code;
  148. taskInfo.AddrNext = tunnel.Code;
  149. db.Updateable(taskInfo).ExecuteCommand();
  150. taskInfo.AddWCS_TASK_DTL(_db, obj.Entity.Code, "SRM", $"任务分配巷道[{tunnel.Code}],目标站台[{nextPos.Entity.Code}]");
  151. var taskCur1 = db.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agvTaskCur.ID);
  152. var dev1 = sta.Find(v => v.Entity.Code == obj.Entity.Code);
  153. //条码已读且请求信号还在
  154. if (taskCur1 != null && !taskCur1.BarCode.StartsWith("Test"))
  155. {
  156. if (dev1 != null && dev1.Data2.GoodsStart == obj.Entity.Code.ToShort())
  157. {
  158. obj.Data.GoodsStart = 0;
  159. }
  160. }
  161. task = taskInfo;
  162. if (task == null) throw new Exception();
  163. });
  164. }
  165. catch (Exception ex)
  166. {
  167. throw new KnownException(ex.Message, LogLevelEnum.High);
  168. }
  169. }
  170. public override bool Select(Device dev)
  171. {
  172. return dev.HasFlag(DeviceFlags.检测门);
  173. }
  174. }
  175. }