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
{
///
/// 机械手任务作业 - 负责协调机械手客户端连接、消息处理和任务执行
///
[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消息事件已订阅");
}
}
///
/// 客户端断开连接时的处理
///
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)
{
// 异常处理已在各组件中处理
}
}
///
/// 处理机械手任务
///
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);
}
}
}
///
/// 处理取货完成状态
///
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);
}
}
}
///
/// 处理放货完成状态
///
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);
}
}
}
}