TaskService.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. using WCS.DeviceProtocol;
  2. using WCS.Repository;
  3. using Microsoft.EntityFrameworkCore;
  4. using Newtonsoft.Json;
  5. using WCS.Common;
  6. using WCS.Entitys;
  7. using WCS.Model;
  8. using WCS.Services;
  9. using HslCommunication.Profinet.Siemens;
  10. using HslCommunication;
  11. using WCS.Utils;
  12. using IMCS.CCS.Services;
  13. using StackExchange.Redis;
  14. using WCS.Models;
  15. namespace WCS.Service.Impl
  16. {
  17. public class TaskService : ITaskService
  18. {
  19. private readonly IDeviceRepository deviceRepository;
  20. private readonly IWcsActionService wcsActionService;
  21. private readonly IWcsActionAddressService wcsActionAddressService;
  22. private readonly ITaskCallbackService taskCallbackService;
  23. private readonly IConnectionMultiplexer _redis;
  24. private readonly IDeviceService _deviceService;
  25. private readonly IWcsTagValueService _wcsTagValueService;
  26. private readonly IApiRequestService _apiRequestService;
  27. private string wcs_callback_url;
  28. private string wcs_redis_key = "WCS:";
  29. private string LOG_TITLE_S7 = "S7采集";
  30. private string LOG_TITLE_CALLBACK = "回调任务";
  31. public IConfiguration Configuration { get; }
  32. public TaskService(IDeviceRepository deviceRepository,
  33. IWcsActionService wcsActionService,
  34. IWcsTagValueService wcsTagValueService,
  35. IWcsActionAddressService wcsActionAddressService,
  36. ITaskCallbackService taskCallbackService,
  37. IConnectionMultiplexer redisService,
  38. IDeviceService deviceService,
  39. IApiRequestService _apiRequestService,
  40. IConfiguration configuration
  41. )
  42. {
  43. this.deviceRepository = deviceRepository;
  44. this.wcsActionService = wcsActionService;
  45. this.wcsActionAddressService = wcsActionAddressService;
  46. this.taskCallbackService = taskCallbackService;
  47. this._redis = redisService;
  48. this._deviceService = deviceService;
  49. this._wcsTagValueService = wcsTagValueService;
  50. this._apiRequestService = _apiRequestService;
  51. wcs_callback_url = Configuration.GetConnectionString("wcsCallbackUrl");
  52. }
  53. public async Task<ResponseData> ExcuteTask(RequestData<LocationData> data)
  54. {
  55. ResponseData responseData = new ResponseData(data.taskNodeId);
  56. try
  57. {
  58. List<WcsDevice> devices = deviceRepository.GetDeviceList();
  59. WcsDevice? wcsDevice = devices.FirstOrDefault(x => x.Ip == data.ip);
  60. //WcsDevice device = devices.Where(x => x.Ip == data.url && x.Port == data.port).FirstOrDefault();
  61. if (wcsDevice == null)
  62. {
  63. Log.Instance.WriteLogAdd("设备已离线===>>" + JsonConvert.SerializeObject(data));
  64. responseData.IsSuccess = false;
  65. return responseData;
  66. }
  67. WcsAction action = new WcsAction();
  68. action.Ip = data.ip;
  69. action.OperateType = data.data.operateType.ToString();
  70. WcsAction? actionInfo = wcsActionService.GetList(action).FirstOrDefault();
  71. if (actionInfo == null)
  72. {
  73. Log.Instance.WriteLogAdd(data.data.operateType.ToString() + "异常===>>" + "找不到对应实例" + JsonConvert.SerializeObject(data),
  74. EnumHelper.GetEnumDescription<WcsActionType>(data.data.operateType));
  75. responseData.IsSuccess = false;
  76. return responseData;
  77. }
  78. WcsDevice? plcDevice = devices.FirstOrDefault(x => x.ProtocolType == "S7_1500");
  79. SiemensS7Net s7 = DevicePlcS7.SiemensS7(plcDevice.Ip);
  80. OperateResult ConnectionResult = s7.ConnectServer();
  81. if (!ConnectionResult.IsSuccess)
  82. {
  83. s7.ConnectClose();
  84. Log.Instance.WriteLogAdd(data.data.operateType.ToString() + "异常===>>" + "PLC连接不上" + JsonConvert.SerializeObject(data),
  85. EnumHelper.GetEnumDescription<WcsActionType>(data.data.operateType));
  86. responseData.IsSuccess = false;
  87. return responseData;
  88. }
  89. WcsActionAddress actionAddressQuery = new WcsActionAddress();
  90. actionAddressQuery.ActionId = actionInfo.Id;
  91. /*actionAddressQuery.Type = ActionAddressTypeEnum.WRITE.ToString();*/
  92. /*actionAddressQuery.Sort = data.data.type;*/
  93. List<WcsActionAddress> WcsActionAddresses = wcsActionAddressService.GetList(actionAddressQuery);
  94. WcsActionAddress? wcsActionAddress = WcsActionAddresses.Where(o=>o.Type== ActionAddressTypeEnum.WRITE.ToString() && o.Sort == data.data.type).FirstOrDefault();
  95. if (WcsActionAddresses != null && data.data.type == 0)
  96. {
  97. OperateResult operateResult = s7.Write(wcsActionAddress.Address, Convert.ToInt16(data.data.startPosition));
  98. }
  99. else if (WcsActionAddresses != null && data.data.type == 1)
  100. {
  101. s7.Write(wcsActionAddress.Address, Convert.ToInt16(data.data.endPosition));
  102. }
  103. s7.ConnectClose();
  104. //插入回调
  105. TaskCallback taskCallbackData = new TaskCallback(data.url, data.data.operateType.ToString(),
  106. EnumHelper.GetEnumDescription<WcsActionType>(data.data.operateType), data.taskId, data.taskNodeId);
  107. taskCallbackData = setCallBackValue(WcsActionAddresses, taskCallbackData, data);
  108. await taskCallbackService.CreateOrUpdateAndCache(taskCallbackData);
  109. Log.Instance.WriteLogAdd(EnumHelper.GetEnumDescription<WcsActionType>(data.data.operateType) + "成功===>>" + JsonConvert.SerializeObject(data)
  110. , EnumHelper.GetEnumDescription<WcsActionType>(data.data.operateType));
  111. return responseData;
  112. }
  113. catch (Exception ex)
  114. {
  115. Log.Instance.WriteLogAdd(data.data.operateType + "异常===>>" + ex.Message + JsonConvert.SerializeObject(data),
  116. EnumHelper.GetEnumDescription<WcsActionType>(data.data.operateType));
  117. responseData.IsSuccess = false;
  118. responseData.Msg=ex.Message;
  119. return responseData;
  120. }
  121. }
  122. /// <summary>
  123. /// 采集数据S7
  124. /// </summary>
  125. /// <returns></returns>
  126. public async Task<string> DataCollectS7Job()
  127. {
  128. try
  129. {
  130. List<WcsDevice> deviceList = await getDeviceList();
  131. deviceList = deviceList.Where(x => x.ProtocolType.Equals(ProtocalTypeEnum.S7_1500.ToString()) && x.State).ToList();
  132. foreach (WcsDevice device in deviceList)
  133. {
  134. List<WcsTagValue> tagValues = new List<WcsTagValue>();
  135. string redis_key = "WCS:" + device.Ip + ":" + device.ProtocolType;
  136. var data = await _redis.GetDatabase().StringGetAsync(redis_key);
  137. if (data.IsNullOrEmpty)
  138. {
  139. WcsTagValue tagQuery = new WcsTagValue();
  140. tagQuery.ProtocolType = device.ProtocolType;
  141. tagQuery.Ip = device.Ip;
  142. tagValues = _wcsTagValueService.GetList(tagQuery);
  143. //首次设置redis
  144. if (tagValues != null && tagValues.Count > 0)
  145. {
  146. await _redis.GetDatabase().StringSetAsync(redis_key, JsonConvert.SerializeObject(tagValues));
  147. }
  148. }
  149. else
  150. {
  151. tagValues = JsonConvert.DeserializeObject<List<WcsTagValue>>(data);
  152. }
  153. if (tagValues != null && tagValues.Count > 0)
  154. {
  155. tagValues = JsonConvert.DeserializeObject<List<WcsTagValue>>(data);
  156. List<WcsTagValue> changTagValues = new List<WcsTagValue>();
  157. //Plc s7 = DevicePlcS7.S7(device.ServerUrl, ProtocalTypeEnum.S7_1500.ToString());
  158. SiemensS7Net s7 = DevicePlcS7.SiemensS7(device.Ip);
  159. OperateResult ConnectionResult = s7.ConnectServer();
  160. if (!ConnectionResult.IsSuccess)
  161. {
  162. device.State = false;
  163. await _deviceService.UpdateDevice(device);
  164. s7.ConnectClose();
  165. Log.Instance.WriteLogAdd("S7采集异常,plc连不上==>" + device.Ip, LOG_TITLE_S7);
  166. return "采集失败,plc连不上";
  167. }
  168. else
  169. {
  170. foreach (WcsTagValue tagValueData in tagValues)
  171. {
  172. string operateResult = "";
  173. if (tagValueData.Type.Equals(TagValueReadTypeEnum.BOOL.ToString()))
  174. {
  175. operateResult = s7.ReadBool(tagValueData.Address).Content.ToString();
  176. }
  177. else if (tagValueData.Type.Equals(TagValueReadTypeEnum.SHORT.ToString()))
  178. {
  179. operateResult = s7.ReadInt16(tagValueData.Address).Content.ToString();
  180. }
  181. else if (tagValueData.Type.Equals(TagValueReadTypeEnum.String.ToString()))
  182. {
  183. operateResult = s7.ReadString(tagValueData.Address).Content.ToString();
  184. }
  185. else if (tagValueData.Type.Equals(TagValueReadTypeEnum.Array.ToString()))
  186. {
  187. operateResult = ToolUtils.ReturnStringByBytes(s7.Read(tagValueData.Address, 40).Content);
  188. }
  189. if (!string.IsNullOrEmpty(operateResult) && tagValueData.TagValue != operateResult)
  190. {
  191. tagValueData.TagValue = operateResult.ToString();
  192. tagValueData.UpdateTime = DateTime.Now;
  193. changTagValues.Add(tagValueData);
  194. Log.Instance.WriteLogAdd("S7采集,Ip:" + tagValueData.Ip + " 地址:" + tagValueData.Address + ",值:" + tagValueData.TagValue + ",发生变化", LOG_TITLE_S7);
  195. //有变化更新数据库
  196. await _wcsTagValueService.Update(tagValueData);
  197. }
  198. Thread.Sleep(50);
  199. }
  200. s7.ConnectClose();
  201. //值有变化,重新设置一次redis
  202. if (changTagValues != null && changTagValues.Count > 0)
  203. {
  204. await _redis.GetDatabase().StringSetAsync(redis_key, JsonConvert.SerializeObject(tagValues));
  205. }
  206. //存储采集数据
  207. CollectDataLog.Instance.WriteLogAdd(data, LOG_TITLE_S7);
  208. }
  209. }
  210. }
  211. return "S7采集成功";
  212. }
  213. catch (Exception ex)
  214. {
  215. string errorMessage = $"S7采集异常===>> {ex.Message}\nStack Trace: {ex.StackTrace}";
  216. Log.Instance.WriteLogAdd(errorMessage, LOG_TITLE_S7);
  217. return "S7采集失败";
  218. }
  219. }
  220. /// <summary>
  221. /// 获取redis 设备在线列表
  222. /// </summary>
  223. /// <param name="strData"></param>
  224. /// <returns></returns>
  225. private async Task<List<WcsDevice>> getDeviceList()
  226. {
  227. List<WcsDevice> deviceList = new List<WcsDevice>();
  228. var deviceListData = await _redis.GetDatabase().StringGetAsync(wcs_redis_key + RedisKeyEnum.DeviceList);
  229. if (deviceListData.IsNullOrEmpty || deviceListData.Length() == 0)
  230. {
  231. deviceList = _deviceService.GetDeviceList();
  232. await _redis.GetDatabase().StringSetAsync(wcs_redis_key + RedisKeyEnum.DeviceList, JsonConvert.SerializeObject(deviceList));
  233. }
  234. else
  235. {
  236. deviceList = JsonConvert.DeserializeObject<List<WcsDevice>>(deviceListData);
  237. }
  238. return deviceList;
  239. }
  240. public Task<string> Test()
  241. {
  242. Console.WriteLine(DateTime.Now);
  243. return null;
  244. }
  245. /// <summary>
  246. /// 柔性产线,伺服等取和放回调任务
  247. /// </summary>
  248. /// <returns></returns>
  249. public async Task<string> CallbackJob2()
  250. {
  251. List<TaskCallback> taskList = new List<TaskCallback>();
  252. var taskCallbackListData = await _redis.GetDatabase().StringGetAsync(wcs_redis_key + RedisKeyEnum.CallbackTaskList);
  253. if (taskCallbackListData.IsNullOrEmpty)
  254. {
  255. taskList = await taskCallbackService.GetAllList();
  256. }
  257. else
  258. {
  259. taskList = JsonConvert.DeserializeObject<List<TaskCallback>>(taskCallbackListData);
  260. }
  261. //在线设备
  262. List<WcsDevice> deviceList = await getDeviceList();
  263. //taskList = taskList.Where(x => x.OperateType.Equals(ActionTypeEnum.RobotAction.ToString())).ToList();
  264. taskList = taskList.Where(key => deviceList.Any(device => device.Ip == key.IP)).ToList();
  265. //TaskCallback task = taskList.Where(key => deviceList.Any(device => device.Ip == key.IP)).FirstOrDefault() ;
  266. if (taskList == null || taskList.Count == 0)
  267. {
  268. return "无回调任务";
  269. }
  270. string message = "";
  271. try
  272. {
  273. foreach (TaskCallback task in taskList)
  274. {
  275. WcsTagValue tagValueQuery = new WcsTagValue();
  276. tagValueQuery.Ip = task.IP;
  277. tagValueQuery.Address = task.Address;
  278. List<WcsTagValue> tagValues = _wcsTagValueService.GetList(tagValueQuery).ToList();
  279. WcsTagValue callBacktagValue = tagValues.Where(o => o.Address == task.Address).FirstOrDefault();
  280. //if ((callBacktagValue != null && callBacktagValue.TagValue == task.CallbackValue))
  281. if (callBacktagValue != null)
  282. {
  283. CallBackRequestData requestData = new CallBackRequestData();
  284. requestData.taskId = long.Parse(task.TaskId);
  285. requestData.taskNodeId = long.Parse(task.TaskNodeId);
  286. requestData.TagValue = callBacktagValue.TagValue;
  287. var result = await _apiRequestService.RequestAsync(RequsetModeEnum.Post, wcs_callback_url, requestData, null);
  288. ResponseWCSCallbackData responseECSCallback = JsonConvert.DeserializeObject<ResponseWCSCallbackData>(result.Message);
  289. if (result.IsSuccess && responseECSCallback.code == 0)
  290. {
  291. //取 放动作结果 如果完成修改状态,否则
  292. if (callBacktagValue.TagValue == "3")
  293. {
  294. task.State = false;
  295. task.UpdateTime = DateTime.Now;
  296. await taskCallbackService.CreateOrUpdateAndCache(task);
  297. message = task.OperateName + "==>taskId:" + task.TaskId + ",taskNodeId:" + task.TaskNodeId + ",请求结果:" + result.Message + ";";
  298. Log.Instance.WriteLogAdd(message, LOG_TITLE_CALLBACK);
  299. }
  300. else
  301. {
  302. message = task.OperateName + "==>taskId:" + task.TaskId + ",taskNodeId:" + task.TaskNodeId + ",请求结果:" + result.Message + ",返回结果:" + callBacktagValue.TagValue + ";";
  303. Log.Instance.WriteLogAdd(message, LOG_TITLE_CALLBACK);
  304. }
  305. }else{
  306. //ecs返回-5 任务作废
  307. if (result.IsSuccess && responseECSCallback.code == -5)
  308. {
  309. task.State = false;
  310. task.UpdateTime = DateTime.Now;
  311. task.Description = "ecs返回-5,回调任务作废";
  312. await taskCallbackService.CreateOrUpdateAndCache(task);
  313. message = message + JsonConvert.SerializeObject(task) + ",请求失败! WebApi 返回结果" + ";";
  314. Log.Instance.WriteLogAdd("回调异常,请求接口失败,wcs通知任务作废==>" + JsonConvert.SerializeObject(result), LOG_TITLE_CALLBACK);
  315. }
  316. else
  317. {
  318. message = message + JsonConvert.SerializeObject(task) + ",请求失败! WebApi 返回结果" + ";";
  319. Log.Instance.WriteLogAdd("回调异常,请求接口失败" + JsonConvert.SerializeObject(result), LOG_TITLE_CALLBACK);
  320. }
  321. }
  322. }
  323. //回调检测到失败,回调通知ecs
  324. /*if (!string.IsNullOrEmpty(task.FailAddress) || !string.IsNullOrEmpty(task.FailAddress2) || !string.IsNullOrEmpty(task.FailAddress3))
  325. {
  326. bool failFalg = false;
  327. if (!string.IsNullOrEmpty(task.FailAddress))
  328. {
  329. List<WcsTagValue> FailCallbackTagValues = tagValues.Where(o => o.Address == task.FailAddress && o.TagValue == task.CallbackFailValue).ToList();
  330. if (FailCallbackTagValues != null && FailCallbackTagValues.Count > 0)
  331. {
  332. failFalg = true;
  333. }
  334. }
  335. if (!string.IsNullOrEmpty(task.FailAddress2))
  336. {
  337. List<WcsTagValue> FailCallbackTagValues = tagValues.Where(o => o.Address == task.FailAddress2 && o.TagValue == task.CallbackFailValue2).ToList();
  338. if (FailCallbackTagValues != null && FailCallbackTagValues.Count > 0)
  339. {
  340. failFalg = true;
  341. }
  342. }
  343. if (!string.IsNullOrEmpty(task.FailAddress3))
  344. {
  345. List<WcsTagValue> FailCallbackTagValues = tagValues.Where(o => o.Address == task.FailAddress3 && o.TagValue == task.CallbackFailValue3).ToList();
  346. if (FailCallbackTagValues != null && FailCallbackTagValues.Count > 0)
  347. {
  348. failFalg = true;
  349. }
  350. }
  351. if (failFalg)
  352. {
  353. CallBackRequestData requestData = new CallBackRequestData();
  354. requestData.taskId = long.Parse(task.TaskId);
  355. requestData.taskNodeId = long.Parse(task.TaskNodeId);
  356. requestData.code = "0";
  357. requestData.msg = "操作失败";
  358. var result = await _apiRequestService.RequestAsync(RequsetModeEnum.Post, wcs_callback_url, requestData, null);
  359. if (result.IsSuccess)
  360. {
  361. task.State = false;
  362. task.UpdateTime = DateTime.Now;
  363. await taskCallbackService.CreateOrUpdateAndCache(task);
  364. message = task.OperateName + "==>taskId:" + task.TaskId + ",taskNodeId:" + task.TaskNodeId + message + ",请求结果:" + result.Message + ";";
  365. Log.Instance.WriteLogAdd(message, LOG_TITLE_CALLBACK);
  366. }
  367. else
  368. {
  369. message = message + JsonConvert.SerializeObject(task) + ",请求失败! WebApi 返回结果" + ";";
  370. Log.Instance.WriteLogAdd("回调异常,请求接口失败" + JsonConvert.SerializeObject(task), LOG_TITLE_CALLBACK);
  371. }
  372. }
  373. }*/
  374. Thread.Sleep(1000);
  375. }
  376. return string.IsNullOrEmpty(message) ? "无回调任务" : message;
  377. }
  378. catch (Exception ex)
  379. {
  380. Log.Instance.WriteLogAdd("回调异常===>>" + ex.Message, LOG_TITLE_CALLBACK);
  381. return "回调异常" + ex.Message;
  382. }
  383. }
  384. //设置回调值
  385. private TaskCallback setCallBackValue(List<WcsActionAddress> CcsActionAddresses, TaskCallback taskCallbackData,RequestData<LocationData> data)
  386. {
  387. WcsActionAddress actionAddress = CcsActionAddresses.Where(o => o.Type == ActionAddressTypeEnum.CALLBACK.ToString() && o.Sort == data.data.type).FirstOrDefault();
  388. if(actionAddress != null)
  389. {
  390. taskCallbackData.Address = actionAddress.Address;
  391. taskCallbackData.CallbackValue = actionAddress.Value;
  392. }
  393. /*List<WcsActionAddress> CcsActionAddressCallBackFails = CcsActionAddresses.Where(o => o.Type == ActionAddressTypeEnum.CALLBACK_FAIL.ToString()).ToList();
  394. List<WcsActionAddress> CcsActionAddressCallBackResets = CcsActionAddresses.Where(o => o.Type == ActionAddressTypeEnum.RESET.ToString()).ToList();
  395. foreach (WcsActionAddress actionAddress in CcsActionAddressCallBacks)
  396. {
  397. if (actionAddress.Sort == data.data.type)
  398. {
  399. taskCallbackData.Address = actionAddress.Address;
  400. taskCallbackData.CallbackValue = actionAddress.Value;
  401. }
  402. }
  403. foreach (WcsActionAddress actionAddress in CcsActionAddressCallBackFails)
  404. {
  405. if (actionAddress.Sort == 1)
  406. {
  407. taskCallbackData.FailAddress = actionAddress.Address;
  408. taskCallbackData.CallbackFailValue = actionAddress.Value;
  409. }
  410. else if (actionAddress.Sort == 2)
  411. {
  412. taskCallbackData.FailAddress2 = actionAddress.Address;
  413. taskCallbackData.CallbackFailValue2 = actionAddress.Value;
  414. }
  415. else if (actionAddress.Sort == 3)
  416. {
  417. taskCallbackData.FailAddress3 = actionAddress.Address;
  418. taskCallbackData.CallbackFailValue3 = actionAddress.Value;
  419. }
  420. }
  421. foreach (WcsActionAddress actionAddress in CcsActionAddressCallBackResets)
  422. {
  423. if (actionAddress.Sort == 1)
  424. {
  425. taskCallbackData.SuccessResetAddress = actionAddress.Address;
  426. taskCallbackData.SuccessResetValue = actionAddress.Value;
  427. }
  428. else if (actionAddress.Sort == 2)
  429. {
  430. taskCallbackData.SuccessResetAddress2 = actionAddress.Address;
  431. taskCallbackData.SuccessResetValue2 = actionAddress.Value;
  432. }
  433. }
  434. return taskCallbackData;*/
  435. return taskCallbackData;
  436. }
  437. }
  438. }