using Quartz;
|
using WIDESEA_Core;
|
using WIDESEAWCS_Common.TaskEnum;
|
using WIDESEAWCS_Core.Caches;
|
using WIDESEAWCS_Core.Helper;
|
using WIDESEAWCS_ITaskInfoService;
|
using WIDESEAWCS_Model.Models;
|
using WIDESEAWCS_QuartzJob;
|
using WIDESEAWCS_Tasks.SocketServer;
|
|
namespace WIDESEAWCS_Tasks
|
{
|
/// <summary>
|
/// 机械手任务作业 - 负责协调机械手客户端连接、消息处理和任务执行
|
/// </summary>
|
[DisallowConcurrentExecution]
|
public class RobotJob : IJob
|
{
|
private const int MaxTaskTotalNum = 48;
|
|
private static int _messageSubscribedFlag;
|
|
private readonly RobotClientManager _clientManager;
|
private readonly RobotStateManager _stateManager;
|
private readonly RobotMessageHandler _messageHandler;
|
private readonly RobotTaskProcessor _taskProcessor;
|
private readonly IRobotTaskService _robotTaskService;
|
|
public RobotJob(
|
TcpSocketServer tcpSocket,
|
IRobotTaskService robotTaskService,
|
ITaskService taskService,
|
ICacheService cache,
|
HttpClientHelper httpClientHelper)
|
{
|
_robotTaskService = robotTaskService;
|
|
// 初始化管理器
|
_stateManager = new RobotStateManager(cache);
|
_taskProcessor = new RobotTaskProcessor(tcpSocket, _stateManager, robotTaskService, taskService, httpClientHelper);
|
_clientManager = new RobotClientManager(tcpSocket, _stateManager);
|
_messageHandler = new RobotMessageHandler(tcpSocket, _stateManager, cache, robotTaskService, _taskProcessor);
|
|
// 订阅客户端管理器的事件
|
_clientManager.OnClientDisconnected += OnClientDisconnected;
|
|
// 订阅TCP服务器的消息事件(全局只订阅一次)
|
if (System.Threading.Interlocked.CompareExchange(ref _messageSubscribedFlag, 1, 0) == 0)
|
{
|
tcpSocket.MessageReceived += _messageHandler.HandleMessageReceivedAsync;
|
Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 机器人TCP消息事件已订阅");
|
}
|
}
|
|
/// <summary>
|
/// 客户端断开连接时的处理
|
/// </summary>
|
private void OnClientDisconnected(object? sender, RobotSocketState state)
|
{
|
// 可以在这里添加断开连接后的处理逻辑
|
Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 客户端已断开连接: {state.IPAddress}");
|
}
|
|
public async Task Execute(IJobExecutionContext context)
|
{
|
bool flag = context.JobDetail.JobDataMap.TryGetValue("JobParams", out object? value);
|
RobotCraneDevice robotCrane = (RobotCraneDevice?)value ?? new RobotCraneDevice();
|
if (!flag || robotCrane.IsNullOrEmpty())
|
{
|
return;
|
}
|
|
string ipAddress = robotCrane.IPAddress;
|
|
// 获取或创建状态
|
RobotSocketState state = _stateManager.GetOrCreateState(ipAddress, robotCrane);
|
state.RobotCrane = robotCrane;
|
|
try
|
{
|
// 确保客户端已连接并订阅消息事件
|
if (!_clientManager.EnsureClientSubscribed(ipAddress, robotCrane))
|
{
|
return; // 客户端未连接或订阅失败,跳过本次执行
|
}
|
|
// 获取任务并处理
|
Dt_RobotTask? task = _taskProcessor.GetTask(robotCrane);
|
if (task != null)
|
{
|
// 每次判断前重新从缓存获取最新状态
|
var latestState = _stateManager.GetState(ipAddress);
|
if (latestState == null) return;
|
|
if (latestState.RobotTaskTotalNum < MaxTaskTotalNum)
|
{
|
await ProcessTaskAsync(latestState, task, ipAddress);
|
}
|
}
|
}
|
catch (Exception)
|
{
|
// 异常处理已在各组件中处理
|
}
|
}
|
|
/// <summary>
|
/// 处理机械手任务
|
/// </summary>
|
private async Task ProcessTaskAsync(RobotSocketState latestState, Dt_RobotTask task, string ipAddress)
|
{
|
// 处理正在执行的任务
|
if (latestState.RobotRunMode == 2 && latestState.RobotControlMode == 1 && latestState.OperStatus != "Running")
|
{
|
// 取货完成状态处理
|
if ((latestState.CurrentAction == "PickFinished" || latestState.CurrentAction == "AllPickFinished") && latestState.RobotArmObject == 1 &&
|
task.RobotTaskState == TaskRobotStatusEnum.RobotPickFinish.GetHashCode())
|
{
|
await HandlePickFinishedStateAsync(latestState, task, ipAddress);
|
}
|
// 放货完成状态处理
|
else if ((latestState.CurrentAction == "PutFinished" || latestState.CurrentAction == "AllPutFinished") && latestState.OperStatus == "Homed" &&
|
latestState.RobotArmObject == 0 &&
|
(task.RobotTaskState == TaskRobotStatusEnum.RobotPutFinish.GetHashCode() ||
|
task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode()))
|
{
|
await HandlePutFinishedStateAsync(latestState, task, ipAddress);
|
}
|
}
|
}
|
|
/// <summary>
|
/// 处理取货完成状态
|
/// </summary>
|
private async Task HandlePickFinishedStateAsync(RobotSocketState latestState, Dt_RobotTask task, string ipAddress)
|
{
|
string taskString = $"Putbattery,{task.RobotTargetAddress}";
|
bool result = await _clientManager.SendToClientAsync(ipAddress, taskString);
|
if (result)
|
{
|
task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
|
|
// 重新获取最新状态并更新
|
var stateToUpdate = _stateManager.GetState(ipAddress);
|
if (stateToUpdate != null)
|
{
|
stateToUpdate.CurrentTask = task;
|
if (_stateManager.TryUpdateStateSafely(ipAddress, stateToUpdate))
|
await _robotTaskService.UpdateRobotTaskAsync(task);
|
}
|
}
|
}
|
|
/// <summary>
|
/// 处理放货完成状态
|
/// </summary>
|
private async Task HandlePutFinishedStateAsync(RobotSocketState latestState, Dt_RobotTask task, string ipAddress)
|
{
|
// 重新获取最新状态
|
var stateForUpdate = _stateManager.GetState(ipAddress);
|
if (stateForUpdate == null) return;
|
|
if (!stateForUpdate.IsSplitPallet && !stateForUpdate.IsGroupPallet)
|
{
|
stateForUpdate.IsSplitPallet = task.RobotTaskType == RobotTaskTypeEnum.SplitPallet.GetHashCode();
|
stateForUpdate.IsGroupPallet = task.RobotTaskType == RobotTaskTypeEnum.GroupPallet.GetHashCode() ||
|
task.RobotTaskType == RobotTaskTypeEnum.ChangePallet.GetHashCode();
|
}
|
|
if (task.RobotTaskType == RobotTaskTypeEnum.GroupPallet.GetHashCode())
|
{
|
string prefix = "TRAY";
|
|
// 生成两个托盘条码
|
string trayBarcode1 = RobotBarcodeGenerator.GenerateTrayBarcode(prefix);
|
string trayBarcode2 = RobotBarcodeGenerator.GenerateTrayBarcode(prefix);
|
if (!trayBarcode1.IsNullOrEmpty() && !trayBarcode2.IsNullOrEmpty())
|
{
|
stateForUpdate.CellBarcode.Add(trayBarcode1);
|
stateForUpdate.CellBarcode.Add(trayBarcode2);
|
await _taskProcessor.SendSocketRobotPickAsync(task, stateForUpdate);
|
}
|
}
|
else // 任务开始执行直接发送取货地址
|
{
|
await _taskProcessor.SendSocketRobotPickAsync(task, stateForUpdate);
|
}
|
}
|
}
|
}
|