AgvSystems.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. using Microsoft.AspNetCore.DataProtection.KeyManagement;
  2. using Newtonsoft.Json;
  3. using PlcSiemens.Core.Extension;
  4. using ServiceCenter.Extensions;
  5. using ServiceCenter.Logs;
  6. using ServiceCenter.Redis;
  7. using ServiceCenter.SqlSugars;
  8. using SqlSugar;
  9. using System.ComponentModel;
  10. using WCS.Core;
  11. using WCS.Entity;
  12. using WCS.Entity.Protocol.SRM;
  13. using WCS.Entity.Protocol.Station;
  14. using WCS.WorkEngineering.Extensions;
  15. using WCS.WorkEngineering.WebApi.Controllers;
  16. using WCS.WorkEngineering.Worlds;
  17. using static System.Runtime.InteropServices.JavaScript.JSType;
  18. using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
  19. namespace WCS.WorkEngineering.Systems
  20. {
  21. /// <summary>
  22. /// Agv交互系统
  23. /// </summary>
  24. [BelongTo(typeof(AgvWorld))]
  25. [Description("Agv交互系统")]
  26. public class AgvSystems : DeviceSystem<Station>
  27. {
  28. protected override bool ParallelDo => true;
  29. protected override bool SaveLogsToFile => true;
  30. private List<Station> devs = new List<Station>();
  31. private List<SRM> srms = new List<SRM>();
  32. public AgvSystems()
  33. {
  34. var stations = new List<string>() { "1011", "1012", "1013", "1014", "1015", "1016", "1021", "1022", "1023", "1024", "1025", "1026", "1117", "1118",
  35. "1131", "1132", "1133", "1134", "1135", "1136", "1137", "1138", "1139","1127" };
  36. devs = Device.All.Where(v => stations.Contains(v.Code)).Select(v => new Station(v, this.World)).ToList();
  37. srms = Device.All.Where(v => v.Code is "SRM1" or "SRM2" or "SRM3" or "SRM4").Select(v => new SRM(v, this.World)).ToList();
  38. }
  39. public override void Do(Station obj)
  40. {
  41. if (obj.Entity.Code == "1018"/*.HasFlag(DeviceFlags.出库)*/)
  42. {
  43. List<WCS_AgvTaskInfo> agvTaskInfos = new List<WCS_AgvTaskInfo>();
  44. //获取所有未结束的叫料及背负式补空AGV任务
  45. SqlSugarHelper.Do(db =>
  46. {
  47. agvTaskInfos = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => (v.TaskType == AGVTaskType.CallMaterial || v.TaskType == AGVTaskType.CallForMaterial || v.TaskType == AGVTaskType.ForkliftFilling))
  48. .Where(v => v.Status < AGVTaskStatus.MissionCompleted)
  49. .SplitTable(tabs => tabs.Take(2)).OrderBy(v => v.AddTime).ToList();
  50. });
  51. //有需要处理的AGV任务
  52. if (agvTaskInfos.Any())
  53. {
  54. //this.ExRecord(obj.Entity.Code, "可用出库AGV任务列表", agvTaskInfos.Select(v => v.ID).ToList());
  55. //List<WCS_TaskInfo> taskInfos = new List<WCS_TaskInfo>();
  56. foreach (var agv in agvTaskInfos)
  57. {
  58. try
  59. {
  60. SqlSugarHelper.Do(db =>
  61. {
  62. //取货点安全交互
  63. if (agv.AgvStatus == AGVTaskStatus.RequestOrPermission2 && agv.Status != AGVTaskStatus.Complete2)
  64. {
  65. var taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agv.ID);
  66. agv.Status = AGVTaskStatus.Complete2;
  67. db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  68. taskInfo.AddWCS_TASK_DTL(db, "agv", $"允许AGV任务{agv.ID}在站台{agv.Station}取货");
  69. AgvApi.ContinueTask(agv.AgvID, agv.Station);
  70. }
  71. //完成任务
  72. else if (agv.AgvStatus == AGVTaskStatus.MissionCompleted && agv.Status != AGVTaskStatus.MissionCompleted)
  73. {
  74. if (agv.TaskType is AGVTaskType.CallForMaterial or AGVTaskType.ForkliftFilling or AGVTaskType.CallMaterial)
  75. {
  76. var taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agv.ID);
  77. if (taskInfo == null) throw new Exception($"未找到AGV任务{agv.ID}对应WCS任务");
  78. //更新AGV任务状态
  79. agv.Status = AGVTaskStatus.MissionCompleted;
  80. db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  81. //更新WCS任务状态
  82. taskInfo.Status = Entity.TaskStatus.Finish;
  83. taskInfo.EedTime = DateTime.Now;
  84. db.Default.Updateable(taskInfo).ExecuteCommand();
  85. taskInfo.AddWCS_TASK_DTL(db, "agv", "任务完成");
  86. //通知WMS任务完成
  87. WmsApi.CompleteTask(taskInfo.ID);
  88. taskInfo.CompleteOrCancelTasks(db);
  89. //taskInfos.Add(taskInfo);
  90. }
  91. else
  92. {
  93. agv.Status = AGVTaskStatus.MissionCompleted;
  94. db.Default.Updateable(agv).SplitTable(x => x.Take(2)).ExecuteCommand();
  95. }
  96. }
  97. });
  98. }
  99. catch (Exception ex)
  100. {
  101. World.Log(ex.Message, LogLevelEnum.Mid);
  102. this.ExRecord(obj.Entity.Code, ex.Message);
  103. continue;
  104. }
  105. }
  106. //foreach (var item in taskInfos)
  107. //{
  108. // WmsApi.CompleteTask(item.ID);
  109. //}
  110. }
  111. }
  112. else if (obj.Entity.Code == "1017"/*.HasFlag(DeviceFlags.入库)*/)
  113. {
  114. List<WCS_AgvTaskInfo> agvTaskInfos = new List<WCS_AgvTaskInfo>();
  115. //获取所有未结束的入库AGV任务
  116. SqlSugarHelper.Do(db =>
  117. {
  118. agvTaskInfos = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status < AGVTaskStatus.MissionCompleted && v.TaskType == AGVTaskType.EnterDepot).SplitTable(tabs => tabs.Take(2)).OrderBy(v => v.EditTime).ToList();
  119. });
  120. if (agvTaskInfos.Any())
  121. {
  122. //this.ExRecord(obj.Entity.Code, "可用入库AGV任务列表", agvTaskInfos.Select(v => v.ID).ToList());
  123. var guid = Guid.NewGuid();
  124. World.Log($"agv任务处理:开始[{guid}]", LogLevelEnum.Mid);
  125. foreach (var agv in agvTaskInfos)
  126. {
  127. try
  128. {
  129. int isApplyContainue = 0;
  130. string agvid = "";
  131. string nextpos = "";
  132. SqlSugarHelper.Do(db =>
  133. {
  134. //找到对应WCS任务
  135. //var task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agv.ID);
  136. //if (task == null) throw new Exception($"AGV任务{agv.ID}未找到对应WCS任务");
  137. var agvInfo = db.Default.Queryable<WCS_AgvTaskInfo>().Where(x => x.ID == agv.ID).SplitTable(s => s.Take(3)).First();
  138. #region 开始跟据AGV状态做出处理
  139. //巷道分配
  140. if (agvInfo.AgvStatus == AGVTaskStatus.RequestOrPermission1 && agvInfo.Status != AGVTaskStatus.Complete1)
  141. {
  142. //找到对应WCS任务
  143. var task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agvInfo.ID);
  144. if (task == null) throw new Exception($"AGV任务{agvInfo.ID}未找到对应WCS任务");
  145. this.ExRecord(obj.Entity.Code, $"AGV任务{agvInfo.ID}开始进行巷道分配");
  146. //向WMS获取巷道优先级'
  147. var res = WmsApi.GetTunnelPriorityList(task.ID);
  148. this.ExRecord(obj.Entity.Code, $"AGV任务{agvInfo.ID},WMS返回巷道优先级{res.ResData}");
  149. var tunnelNo = res.ResData.Split(",").Select(v => "SRM" + v).ToList();
  150. //开始获取堆垛机与可用站台信息
  151. SRM srm = null;
  152. List<Station> stations = new List<Station>();
  153. if (task.Floor == 1) //一楼
  154. {
  155. //一楼三个入库口 新增一个巷道,两个入库口
  156. //proline 6-12
  157. if (agvInfo.WorkShop == 1138)
  158. {
  159. stations = devs.Where(v => v.Entity.Code is "1138").ToList();
  160. //过滤有任务的站台
  161. var taskinstations = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.TaskType == AGVTaskType.EnterDepot && v.Status < AGVTaskStatus.MissionCompleted && (v.Position == "1138")).SplitTable(v => v.Take(2)).Select(v => v.Position).ToList();
  162. stations = stations.Where(p => !taskinstations.Contains(p.Entity.Code)).ToList();
  163. //筛选出可用站台
  164. stations = stations.Where(v => v.Data.VoucherNo == v.Data2.VoucherNo && v.Data3.Status.HasFlag(StatusEunm.Auto))
  165. .Where(v => !v.Data3.Status.HasFlag(StatusEunm.PH_Status) && !v.Data3.Status.HasFlag(StatusEunm.OT_Status))
  166. .Where(v => !v.Data3.Status.HasFlag(StatusEunm.Run)).ToList(); // 筛选出可用站台
  167. //可用堆垛机
  168. srm = stations.Select(v => v.Entity.Sources).SelectMany(v => v).Where(v => v.IsTunnel()) //上一个地址是巷道的
  169. .Select(v => v.Sources).SelectMany(v => v).Where(v => v.HasProtocol(typeof(ISRM520))) //筛选出堆垛机
  170. .Select(v => new SRM(v, this.World)) //转换为SRM
  171. .Where(v => v != null && !v.Data2.Status.HasFlag(SrmStatus.Alarm) && v.Data2.AutoStatus == SrmAutoStatus.Automatic) //筛选出可用堆垛机
  172. .Where(v => tunnelNo.Contains(v.Entity.Code)) //筛选出巷道优先级最高的堆垛机
  173. .MinBy(v => tunnelNo.IndexOf(v.Entity.Code));//按照巷道优先级排序
  174. if (srm == null)
  175. {
  176. stations = devs.Where(v => v.Entity.Code is "1011" or "1013" or "1015" or "1117").ToList();
  177. //过滤有任务的站台
  178. var taskinstations1 = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.TaskType == AGVTaskType.EnterDepot && v.Status < AGVTaskStatus.MissionCompleted && (v.Position == "1011" || v.Position == "1013" || v.Position == "1015" || v.Position == "1117")).SplitTable(v => v.Take(2)).Select(v => v.Position).ToList();
  179. stations = stations.Where(p => !taskinstations1.Contains(p.Entity.Code)).ToList();
  180. //筛选出可用站台
  181. stations = stations.Where(v => v.Data.VoucherNo == v.Data2.VoucherNo && v.Data3.Status.HasFlag(StatusEunm.Auto))
  182. .Where(v => !v.Data3.Status.HasFlag(StatusEunm.PH_Status) && !v.Data3.Status.HasFlag(StatusEunm.OT_Status))
  183. .Where(v => !v.Data3.Status.HasFlag(StatusEunm.Run)).ToList(); // 筛选出可用站台
  184. //可用堆垛机
  185. srm = stations.Select(v => v.Entity.Sources).SelectMany(v => v).Where(v => v.IsTunnel()) //上一个地址是巷道的
  186. .Select(v => v.Sources).SelectMany(v => v).Where(v => v.HasProtocol(typeof(ISRM520))) //筛选出堆垛机
  187. .Select(v => new SRM(v, this.World)) //转换为SRM
  188. .Where(v => v != null && !v.Data2.Status.HasFlag(SrmStatus.Alarm) && v.Data2.AutoStatus == SrmAutoStatus.Automatic) //筛选出可用堆垛机
  189. .Where(v => tunnelNo.Contains(v.Entity.Code)) //筛选出巷道优先级最高的堆垛机
  190. .MinBy(v => tunnelNo.IndexOf(v.Entity.Code));//按照巷道优先级排序
  191. }
  192. }
  193. else
  194. {
  195. stations = devs.Where(v => v.Entity.Code is "1011" or "1013" or "1015" or "1117").ToList();
  196. //过滤有任务的站台
  197. var taskinstations = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.TaskType == AGVTaskType.EnterDepot && v.Status < AGVTaskStatus.MissionCompleted && (v.Position == "1011" || v.Position == "1013" || v.Position == "1015" || v.Position == "1117")).SplitTable(v => v.Take(2)).Select(v => v.Position).ToList();
  198. stations = stations.Where(p => !taskinstations.Contains(p.Entity.Code)).ToList();
  199. //筛选出可用站台
  200. stations = stations.Where(v => v.Data.VoucherNo == v.Data2.VoucherNo && v.Data3.Status.HasFlag(StatusEunm.Auto))
  201. .Where(v => !v.Data3.Status.HasFlag(StatusEunm.PH_Status) && !v.Data3.Status.HasFlag(StatusEunm.OT_Status))
  202. .Where(v => !v.Data3.Status.HasFlag(StatusEunm.Run)).ToList(); // 筛选出可用站台
  203. this.ExRecord(obj.Entity.Code, $"AGV任务{agvInfo.ID},可用放货站台", stations.Select(v => v.Entity.Code).ToList());
  204. //可用堆垛机
  205. srm = stations.Select(v => v.Entity.Sources).SelectMany(v => v).Where(v => v.IsTunnel()) //上一个地址是巷道的
  206. .Select(v => v.Sources).SelectMany(v => v).Where(v => v.HasProtocol(typeof(ISRM520))) //筛选出堆垛机
  207. .Select(v => new SRM(v, this.World)) //转换为SRM
  208. .Where(v => v != null && !v.Data2.Status.HasFlag(SrmStatus.Alarm) && v.Data2.AutoStatus == SrmAutoStatus.Automatic) //筛选出可用堆垛机
  209. .Where(v => tunnelNo.Contains(v.Entity.Code)) //筛选出巷道优先级最高的堆垛机
  210. .MinBy(v => tunnelNo.IndexOf(v.Entity.Code));//按照巷道优先级排序
  211. }
  212. }
  213. else //二楼
  214. {
  215. //二楼三个入库口 新增一个巷道,1个入库口
  216. stations = devs.Where(v => v.Entity.Code is "1021" or "1023" or "1025" or "1127").ToList();
  217. //过滤有任务的站台
  218. var taskinstations = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.TaskType == AGVTaskType.EnterDepot && v.Status < AGVTaskStatus.MissionCompleted && (v.Position == "1021" || v.Position == "1023" || v.Position == "1025" || v.Position == "1127")).SplitTable(v => v.Take(2)).Select(v => v.Position).ToList();
  219. stations = stations.Where(p => !taskinstations.Contains(p.Entity.Code)).ToList();
  220. //筛选出可用站台
  221. stations = stations.Where(v => v.Data.VoucherNo == v.Data2.VoucherNo && v.Data3.Status.HasFlag(StatusEunm.Auto))
  222. .Where(v => !v.Data3.Status.HasFlag(StatusEunm.PH_Status) && !v.Data3.Status.HasFlag(StatusEunm.OT_Status))
  223. .Where(v => !v.Data3.Status.HasFlag(StatusEunm.Run)).ToList(); // 筛选出可用站台
  224. //var putS1 = stations.Select(v => v.Entity.Code);
  225. var dev = devs.Find(v => v.Entity.Code == "1127");
  226. World.Log($"放货站台1127信号凭证号{dev.Data.VoucherNo}-{dev.Data2.VoucherNo}-自动{dev.Data3.Status.HasFlag(StatusEunm.Auto)}-光电{dev.Data3.Status.HasFlag(StatusEunm.PH_Status)}-有货光电{dev.Data3.Status.HasFlag(StatusEunm.OT_Status)}-{dev.Data3.Status.HasFlag(StatusEunm.Run)}");
  227. this.ExRecord(obj.Entity.Code, $"AGV任务{agvInfo.ID},可用放货站台", stations.Select(v => v.Entity.Code).ToList());
  228. //可用堆垛机
  229. srm = stations.Select(v => v.Entity.Sources).SelectMany(v => v).Where(v => v.IsTunnel()) //上一个地址是巷道的
  230. .Select(v => v.Sources).SelectMany(v => v).Where(v => v.HasProtocol(typeof(ISRM520))) //筛选出堆垛机
  231. .Select(v => new SRM(v, this.World)) //转换为SRM
  232. .Where(v => v != null && !v.Data2.Status.HasFlag(SrmStatus.Alarm) && v.Data2.AutoStatus == SrmAutoStatus.Automatic) //筛选出可用堆垛机
  233. .Where(v => tunnelNo.Contains(v.Entity.Code)) //筛选出巷道优先级最高的堆垛机
  234. .MinBy(v => tunnelNo.IndexOf(v.Entity.Code));//按照巷道优先级排序
  235. }
  236. if (srm == null) throw new Exception($"agv任务{agvInfo.ID}无可用堆垛机");
  237. //筛选出堆垛机的放货站台
  238. var nextPos = stations.FirstOrDefault(v => v.Entity.Sources.Where(t => t.IsTunnel()).Select(t => t.Sources).SelectMany(v => v) //获取所有巷道
  239. .Where(t => t.HasProtocol(typeof(ISRM520)))//筛选出堆垛机
  240. .SelectMany(v => v.Sources).Any(t => t.Code == srm.Entity.Parent.Code));
  241. this.ExRecord(obj.Entity.Code, $"AGV任务{agvInfo.ID},放货站台{nextPos}");
  242. bool flag = false;
  243. var agvs = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status < AGVTaskStatus.MissionCompleted && v.Position == nextPos.Entity.Code).SplitTable(v => v.Take(2)).ToList();
  244. if (agvs.Any())
  245. {
  246. var msg = "已无可用放货站台,任务正在执行中:";
  247. foreach (var ag in agvs)
  248. {
  249. msg = msg + $"[任务号:{ag.ID},目标地址:{ag.Position}]";
  250. }
  251. throw new Exception(msg);
  252. }
  253. //wcs任务状态卡控,防止因光电异常误判
  254. if (db.Default.Queryable<WCS_TaskInfo>().Any(v => v.AddrNext == nextPos.Entity.Code && v.Status == Entity.TaskStatus.ConveyorExecution)) return;
  255. //if (db.Default.Queryable<WCS_TaskDtl>().SplitTable(v => v.Take(2)).Any(v => v.NextPoint == nextPos.Entity.Code && v.Desc.Contains("任务分配至堆垛机"))) return;
  256. if (RedisHub.Default.Get("TaskTun:" + task.ID) != null && RedisHub.Default.Get("TaskTun:" + task.ID) != nextPos.Entity.Code)
  257. {
  258. throw new Exception("WCS任务:" + task.ID + "已经分配过巷道,不允许重新分配不同巷道");
  259. }
  260. if (task.BusType == "二楼湿拉空轮回立库")
  261. {
  262. //获取在途任务
  263. var n = db.Default.Queryable<WCS_TaskInfo>().Count(v => v.BusType == "二楼湿拉空轮回立库" && v.Status == Entity.TaskStatus.AGVExecution && v.AddrTo == "srm" && v.AddrNext == null);
  264. var config = db.Default.Queryable<hjSysConfig>().First(v => v.Code == "MaxAgvTaskNum");
  265. if (nextPos.Entity.Code != "1127" && config != null && config.SContent.ToShort() > n)
  266. {
  267. throw new Exception($"当前在途任务数{n}不足{config.SContent.ToShort()},需在此等待或修改配置数量");
  268. }
  269. }
  270. //更新AGV任务状态
  271. agvInfo.Status = AGVTaskStatus.Complete1;
  272. //agv.Position = flag == true ? "1025" : nextPos.Entity.Code;
  273. agvInfo.Position = nextPos.Entity.Code;
  274. var upres1 = db.Default.Updateable(agvInfo).SplitTable(x => x.Take(2)).ExecuteCommand();
  275. //更新WCS任务状态
  276. //if (flag)
  277. //{
  278. // srm.Entity.Code = "SRM3";
  279. // task.Device = srm.Entity.Code;
  280. // task.Tunnel = "3";
  281. // task.AddrNext = "1025";
  282. // task.SrmStation = "1025";
  283. //}
  284. //else
  285. {
  286. task.Device = srm.Entity.Code;
  287. task.Tunnel = task.Device.GetLastDigit().ToString();
  288. task.AddrNext = agvInfo.Position;
  289. task.SrmStation = nextPos.Entity.Code;
  290. }
  291. var upres = db.Default.Updateable(task).ExecuteCommand();
  292. task.AddWCS_TASK_DTL(db, "AGV巷道分配点", nextPos.Entity.Code, $"任务分配至堆垛机:{srm.Entity.Code}");
  293. this.ExRecord(obj.Entity.Code, $"AGV任务{agvInfo.ID}分配至堆垛机:{srm.Entity.Code}");
  294. if (upres > 0 && upres1 > 0)
  295. {
  296. //调继续执行任务接口(监控发现海康接口有不响应的情况,会导致事务不执行,把接口调用拿到事务外面)
  297. //AgvApi.ContinueTask(agvInfo.AgvID, nextPos.Entity.Code);
  298. isApplyContainue = 1;
  299. agvid = agvInfo.AgvID;
  300. nextpos = nextPos.Entity.Code;
  301. RedisHub.Default.Set("TaskTun:" + task.ID, nextPos.Entity.Code, 600);
  302. }
  303. }
  304. //放货站点安全交互
  305. else if (agvInfo.AgvStatus == AGVTaskStatus.RequestOrPermission2 && agvInfo.Status != AGVTaskStatus.Complete2)
  306. {
  307. //找到对应WCS任务
  308. var task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agvInfo.ID);
  309. if (task == null) throw new Exception($"AGV任务{agvInfo.ID}未找到对应WCS任务");
  310. if (agvInfo.Position.IsNullOrEmpty()) throw new Exception($"无有效放货地址");
  311. if (db.Default.Queryable<WCS_TaskInfo>().Any(v => v.AddrNext == agvInfo.Position && v.Status == Entity.TaskStatus.ConveyorExecution)) throw new Exception($"AGV请求放货,但{agvInfo.Position}上任务状态异常"); ;
  312. var dev = devs.Find(v => v.Entity.Code == agvInfo.Position);
  313. if (dev.Data.VoucherNo != dev.Data2.VoucherNo) throw new Exception($"AGV请求放货,但{dev.Entity.Code}凭证号不一致");
  314. if (!dev.Data3.Status.HasFlag(StatusEunm.Auto)) throw new Exception($"AGV请求放货,但{dev.Entity.Code}不在自动状态");
  315. if (dev.Data3.Status.HasFlag(StatusEunm.PH_Status)) throw new Exception($"AGV请求放货,但{dev.Entity.Code}光电有货");
  316. if (dev.Data3.Status.HasFlag(StatusEunm.OT_Status)) throw new Exception($"AGV请求放货,但{dev.Entity.Code}任务有货");
  317. if (dev.Data3.Status.HasFlag(StatusEunm.Run)) throw new Exception($"AGV请求放货,但{dev.Entity.Code}在运行状态");
  318. agvInfo.Status = AGVTaskStatus.Complete2;
  319. db.Default.Updateable(agvInfo).SplitTable(x => x.Take(2)).ExecuteCommand();
  320. dev.Data.TaskNumber = task.ID;
  321. World.Log($"agvRequestOrPermission2:taskid[{dev.Data.TaskNumber}]", LogLevelEnum.Mid);
  322. //调继续执行任务接口
  323. AgvApi.ContinueTask(agvInfo.AgvID, dev.Entity.Code);
  324. }
  325. //完成任务
  326. else if (agvInfo.AgvStatus == AGVTaskStatus.MissionCompleted && agvInfo.Status != AGVTaskStatus.MissionCompleted)
  327. {
  328. agvInfo.Status = AGVTaskStatus.MissionCompleted;
  329. db.Default.Updateable(agvInfo).SplitTable(x => x.Take(2)).ExecuteCommand();
  330. }
  331. #endregion 开始跟据AGV状态做出处理
  332. });
  333. if (isApplyContainue > 0)
  334. {
  335. SqlSugarHelper.Do(db =>
  336. {
  337. var agvInfo = db.Default.Queryable<WCS_AgvTaskInfo>().Where(x => x.AgvID == agvid).SplitTable(s => s.Take(2)).First();
  338. if (agvInfo.Status == AGVTaskStatus.Complete1)
  339. {
  340. AgvApi.ContinueTask(agvid, nextpos);
  341. }
  342. });
  343. //AgvApi.ContinueTask(agvid, nextpos);
  344. }
  345. }
  346. catch (Exception ex)
  347. {
  348. World.Log(ex.Message, LogLevelEnum.Mid);
  349. this.ExRecord(obj.Entity.Code, ex.Message);
  350. continue;
  351. }
  352. }
  353. World.Log($"agv任务处理:结束[{guid}]", LogLevelEnum.Mid);
  354. }
  355. }
  356. }
  357. /// <summary>
  358. /// 配置信息表
  359. /// </summary>
  360. [Tenant("hj")]
  361. [SugarTable("sys_config", "配置信息表")]
  362. public class hjSysConfig : BaseModel
  363. {
  364. /// <summary>
  365. /// 编号
  366. /// </summary>
  367. [SugarColumn(ColumnName = "code", Length = 100)]
  368. public string Code { get; set; }
  369. /// <summary>
  370. /// 名称
  371. /// </summary>
  372. [SugarColumn(ColumnName = "name", Length = 100)]
  373. public string Name { get; set; }
  374. /// <summary>
  375. /// 内容
  376. /// </summary>
  377. [SugarColumn(ColumnName = "scontent", Length = 100)]
  378. public string SContent { get; set; }
  379. /// <summary>
  380. /// 类型
  381. /// </summary>
  382. [SugarColumn(ColumnName = "stype", Length = 50)]
  383. public string SType { get; set; }
  384. [SugarColumn(ColumnName = "default1", Length = 100, IsNullable = true)]
  385. public string Default1 { get; set; }
  386. [SugarColumn(ColumnName = "default2", Length = 100, IsNullable = true)]
  387. public string Default2 { get; set; }
  388. [SugarColumn(ColumnName = "default3", Length = 100, IsNullable = true)]
  389. public string Default3 { get; set; }
  390. }
  391. public override bool Select(Device dev)
  392. {
  393. return dev.Code is "1017" or "1018";
  394. }
  395. }
  396. }