AgvSystems.cs 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. using Newtonsoft.Json;
  2. using PlcSiemens.Core.Extension;
  3. using ServiceCenter.Extensions;
  4. using ServiceCenter.Logs;
  5. using ServiceCenter.SqlSugars;
  6. using System.ComponentModel;
  7. using System.Security.Cryptography.Xml;
  8. using WCS.Core;
  9. using WCS.Entity;
  10. using WCS.Entity.Protocol.Station;
  11. using WCS.WorkEngineering.Extensions;
  12. using WCS.WorkEngineering.WebApi.Controllers;
  13. using WCS.WorkEngineering.WebApi.Models.WMS.Request;
  14. using WCS.WorkEngineering.Worlds;
  15. using TaskStatus = WCS.Entity.TaskStatus;
  16. namespace WCS.WorkEngineering.Systems
  17. {
  18. /// <summary>
  19. /// Agv交互系统
  20. /// </summary>
  21. [BelongTo(typeof(MainWorld))]
  22. [Description("Agv交互系统")]
  23. public class AgvSystems : DeviceSystem<Device<IStation520>>
  24. {
  25. protected override bool ParallelDo => true;
  26. public AgvSystems()
  27. {
  28. }
  29. public override void Do(Device<IStation520> obj)
  30. {
  31. if (obj.Entity.Code == "AGVOut")
  32. {
  33. var agvTaskInfos = new List<WCS_AgvTaskInfo>();
  34. //获取所有未结束的叫料及背负式补空AGV任务
  35. SqlSugarHelper.Do(db =>
  36. {
  37. agvTaskInfos = db.Default.Queryable<WCS_AgvTaskInfo>().ReadPast().Where(v => v.TaskType == AGVTaskType.CallMaterial)
  38. .Where(v => v.Status < AGVTaskStatus.MissionCompleted)
  39. .SplitTable(tabs => tabs.Take(2)).OrderBy(v => v.AddTime).ToList();
  40. });
  41. //有需要处理的AGV任务
  42. if (agvTaskInfos.Any())
  43. {
  44. this.ExRecord(obj.Entity.Code, "可用出库AGV任务列表", agvTaskInfos.Select(v => v.ID).ToList());
  45. var taskInfos = new List<WCS_TaskInfo>();
  46. foreach (var agv in agvTaskInfos)
  47. {
  48. try
  49. {
  50. SqlSugarHelper.Do(db =>
  51. {
  52. switch (agv.AgvStatus)
  53. {
  54. //取货点安全交互
  55. case AGVTaskStatus.RequestOrPermission2 when agv.Status != AGVTaskStatus.RequestOrPermission2:
  56. {
  57. var taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.ID == agv.TaskId);
  58. agv.Status = AGVTaskStatus.RequestOrPermission2;
  59. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  60. taskInfo.AddWCS_TASK_DTL(db.Default, "agv", $"允许AGV任务{agv.ID}在站台{agv.Station}取货");
  61. AgvApi.ContinueTask(agv.AgvID, agv.Station);
  62. break;
  63. }
  64. case AGVTaskStatus.PutRequestOrPermission when agv.Status != AGVTaskStatus.PutRequestOrPermission:
  65. {
  66. agv.Status = AGVTaskStatus.PutRequestOrPermission;
  67. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  68. AgvApi.ContinueTask(agv.AgvID, agv.Station);
  69. break;
  70. }
  71. case AGVTaskStatus.LeaveGet when agv.Status != AGVTaskStatus.LeaveGet:
  72. World.Log($"AGV取货结束:开始{agv.ID}--{agv.Station}");
  73. var devinfo = new Device<IStation520>(Device.All.First(x => x.Code == agv.Station), World);
  74. devinfo.Data.CmdType = StationCmd.Res5;
  75. agv.Status = AGVTaskStatus.LeaveGet;
  76. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  77. World.Log($"AGV取货结束:结束{agv.ID}--{agv.Station}");
  78. break;
  79. //完成任务
  80. case AGVTaskStatus.MissionCompleted when agv.Status != AGVTaskStatus.MissionCompleted:
  81. {
  82. if (agv.TaskType is AGVTaskType.CallForMaterial or AGVTaskType.ForkliftFilling or AGVTaskType.CallMaterial)
  83. {
  84. var taskInfo = db.Default.Queryable<WCS_TaskInfo>().UpdLock().First(v => v.AgvTaskID == agv.ID);
  85. //if (taskInfo == null) throw new Exception($"未找到AGV任务{agv.ID}对应WCS任务");
  86. //更新AGV任务状态
  87. agv.Status = AGVTaskStatus.MissionCompleted;
  88. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  89. //更新WCS任务状态
  90. if (taskInfo != null)
  91. {
  92. taskInfo.Status = Entity.TaskStatus.Finish;
  93. taskInfo.EndTime = DateTime.Now;
  94. db.Default.UpdateableRowLock(taskInfo).UpdateColumns(x => new { x.Status, x.EndTime }).ExecuteCommand();
  95. taskInfo.AddWCS_TASK_DTL(db.Default, "agv", "任务完成");
  96. taskInfos.Add(taskInfo);
  97. }
  98. }
  99. else
  100. {
  101. agv.Status = AGVTaskStatus.MissionCompleted;
  102. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  103. }
  104. break;
  105. }
  106. }
  107. });
  108. }
  109. catch (Exception ex)
  110. {
  111. World.Log(ex.Message, LogLevelEnum.Mid);
  112. this.ExRecord(obj.Entity.Code, ex.Message);
  113. }
  114. }
  115. }
  116. }
  117. else if (obj.Entity.Code == "AGVIn")
  118. {
  119. List<WCS_AgvTaskInfo> agvTaskInfos = new List<WCS_AgvTaskInfo>();
  120. //获取所有未结束的入库AGV任务
  121. SqlSugarHelper.Do(db =>
  122. {
  123. agvTaskInfos = db.Default.Queryable<WCS_AgvTaskInfo>()
  124. .Where(v => v.Status < AGVTaskStatus.MissionCompleted && v.TaskType == AGVTaskType.EnterDepot)
  125. .SplitTable(tabs => tabs.Take(2)).OrderBy(v => v.EditTime).ToList();
  126. });
  127. if (agvTaskInfos.Any())
  128. {
  129. foreach (var agv in agvTaskInfos)
  130. {
  131. try
  132. {
  133. SqlSugarHelper.Do(db =>
  134. {
  135. #region 开始跟据AGV状态做出处理
  136. switch (agv.AgvStatus)
  137. {
  138. case AGVTaskStatus.NewBuild when agv.Status == AGVTaskStatus.NewBuild:
  139. agv.AgvID = agv.ID.ToString();
  140. agv.Status = AGVTaskStatus.Confirm;
  141. agv.AgvStatus = AGVTaskStatus.Confirm;
  142. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  143. if (agv.TaskType == AGVTaskType.EnterDepot &&(agv.Station == "2533" || agv.Station == "2933"))
  144. {
  145. AgvApi.满托入库(agv.Position, agv.ID.ToString(), agv.Station);
  146. var tasknew = db.Default.Queryable<WCS_TaskInfo>().NoLock().Where(x => x.ID == agv.TaskId).First();
  147. if (tasknew != null)
  148. {
  149. tasknew.Status = TaskStatus.AGVExecution;
  150. tasknew.EditTime = DateTime.Now;
  151. db.Default.UpdateableRowLock(tasknew).UpdateColumns(x => new { x.Status, x.EditTime }).ExecuteCommand();
  152. tasknew.AddWCS_TASK_DTL(db.Default, "agv", "任务下发agv执行");
  153. }
  154. }
  155. else if (agv.WorkShop == 222)//退料重绕
  156. {
  157. AgvApi.退料重绕(agv.Position, agv.ID.ToString(), agv.Station);
  158. var tasknew = db.Default.Queryable<WCS_TaskInfo>().NoLock().Where(x => x.ID == agv.TaskId).First();
  159. if (tasknew != null)
  160. {
  161. tasknew.Status = TaskStatus.AGVExecution;
  162. tasknew.EditTime = DateTime.Now;
  163. db.Default.UpdateableRowLock(tasknew).UpdateColumns(x => new { x.Status, x.EditTime }).ExecuteCommand();
  164. tasknew.AddWCS_TASK_DTL(db.Default, "agv", "任务下发agv执行");
  165. }
  166. }
  167. else if (agv.WorkShop != 111)
  168. {
  169. AgvApi.托盘回库(agv.Position, agv.ID.ToString(), agv.Station);
  170. }
  171. break;
  172. //巷道分配
  173. case AGVTaskStatus.RequestOrPermission1 when agv.Status != AGVTaskStatus.Complete1:
  174. {
  175. var task = db.Default.Queryable<WCS_TaskOld>().NoLock().Where(x => x.Id == agv.TaskId).SplitTable(x => x.Take(2)).First();
  176. if (task == null) throw new Exception($"未找到对应的WCS任务{agv.TaskId}");
  177. if (task.BusType == TaskBusType.帘线退料重绕.GetDescription())
  178. {
  179. //首先判断退料输送线是否可放货
  180. var ph_9001 = new Device<IStation523>(Device.All.First(x => x.Code == "9001"), World);
  181. var ph_9101 = new Device<IStation523>(Device.All.First(x => x.Code == "9101"), World);
  182. var flag1 = !db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status > AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.MissionCompleted && v.TaskType == AGVTaskType.EnterDepot && v.Station == "9001")
  183. .SplitTable(v => v.Take(2)).Any() && !ph_9001.Data.Status.HasFlag(StationStatus.PH_Status);
  184. var flag2 = !db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status > AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.MissionCompleted && v.TaskType == AGVTaskType.EnterDepot && v.Station == "9101")
  185. .SplitTable(v => v.Take(2)).Any() && !ph_9101.Data.Status.HasFlag(StationStatus.PH_Status);
  186. if (flag2)
  187. {
  188. agv.Status = AGVTaskStatus.Complete1;
  189. agv.Station = "9101";
  190. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  191. task.AddrTo = agv.Station;
  192. db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.AddrTo }).ExecuteCommand();
  193. task.AddWCS_TASK_DTL(db.Default, "帘线退料重绕分配目标放货点", agv.Station, $"任务分配至:{agv.Station}");
  194. AgvApi.ContinueTask(agv.AgvID, agv.Station);
  195. return;
  196. }
  197. else if (flag1)
  198. {
  199. agv.Status = AGVTaskStatus.Complete1;
  200. agv.Station = "9001";
  201. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  202. task.AddrTo = agv.Station;
  203. db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.AddrTo }).ExecuteCommand();
  204. task.AddWCS_TASK_DTL(db.Default, "帘线退料重绕分配目标放货点", agv.Station, $"任务分配至:{agv.Station}");
  205. AgvApi.ContinueTask(agv.AgvID, agv.Station);
  206. return;
  207. }
  208. else//请求WMS分配可用放货点
  209. {
  210. List<string> allDevs = new List<string> { "9201", "9202", "9203", "9204", "9205", "9206", "9207", "9208", "9209" };
  211. var agvStas = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status > AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.MissionCompleted && v.TaskType == AGVTaskType.EnterDepot && allDevs.Contains(v.Station))
  212. .SplitTable(v => v.Take(2)).ToList();
  213. var agvStaLists = agvStas.Select(x => x.Station).Distinct();
  214. var devs = allDevs.Where(x => !agvStaLists.Contains(x)).ToList();
  215. var devsPut = Device.All.Where(x => devs.Contains(x.Code)).Select(x =>
  216. new Device<IStation520, IStation521, IStation523>(x, World));
  217. devsPut = devsPut.Where(x =>
  218. !x.Data3.Status.HasFlag(StationStatus.Run) &&
  219. !x.Data3.Status.HasFlag(StationStatus.PH_Status) &&
  220. x.Data3.Status.HasFlag(StationStatus.Auto)).ToList();
  221. if (devsPut.Any())
  222. {
  223. foreach (var dev in devsPut)
  224. {
  225. if (!dev.Data3.Status.HasFlag(StationStatus.Run) && !dev.Data3.Status.HasFlag(StationStatus.PH_Status) && dev.Data3.Status.HasFlag(StationStatus.Auto))
  226. {
  227. agv.Status = AGVTaskStatus.Complete1;
  228. agv.Station = dev.Entity.Code;
  229. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  230. task.AddrTo = agv.Station;
  231. db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.AddrTo }).ExecuteCommand();
  232. task.AddWCS_TASK_DTL(db.Default, "帘线退料重绕分配目标放货点", agv.Station, $"任务分配至:{agv.Station}");
  233. AgvApi.ContinueTask(agv.AgvID, agv.Station);
  234. return;
  235. }
  236. }
  237. }
  238. else
  239. {
  240. throw new Exception("已无可用放货站台,请等待");
  241. }
  242. }
  243. }
  244. else
  245. {
  246. //获取当前任务可以去的目标地址
  247. var positionList = new List<string>(); //当前分配点对应的放货点
  248. var allPositionList = new List<string>(); //同库区另一侧的放货点
  249. var nearPositionList = new List<string>(); //所有的放货点
  250. GetPositionList(positionList, nearPositionList, allPositionList, task.WarehouseCode);
  251. List<WCS_AgvTaskInfo> agvs = new List<WCS_AgvTaskInfo>(); //当前分配点对应的放货点已用点
  252. List<WCS_AgvTaskInfo> agvsNear = new List<WCS_AgvTaskInfo>(); //同库区另一侧的放货点已用点
  253. List<WCS_AgvTaskInfo> agvsAll = new List<WCS_AgvTaskInfo>(); //所有的放货点已用点
  254. agvs = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status > AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.MissionCompleted && v.TaskType == AGVTaskType.EnterDepot && positionList.Contains(v.Station))
  255. .SplitTable(v => v.Take(2)).ToList();
  256. agvsAll = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status > AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.MissionCompleted && v.TaskType == AGVTaskType.EnterDepot && allPositionList.Contains(v.Station))
  257. .SplitTable(v => v.Take(2)).ToList();
  258. agvsNear = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status > AGVTaskStatus.Confirm && v.Status < AGVTaskStatus.MissionCompleted && v.TaskType == AGVTaskType.EnterDepot && nearPositionList.Contains(v.Station))
  259. .SplitTable(v => v.Take(2)).ToList();
  260. //获取放货点
  261. var agvPositionLists = agvs.Select(x => x.Station).Distinct();
  262. var agvPositionListsNear = agvsNear.Select(x => x.Station).Distinct();
  263. var agvPositionListsAll = agvsAll.Select(x => x.Station).Distinct();
  264. //获取各区域可用点
  265. var endDev = positionList.Where(x => !agvPositionLists.Contains(x)).ToList();
  266. var endNearDev = nearPositionList.Where(x => !agvPositionListsNear.Contains(x)).ToList();
  267. var endAllDev = allPositionList.Where(x => !agvPositionListsAll.Contains(x)).ToList();
  268. World.Log($"agv可用巷道信息:{JsonConvert.SerializeObject(endDev)}");
  269. World.Log($"agv可用巷道信息(所有):{JsonConvert.SerializeObject(endAllDev)}");
  270. if (!endDev.Any() && !endAllDev.Any() && !endNearDev.Any())//没有可用放货站台
  271. {
  272. var msg = "已无可用放货站台,任务正在执行中:";
  273. foreach (var ag in agvs)
  274. {
  275. msg += $"[任务号:{ag.ID},目标地址:{ag.Station}]";
  276. }
  277. throw new Exception(msg);
  278. }
  279. //获取没有光电信息的设备集合
  280. try
  281. {
  282. // 获取可用站台
  283. var devs = Device.All.Where(x => endDev.Contains(x.Code)).Select(x =>
  284. new Device<IStation520, IStation521, IStation523>(x, World));
  285. devs = devs.Where(x =>
  286. !x.Data3.Status.HasFlag(StationStatus.Run) &&
  287. !x.Data3.Status.HasFlag(StationStatus.PH_Status) &&
  288. x.Data3.Status.HasFlag(StationStatus.Auto)).ToList();
  289. var devsNear = Device.All.Where(x => endNearDev.Contains(x.Code)).Select(x =>
  290. new Device<IStation520, IStation521, IStation523>(x, World));
  291. devsNear = devsNear.Where(x =>
  292. !x.Data3.Status.HasFlag(StationStatus.Run) &&
  293. !x.Data3.Status.HasFlag(StationStatus.PH_Status) &&
  294. x.Data3.Status.HasFlag(StationStatus.Auto)).ToList();
  295. var devsAll = Device.All.Where(x => endAllDev.Contains(x.Code)).Select(x =>
  296. new Device<IStation520, IStation521, IStation523>(x, World));
  297. devsAll = devsAll.Where(x =>
  298. !x.Data3.Status.HasFlag(StationStatus.Run) &&
  299. !x.Data3.Status.HasFlag(StationStatus.PH_Status) &&
  300. x.Data3.Status.HasFlag(StationStatus.Auto)).OrderBy(v => allPositionList.Contains(v.Entity.Code)).ToList();
  301. if (!devs.Any()) //自身所属位置无可用放货点
  302. {
  303. if (devsNear.Any())//先判断同库一侧
  304. {
  305. foreach (var dev in devsNear)
  306. {
  307. if (!dev.Data3.Status.HasFlag(StationStatus.Run) && !dev.Data3.Status.HasFlag(StationStatus.PH_Status) && dev.Data3.Status.HasFlag(StationStatus.Auto))
  308. {
  309. World.Log($"任务执行过程:开始{agv.ID}-{JsonConvert.SerializeObject(devsAll.Select(x => x.Entity.Code).ToList())}");
  310. agv.Status = AGVTaskStatus.Complete1;
  311. agv.Station = dev.Entity.Code;
  312. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  313. World.Log($"任务执行过程:完成agv任务更新{agv.ID}--{agv.Station}");
  314. task.AddWCS_TASK_DTL(db.Default, "皮盘返库任务分配巷道", agv.Station, $"任务分配至:{agv.Station}");
  315. World.Log($"任务执行过程:完成任务明细添加{agv.Station}");
  316. AgvApi.ContinueTask(agv.AgvID, agv.Station);
  317. World.Log($"任务执行过程:任务成功下发AGV{agv.AgvID}--{agv.Station}");
  318. return;
  319. }
  320. }
  321. }
  322. else if (devsAll.Any())
  323. {
  324. foreach (var dev in devsAll)
  325. {
  326. if (!dev.Data3.Status.HasFlag(StationStatus.Run) && !dev.Data3.Status.HasFlag(StationStatus.PH_Status) && dev.Data3.Status.HasFlag(StationStatus.Auto))
  327. {
  328. World.Log($"任务执行过程:开始{agv.ID}-{JsonConvert.SerializeObject(devsAll.Select(x => x.Entity.Code).ToList())}");
  329. agv.Status = AGVTaskStatus.Complete1;
  330. agv.Station = dev.Entity.Code;
  331. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  332. World.Log($"任务执行过程:完成agv任务更新{agv.ID}--{agv.Station}");
  333. task.AddWCS_TASK_DTL(db.Default, "皮盘返库任务分配巷道", agv.Station, $"任务分配至:{agv.Station}");
  334. World.Log($"任务执行过程:完成任务明细添加{agv.Station}");
  335. AgvApi.ContinueTask(agv.AgvID, agv.Station);
  336. World.Log($"任务执行过程:任务成功下发AGV{agv.AgvID}--{agv.Station}");
  337. return;
  338. }
  339. }
  340. }
  341. World.Log("可用站台均有货或有执行中任务");
  342. return;
  343. }
  344. World.Log($"任务执行过程:开始{agv.ID}-{JsonConvert.SerializeObject(devs.Select(x => x.Entity.Code).ToList())}");
  345. agv.Status = AGVTaskStatus.Complete1;
  346. agv.Station = devs.MinBy(x => x.Entity.Code).Entity.Code;
  347. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  348. World.Log($"任务执行过程:完成agv任务更新{agv.ID}--{agv.Station}");
  349. task.AddWCS_TASK_DTL(db.Default, "皮盘返库任务分配巷道", agv.Station, $"任务分配至:{agv.Station}");
  350. World.Log($"任务执行过程:完成任务明细添加{agv.Station}");
  351. AgvApi.ContinueTask(agv.AgvID, agv.Station);
  352. World.Log($"任务执行过程:任务成功下发AGV{agv.AgvID}--{agv.Station}");
  353. }
  354. catch (Exception e)
  355. {
  356. throw new Exception($"执行错误:{e.Message + e.StackTrace}");
  357. }
  358. }
  359. break;
  360. }
  361. //放货站点安全交互
  362. case AGVTaskStatus.RequestOrPermission2 when agv.Status != AGVTaskStatus.RequestOrPermission2:
  363. {
  364. if (agv.Station.IsNullOrEmpty()) throw new Exception($"无有效放货地址");
  365. var taskBus = db.Default.Queryable<WCS_TaskInfo>().NoLock().Where(x => x.ID == agv.TaskId).First();
  366. var flag = false;
  367. if (taskBus != null && taskBus.BusType == "人工满托入库")
  368. {
  369. flag = true;
  370. }
  371. var dev = Device.All.First(x => x.Code == agv.Station);
  372. var ph = new Device<IStation523>(Device.All.First(x => x.Code == agv.Station), World);
  373. if (ph.Data.Status.HasFlag(StationStatus.PH_Status))
  374. {
  375. throw new Exception($"{agv.Station}站台有光电小车无法放货,请检查并处理");
  376. }
  377. if (flag)
  378. {
  379. if (!ph.Data.Status.HasFlag(StationStatus.Low_Station_2))
  380. {
  381. throw new Exception($"{agv.Station}站台不在低位小车无法放货,请检查并处理");
  382. }
  383. else if (db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status < AGVTaskStatus.MissionCompleted && v.TaskType == AGVTaskType.EnterDepot
  384. && v.Station == agv.Station && v.GoodsSum == 1).SplitTable(tabs => tabs.Take(2)).Any())
  385. {
  386. throw new Exception($"{agv.Station}站台有执行中任务{agv.ID}");
  387. }
  388. agv.GoodsSum = 1;
  389. }
  390. agv.Status = AGVTaskStatus.RequestOrPermission2;
  391. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  392. var devinfo = new Device<IStation520, IStation521>(Device.All.First(x => x.Code == agv.Station), World);
  393. devinfo.Data.CmdType = StationCmd.Res1;
  394. //调继续执行任务接口
  395. AgvApi.ContinueTask(agv.AgvID, dev.Code);
  396. break;
  397. }
  398. case AGVTaskStatus.LeavePut when agv.Status != AGVTaskStatus.LeavePut:
  399. break;
  400. //完成任务
  401. case AGVTaskStatus.MissionCompleted when agv.Status != AGVTaskStatus.MissionCompleted:
  402. var taskold = db.Default.Queryable<WCS_TaskOld>().NoLock().Where(x => x.Id == agv.TaskId).SplitTable(x => x.Take(2)).First();
  403. if (agv.TaskType == AGVTaskType.EnterDepot)
  404. {
  405. agv.Status = AGVTaskStatus.MissionCompleted;
  406. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  407. var devinfo = new Device<IStation520, IStation521>(Device.All.First(x => x.Code == agv.Station), World);
  408. devinfo.Data.CmdType = StationCmd.Res2;
  409. if (taskold.LastInteractionPoint == "2" || taskold.BusType == TaskBusType.重绕满托入库.GetDescription() || taskold.BusType == TaskBusType.帘线退料重绕.GetDescription()) //如果是单独取空任务直接完成
  410. {
  411. var task = db.Default.Queryable<WCS_TaskInfo>().NoLock().Where(x => x.ID == agv.TaskId).First();
  412. if (task != null)
  413. {
  414. task.Status = TaskStatus.Finish;
  415. task.EndTime = DateTime.Now;
  416. db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.EndTime }).ExecuteCommand();
  417. task.AddWCS_TASK_DTL(db.Default, "agv", "任务完成");
  418. }
  419. }
  420. else if (taskold.BusType == "人工满托入库")
  421. {
  422. var task = db.Default.Queryable<WCS_TaskInfo>().NoLock().Where(x => x.ID == agv.TaskId).First();
  423. if (task != null)
  424. {
  425. task.Status = TaskStatus.ConveyorExecution;
  426. devinfo.Data.TaskNumber = task.ID;
  427. task.EndTime = DateTime.Now;
  428. db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.EndTime }).ExecuteCommand();
  429. task.AddWCS_TASK_DTL(db.Default, "agv", "任务放货完成");
  430. }
  431. }
  432. }
  433. break;
  434. case AGVTaskStatus.Cancel when agv.Status != AGVTaskStatus.Cancel:
  435. var taskold1 = db.Default.Queryable<WCS_TaskOld>().NoLock().Where(x => x.Id == agv.TaskId).SplitTable(x => x.Take(2)).First();
  436. agv.Status = AGVTaskStatus.Cancel;
  437. db.Default.UpdateableRowLock(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  438. if (taskold1.LastInteractionPoint == "2") //如果是单独取空任务直接取消
  439. {
  440. var task = db.Default.Queryable<WCS_TaskInfo>().NoLock().Where(x => x.ID == agv.TaskId).First();
  441. if (task != null)
  442. {
  443. task.Status = TaskStatus.Cancel;
  444. task.EndTime = DateTime.Now;
  445. db.Default.UpdateableRowLock(task).UpdateColumns(x => new { x.Status, x.EndTime }).ExecuteCommand();
  446. task.AddWCS_TASK_DTL(db.Default, "agv", "任务取消");
  447. }
  448. }
  449. break;
  450. }
  451. #endregion 开始跟据AGV状态做出处理
  452. });
  453. }
  454. catch (Exception ex)
  455. {
  456. if (ex.Message.Contains("SqlTransaction")) World.Log($"{ex.Message}:{ex.StackTrace}");
  457. else World.Log(ex.Message, LogLevelEnum.Mid);
  458. }
  459. }
  460. }
  461. }
  462. }
  463. public override bool Select(Device dev)
  464. {
  465. return dev.Code is "AGVIn" or "AGVOut";
  466. }
  467. /// <summary>
  468. /// 获取可用放货点
  469. /// </summary>
  470. /// <param name="positionList"></param>
  471. /// <param name="nearPositionList"></param>
  472. /// <param name="allPositionList"></param>
  473. /// <param name="warehouseCode"></param>
  474. private void GetPositionList(List<string> positionList, List<string> nearPositionList, List<string> allPositionList, string warehouseCode)
  475. {
  476. switch (warehouseCode)
  477. {
  478. case "1N":
  479. positionList.AddRange(new List<string>() { "2501", "2505", "2509", "2513" });
  480. nearPositionList.AddRange(new List<string>() {
  481. "2701", "2705", "2709", "2713" });
  482. allPositionList.AddRange(new List<string>() {
  483. "2901", "2905", "2909", "2913","3101", "3105", "3109", "3113", "3301", "3305", "3309", "3313","3501", "3505", "3509", "3513"});
  484. break;
  485. case "1S":
  486. positionList.AddRange(new List<string>() { "2701", "2705", "2709", "2713" });
  487. nearPositionList.AddRange(new List<string>() {
  488. "2501", "2505", "2509", "2513" });
  489. allPositionList.AddRange(new List<string>() {
  490. "3101", "3105", "3109", "3113", "2901", "2905", "2909", "2913", "3501", "3505", "3509", "3513", "3301", "3305", "3309", "3313"});
  491. break;
  492. case "2N":
  493. positionList.AddRange(new List<string>() { "2901", "2905", "2909", "2913" });
  494. nearPositionList.AddRange(new List<string>() {
  495. "3101", "3105", "3109", "3113" });
  496. allPositionList.AddRange(new List<string>() {
  497. "2501" , "2505" , "2509" , "2513" , "2701", "2705", "2709", "2713","3301", "3305", "3309", "3313", "3501", "3505", "3509", "3513"});
  498. break;
  499. case "2S":
  500. positionList.AddRange(new List<string>() { "3101", "3105", "3109", "3113" });
  501. nearPositionList.AddRange(new List<string>() {
  502. "2901", "2905", "2909", "2913" });
  503. allPositionList.AddRange(new List<string>() {
  504. "2701" , "2705" , "2709" , "2713" ,"2501" , "2505" , "2509" , "2513" , "3501" , "3505" , "3509" , "3513","3301", "3305", "3309", "3313"});
  505. break;
  506. case "3N":
  507. positionList.AddRange(new List<string>() { "3301", "3305", "3309", "3313" });
  508. nearPositionList.AddRange(new List<string>() {
  509. "3501", "3505", "3509", "3513" });
  510. allPositionList.AddRange(new List<string>() {
  511. "2901", "2905", "2909", "2913", "3101", "3105", "3109", "3113","2501" , "2505" , "2509" , "2513" , "2701", "2705", "2709", "2713" });
  512. break;
  513. case "3S":
  514. positionList.AddRange(new List<string>() { "3501", "3505", "3509", "3513" });
  515. nearPositionList.AddRange(new List<string>() {
  516. "3301", "3305", "3309", "3313" });
  517. allPositionList.AddRange(new List<string>() {
  518. "3101", "3105", "3109", "3113", "2901", "2905", "2909", "2913", "2701" , "2705" , "2709" , "2713" ,"2501" , "2505" , "2509" , "2513" });
  519. break;
  520. }
  521. }
  522. }
  523. }