using WIDESEAWCS_Common.AGVEnum; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_ITaskInfoRepository; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob; namespace WIDESEAWCS_Tasks.AGVJob { public class UpdateTaskAGV { private static int _readUpdateAGVTaskSignalso = 0; public void UpdateTask2(AGV plcClient, ITaskRepository _taskRepository) { //TODO: Update the task status and result in the database if (Interlocked.Exchange(ref _readUpdateAGVTaskSignalso, 1) == 0) { try { if (plcClient == null) { return; } //读取任务状态 var taskFbInteractiveR = plcClient.DeviceProDTOs.Where(r => r.DeviceProParamName == TaskDBName.taskFbInteractiveR.ToString()).FirstOrDefault().DeviceProAddress; var taskFbInteractive2 = plcClient.DeviceProDTOs.Where(r => r.DeviceProParamName == TaskDBName.taskFbInteractiveW.ToString()).FirstOrDefault().DeviceProAddress; var resetTaskFbInteractiveR = plcClient.DeviceProDTOs.Where(r => r.DeviceProParamName == TaskDBName.resetTaskFbInteractiveR.ToString()).FirstOrDefault().DeviceProAddress; var taskIDFb = plcClient.DeviceProDTOs.Where(r => r.DeviceProParamName == TaskDBName.taskIDFb.ToString()).FirstOrDefault().DeviceProAddress; var taskStatusFb = plcClient.DeviceProDTOs.Where(r => r.DeviceProParamName == TaskDBName.taskStatusFb.ToString()).FirstOrDefault().DeviceProAddress; int taskFbInteractive = plcClient.Communicator.Read(taskFbInteractiveR); int taskFbInteractiveW = plcClient.Communicator.Read(taskFbInteractive2); int resetTaskFbInteractiver = plcClient.Communicator.Read(resetTaskFbInteractiveR); //0初始状态 1 RCS更新了一条任务状态 if (resetTaskFbInteractiver == 1) { plcClient.Communicator.Write(taskFbInteractive2, 0); for (int i = 0; i < 5; i++) { Thread.Sleep(300); var agvnumber = plcClient.Communicator.Read(taskFbInteractive2); if (agvnumber != 0) { plcClient.Communicator.Write(taskFbInteractive2, 0); } else { break; } } } if (1 == taskFbInteractive && taskFbInteractiveW == 0) { string taskId = plcClient.Communicator.Read(taskIDFb).ToString();//任务ID if (taskId.Contains("\b")) { taskId = taskId.Remove(0, 1); } int taskState = plcClient.Communicator.Read(taskStatusFb);//1起点执行中,2起点已完成,3终点执行中,4终点已完成 if (0 == taskState)//无含义 return; //WriteLog.Info("AGV更新任务状态").Write("任务号" + taskId + "任务状态" + taskState, "AGV更新任务状态"); Dt_Task agvTask = _taskRepository.QueryFirst(r => r.TaskNum.ToString() == taskId); if (1 == taskState)//任务起点执行中 { if (null == agvTask) { plcClient.Communicator.Write(taskFbInteractive2, 1); //WriteLog.Info("AGV更新任务状态").Write("WCS写入AGV任务号,当前任务号不存在任务列表里," + taskId + DateTime.Now + "任务起点执行中状态确认1", "AGV更新任务状态"); } if (agvTask.TaskState == (int)TaskInStatusEnum.Line_InExecuting) { plcClient.Communicator.Write(taskFbInteractive2, 1); //WriteLog.Info("AGV更新任务状态").Write("WCS再次写入AGV任务号" + taskId + DateTime.Now + "任务起点执行中状态确认1", "AGV更新任务状态"); } int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus(); agvTask.TaskState = nextStatus; _taskRepository.UpdateData(agvTask); plcClient.Communicator.Write(taskFbInteractive2, 1); for (int i = 0; i < 5; i++) { Thread.Sleep(300); var agvnumber = plcClient.Communicator.Read(taskFbInteractive2); if (agvnumber != 1) { plcClient.Communicator.Write(taskFbInteractive2, 1); } else { break; } } //WriteLog.Info("AGV更新任务状态").Write("WCS写入AGV任务号" + taskId + "任务起点执行中状态确认1", "AGV更新任务状态"); } else if (2 == taskState)//任务起点已完成 { if (null == agvTask) { plcClient.Communicator.Write(taskFbInteractive2, 1); //WriteLog.Info("AGV更新任务状态").Write("WCS写入AGV任务号,当前任务号不存在任务列表里," + taskId + DateTime.Now + "任务起点完成状态确认1", "AGV更新任务状态"); return; } if (agvTask.TaskState == (int)TaskInStatusEnum.Line_InFinish) { plcClient.Communicator.Write(taskFbInteractive2, 1); //WriteLog.Info("AGV更新任务状态").Write("WCS再次写入AGV任务号" + taskId + DateTime.Now + "任务起点完成状态确认1", "AGV更新任务状态"); } else if (agvTask.TaskState == (int)TaskInStatusEnum.Line_InExecuting) { plcClient.Communicator.Write(taskFbInteractive2, 1); //WriteLog.Info("AGV更新任务状态").Write("WCS写入AGV任务号,当前任务号的任务状态不是起点执行中," + taskId + DateTime.Now + "任务起点完成状态确认1", "AGV更新任务状态"); } int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus(); agvTask.TaskState = nextStatus; _taskRepository.UpdateData(agvTask); plcClient.Communicator.Write(taskFbInteractive2, 1); for (int i = 0; i < 5; i++) { Thread.Sleep(300); var agvnumber = plcClient.Communicator.Read(taskFbInteractive2); if (agvnumber != 1) { plcClient.Communicator.Write(taskFbInteractive2, 1); } else { break; } } //WriteLog.Info("AGV更新任务状态").Write("WCS写入AGV任务号" + taskId + DateTime.Now + "任务起点完成状态确认1", "AGV更新任务状态"); } else if (3 == taskState)//任务终点执行中 { if (null == agvTask) { plcClient.Communicator.Write(taskFbInteractive2, 1); //WriteLog.Info("AGV更新任务状态").Write("WCS写入AGV任务号,当前任务号不存在任务列表里," + taskId + DateTime.Now + "任务终点执行中状态确认1", "AGV更新任务状态"); } if (agvTask.TaskState == (int)TaskInStatusEnum.SC_InExecuting) { plcClient.Communicator.Write(taskFbInteractive2, 1); //WriteLog.Info("AGV更新任务状态").Write("WCS再次写入AGV任务号" + taskId + DateTime.Now + "任务终点执行中状态确认1", "AGV更新任务状态"); } int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus(); agvTask.TaskState = nextStatus; _taskRepository.UpdateData(agvTask); plcClient.Communicator.Write(taskFbInteractive2, 1); for (int i = 0; i < 5; i++) { Thread.Sleep(300); var agvnumber = plcClient.Communicator.Read(taskFbInteractive2); if (agvnumber != 1) { plcClient.Communicator.Write(taskFbInteractive2, 1); } else { break; } } //WriteLog.Info("AGV更新任务状态").Write("WCS写入AGV任务号" + taskId + DateTime.Now + "任务终点执行中状态确认1", "AGV更新任务状态"); } else if (4 == taskState)//任务终点完成 { if (null == agvTask) { plcClient.Communicator.Write(taskFbInteractive2, 1); //WriteLog.Info("AGV更新任务状态").Write("WCS写入AGV任务号,当前任务号不存在任务列表里," + taskId + DateTime.Now + "任务终点完成状态确认1", "AGV更新任务状态"); return; } else if (agvTask.TaskState != (int)TaskInStatusEnum.SC_InExecuting) { plcClient.Communicator.Write(taskFbInteractive2, 1); //throw new Exception("任务状态更改为4终点已完成失败,任务ID:" + agvTask.agv_tasknum + DateTime.Now + ",任务状态不是终点执行中!"); } //agvtask_HtyRepository.AddTaskHistory(agvTask, OperateType.Finished.ToString()); _taskRepository.DeleteData(agvTask); plcClient.Communicator.Write(taskFbInteractive2, 1); for (int i = 0; i < 5; i++) { Thread.Sleep(300); var agvnumber = plcClient.Communicator.Read(taskFbInteractive2); if (agvnumber != 1) { plcClient.Communicator.Write(taskFbInteractive2, 1); } else { break; } } //WriteLog.Info("AGV更新任务状态").Write("WCS写入AGV任务号" + taskId + DateTime.Now + "任务终点完成状态确认1", "AGV更新任务状态"); } else if (5 == taskState) { plcClient.Communicator.Write(taskFbInteractive2, 1); } } //if (taskFbInteractive == 1 && taskFbInteractiveW == 1)//反馈没收到重新反馈 // plcClient.Communicator.Write(taskFbInteractive2, 0); if (taskFbInteractive == 0 && taskFbInteractiveW == 1) { plcClient.Communicator.Write(taskFbInteractive2, 0); for (int i = 0; i < 5; i++) { Thread.Sleep(300); var agvnumber = Convert.ToInt32(plcClient.Communicator.Read(taskFbInteractive2)); if (agvnumber != 0) { plcClient.Communicator.Write(taskFbInteractive2, 0); } else { break; } } } } catch (Exception ex) { //WriteLog.Info("AGV更新任务状态").Write("WCS接收AGV任务反馈异常" + ex.Message.ToString() + DateTime.Now, "AGV更新任务状态"); } finally { Interlocked.Exchange(ref _readUpdateAGVTaskSignalso, 0); } } } public static void UpdateTask(AGV plcClient, ITaskRepository taskRepository) { // 使用Interlocked.Exchange保证同一时间只有一个线程可以执行任务更新 if (Interlocked.Exchange(ref _readUpdateAGVTaskSignalso, 1) == 0) { try { if (plcClient == null) { return; } // 从AGV设备中获取各个任务状态的地址 var taskFbInteractiveR = plcClient.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.taskFbInteractiveR.ToString())?.DeviceProAddress; var taskFbInteractive2 = plcClient.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.taskFbInteractiveW.ToString())?.DeviceProAddress; var resetTaskFbInteractiveR = plcClient.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.resetTaskFbInteractiveR.ToString())?.DeviceProAddress; var taskIDFb = plcClient.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.taskIDFb.ToString())?.DeviceProAddress; var taskStatusFb = plcClient.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.taskStatusFb.ToString())?.DeviceProAddress; // 检查是否找到有效的地址,如果没有找到则直接返回 if (taskFbInteractiveR == null || taskFbInteractive2 == null || resetTaskFbInteractiveR == null || taskIDFb == null || taskStatusFb == null) { return; } // 读取任务状态 int taskFbInteractive = plcClient.Communicator.Read(taskFbInteractiveR); int taskFbInteractiveW = plcClient.Communicator.Read(taskFbInteractive2); int resetTaskFbInteractiveRValue = plcClient.Communicator.Read(resetTaskFbInteractiveR); // 如果resetTaskFbInteractiveR为1,则重置taskFbInteractiveW为0,并等待其变为0 if (resetTaskFbInteractiveRValue == 1) { plcClient.Communicator.Write(taskFbInteractive2, 0); // 避免使用Thread.Sleep来等待状态变化,使用更高效的等待机制 for (int i = 0; i < 5; i++) { Task.Delay(300).Wait(); // 使用Task.Delay替代Thread.Sleep,避免阻塞线程池中的线程 int agvNumber = plcClient.Communicator.Read(taskFbInteractive2); if (agvNumber != 0) { plcClient.Communicator.Write(taskFbInteractive2, 0); } else { break; } } } // 只有当taskFbInteractive为1且taskFbInteractiveW为0时才处理任务状态 if (taskFbInteractive == 1 && taskFbInteractiveW == 0) { string taskId = plcClient.Communicator.Read(taskIDFb).ToString(); // 任务ID int taskState = plcClient.Communicator.Read(taskStatusFb); // 任务状态 // 如果任务状态无效,则直接返回 if (taskState == 0) { return; } // 根据任务ID查询数据库中的任务 var agvTask = taskRepository.QueryFirst(r => r.TaskNum.ToString() == taskId); if (agvTask == null) { plcClient.Communicator.Write(taskFbInteractive2, 1); return; // 如果任务不存在,直接返回,不需要再次写入 } // 根据任务状态更新任务状态 if (taskState == 1) // 任务起点执行中 { UpdateTaskStatus(plcClient, agvTask, TaskInStatusEnum.Line_InExecuting, taskRepository, taskFbInteractive2); } else if (taskState == 2) // 任务起点已完成 { UpdateTaskStatus(plcClient, agvTask, TaskInStatusEnum.Line_InFinish, taskRepository, taskFbInteractive2); } else if (taskState == 3) // 任务终点执行中 { UpdateTaskStatus(plcClient, agvTask, TaskInStatusEnum.SC_InExecuting, taskRepository, taskFbInteractive2); } else if (taskState == 4) // 任务终点完成 { if (agvTask.TaskState != (int)TaskInStatusEnum.SC_InExecuting) { // 如果任务状态不是终点执行中,抛出异常 throw new Exception($"任务状态更改为4终点已完成失败,任务ID:{taskId},当前状态:{agvTask.TaskState}"); } // 删除已完成的任务 taskRepository.DeleteData(agvTask); plcClient.Communicator.Write(taskFbInteractive2, 1); EnsureTaskFeedback(taskFbInteractive2, plcClient); } else if (taskState == 5) { plcClient.Communicator.Write(taskFbInteractive2, 1); } } // 如果taskFbInteractive为0且taskFbInteractiveW为1,则重置taskFbInteractiveW为0 if (taskFbInteractive == 0 && taskFbInteractiveW == 1) { plcClient.Communicator.Write(taskFbInteractive2, 0); EnsureTaskFeedback(taskFbInteractive2, plcClient); } } catch (Exception ex) { // 记录异常信息 Console.WriteLine($"WCS接收AGV任务反馈异常 {ex.Message}"); } finally { Interlocked.Exchange(ref _readUpdateAGVTaskSignalso, 0); } } } // 更新任务状态并写入AGV反馈地址 private static void UpdateTaskStatus(AGV plcClient, Dt_Task agvTask, TaskInStatusEnum targetStatus, ITaskRepository taskRepository, string taskFbInteractive2) { if (agvTask.TaskState != (int)targetStatus) { plcClient.Communicator.Write(taskFbInteractive2, 1); // 状态不匹配,写入反馈 } // 更新任务状态为下一个未完成状态 agvTask.TaskState = agvTask.TaskState.GetNextNotCompletedStatus(); taskRepository.UpdateData(agvTask); plcClient.Communicator.Write(taskFbInteractive2, 1); EnsureTaskFeedback(taskFbInteractive2, plcClient); } // 确保任务反馈地址的状态为1 private static void EnsureTaskFeedback(string taskFbInteractive2, AGV plcClient) { for (int i = 0; i < 5; i++) { Task.Delay(300).Wait(); int agvNumber = plcClient.Communicator.Read(taskFbInteractive2); if (agvNumber != 1) { plcClient.Communicator.Write(taskFbInteractive2, 1); } else { break; } } } } }