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); } } } }