using System.Diagnostics;
|
using System.Text;
|
using Microsoft.Data.SqlClient;
|
using WIDESEAWCS_Common.AGVEnum;
|
using WIDESEAWCS_Common.TaskEnum;
|
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 void SendAGVTask1(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_Task> 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}");
|
}
|
}
|
|
}
|
|
public static void SendAGVTask(AGV agv, ITaskRepository _taskRepository)
|
{
|
// 检查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<Int16>(taskInteractiveR); // 1表示收到
|
int taskInteractiveW = agv.Communicator.Read<Int16>(taskInteractiveW1); // 0初始/1下发/2取消/3更改
|
int resetTaskInteractiveW = agv.Communicator.Read<Int16>(resetTaskW);
|
int resetTaskInteractiver = agv.Communicator.Read<Int16>(resetTaskInteractiveR);
|
|
// 处理任务交互W和重置交互W不为0的情况
|
if (isTrue1 && name1 == agv.DeviceName)
|
{
|
if (taskInteractiveW != 0 || resetTaskInteractiveW != 0 || taskInteractive != 0)
|
{
|
agv.Communicator.Write<UInt16>(resetTaskW, 1);
|
Task.Delay(2000).Wait();
|
resetTaskInteractiveW = agv.Communicator.Read<Int16>(resetTaskW);
|
|
if (resetTaskInteractiveW == 1)
|
{
|
agv.Communicator.Write<UInt16>(resetTaskW, 0);
|
agv.Communicator.Write<UInt16>(taskInteractiveW1, 0);
|
Task.Delay(2000).Wait();
|
}
|
return;
|
}
|
isTrue1 = false;
|
name1 = "";
|
}
|
|
// 如果重置交互R为1,则重置任务交互W
|
if (resetTaskInteractiver == 1)
|
{
|
agv.Communicator.Write<UInt16>(taskInteractiveW1, 0);
|
for (int i = 0; i < 5; i++)
|
{
|
Task.Delay(300).Wait(); // 用Task.Delay代替Thread.Sleep,以避免线程阻塞
|
int agvNumber = agv.Communicator.Read<Int16>(taskInteractiveW1);
|
if (agvNumber != 0)
|
{
|
agv.Communicator.Write<UInt16>(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<string>(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<UInt16>(taskInteractiveW1, 1);
|
Task.Delay(1000).Wait();
|
|
// 读取AGV的确认信号
|
int readTask1Ok = agv.Communicator.Read<Int16>(taskInteractiveR);
|
if (readTask1Ok == 1)
|
{
|
// 写入WCS的确认信号0
|
agv.Communicator.Write<UInt16>(taskInteractiveW1, 0);
|
Task.Delay(2000).Wait();
|
|
// 再次读取AGV的确认信号
|
int readTask0Ok = agv.Communicator.Read<Int16>(taskInteractiveR);
|
if (readTask0Ok == 0)
|
{
|
// 更新任务状态并保存
|
int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus<TaskInStatusEnum>();
|
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<UInt16>(taskInteractiveW1, 0);
|
Task.Delay(2000).Wait();
|
int readTask0Error = agv.Communicator.Read<int>(taskInteractiveR);
|
|
if (readTask0Error == 0)
|
{
|
// 更新任务状态为异常并保存
|
int nextStatus = agvTask.TaskState.GetNextNotCompletedStatus<TaskOutStatusEnum>();
|
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<byte> sendData = new List<byte>();
|
string tmp = "KH-" + agvTask.TaskNum.ToString();
|
List<byte> 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<byte> 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<byte> 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<byte> 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 "";
|
}
|
}
|
}
|