using WCS.DeviceProtocol; using WCS.Repository; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; using WCS.Common; using WCS.Entitys; using WCS.Model; using WCS.Services; using HslCommunication.Profinet.Siemens; using HslCommunication; using WCS.Utils; using IMCS.CCS.Services; using StackExchange.Redis; using WCS.Models; namespace WCS.Service.Impl { public class TaskService : ITaskService { private readonly IDeviceRepository deviceRepository; private readonly IWcsActionService wcsActionService; private readonly IWcsActionAddressService wcsActionAddressService; private readonly ITaskCallbackService taskCallbackService; private readonly IConnectionMultiplexer _redis; private readonly IDeviceService _deviceService; private readonly IWcsTagValueService _wcsTagValueService; private readonly IApiRequestService _apiRequestService; private string wcs_callback_url; private string wcs_redis_key = "WCS:"; private string LOG_TITLE_S7 = "S7采集"; private string LOG_TITLE_CALLBACK = "回调任务"; public IConfiguration Configuration { get; } public TaskService(IDeviceRepository deviceRepository, IWcsActionService wcsActionService, IWcsTagValueService wcsTagValueService, IWcsActionAddressService wcsActionAddressService, ITaskCallbackService taskCallbackService, IConnectionMultiplexer redisService, IDeviceService deviceService, IApiRequestService _apiRequestService, IConfiguration configuration ) { this.deviceRepository = deviceRepository; this.wcsActionService = wcsActionService; this.wcsActionAddressService = wcsActionAddressService; this.taskCallbackService = taskCallbackService; this._redis = redisService; this._deviceService = deviceService; this._wcsTagValueService = wcsTagValueService; this._apiRequestService = _apiRequestService; wcs_callback_url = Configuration.GetConnectionString("wcsCallbackUrl"); } public async Task ExcuteTask(RequestData data) { ResponseData responseData = new ResponseData(data.taskNodeId); try { List devices = deviceRepository.GetDeviceList(); WcsDevice? wcsDevice = devices.FirstOrDefault(x => x.Ip == data.ip); //WcsDevice device = devices.Where(x => x.Ip == data.url && x.Port == data.port).FirstOrDefault(); if (wcsDevice == null) { Log.Instance.WriteLogAdd("设备已离线===>>" + JsonConvert.SerializeObject(data)); responseData.IsSuccess = false; return responseData; } WcsAction action = new WcsAction(); action.Ip = data.ip; action.OperateType = data.data.operateType.ToString(); WcsAction? actionInfo = wcsActionService.GetList(action).FirstOrDefault(); if (actionInfo == null) { Log.Instance.WriteLogAdd(data.data.operateType.ToString() + "异常===>>" + "找不到对应实例" + JsonConvert.SerializeObject(data), EnumHelper.GetEnumDescription(data.data.operateType)); responseData.IsSuccess = false; return responseData; } WcsDevice? plcDevice = devices.FirstOrDefault(x => x.ProtocolType == "S7_1500"); SiemensS7Net s7 = DevicePlcS7.SiemensS7(plcDevice.Ip); OperateResult ConnectionResult = s7.ConnectServer(); if (!ConnectionResult.IsSuccess) { s7.ConnectClose(); Log.Instance.WriteLogAdd(data.data.operateType.ToString() + "异常===>>" + "PLC连接不上" + JsonConvert.SerializeObject(data), EnumHelper.GetEnumDescription(data.data.operateType)); responseData.IsSuccess = false; return responseData; } WcsActionAddress actionAddressQuery = new WcsActionAddress(); actionAddressQuery.ActionId = actionInfo.Id; /*actionAddressQuery.Type = ActionAddressTypeEnum.WRITE.ToString();*/ /*actionAddressQuery.Sort = data.data.type;*/ List WcsActionAddresses = wcsActionAddressService.GetList(actionAddressQuery); WcsActionAddress? wcsActionAddress = WcsActionAddresses.Where(o=>o.Type== ActionAddressTypeEnum.WRITE.ToString() && o.Sort == data.data.type).FirstOrDefault(); if (WcsActionAddresses != null && data.data.type == 0) { OperateResult operateResult = s7.Write(wcsActionAddress.Address, Convert.ToInt16(data.data.startPosition)); } else if (WcsActionAddresses != null && data.data.type == 1) { s7.Write(wcsActionAddress.Address, Convert.ToInt16(data.data.endPosition)); } s7.ConnectClose(); //插入回调 TaskCallback taskCallbackData = new TaskCallback(data.url, data.data.operateType.ToString(), EnumHelper.GetEnumDescription(data.data.operateType), data.taskId, data.taskNodeId); taskCallbackData = setCallBackValue(WcsActionAddresses, taskCallbackData, data); await taskCallbackService.CreateOrUpdateAndCache(taskCallbackData); Log.Instance.WriteLogAdd(EnumHelper.GetEnumDescription(data.data.operateType) + "成功===>>" + JsonConvert.SerializeObject(data) , EnumHelper.GetEnumDescription(data.data.operateType)); return responseData; } catch (Exception ex) { Log.Instance.WriteLogAdd(data.data.operateType + "异常===>>" + ex.Message + JsonConvert.SerializeObject(data), EnumHelper.GetEnumDescription(data.data.operateType)); responseData.IsSuccess = false; responseData.Msg=ex.Message; return responseData; } } /// /// 采集数据S7 /// /// public async Task DataCollectS7Job() { try { List deviceList = await getDeviceList(); deviceList = deviceList.Where(x => x.ProtocolType.Equals(ProtocalTypeEnum.S7_1500.ToString()) && x.State).ToList(); foreach (WcsDevice device in deviceList) { List tagValues = new List(); string redis_key = "WCS:" + device.Ip + ":" + device.ProtocolType; var data = await _redis.GetDatabase().StringGetAsync(redis_key); if (data.IsNullOrEmpty) { WcsTagValue tagQuery = new WcsTagValue(); tagQuery.ProtocolType = device.ProtocolType; tagQuery.Ip = device.Ip; tagValues = _wcsTagValueService.GetList(tagQuery); //首次设置redis if (tagValues != null && tagValues.Count > 0) { await _redis.GetDatabase().StringSetAsync(redis_key, JsonConvert.SerializeObject(tagValues)); } } else { tagValues = JsonConvert.DeserializeObject>(data); } if (tagValues != null && tagValues.Count > 0) { tagValues = JsonConvert.DeserializeObject>(data); List changTagValues = new List(); //Plc s7 = DevicePlcS7.S7(device.ServerUrl, ProtocalTypeEnum.S7_1500.ToString()); SiemensS7Net s7 = DevicePlcS7.SiemensS7(device.Ip); OperateResult ConnectionResult = s7.ConnectServer(); if (!ConnectionResult.IsSuccess) { device.State = false; await _deviceService.UpdateDevice(device); s7.ConnectClose(); Log.Instance.WriteLogAdd("S7采集异常,plc连不上==>" + device.Ip, LOG_TITLE_S7); return "采集失败,plc连不上"; } else { foreach (WcsTagValue tagValueData in tagValues) { string operateResult = ""; if (tagValueData.Type.Equals(TagValueReadTypeEnum.BOOL.ToString())) { operateResult = s7.ReadBool(tagValueData.Address).Content.ToString(); } else if (tagValueData.Type.Equals(TagValueReadTypeEnum.SHORT.ToString())) { operateResult = s7.ReadInt16(tagValueData.Address).Content.ToString(); } else if (tagValueData.Type.Equals(TagValueReadTypeEnum.String.ToString())) { operateResult = s7.ReadString(tagValueData.Address).Content.ToString(); } else if (tagValueData.Type.Equals(TagValueReadTypeEnum.Array.ToString())) { operateResult = ToolUtils.ReturnStringByBytes(s7.Read(tagValueData.Address, 40).Content); } if (!string.IsNullOrEmpty(operateResult) && tagValueData.TagValue != operateResult) { tagValueData.TagValue = operateResult.ToString(); tagValueData.UpdateTime = DateTime.Now; changTagValues.Add(tagValueData); Log.Instance.WriteLogAdd("S7采集,Ip:" + tagValueData.Ip + " 地址:" + tagValueData.Address + ",值:" + tagValueData.TagValue + ",发生变化", LOG_TITLE_S7); //有变化更新数据库 await _wcsTagValueService.Update(tagValueData); } Thread.Sleep(50); } s7.ConnectClose(); //值有变化,重新设置一次redis if (changTagValues != null && changTagValues.Count > 0) { await _redis.GetDatabase().StringSetAsync(redis_key, JsonConvert.SerializeObject(tagValues)); } //存储采集数据 CollectDataLog.Instance.WriteLogAdd(data, LOG_TITLE_S7); } } } return "S7采集成功"; } catch (Exception ex) { string errorMessage = $"S7采集异常===>> {ex.Message}\nStack Trace: {ex.StackTrace}"; Log.Instance.WriteLogAdd(errorMessage, LOG_TITLE_S7); return "S7采集失败"; } } /// /// 获取redis 设备在线列表 /// /// /// private async Task> getDeviceList() { List deviceList = new List(); var deviceListData = await _redis.GetDatabase().StringGetAsync(wcs_redis_key + RedisKeyEnum.DeviceList); if (deviceListData.IsNullOrEmpty || deviceListData.Length() == 0) { deviceList = _deviceService.GetDeviceList(); await _redis.GetDatabase().StringSetAsync(wcs_redis_key + RedisKeyEnum.DeviceList, JsonConvert.SerializeObject(deviceList)); } else { deviceList = JsonConvert.DeserializeObject>(deviceListData); } return deviceList; } public Task Test() { Console.WriteLine(DateTime.Now); return null; } /// /// 柔性产线,伺服等取和放回调任务 /// /// public async Task CallbackJob2() { List taskList = new List(); var taskCallbackListData = await _redis.GetDatabase().StringGetAsync(wcs_redis_key + RedisKeyEnum.CallbackTaskList); if (taskCallbackListData.IsNullOrEmpty) { taskList = await taskCallbackService.GetAllList(); } else { taskList = JsonConvert.DeserializeObject>(taskCallbackListData); } //在线设备 List deviceList = await getDeviceList(); //taskList = taskList.Where(x => x.OperateType.Equals(ActionTypeEnum.RobotAction.ToString())).ToList(); taskList = taskList.Where(key => deviceList.Any(device => device.Ip == key.IP)).ToList(); //TaskCallback task = taskList.Where(key => deviceList.Any(device => device.Ip == key.IP)).FirstOrDefault() ; if (taskList == null || taskList.Count == 0) { return "无回调任务"; } string message = ""; try { foreach (TaskCallback task in taskList) { WcsTagValue tagValueQuery = new WcsTagValue(); tagValueQuery.Ip = task.IP; tagValueQuery.Address = task.Address; List tagValues = _wcsTagValueService.GetList(tagValueQuery).ToList(); WcsTagValue callBacktagValue = tagValues.Where(o => o.Address == task.Address).FirstOrDefault(); //if ((callBacktagValue != null && callBacktagValue.TagValue == task.CallbackValue)) if (callBacktagValue != null) { CallBackRequestData requestData = new CallBackRequestData(); requestData.taskId = long.Parse(task.TaskId); requestData.taskNodeId = long.Parse(task.TaskNodeId); requestData.TagValue = callBacktagValue.TagValue; var result = await _apiRequestService.RequestAsync(RequsetModeEnum.Post, wcs_callback_url, requestData, null); ResponseWCSCallbackData responseECSCallback = JsonConvert.DeserializeObject(result.Message); if (result.IsSuccess && responseECSCallback.code == 0) { //取 放动作结果 如果完成修改状态,否则 if (callBacktagValue.TagValue == "3") { task.State = false; task.UpdateTime = DateTime.Now; await taskCallbackService.CreateOrUpdateAndCache(task); message = task.OperateName + "==>taskId:" + task.TaskId + ",taskNodeId:" + task.TaskNodeId + ",请求结果:" + result.Message + ";"; Log.Instance.WriteLogAdd(message, LOG_TITLE_CALLBACK); } else { message = task.OperateName + "==>taskId:" + task.TaskId + ",taskNodeId:" + task.TaskNodeId + ",请求结果:" + result.Message + ",返回结果:" + callBacktagValue.TagValue + ";"; Log.Instance.WriteLogAdd(message, LOG_TITLE_CALLBACK); } }else{ //ecs返回-5 任务作废 if (result.IsSuccess && responseECSCallback.code == -5) { task.State = false; task.UpdateTime = DateTime.Now; task.Description = "ecs返回-5,回调任务作废"; await taskCallbackService.CreateOrUpdateAndCache(task); message = message + JsonConvert.SerializeObject(task) + ",请求失败! WebApi 返回结果" + ";"; Log.Instance.WriteLogAdd("回调异常,请求接口失败,wcs通知任务作废==>" + JsonConvert.SerializeObject(result), LOG_TITLE_CALLBACK); } else { message = message + JsonConvert.SerializeObject(task) + ",请求失败! WebApi 返回结果" + ";"; Log.Instance.WriteLogAdd("回调异常,请求接口失败" + JsonConvert.SerializeObject(result), LOG_TITLE_CALLBACK); } } } //回调检测到失败,回调通知ecs /*if (!string.IsNullOrEmpty(task.FailAddress) || !string.IsNullOrEmpty(task.FailAddress2) || !string.IsNullOrEmpty(task.FailAddress3)) { bool failFalg = false; if (!string.IsNullOrEmpty(task.FailAddress)) { List FailCallbackTagValues = tagValues.Where(o => o.Address == task.FailAddress && o.TagValue == task.CallbackFailValue).ToList(); if (FailCallbackTagValues != null && FailCallbackTagValues.Count > 0) { failFalg = true; } } if (!string.IsNullOrEmpty(task.FailAddress2)) { List FailCallbackTagValues = tagValues.Where(o => o.Address == task.FailAddress2 && o.TagValue == task.CallbackFailValue2).ToList(); if (FailCallbackTagValues != null && FailCallbackTagValues.Count > 0) { failFalg = true; } } if (!string.IsNullOrEmpty(task.FailAddress3)) { List FailCallbackTagValues = tagValues.Where(o => o.Address == task.FailAddress3 && o.TagValue == task.CallbackFailValue3).ToList(); if (FailCallbackTagValues != null && FailCallbackTagValues.Count > 0) { failFalg = true; } } if (failFalg) { CallBackRequestData requestData = new CallBackRequestData(); requestData.taskId = long.Parse(task.TaskId); requestData.taskNodeId = long.Parse(task.TaskNodeId); requestData.code = "0"; requestData.msg = "操作失败"; var result = await _apiRequestService.RequestAsync(RequsetModeEnum.Post, wcs_callback_url, requestData, null); if (result.IsSuccess) { task.State = false; task.UpdateTime = DateTime.Now; await taskCallbackService.CreateOrUpdateAndCache(task); message = task.OperateName + "==>taskId:" + task.TaskId + ",taskNodeId:" + task.TaskNodeId + message + ",请求结果:" + result.Message + ";"; Log.Instance.WriteLogAdd(message, LOG_TITLE_CALLBACK); } else { message = message + JsonConvert.SerializeObject(task) + ",请求失败! WebApi 返回结果" + ";"; Log.Instance.WriteLogAdd("回调异常,请求接口失败" + JsonConvert.SerializeObject(task), LOG_TITLE_CALLBACK); } } }*/ Thread.Sleep(1000); } return string.IsNullOrEmpty(message) ? "无回调任务" : message; } catch (Exception ex) { Log.Instance.WriteLogAdd("回调异常===>>" + ex.Message, LOG_TITLE_CALLBACK); return "回调异常" + ex.Message; } } //设置回调值 private TaskCallback setCallBackValue(List CcsActionAddresses, TaskCallback taskCallbackData,RequestData data) { WcsActionAddress actionAddress = CcsActionAddresses.Where(o => o.Type == ActionAddressTypeEnum.CALLBACK.ToString() && o.Sort == data.data.type).FirstOrDefault(); if(actionAddress != null) { taskCallbackData.Address = actionAddress.Address; taskCallbackData.CallbackValue = actionAddress.Value; } /*List CcsActionAddressCallBackFails = CcsActionAddresses.Where(o => o.Type == ActionAddressTypeEnum.CALLBACK_FAIL.ToString()).ToList(); List CcsActionAddressCallBackResets = CcsActionAddresses.Where(o => o.Type == ActionAddressTypeEnum.RESET.ToString()).ToList(); foreach (WcsActionAddress actionAddress in CcsActionAddressCallBacks) { if (actionAddress.Sort == data.data.type) { taskCallbackData.Address = actionAddress.Address; taskCallbackData.CallbackValue = actionAddress.Value; } } foreach (WcsActionAddress actionAddress in CcsActionAddressCallBackFails) { if (actionAddress.Sort == 1) { taskCallbackData.FailAddress = actionAddress.Address; taskCallbackData.CallbackFailValue = actionAddress.Value; } else if (actionAddress.Sort == 2) { taskCallbackData.FailAddress2 = actionAddress.Address; taskCallbackData.CallbackFailValue2 = actionAddress.Value; } else if (actionAddress.Sort == 3) { taskCallbackData.FailAddress3 = actionAddress.Address; taskCallbackData.CallbackFailValue3 = actionAddress.Value; } } foreach (WcsActionAddress actionAddress in CcsActionAddressCallBackResets) { if (actionAddress.Sort == 1) { taskCallbackData.SuccessResetAddress = actionAddress.Address; taskCallbackData.SuccessResetValue = actionAddress.Value; } else if (actionAddress.Sort == 2) { taskCallbackData.SuccessResetAddress2 = actionAddress.Address; taskCallbackData.SuccessResetValue2 = actionAddress.Value; } } return taskCallbackData;*/ return taskCallbackData; } } }