AgvController.cs 12 KB

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