using System.Diagnostics; using System.Text; using Microsoft.Data.SqlClient; using Newtonsoft.Json; using WIDESEA_Core.Enums; using WIDESEAWCS_Common.AGVEnum; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_Core; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_Core.Tool; using WIDESEAWCS_DTO.TaskInfo; using WIDESEAWCS_ISystemRepository; using WIDESEAWCS_ITaskInfoRepository; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob; namespace WIDESEAWCS_Tasks { public class SendTaskAGV { private static int _readSendAGVTaskSignalso = 0; private static bool isTrue1 = false; private static string name1 = ""; public static string url = AppSettings.Configuration["AGVTaskGeneration"]; public static void SendAGVTask1(ITaskRepository _taskRepository, IDt_StationinfoRepository _stationinfoRepository) { WebResponseContent content = new WebResponseContent(); try { Dt_Task task = _taskRepository.QueryData(x => x.TaskState == (int)TaskInStatusEnum.InNew).OrderBy(r => r.CreateDate).FirstOrDefault(); //.ThenByDescending(r => r.Grade) if (task != null) { TaskGenerationDto taskGenerationDto = new TaskGenerationDto(); { taskGenerationDto.taskid = task.TaskNum.ToString(); taskGenerationDto.taskType = task.TaskType.ToString(); taskGenerationDto.floor = task.Floor.ToString(); taskGenerationDto.param1 = task.SourceAddress.ToString(); taskGenerationDto.param2 = task.TargetAddress.ToString(); taskGenerationDto.param3 = ""; taskGenerationDto.param4 = ""; taskGenerationDto.param5 = ""; taskGenerationDto.param6 = ""; taskGenerationDto.param7 = ""; taskGenerationDto.param8 = ""; taskGenerationDto.param9 = ""; } var ResultData = HttpHelper.Post(url, taskGenerationDto.ToJson(), headers: new Dictionary()); var res = JsonConvert.DeserializeObject(ResultData); if (res.code == 200) { WriteLog.Info("任务下发成功").Write($"任务号{task.TaskNum}", "任务下发成功"); int nextStatus = task.TaskState.GetNextNotCompletedStatus(); task.TaskState = nextStatus; task.Dispatchertime = DateTime.Now; _taskRepository.UpdateData(task); } else { WriteLog.Info("任务下发失败").Write($"任务号{task.TaskNum},信息{res.Message}", "任务下发失败"); //_unitOfWorkManage.RollbackTran(); content = WebResponseContent.Instance.Error($"{res.Message}"); } } Thread.Sleep(100); Dt_Task dt_Task = _taskRepository.QueryData(x => x.TaskState == (int)TaskInStatusEnum.AGV_Queue).OrderBy(r => r.CreateDate).FirstOrDefault(); if (dt_Task != null) { var station = _stationinfoRepository.QueryFirst(x => x.StationCode == dt_Task.SourceAddress); // 查找两个可用的空缓存架 var freeStations = _stationinfoRepository .QueryData(x => x.Location_state == LocationStatusEnum.Free.ObjToInt() && x.Enable && x.Remark == station.Remark && x.Area == station.Area)// && x.Stationtype == station.Stationtype .Take(2) // 只取前两个 .ToList(); int floor = 0; if (station.Area.Contains("A区")) { floor = 32; } else { floor = 128; } if (freeStations.Count < 2) { throw new Exception("未找到两个可用的空缓存架"); } // 检查这两个缓存架是否被任务占用 var stationCodes = freeStations.Select(s => s.StationCode).ToList(); freeStations[0].Location_state = LocationStatusEnum.Lock.ObjToInt(); _stationinfoRepository.UpdateData(freeStations[0]); freeStations[1].Location_state = LocationStatusEnum.Lock.ObjToInt(); _stationinfoRepository.UpdateData(freeStations[1]); //stationCodes. var tasks = _taskRepository.QueryData(x => stationCodes.Contains(x.SourceAddress) || stationCodes.Contains(x.TargetAddress)).ToList(); if (tasks.Any()) { throw new Exception("缓存架已有任务"); } dt_Task.TargetAddress = string.Join("||", freeStations.Select(s => s.StationCode)); dt_Task.NextAddress = string.Join("||", freeStations.Select(s => s.StationCode)); dt_Task.TaskState = (int)TaskInStatusEnum.InNew; dt_Task.TaskType = floor; _taskRepository.UpdateData(dt_Task); } } catch (Exception ex) { } } public static void SendAGVTask(AGV agv, ITaskRepository _taskRepository) { // 连接字符串 - 根据你的服务器信息修改 string connectionString = "Data Source=.;Initial Catalog=WIDESEAWCS_GanFengLiYeNew;User ID=sa;Password=sa123456;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"; List dt_Tasks = _taskRepository.QueryData(x => x.TaskState == (int)TaskInStatusEnum.InNew); foreach (Dt_Task task in dt_Tasks) { // 要插入的SQL语句 string insertSql = "INSERT INTO Dt_Stationinfo (StationCode, Location_state,Area,Enable,LastUpdateTime,Remark) VALUES (@StationCode, @Location_state,@Area,@Enable,@LastUpdateTime,@Remark)"; try { using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); using (SqlCommand command = new SqlCommand(insertSql, connection)) { // 添加参数防止SQL注入 command.Parameters.AddWithValue("StationCode", task.TaskNum); command.Parameters.AddWithValue("Location_state", task.TaskNum); command.Parameters.AddWithValue("Area", task.Roadway); command.Parameters.AddWithValue("Enable", task.TaskNum); command.Parameters.AddWithValue("LastUpdateTime", DateTime.Now); command.Parameters.AddWithValue("Remark", task.Roadway); command.Parameters.AddWithValue("Creater", "WCS"); command.Parameters.AddWithValue("CreateDate", DateTime.Now); int rowsAffected = command.ExecuteNonQuery(); Console.WriteLine($"成功插入 {rowsAffected} 行数据"); } } } catch (Exception ex) { Console.WriteLine($"发生错误: {ex.Message}"); } } // 检查AGV是否为空 if (agv == null) { return; } // 获取任务交互和重置交互的设备地址 var taskInteractiveR = agv.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.taskInteractiveR.ToString())?.DeviceProAddress; var taskInteractiveW1 = agv.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.taskInteractiveW.ToString())?.DeviceProAddress; var resetTaskW = agv.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.resetTaskInteractiveW.ToString())?.DeviceProAddress; var resetTaskInteractiveR = agv.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.resetTaskInteractiveR.ToString())?.DeviceProAddress; var taskID = agv.DeviceProDTOs.FirstOrDefault(r => r.DeviceProParamName == TaskDBName.taskID.ToString())?.DeviceProAddress; // 如果地址未找到,直接返回 if (taskInteractiveR is null || taskInteractiveW1 is null || resetTaskW is null || resetTaskInteractiveR is null || taskID is null) { return; } try { // 读取任务交互和重置交互的状态 int taskInteractive = agv.Communicator.Read(taskInteractiveR); // 1表示收到 int taskInteractiveW = agv.Communicator.Read(taskInteractiveW1); // 0初始/1下发/2取消/3更改 int resetTaskInteractiveW = agv.Communicator.Read(resetTaskW); int resetTaskInteractiver = agv.Communicator.Read(resetTaskInteractiveR); // 处理任务交互W和重置交互W不为0的情况 if (isTrue1 && name1 == agv.DeviceName) { if (taskInteractiveW != 0 || resetTaskInteractiveW != 0 || taskInteractive != 0) { agv.Communicator.Write(resetTaskW, 1); Task.Delay(2000).Wait(); resetTaskInteractiveW = agv.Communicator.Read(resetTaskW); if (resetTaskInteractiveW == 1) { agv.Communicator.Write(resetTaskW, 0); agv.Communicator.Write(taskInteractiveW1, 0); Task.Delay(2000).Wait(); } return; } isTrue1 = false; name1 = ""; } // 如果重置交互R为1,则重置任务交互W if (resetTaskInteractiver == 1) { agv.Communicator.Write(taskInteractiveW1, 0); for (int i = 0; i < 5; i++) { Task.Delay(300).Wait(); // 用Task.Delay代替Thread.Sleep,以避免线程阻塞 int agvNumber = agv.Communicator.Read(taskInteractiveW1); if (agvNumber != 0) { agv.Communicator.Write(taskInteractiveW1, 0); } else { break; } } } // 如果AGV没有任务且任务交互W为0 if (taskInteractive == 0 && taskInteractiveW == 0) { // 查询新任务 Dt_Task agvTask = _taskRepository.QueryData(r => r.TaskState == (int)TaskInStatusEnum.InNew && r.Roadway == agv.DeviceName && r.TaskType == (int)TaskOutboundTypeEnum.Outbound) .OrderBy(r => r.CreateDate).ThenByDescending(r => r.Grade).FirstOrDefault(); if (agvTask != null) { // 写入任务信息 string rel = TaskWrite(agv, agvTask, AGVJobEnum.newTaskEnum); Task.Delay(1000).Wait(); // 检查任务ID是否写入正确 string taskId = agv.Communicator.Read(taskID); string numberPart = taskId.Split('-')[1]; if (numberPart != agvTask.TaskNum.ToString()) { throw new Exception($"给AGV写入任务失败,任务号{agvTask.TaskNum}"); } // 如果任务信息写入成功 if (string.IsNullOrEmpty(rel)) { // 写入任务确认信号1 agv.Communicator.Write(taskInteractiveW1, 1); Task.Delay(1000).Wait(); // 读取AGV的确认信号 int readTask1Ok = agv.Communicator.Read(taskInteractiveR); if (readTask1Ok == 1) { // 写入WCS的确认信号0 agv.Communicator.Write(taskInteractiveW1, 0); Task.Delay(2000).Wait(); // 再次读取AGV的确认信号 int readTask0Ok = agv.Communicator.Read(taskInteractiveR); if (readTask0Ok == 0) { // 更新任务状态并保存 int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus(); agvTask.TaskState = nextStatus; agvTask.Dispatchertime = DateTime.Now; _taskRepository.UpdateData(agvTask); // 上传AGV运行数据(注释掉的代码) // SendMESTask.SendMesTask(agvTask, 0); } else { throw new Exception($"给AGV写入任务确认0失败,任务号{agvTask.TaskNum}"); } } else if (readTask1Ok == 11) { // 处理任务异常情况 agv.Communicator.Write(taskInteractiveW1, 0); Task.Delay(2000).Wait(); int readTask0Error = agv.Communicator.Read(taskInteractiveR); if (readTask0Error == 0) { // 更新任务状态为异常并保存 int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus(); agvTask.TaskState = nextStatus; agvTask.Dispatchertime = DateTime.Now; _taskRepository.UpdateData(agvTask); } else { throw new Exception($"给AGV写入任务异常确认0失败,任务号{agvTask.TaskNum}"); } } else { throw new Exception($"给AGV写入任务确认1失败,任务号{agvTask.TaskNum}"); } } else { throw new Exception($"给AGV写入任务失败,任务号{agvTask.TaskNum} {rel}"); } } } } catch (Exception ex) { // 记录异常信息(注释掉的代码) // StackTrace sta = new StackTrace(ex, true); // StackFrame sf = sta.GetFrame(0); // WriteLog.Info("SendAGVTask").Write(ex.Message + " 行号 " + sf.GetFileLineNumber(), "SendAGVTask"); } finally { // 记录日志(注释掉的代码) // WriteLog.Info("SendAGVTask").Write(agv.PLCName + "\t" + DateTime.Now, "SendAGVTask"); // 重置信号量 Interlocked.Exchange(ref _readSendAGVTaskSignalso, 0); } } public static string TaskWrite(AGV client, Dt_Task agvTask, AGVJobEnum jobEnum) { List sendData = new List(); string tmp = "KH-" + agvTask.TaskNum.ToString(); List taskID = Encoding.Default.GetBytes(tmp).ToList();//任务ID taskID.Insert(0, 30); taskID.Insert(1, Convert.ToByte(tmp.Length)); for (int i = 0; i < 30 - tmp.Length; i++) { taskID.Add(0); } sendData.AddRange(taskID); List taskStart = Encoding.Default.GetBytes(agvTask.SourceAddress).ToList(); taskStart.Insert(0, 20); taskStart.Insert(1, Convert.ToByte(agvTask.SourceAddress.Length)); for (int i = 0; i < 20 - agvTask.SourceAddress.Length; i++) { taskStart.Add(0); } sendData.AddRange(taskStart); List taskEnd = Encoding.Default.GetBytes(agvTask.TargetAddress).ToList(); taskEnd.Insert(0, 20); taskEnd.Insert(1, Convert.ToByte(agvTask.TargetAddress.Length)); for (int i = 0; i < 20 - agvTask.TargetAddress.Length; i++) { taskEnd.Add(0); } sendData.AddRange(taskEnd); byte[] taskType = BitConverter.GetBytes((ushort)1).ToArray(); Array.Reverse(taskType); sendData.AddRange(taskType); List containerType = Encoding.Default.GetBytes(agvTask.Barcode).ToList(); containerType.Insert(0, 30); containerType.Insert(1, Convert.ToByte(agvTask.Barcode.Length)); for (int i = 0; i < 30 - agvTask.Barcode.Length; i++) { containerType.Add(0); } sendData.AddRange(containerType); byte[] taskPriority = BitConverter.GetBytes((ushort)1).ToArray(); Array.Reverse(taskPriority); sendData.AddRange(taskPriority); byte[] taskFlag = BitConverter.GetBytes((ushort)jobEnum).ToArray(); Array.Reverse(taskFlag); sendData.AddRange(taskFlag); var operateResult = client.Communicator.Write("DB1000.0", sendData.ToArray()); if (!operateResult) return "AGV发送任务失败"; //WriteLog.Info("AGV发送任务").Write("任务号" + agvTask.agv_tasknum + "AGV编号" + client.PLCName + DateTime.Now, "AGV发送任务"); return ""; } } }