| | |
| | | using WIDESEAWCS_Common.HttpEnum; |
| | | using WIDESEAWCS_Common.TaskEnum; |
| | | using WIDESEAWCS_Core; |
| | | using WIDESEAWCS_Core.Caches; |
| | | using WIDESEAWCS_Core.Helper; |
| | | using WIDESEAWCS_Core.Http; |
| | | using WIDESEAWCS_DTO.Stock; |
| | |
| | | private const int MaxTaskTotalNum = 48; |
| | | |
| | | private readonly TcpSocketServer _TcpSocket; |
| | | private static readonly ConcurrentDictionary<string, RobotSocketState> _socketStates = new(); |
| | | //private static readonly ConcurrentDictionary<string, RobotSocketState> _socketStates = new(); |
| | | private static int _eventSubscribedFlag; |
| | | |
| | | private readonly ITaskService _taskService; |
| | | private readonly IRobotTaskService _robotTaskService; |
| | | private readonly ICacheService _cache; |
| | | |
| | | private static IRobotTaskService _latestRobotTaskService = null!; |
| | | private static ITaskService _latestTaskService = null!; |
| | | |
| | | public RobotJob(TcpSocketServer TcpSocket, IRobotTaskService RobottaskService, ITaskService TaskService) |
| | | public RobotJob(TcpSocketServer TcpSocket, IRobotTaskService RobottaskService, ITaskService TaskService, ICacheService cache) |
| | | { |
| | | _TcpSocket = TcpSocket; |
| | | _robotTaskService = RobottaskService; |
| | | _taskService = TaskService; |
| | | _cache = cache; |
| | | |
| | | _latestRobotTaskService = RobottaskService; |
| | | _latestTaskService = TaskService; |
| | |
| | | string ipAddress = robotCrane.IPAddress; |
| | | |
| | | // 获取或创建状态 |
| | | RobotSocketState state = _socketStates.GetOrAdd(ipAddress, _ => new RobotSocketState |
| | | RobotSocketState state = _cache.GetOrAdd(ipAddress, _ => new RobotSocketState |
| | | { |
| | | IPAddress = ipAddress, |
| | | RobotCrane = robotCrane |
| | |
| | | // 更新设备信息 |
| | | state.RobotCrane = robotCrane; |
| | | |
| | | // 检查是否有该客户端连接 |
| | | var clientIds = _TcpSocket.GetClientIds(); |
| | | if (!clientIds.Contains(ipAddress)) |
| | | try |
| | | { |
| | | return; |
| | | } |
| | | |
| | | // 订阅一次 message 事件(全局一次) |
| | | if (Interlocked.CompareExchange(ref _eventSubscribedFlag, 1, 0) == 0) |
| | | { |
| | | _TcpSocket.MessageReceived += _TcpSocket_MessageReceived; |
| | | _TcpSocket.RobotReceived += _TcpSocket_RobotReceived; |
| | | } |
| | | |
| | | if (!state.IsEventSubscribed) |
| | | { |
| | | if (_TcpSocket._clients.TryGetValue(ipAddress, out TcpClient client)) |
| | | // 检查是否有该客户端连接 |
| | | var clientIds = _TcpSocket.GetClientIds(); |
| | | if (!clientIds.Contains(ipAddress)) |
| | | { |
| | | _ = _TcpSocket.HandleClientAsync(client, robotCrane.IPAddress, _TcpSocket._cts.Token, state) |
| | | .ContinueWith(t => |
| | | { |
| | | if (t.IsFaulted) |
| | | Console.WriteLine($"HandleClientAsync error: {t.Exception?.GetBaseException().Message}"); |
| | | }, TaskContinuationOptions.OnlyOnFaulted); |
| | | state.IsEventSubscribed = true; |
| | | return; |
| | | } |
| | | } |
| | | |
| | | // 获取任务并缓存到状态中 |
| | | Dt_RobotTask? task = GetTask(robotCrane); |
| | | if (task != null) |
| | | { |
| | | state.IsSplitPallet = task.RobotTaskType == RobotTaskTypeEnum.SplitPallet.GetHashCode(); |
| | | state.IsGroupPallet = task.RobotTaskType == RobotTaskTypeEnum.GroupPallet.GetHashCode() || task.RobotTaskType == RobotTaskTypeEnum.ChangePallet.GetHashCode(); |
| | | state.CurrentTask = task; |
| | | if (task.RobotTaskTotalNum <= MaxTaskTotalNum) |
| | | // 订阅一次 message 事件(全局一次) |
| | | if (Interlocked.CompareExchange(ref _eventSubscribedFlag, 1, 0) == 0) |
| | | { |
| | | // 处理正在执行的任务 |
| | | if (state.RobotRunMode == 2 && state.RobotControlMode == 1 && state.OperStatus != "Running") |
| | | _TcpSocket.MessageReceived += _TcpSocket_MessageReceived; |
| | | _TcpSocket.RobotReceived += _TcpSocket_RobotReceived; |
| | | } |
| | | |
| | | if (!state.IsEventSubscribed) |
| | | { |
| | | if (_TcpSocket._clients.TryGetValue(ipAddress, out TcpClient client)) |
| | | { |
| | | await Task.Delay(1000); |
| | | if (state.CurrentAction == "PickFinished" && state.RobotArmObject == 1 && task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode()) |
| | | _ = _TcpSocket.HandleClientAsync(client, robotCrane.IPAddress, _TcpSocket._cts.Token, state) |
| | | .ContinueWith(t => |
| | | { |
| | | if (t.IsFaulted) |
| | | Console.WriteLine($"HandleClientAsync error: {t.Exception?.GetBaseException().Message}"); |
| | | }, TaskContinuationOptions.OnlyOnFaulted); |
| | | state.IsEventSubscribed = true; |
| | | } |
| | | } |
| | | |
| | | // 获取任务并缓存到状态中 |
| | | Dt_RobotTask? task = GetTask(robotCrane); |
| | | if (task != null) |
| | | { |
| | | state.IsSplitPallet = task.RobotTaskType == RobotTaskTypeEnum.SplitPallet.GetHashCode(); |
| | | state.IsGroupPallet = task.RobotTaskType == RobotTaskTypeEnum.GroupPallet.GetHashCode() || task.RobotTaskType == RobotTaskTypeEnum.ChangePallet.GetHashCode(); |
| | | state.CurrentTask = task; |
| | | if (task.RobotTaskTotalNum <= MaxTaskTotalNum) |
| | | { |
| | | // 处理正在执行的任务 |
| | | if (state.RobotRunMode == 2 && state.RobotControlMode == 1 && state.OperStatus != "Running") |
| | | { |
| | | string taskString = $"Putbattery,{task.RobotTargetAddress}"; |
| | | bool result = await _TcpSocket.SendToClientAsync(ipAddress, taskString); |
| | | if (result) |
| | | await Task.Delay(1000); |
| | | if (state.CurrentAction == "PickFinished" && state.RobotArmObject == 1 && task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode()) |
| | | { |
| | | string taskString = $"Putbattery,{task.RobotTargetAddress}"; |
| | | bool result = await _TcpSocket.SendToClientAsync(ipAddress, taskString); |
| | | if (result) |
| | | { |
| | | task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode(); |
| | | await _robotTaskService.UpdateRobotTaskAsync(task); |
| | | } |
| | | } |
| | | else if (state.CurrentAction == "PutFinished" && state.RobotArmObject == 0 && task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode()) |
| | | { |
| | | task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode(); |
| | | await _robotTaskService.UpdateRobotTaskAsync(task); |
| | | } |
| | | } |
| | | else if (state.CurrentAction == "PutFinished" && state.RobotArmObject == 0 && task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode()) |
| | | { |
| | | task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode(); |
| | | await _robotTaskService.UpdateRobotTaskAsync(task); |
| | | } |
| | | else if (state.OperStatus == "Homed" && state.RobotArmObject == 0 && task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode()) |
| | | { |
| | | // TODO 读取线体电池条码,发送取电池指令 |
| | | // 随机生成两天托盘条码存放到两个变量里面 |
| | | // 定义前缀(例如:TRAY代表托盘) |
| | | string prefix = "TRAY"; |
| | | |
| | | // 生成两个托盘条码 |
| | | string trayBarcode1 = GenerateTrayBarcode(state, prefix); |
| | | string trayBarcode2 = GenerateTrayBarcode(state, prefix); |
| | | if (!trayBarcode1.IsNullOrEmpty() && !trayBarcode2.IsNullOrEmpty()) |
| | | else if (state.OperStatus == "Homed" && state.RobotArmObject == 0 && task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode()) |
| | | { |
| | | string taskString = $"Pickbattery,{task.RobotSourceAddress}"; |
| | | // 发送任务指令 |
| | | bool result = await _TcpSocket.SendToClientAsync(ipAddress, taskString); |
| | | if (result) |
| | | // TODO 读取线体电池条码,发送取电池指令 |
| | | // 随机生成两天托盘条码存放到两个变量里面 |
| | | // 定义前缀(例如:TRAY代表托盘) |
| | | string prefix = "TRAY"; |
| | | |
| | | // 生成两个托盘条码 |
| | | string trayBarcode1 = GenerateTrayBarcode(state, prefix); |
| | | string trayBarcode2 = GenerateTrayBarcode(state, prefix); |
| | | if (!trayBarcode1.IsNullOrEmpty() && !trayBarcode2.IsNullOrEmpty()) |
| | | { |
| | | // TODO 处理成功发送任务指令后的逻辑 |
| | | task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode(); |
| | | result = await _robotTaskService.UpdateRobotTaskAsync(task); |
| | | string taskString = $"Pickbattery,{task.RobotSourceAddress}"; |
| | | // 发送任务指令 |
| | | bool result = await _TcpSocket.SendToClientAsync(ipAddress, taskString); |
| | | if (result) |
| | | { |
| | | // TODO 处理成功发送任务指令后的逻辑 |
| | | task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode(); |
| | | result = await _robotTaskService.UpdateRobotTaskAsync(task); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (Exception) |
| | | { |
| | | |
| | | } |
| | | finally |
| | | { |
| | | // 可选:在这里处理任何需要在任务完成后执行的清理工作 |
| | | // 更新缓存中的状态 |
| | | _cache.AddOrUpdate(ipAddress, state); |
| | | } |
| | | } |
| | | |
| | |
| | | /// <returns></returns> |
| | | private Task<string?> _TcpSocket_RobotReceived(string clientId) |
| | | { |
| | | _socketStates.TryRemove(clientId, out _); |
| | | _cache.TryRemove(clientId, out _); |
| | | return Task.FromResult<string?>(null); |
| | | } |
| | | |