using Newtonsoft.Json;
|
using WIDESEAWCS_Common.AGVEnum;
|
using WIDESEAWCS_Common.TaskEnum;
|
using WIDESEAWCS_ITaskInfoRepository;
|
using WIDESEAWCS_Model.Models;
|
using WIDESEAWCS_QuartzJob;
|
|
namespace WIDESEAWCS_Tasks
|
{
|
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<int>(taskFbInteractiveR);
|
int taskFbInteractiveW = plcClient.Communicator.Read<int>(taskFbInteractive2);
|
int resetTaskFbInteractiver = plcClient.Communicator.Read<int>(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<int>(taskFbInteractive2);
|
if (agvnumber != 0)
|
{
|
plcClient.Communicator.Write(taskFbInteractive2, 0);
|
}
|
else
|
{
|
break;
|
}
|
}
|
}
|
if (1 == taskFbInteractive && taskFbInteractiveW == 0)
|
{
|
string taskId = plcClient.Communicator.Read<int>(taskIDFb).ToString();//任务ID
|
if (taskId.Contains("\b")) { taskId = taskId.Remove(0, 1); }
|
int taskState = plcClient.Communicator.Read<int>(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<TaskInStatusEnum>();
|
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<int>(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<TaskInStatusEnum>();
|
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<int>(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<TaskInStatusEnum>();
|
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<int>(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 + ",任务状态不是终点执行中!");
|
}
|
if (agvTask.TargetAddress.Contains("HXWLX"))
|
{
|
if (agvTask.SourceAddress.Contains("KPHLX"))
|
{
|
// 空盘线进烘箱
|
// TODO: 调用创智接口获取完整条码
|
var materials = new List<BakingClass>
|
{
|
new BakingClass { BarCode = "1", MaterialType = "1" },
|
};
|
MESback WMSbackresult = MESAPIInvoke.BakingFeedingBinding(agvTask.TargetAddress, materials);
|
if (WMSbackresult.Code > 0) { new Exception(WMSbackresult.Message); return; }
|
}
|
else
|
{
|
// 提升机进烘箱
|
// TODO: 调用创智接口获取完整条码
|
var materials = new List<BakingClass>
|
{
|
new BakingClass { BarCode = "1", MaterialType = "1" },
|
};
|
MESback WMSbackresult = MESAPIInvoke.BakingFeedingBinding(agvTask.TargetAddress, materials);
|
if (WMSbackresult.Code > 0) { new Exception(WMSbackresult.Message); return; }
|
}
|
}
|
|
|
//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<int>(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<int>(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<int>(taskFbInteractiveR);
|
int taskFbInteractiveW = plcClient.Communicator.Read<int>(taskFbInteractive2);
|
int resetTaskFbInteractiveRValue = plcClient.Communicator.Read<int>(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<int>(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<int>(taskIDFb).ToString(); // 任务ID
|
int taskState = plcClient.Communicator.Read<int>(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<TaskInStatusEnum>();
|
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<int>(taskFbInteractive2);
|
if (agvNumber != 1)
|
{
|
plcClient.Communicator.Write(taskFbInteractive2, 1);
|
}
|
else
|
{
|
break;
|
}
|
}
|
}
|
}
|
|
public class BakingFeedingClass
|
{
|
public string Devid { get; set; }
|
|
public List<BakingClass> Materials { get; set; }
|
}
|
|
public class BakingClass
|
{
|
public string MaterialType { get; set; }
|
public string BarCode { get; set; }
|
}
|
}
|