AgvController.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. using Microsoft.AspNetCore.Mvc;
  2. using PlcSiemens.Core.Extension;
  3. using ServiceCenter.SqlSugars;
  4. using WCS.Core;
  5. using WCS.Entity;
  6. using WCS.Entity.Protocol.Station;
  7. using WCS.WorkEngineering.Extensions;
  8. using WCS.WorkEngineering.Systems;
  9. using WCS.WorkEngineering.WebApi.Models.AGV;
  10. using WCS.WorkEngineering.WebApi.Models.AGV.Request;
  11. using WCS.WorkEngineering.WebApi.Models.AGV.Response;
  12. namespace WCS.WorkEngineering.WebApi.Controllers
  13. {
  14. /// <summary>
  15. /// AGV相关接口控制器
  16. /// </summary>
  17. [ApiController]
  18. [Route("api/[controller]/[action]")]
  19. public class AgvController : ControllerBase
  20. {
  21. /// <summary>
  22. /// AGV任务下发测试
  23. /// </summary>
  24. /// <param name="type">任务类型</param>
  25. /// <param name="code">RFID</param>
  26. /// <param name="pos">目标位置</param>
  27. /// <returns></returns>
  28. [HttpPost]
  29. public string AgvDebug(int type, string code, string pos)
  30. {
  31. try
  32. {
  33. switch (type)
  34. {
  35. case 1:
  36. AgvApi.机台补空(pos, code, "1");
  37. break;
  38. case 2:
  39. //AgvApi.机台补满();
  40. break;
  41. case 3:
  42. AgvApi.满轮入库(code, pos, Guid.NewGuid().ToString().Replace("-", ""), "1");
  43. break;
  44. default:
  45. break;
  46. }
  47. return "成功";
  48. }
  49. catch (Exception ex)
  50. {
  51. return $"Error-----" +
  52. $"{ex.Message}------" +
  53. $"{ex.StackTrace}";
  54. }
  55. }
  56. /// <summary>
  57. /// 背负式agv请求出库任务
  58. /// </summary>
  59. /// <param name="reqDto">请求参数</param>
  60. /// <returns></returns>
  61. [HttpPost]
  62. public ApplyEmptySpoolResponse ApplyEmptySpool([FromBody] AgvFillEmptySpaceRequest reqDto)
  63. {
  64. lock (LockHub.ApplyEmptySpoolLock)
  65. {
  66. ApplyEmptySpoolResponse agvFill = new ApplyEmptySpoolResponse();
  67. try
  68. {
  69. if (!World.IsStart)
  70. {
  71. agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
  72. agvFill.ResMsg = "WCS初始化中";
  73. return agvFill;
  74. }
  75. var obj = World.GetSystemInstance<GetDeviceSystem>().Invoke("输送机") as List<Station>;
  76. // 检测三个站台是否有货
  77. obj = obj.Where(v => v.Entity.Code is "1012" or "1014" or "1016").Where(v => v.Data3.Status.HasFlag(StatusEunm.PH_Status)).ToList();
  78. if (!obj.Any())
  79. {
  80. agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
  81. agvFill.ResMsg = "无空轮";
  82. return agvFill;
  83. }
  84. SqlSugarHelper.Do(db =>
  85. {
  86. var res = WmsApi.GetTunnelEmptyConCount();
  87. var agvStations = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(tabs => tabs.Take(2))
  88. .Where(v => v.Status < AGVTaskStatus.Complete3 && v.TaskType == AGVTaskType.CallForMaterial).Select(v => v.Station).ToList();
  89. obj = obj.Where(v => !agvStations.Contains(v.Entity.Code)).ToList();
  90. if (!obj.Any())
  91. {
  92. agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
  93. agvFill.ResMsg = "无可用取货站点";
  94. return;
  95. }
  96. foreach (var item in res.ResDataList)
  97. {
  98. var station = Device.All.Where(v => v.Code == "TY" + item.Tunnel.ToString())
  99. .Select(v => v.Targets).SelectMany(v => v)
  100. .Where(v => v.HasProtocol(typeof(IStation520)))
  101. .Where(v => v.Code is "1012" or "1014" or "1016")
  102. .FirstOrDefault();
  103. item.Tunnel = station.ToInt();
  104. }
  105. var stationNo = res.ResDataList.OrderBy(v => v.Count).Select(v => v.Tunnel.ToString()).ToList();
  106. agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.Sucess;
  107. var dev = obj.MinBy(v => stationNo.IndexOf(v.Entity.Code));
  108. agvFill.LocCode = dev.Entity.Code;
  109. agvFill.SpoolType = "4";
  110. agvFill.ResMsg = "";
  111. var id = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(v => v.Take(1)).Max(v => v.ID);
  112. var agv = new WCS_AgvTaskInfo()
  113. {
  114. ID = db.GetAGVTaskId(),
  115. TaskType = AGVTaskType.CallForMaterial,
  116. Status = AGVTaskStatus.NewBuild,
  117. Station = agvFill.LocCode,
  118. AddWho = "WCS"
  119. };
  120. //创建对应的AGV任务
  121. db.Default.Insertable(agv).SplitTable().ExecuteCommand();
  122. var task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.ID == dev.Data.TaskNumber) ?? throw new Exception("无有效任务");
  123. task.AgvTaskID = agv.ID;
  124. db.Default.Updateable(task).ExecuteCommand();
  125. });
  126. }
  127. catch (Exception ex)
  128. {
  129. agvFill.ResCode = Models.WMS.Response.ResponseStatusCodeEnum.DataSaveErr;
  130. agvFill.ResMsg = ex.Message;
  131. }
  132. return agvFill;
  133. }
  134. }
  135. /// <summary>
  136. /// AGV执行回调
  137. /// </summary>
  138. /// <param name="reqDto"></param>
  139. /// <returns></returns>
  140. [HttpPost]
  141. public AgvCallbackResponse AgvCallback([FromBody] AgvCallbackRequest reqDto)
  142. {
  143. lock (LockHub.AgvCallbackLock)
  144. {
  145. var res = new AgvCallbackResponse() { code = AgvResponseCode.Success, message = "成功" };
  146. WCS_TaskInfo taskInfo = null;
  147. try
  148. {
  149. SqlSugarHelper.Do(db =>
  150. {
  151. //跟据AGVid找到对应的AGV任务
  152. var agvTask = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(tabs => tabs.Take(2)).First(v => v.AgvID == reqDto.taskCode && v.Status < AGVTaskStatus.MissionCompleted);
  153. if (agvTask == null && reqDto.method != "applySecurity")
  154. {
  155. res.code = AgvResponseCode.Fail;
  156. res.message = "未找到对应的AGV任务";
  157. return;
  158. }
  159. switch (reqDto.method)
  160. {
  161. //case "start": //表示请求巷道
  162. // agvTask.Status = AGVTaskStatus.RequestOrPermission1;
  163. // break;
  164. //case "end": //表示请求巷道
  165. // agvTask.Status = AGVTaskStatus.RequestOrPermission1;
  166. // break;
  167. case "applyContinue": //表示请求巷道
  168. agvTask.Status = AGVTaskStatus.RequestOrPermission1;
  169. break;
  170. case "applySecurity": //表示请求放货或取货
  171. if (reqDto.callCode is "1012" or "1014" or "1016")
  172. {
  173. agvTask = db.Default.Queryable<WCS_AgvTaskInfo>()
  174. .SplitTable(tabs => tabs.Take(2))
  175. .First(v => v.Status == AGVTaskStatus.NewBuild && v.TaskType == AGVTaskType.CallForMaterial && v.Station == reqDto.callCode);
  176. agvTask.AgvID = reqDto.taskCode;
  177. var obj = World.GetSystemInstance<GetDeviceSystem>().Invoke("输送机") as List<Station>;
  178. var id = obj.FirstOrDefault(v => v.Entity.Code == agvTask.Station).Data.TaskNumber;
  179. taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.ID == id);
  180. taskInfo.AgvTaskID = agvTask.ID;
  181. taskInfo.Status = Entity.TaskStatus.AGVExecution;
  182. db.Default.Updateable(taskInfo).ExecuteCommand();
  183. taskInfo.AddWCS_TASK_DTL(db, agvTask.Station, "agv执行中");
  184. }
  185. if (agvTask == null)
  186. {
  187. res.code = AgvResponseCode.Fail;
  188. res.message = "未找到对应的AGV任务";
  189. return;
  190. }
  191. agvTask.Status = AGVTaskStatus.RequestOrPermission2;
  192. break;
  193. case "hjend_2": //补空任务完成
  194. if (agvTask.TaskType == AGVTaskType.CallForMaterial)
  195. {
  196. taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agvTask.ID);
  197. taskInfo.Status = Entity.TaskStatus.Finish;
  198. taskInfo.EedTime = DateTime.Now;
  199. taskInfo.AddWCS_TASK_DTL(db, "agv缓存区", "任务完成");
  200. db.Default.Updateable(taskInfo).ExecuteCommand();
  201. taskInfo.CompleteOrCancelTasks(db);
  202. }
  203. agvTask.Status = AGVTaskStatus.MissionCompleted;
  204. break;
  205. case "endhjBM": //取满任务完成
  206. agvTask.Status = AGVTaskStatus.MissionCompleted;
  207. break;
  208. case "tcEnd": //机台补空任务完成
  209. agvTask.Status = AGVTaskStatus.MissionCompleted;
  210. taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agvTask.ID);
  211. taskInfo.Status = Entity.TaskStatus.Finish;
  212. taskInfo.AddWCS_TASK_DTL(db, "agv", "任务完成");
  213. db.Default.Updateable(taskInfo).ExecuteCommand();
  214. taskInfo.CompleteOrCancelTasks(db);
  215. break;
  216. case "exc_end": //异常信息上抛-值不匹配
  217. agvTask.Status = AGVTaskStatus.MissionCompleted;
  218. break;
  219. case "outbin": //小车退出取货位
  220. agvTask.Status = AGVTaskStatus.Complete3;
  221. break;
  222. default:
  223. break;
  224. }
  225. db.Default.Updateable(agvTask).SplitTable().ExecuteCommand();
  226. });
  227. if (taskInfo != null && taskInfo.Status == Entity.TaskStatus.Finish) WmsApi.CompleteTask(taskInfo.ID);
  228. }
  229. catch (Exception ex)
  230. {
  231. res.code = AgvResponseCode.Error;
  232. res.message = ex.Message;
  233. }
  234. return res;
  235. }
  236. }
  237. }
  238. }