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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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($"条码{barcode}读取有误,请检查条码", LogLevelEnum.High);
  77. //if (db.Queryable<WCS_TaskInfo>().Any(v => v.BarCode == barcode)) throw new KnownException($"已存在该条码{barcode},请检查扫码是否异常", LogLevelEnum.High);
  78. taskInfo.BarCode = barcode;
  79. //分配巷道,agv目标站台
  80. if (agvTaskCur.WorkShop == 1)
  81. {
  82. barcode = "";
  83. }
  84. var res = WmsApi.GetTunnelPriorityList(taskInfo.ID,barcode);
  85. var tunnelNo = res.ResData.Split(",").Select(v => "TY" + v).ToList();
  86. //开始获取堆垛机与可用站台信息
  87. var agvs = db.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status < AGVTaskStatus.MissionCompleted && v.TaskType == AGVTaskType.EnterDepot).SplitTable(v => v.Take(2)).ToList();
  88. var stations = devs.Where(v => v.Entity.Code is "1001" or "1003" or "1005" or "1007").ToList();
  89. //筛选出可用站台
  90. if (agvs == null)
  91. {
  92. stations = stations.Where(v => v.Data.VoucherNo == v.Data2.VoucherNo && v.Data3.Status.HasFlag(StationStatus.Auto))
  93. .Where(v => !v.Data3.Status.HasFlag(StationStatus.PH_Status) && !v.Data3.Status.HasFlag(StationStatus.OT_Status))
  94. .Where(v => !v.Data3.Status.HasFlag(StationStatus.Run))
  95. .ToList(); // 筛选出可用站台
  96. }
  97. else
  98. {
  99. stations = stations.Where(v => v.Data.VoucherNo == v.Data2.VoucherNo && v.Data3.Status.HasFlag(StationStatus.Auto))
  100. .Where(v => !v.Data3.Status.HasFlag(StationStatus.PH_Status) && !v.Data3.Status.HasFlag(StationStatus.OT_Status))
  101. .Where(v => !v.Data3.Status.HasFlag(StationStatus.Run))
  102. .Where(v => !agvs.Select(a => a.Position).Contains(v.Entity.Code)).ToList(); // 筛选出可用站台
  103. }
  104. if (!stations.Any())
  105. {
  106. World.Log($"无可用站台", LogLevelEnum.Mid);
  107. return;
  108. }
  109. //可用堆垛机
  110. var tunnelList = stations.Select(v => v.Entity.Sources).SelectMany(v => v).Where(v => v.IsTunnel()).ToList();//上一个地址是巷道的
  111. var tunnel = stations.Select(v => v.Entity.Sources).SelectMany(v => v).Where(v => v.IsTunnel())//上一个地址是巷道的
  112. .Select(v => v.Sources).SelectMany(v => v).Where(v => v.HasProtocol(typeof(ISRM520))) //筛选出堆垛机
  113. .Select(v => new SRM(v, this.World)) //转换为SRM
  114. .Where(v => !v.Data2.Status.HasFlag(SrmStatus.Alarm) && v.Data2.AutoStatus == SrmAutoStatus.Automatic)//筛选出可用堆垛机
  115. .Select(v => v.Entity.Sources).SelectMany(v => v).Where(v => v.IsTunnel())
  116. .Where(v => tunnelList.Select(s => s.Code).Contains(v.Code))
  117. .Where(v => tunnelNo.Contains(v.Code))
  118. .MinBy(v => tunnelNo.IndexOf(v.Code));//按照巷道优先级排序
  119. if (tunnel == null)
  120. {
  121. World.Log($"无可用巷道", LogLevelEnum.Mid);
  122. return;
  123. };
  124. //筛选出堆垛机的放货站台
  125. var nextPos = stations.FirstOrDefault(v => v.Entity.Sources.Where(t => t.IsTunnel()).Where(t => t.Code== tunnel.Code).Any());
  126. if (nextPos == null)
  127. {
  128. World.Log($"无可用放货站台,请检查", LogLevelEnum.Mid);
  129. return;
  130. };
  131. agvTask.Status = AGVTaskStatus.Complete1;
  132. agvTask.Position = nextPos.Entity.Code;
  133. agvTask.EditTime = DateTime.Now;
  134. db.Updateable(agvTask).SplitTable().ExecuteCommand();
  135. AgvApi.ContinueTask(agvTask.AgvID, nextPos.Entity.Code);
  136. taskInfo.Status = Entity.TaskStatus.AGVExecution;
  137. taskInfo.Tunnel = tunnel.Code.GetLastDigit().ToString();
  138. string srm = "";
  139. if (tunnel.Code.GetLastDigit() > 2)
  140. {
  141. srm = "SRM2";
  142. }
  143. else
  144. {
  145. srm = "SRM1";
  146. }
  147. taskInfo.Device = srm; ;
  148. taskInfo.SrmStation = nextPos.Entity.Code;
  149. taskInfo.AddrNext = tunnel.Code;
  150. db.Updateable(taskInfo).ExecuteCommand();
  151. taskInfo.AddWCS_TASK_DTL(_db, obj.Entity.Code, "SRM", $"任务分配巷道[{tunnel.Code}],目标站台[{nextPos.Entity.Code}]");
  152. var taskCur1 = db.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agvTaskCur.ID);
  153. var dev1 = sta.Find(v => v.Entity.Code == obj.Entity.Code);
  154. //条码已读且请求信号还在
  155. if (taskCur1 != null && !taskCur1.BarCode.StartsWith("Test"))
  156. {
  157. if (dev1 != null && dev1.Data2.GoodsStart == obj.Entity.Code.ToShort())
  158. {
  159. obj.Data.GoodsStart = 0;
  160. }
  161. }
  162. task = taskInfo;
  163. if (task == null) throw new Exception();
  164. });
  165. }
  166. catch (Exception ex)
  167. {
  168. throw new KnownException(ex.Message, LogLevelEnum.High);
  169. }
  170. }
  171. public override bool Select(Device dev)
  172. {
  173. return dev.HasFlag(DeviceFlags.检测门);
  174. }
  175. }
  176. }