AgvController.cs 12 KB

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