WcsController.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. using Microsoft.AspNetCore.Mvc;
  2. using Newtonsoft.Json;
  3. using ServiceCenter;
  4. using ServiceCenter.Redis;
  5. using ServiceCenter.SqlSugars;
  6. using System.Net.NetworkInformation;
  7. using System.Text;
  8. using WCS.Core;
  9. using WCS.Entity;
  10. using WCS.Entity.Protocol.DataStructure;
  11. using WCS.Entity.Protocol.SRM;
  12. using WCS.WorkEngineering.Extensions;
  13. using WCS.WorkEngineering.Systems;
  14. using WCS.WorkEngineering.WebApi.Models.WCS.Request;
  15. using WCS.WorkEngineering.WebApi.Models.WCS.Response;
  16. using WCS.WorkEngineering.WebApi.Models.WMS.Response;
  17. namespace WCS.WorkEngineering.WebApi.Controllers
  18. {
  19. /// <summary>
  20. /// WCS相关接口控制器
  21. /// </summary>
  22. [ApiController]
  23. [Route("api/[controller]/[action]")]
  24. public class WcsController : ControllerBase, IDeviceWriter
  25. {
  26. /// <summary>
  27. /// 任务处理接口
  28. /// </summary>
  29. /// <param name="req"></param>
  30. /// <returns></returns>
  31. [HttpPost]
  32. public SRes<HandleTaskResponse> HandleTask([FromBody] HandleTaskRequest req)
  33. {
  34. SRes<HandleTaskResponse> response = new SRes<HandleTaskResponse>() { ResCode = ResponseStatusCodeEnum.Sucess, ResDataList = new List<HandleTaskResponse>() };
  35. //取消任务
  36. if (req.Type == HandleTaskTypeEnum.取消任务)
  37. {
  38. foreach (var item in req.TaskIds)
  39. {
  40. SqlSugarHelper.Do(db =>
  41. {
  42. var task = db.Default.Queryable<WCS_TaskInfo>().Where(t => t.ID == item).First();
  43. if (task != null)
  44. {
  45. SRes res = new SRes();
  46. //验证wms是否能取消
  47. try
  48. {
  49. res = WmsApi.HandleTaskVerify(new List<int>() { task.ID }, 106);
  50. }
  51. catch (Exception ex)
  52. {
  53. response.ResDataList.Add(new HandleTaskResponse()
  54. {
  55. IsSuccess = false,
  56. TaskNo = item,
  57. Message = ex.Message,
  58. });
  59. return;
  60. }
  61. if (res.ResCode == Models.WMS.Response.ResponseStatusCodeEnum.Sucess)
  62. {
  63. switch (task.Type)
  64. {
  65. case TaskType.SetPlate:
  66. if (task.Status != Entity.TaskStatus.WaitingToExecute)
  67. {
  68. response.ResDataList.Add(new HandleTaskResponse()
  69. {
  70. IsSuccess = false,
  71. TaskNo = item,
  72. Message = $"只能取消待执行状态组盘任务",
  73. });
  74. return;
  75. }
  76. break;
  77. case TaskType.EnterDepot:
  78. if (task.Status > Entity.TaskStatus.WaitingToExecute)
  79. {
  80. response.ResDataList.Add(new HandleTaskResponse()
  81. {
  82. IsSuccess = false,
  83. TaskNo = item,
  84. Message = $"只能取消待执行状态入库任务",
  85. });
  86. return;
  87. }
  88. break;
  89. case TaskType.OutDepot:
  90. if (task.Status != Entity.TaskStatus.WaitingToExecute)
  91. {
  92. response.ResDataList.Add(new HandleTaskResponse()
  93. {
  94. IsSuccess = false,
  95. TaskNo = item,
  96. Message = $"只能取消待执行状态出库任务",
  97. });
  98. return;
  99. }
  100. break;
  101. case TaskType.TransferDepot:
  102. break;
  103. case TaskType.Delivery:
  104. if (task.Status != Entity.TaskStatus.WaitingToExecute)
  105. {
  106. response.ResDataList.Add(new HandleTaskResponse()
  107. {
  108. IsSuccess = false,
  109. TaskNo = item,
  110. Message = $"只能取消待执行搬运任务",
  111. });
  112. return;
  113. }
  114. break;
  115. case TaskType.EmptyInit:
  116. if (task.Status != Entity.TaskStatus.WaitingToExecute)
  117. {
  118. response.ResDataList.Add(new HandleTaskResponse()
  119. {
  120. IsSuccess = false,
  121. TaskNo = item,
  122. Message = $"只能取消待执行状态空轮初始化任务",
  123. });
  124. return;
  125. }
  126. break;
  127. }
  128. SRes cancelRes = new SRes();
  129. //取消任务
  130. try
  131. {
  132. cancelRes = WmsApi.CarryTaskInfo(new List<int>() { task.ID }, 106);
  133. }
  134. catch (Exception ex)
  135. {
  136. response.ResDataList.Add(new HandleTaskResponse()
  137. {
  138. IsSuccess = false,
  139. TaskNo = item,
  140. Message = ex.Message,
  141. });
  142. return;
  143. }
  144. if (cancelRes.ResCode == Models.WMS.Response.ResponseStatusCodeEnum.Sucess)
  145. {
  146. //找到对应的AGV任务
  147. var agv = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.ID == task.AgvTaskID).SplitTable(v => v.Take(2)).First();
  148. if (agv != null)
  149. {
  150. agv.Status = AGVTaskStatus.Cancel;
  151. agv.AgvStatus = AGVTaskStatus.Cancel;
  152. db.Default.Updateable(agv).SplitTable().ExecuteCommand();
  153. }
  154. //更新任务状态
  155. task.Status = Entity.TaskStatus.Cancel;
  156. task.EditTime = DateTime.Now;
  157. task.EditWho = req.User;
  158. task.ManualRemarks = req.ManualRemarks;
  159. task.AddWCS_TASK_DTL(db, "未知", "任务取消");
  160. db.Default.Updateable(task).ExecuteCommand();
  161. task.CompleteOrCancelTasks(db);
  162. response.ResDataList.Add(new HandleTaskResponse()
  163. {
  164. IsSuccess = true,
  165. TaskNo = item,
  166. Message = $"完成",
  167. });
  168. }
  169. else
  170. {
  171. response.ResDataList.Add(new HandleTaskResponse()
  172. {
  173. IsSuccess = false,
  174. TaskNo = item,
  175. Message = $"取消任务失败,{cancelRes.ResMsg}",
  176. });
  177. }
  178. }
  179. else
  180. {
  181. response.ResDataList.Add(new HandleTaskResponse()
  182. {
  183. IsSuccess = false,
  184. TaskNo = item,
  185. Message = $"取消任务失败,{res.ResMsg}",
  186. });
  187. }
  188. }
  189. else
  190. {
  191. response.ResDataList.Add(new HandleTaskResponse()
  192. {
  193. IsSuccess = false,
  194. TaskNo = item,
  195. Message = $"未找到对应任务{item}"
  196. });
  197. }
  198. });
  199. }
  200. }
  201. // 完成任务
  202. else if (req.Type == HandleTaskTypeEnum.完成任务)
  203. {
  204. SqlSugarHelper.Do(db =>
  205. {
  206. foreach (var item in req.TaskIds)
  207. {
  208. var task = db.Default.Queryable<WCS_TaskInfo>().Where(t => t.ID == item).First();
  209. if (task != null)
  210. {
  211. if (task.Type == TaskType.OutDepot && task.Floor == 1)
  212. {
  213. task.Status = Entity.TaskStatus.Finish;
  214. task.EditWho = req.User;
  215. task.ManualRemarks = req.ManualRemarks;
  216. task.AddWCS_TASK_DTL(db, "未知", "手动完成任务");
  217. task.CompleteOrCancelTasks(db);
  218. db.Default.Updateable(task).ExecuteCommand();
  219. }
  220. else
  221. {
  222. response.ResDataList.Add(new HandleTaskResponse()
  223. {
  224. IsSuccess = false,
  225. TaskNo = item,
  226. Message = $"未实现当前任务的完成功能"
  227. });
  228. }
  229. }
  230. else
  231. {
  232. response.ResDataList.Add(new HandleTaskResponse()
  233. {
  234. IsSuccess = false,
  235. TaskNo = item,
  236. Message = $"未找到对应任务{item}"
  237. });
  238. }
  239. }
  240. });
  241. }
  242. else if (req.Type == HandleTaskTypeEnum.重新下发AGV任务)
  243. {
  244. SqlSugarHelper.Do(db =>
  245. {
  246. foreach (var item in req.TaskIds)
  247. {
  248. var task = db.Default.Queryable<WCS_TaskInfo>().Where(t => t.ID == item).First();
  249. if (task != null)
  250. {
  251. if (task.Type == TaskType.SetPlate) //组盘任务
  252. {
  253. response.ResDataList.Add(new HandleTaskResponse()
  254. {
  255. IsSuccess = false,
  256. TaskNo = item,
  257. Message = $"组盘任务无AGV执行流程",
  258. });
  259. }
  260. else if (task.Type == TaskType.EnterDepot) //入库任务
  261. {
  262. if (task.Floor == 1) //一楼入库
  263. {
  264. }
  265. else if (task.Floor == 2) //二楼入库
  266. {
  267. response.ResDataList.Add(new HandleTaskResponse()
  268. {
  269. IsSuccess = false,
  270. TaskNo = item,
  271. Message = $"二楼入库任务重新下发AGV未实现",
  272. });
  273. }
  274. }
  275. else if (task.Type == TaskType.OutDepot) //出库
  276. {
  277. }
  278. else if (task.Type == TaskType.TransferDepot) //移库
  279. {
  280. response.ResDataList.Add(new HandleTaskResponse()
  281. {
  282. IsSuccess = false,
  283. TaskNo = item,
  284. Message = $"组盘任务无AGV执行流程",
  285. });
  286. }
  287. else if (task.Type == TaskType.Delivery) //搬运
  288. {
  289. if (task.Floor == 1)
  290. {
  291. }
  292. else if (task.Floor == 2)
  293. {
  294. response.ResDataList.Add(new HandleTaskResponse()
  295. {
  296. IsSuccess = false,
  297. TaskNo = item,
  298. Message = $"二楼搬运任务重新下发AGV未实现",
  299. });
  300. }
  301. }
  302. else if (task.Type == TaskType.EmptyInit) //空轮初始化
  303. {
  304. response.ResDataList.Add(new HandleTaskResponse()
  305. {
  306. IsSuccess = false,
  307. TaskNo = item,
  308. Message = $"空轮初始化无AGV执行流程",
  309. });
  310. }
  311. //找到对应的AGV任务
  312. var agv = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.ID == task.AgvTaskID).SplitTable(v => v.Take(2)).First();
  313. if (agv != null)
  314. {
  315. agv.Status = AGVTaskStatus.NewBuild;
  316. agv.AgvStatus = AGVTaskStatus.NewBuild;
  317. db.Default.Updateable(agv).SplitTable().ExecuteCommand();
  318. }
  319. if (task.Floor == 1)
  320. {
  321. task.Status = Entity.TaskStatus.WaitingToExecute;
  322. }
  323. else if (task.Floor == 2)
  324. {
  325. task.Status = Entity.TaskStatus.ConveyorExecution;
  326. }
  327. task.AddWCS_TASK_DTL(db, "AGV", "重新下发AGV任务");
  328. db.Default.Updateable(task).ExecuteCommand();
  329. }
  330. else
  331. {
  332. response.ResDataList.Add(new HandleTaskResponse()
  333. {
  334. IsSuccess = false,
  335. TaskNo = item,
  336. Message = $"未找到对应任务{item}"
  337. });
  338. }
  339. }
  340. });
  341. }
  342. return response;
  343. }
  344. /// <summary>
  345. /// 设备信息写入接口
  346. /// </summary>
  347. /// <param name="deviceType">需要写入信息的设备类型</param>
  348. /// <param name="devCode">设备编号</param>
  349. /// <param name="protocol">设备协议类名</param>
  350. /// <param name="propName">写入字段名</param>
  351. /// <param name="value">值</param>
  352. [HttpPost]
  353. public void Write(DeviceTypeEnum deviceType, string devCode, string protocol, string propName, string value)
  354. {
  355. World.GetSystemInstance<DeviceWriteSystem>().Invoke(new DeviceWriteInfo
  356. {
  357. DeviceType = deviceType,
  358. Code = devCode,
  359. Protocol = protocol,
  360. Property = propName,
  361. Value = value
  362. });
  363. }
  364. /// <summary>
  365. /// 设备信息写入接口
  366. /// </summary>
  367. /// <param name="deviceType">需要写入信息的设备类型</param>
  368. /// <param name="devCode">设备编号</param>
  369. /// <param name="protocol">设备协议类名</param>
  370. /// <param name="propName">写入字段名</param>
  371. /// <param name="value">值</param>
  372. [HttpPost]
  373. public void GetDevList()
  374. {
  375. var a = RedisHub.Monitor.LRange("Packs", 0, 80000);
  376. List<DeviceDataPack> packs = new List<DeviceDataPack>();
  377. foreach (var item in a)
  378. {
  379. packs.Add(JsonConvert.DeserializeObject<DeviceDataPack>(item));
  380. }
  381. }
  382. /// <summary>
  383. /// 获取设备配置信息接口
  384. /// </summary>
  385. /// <returns></returns>
  386. [HttpGet]
  387. public List<Device> GetDeviceList()
  388. {
  389. return Device.All.ToList();
  390. }
  391. /// <summary>
  392. /// 获取设备信息
  393. /// </summary>
  394. /// <param name="name">设备名称</param>
  395. /// <returns></returns>
  396. [HttpGet]
  397. public object GetDeviceInfo(string name)
  398. {
  399. var obj = World.GetSystemInstance<GetDeviceSystem>().Invoke(name);
  400. return obj;
  401. }
  402. /// <summary>
  403. /// 堆垛机测试
  404. /// </summary>
  405. /// <param name="srmcod">堆垛机编号</param>
  406. /// <param name="typeEnum">任务类型</param>
  407. /// <param name="value1">起始行</param>
  408. /// <param name="value2">起始列</param>
  409. /// <param name="value3">起始层</param>
  410. /// <param name="value4">目标行</param>
  411. /// <param name="value5">目标列</param>
  412. /// <param name="value6">目标层</param>
  413. [HttpPost]
  414. public void SrmDeBug(string srmcod, SrmTaskTypeEnum typeEnum, short value1, short value2, short value3, short value4, short value5, short value6)
  415. {
  416. World.GetSystemInstance<SrmDebugSystem>().Invoke(new SrmDebugInfo
  417. {
  418. SrmCode = srmcod,
  419. srmTaskType = typeEnum,
  420. SLine = value1,
  421. SCol = value2,
  422. SLayer = value3,
  423. ELine = value4,
  424. ECol = value5,
  425. ELayer = value6
  426. });
  427. }
  428. #region 设备IP相关
  429. /// <summary>
  430. /// 获取设备Ip集合
  431. /// </summary>
  432. /// <returns>设备Ip集合</returns>
  433. [HttpGet]
  434. public List<string> GetDeviceIpList()
  435. {
  436. if (!ServiceHub.DeviceIPList.Any()) throw new Exception("未配置任何Ip");
  437. return ServiceHub.DeviceIPList;
  438. }
  439. /// <summary>
  440. /// 获取设备IP检测结果
  441. /// </summary>
  442. /// <returns>设备IP检测结果</returns>
  443. [HttpGet]
  444. public List<DeviceIpTestResults> DeviceIpTest()
  445. {
  446. if (!ServiceHub.DeviceIPList.Any()) throw new Exception("未配置任何Ip");
  447. List<DeviceIpTestResults> deviceIpTestResults = new List<DeviceIpTestResults>();
  448. ServiceHub.DeviceIPList.ForEach(ip =>
  449. {
  450. deviceIpTestResults.Add(new DeviceIpTestResults
  451. {
  452. Ip = ip,
  453. Result = PingIpOrDomainName(ip)
  454. });
  455. });
  456. return deviceIpTestResults;
  457. }
  458. /// <summary>
  459. /// 检查Ip是否正常联通
  460. /// </summary>
  461. /// <param name="strIpOrDName">输入参数,表示IP地址或域名</param>
  462. /// <returns></returns>
  463. public static bool PingIpOrDomainName(string strIpOrDName)
  464. {
  465. try
  466. {
  467. Ping objPingSender = new Ping();
  468. PingOptions objPinOptions = new PingOptions();
  469. objPinOptions.DontFragment = true;
  470. string data = "";
  471. byte[] buffer = Encoding.UTF8.GetBytes(data);
  472. int intTimeout = 120;
  473. PingReply objPinReply = objPingSender.Send(strIpOrDName, intTimeout, buffer, objPinOptions);
  474. string strInfo = objPinReply.Status.ToString();
  475. if (strInfo == "Success")
  476. {
  477. return true;
  478. }
  479. else
  480. {
  481. return false;
  482. }
  483. }
  484. catch (Exception)
  485. {
  486. return false;
  487. }
  488. }
  489. #endregion 设备IP相关
  490. }
  491. public interface IDeviceWriter
  492. {
  493. [HttpPost]
  494. void Write(DeviceTypeEnum deviceType, string devCode, string protocol, string propName, string value);
  495. }
  496. /// <summary>
  497. /// 设备Ip通讯检测结构
  498. /// </summary>
  499. public class DeviceIpTestResults
  500. {
  501. public string Ip { get; set; }
  502. public bool Result { get; set; }
  503. }
  504. }