WcsController.cs 29 KB

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