wanshenmean
2026-03-04 17e5dbd7bd0364e27a33f1a7dab91cf33d5dcabc
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs
@@ -1,22 +1,22 @@
using HslCommunication;
using Newtonsoft.Json;
using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup;
using Quartz;
using System.Collections.Concurrent;
using System.Net;
using System.Net.Sockets;
using System.Text.Json;
using System.Threading.Tasks;
using WIDESEA_Core;
using WIDESEAWCS_Common;
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;
using WIDESEAWCS_DTO.TaskInfo;
using WIDESEAWCS_ITaskInfoRepository;
using WIDESEAWCS_ITaskInfoService;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
using WIDESEAWCS_QuartzJob.Service;
using WIDESEAWCS_Tasks.SocketServer;
namespace WIDESEAWCS_Tasks
@@ -27,22 +27,25 @@
        private const int MaxTaskTotalNum = 48;
        private readonly TcpSocketServer _TcpSocket;
        //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 readonly HttpClientHelper _httpClientHelper;
        private static IRobotTaskService _latestRobotTaskService = null!;
        private static ITaskService _latestTaskService = null!;
        public RobotJob(TcpSocketServer TcpSocket, IRobotTaskService RobottaskService, ITaskService TaskService, ICacheService cache)
        public RobotJob(TcpSocketServer TcpSocket, IRobotTaskService RobottaskService, ITaskService TaskService, ICacheService cache, HttpClientHelper httpClientHelper)
        {
            _TcpSocket = TcpSocket;
            _robotTaskService = RobottaskService;
            _taskService = TaskService;
            _cache = cache;
            _httpClientHelper = httpClientHelper;
            _latestRobotTaskService = RobottaskService;
            _latestTaskService = TaskService;
@@ -60,7 +63,7 @@
            string ipAddress = robotCrane.IPAddress;
            // 获取或创建状态
            RobotSocketState state = _cache.GetOrAdd(ipAddress, _ => new RobotSocketState
            RobotSocketState state = _cache.GetOrAdd($"{RedisPrefix.Code}:{RedisName.SocketDevices}:{ipAddress}", _ => new RobotSocketState
            {
                IPAddress = ipAddress,
                RobotCrane = robotCrane
@@ -71,7 +74,6 @@
            try
            {
                // 检查是否有该客户端连接
                var clientIds = _TcpSocket.GetClientIds();
                if (!clientIds.Contains(ipAddress))
@@ -97,6 +99,9 @@
                                    Console.WriteLine($"HandleClientAsync error: {t.Exception?.GetBaseException().Message}");
                            }, TaskContinuationOptions.OnlyOnFaulted);
                        state.IsEventSubscribed = true;
                        // 更新缓存中的状态
                        _cache.TryUpdateIfChanged($"{RedisPrefix.Code}:{RedisName.SocketDevices}:{ipAddress}", state);
                    }
                }
@@ -104,16 +109,12 @@
                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")
                        {
                            await Task.Delay(1000);
                            if (state.CurrentAction == "PickFinished" && state.RobotArmObject == 1 && task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode())
                            if (state.CurrentAction == "PickFinished" && state.RobotArmObject == 1 && task.RobotTaskState == TaskRobotStatusEnum.RobotPickFinish.GetHashCode())
                            {
                                string taskString = $"Putbattery,{task.RobotTargetAddress}";
                                bool result = await _TcpSocket.SendToClientAsync(ipAddress, taskString);
@@ -123,33 +124,42 @@
                                    await _robotTaskService.UpdateRobotTaskAsync(task);
                                }
                            }
                            else if (state.CurrentAction == "PutFinished" && state.RobotArmObject == 0 && task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode())
                            else if (state.CurrentAction == "PutFinished" && state.RobotArmObject == 0 && task.RobotTaskState == TaskRobotStatusEnum.RobotPutFinish.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())
                                // 组盘读取线体条码
                                if (task.RobotTaskType == RobotTaskTypeEnum.GroupPallet.GetHashCode())
                                {
                                    string taskString = $"Pickbattery,{task.RobotSourceAddress}";
                                    // 发送任务指令
                                    bool result = await _TcpSocket.SendToClientAsync(ipAddress, taskString);
                                    if (result)
                                    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);
                                        await SendSocketRobotPickAsync(task, state);
                                    }
                                }
                                else // 换盘直接发送取货地址
                                {
                                    await SendSocketRobotPickAsync(task, state);
                                }
                            }
                            if (state.CurrentTask.IsNullOrEmpty() && state.ToJson() != task.ToJson())
                            {
                                state.IsSplitPallet = task.RobotTaskType == RobotTaskTypeEnum.SplitPallet.GetHashCode();
                                state.IsGroupPallet = task.RobotTaskType == RobotTaskTypeEnum.GroupPallet.GetHashCode() || task.RobotTaskType == RobotTaskTypeEnum.ChangePallet.GetHashCode();
                                state.CurrentTask = task;
                                // 更新缓存中的状态
                                _cache.TryUpdateIfChanged($"{RedisPrefix.Code}:{RedisName.SocketDevices}:{ipAddress}", state);
                            }
                        }
                    }
@@ -157,13 +167,10 @@
            }
            catch (Exception)
            {
            }
            finally
            {
                // 可选:在这里处理任何需要在任务完成后执行的清理工作
                // 更新缓存中的状态
                _cache.AddOrUpdate(ipAddress, state);
            }
        }
@@ -181,7 +188,7 @@
            // 组合:前缀 + 日期 + 时间 + 随机数
            var barCode = prefix + datePart + timePart + randomPart;
            state.CellBarcode.Add(randomPart);
            state.CellBarcode.Add(barCode);
            return barCode;
        }
@@ -193,7 +200,14 @@
        /// <returns></returns>
        private Task<string?> _TcpSocket_RobotReceived(string clientId)
        {
            _cache.TryRemove(clientId, out _);
            var robotSocketState = _cache.Get<RobotSocketState>($"{RedisPrefix.Code}:{RedisName.SocketDevices}:{clientId}");
            robotSocketState.IsEventSubscribed = false;
            robotSocketState.CurrentAction = "";
            robotSocketState.OperStatus = "";
            robotSocketState.RobotArmObject = 0;
            robotSocketState.RobotControlMode = 0;
            robotSocketState.RobotRunMode = 0;
            _cache.TryUpdateIfChanged($"{RedisPrefix.Code}:{RedisName.SocketDevices}:{clientId}", robotSocketState);
            return Task.FromResult<string?>(null);
        }
@@ -207,15 +221,16 @@
        /// <returns></returns>
        private async Task<string?> _TcpSocket_MessageReceived(string message, bool isJson, TcpClient client, RobotSocketState state)
        {
            if (!(bool)(_cache?.TryGetValue($"{RedisPrefix.Code}:{RedisName.SocketDevices}:{client.Client.RemoteEndPoint}", out state)))
                return null;
            string messageLower = message.ToLowerInvariant();
            if (await IsSimpleCommandAsync(messageLower, state))
            {
                await _TcpSocket.SendMessageAsync(client, message);
                return null;
            }
            if (IsPrefixCommand(messageLower))
            else if (IsPrefixCommand(messageLower))
            {
                try
                {
@@ -238,9 +253,9 @@
                                var stockDTO = BuildStockDTO(state, positions);
                                state.LastPickPositions = positions;
                                var result = await HttpRequestHelper.HTTPPostAsync(nameof(Category.WMS), stockDTO.ToJsonString(), nameof(ConfigKey.SplitPalletAsync));
                                var result = _httpClientHelper.Post<WebResponseContent>(nameof(ConfigKey.SplitPalletAsync), stockDTO.ToJson());
                                if (result.Status)
                                if (result.Data.Status && result.IsSuccess)
                                {
                                    state.CurrentAction = "PickFinished";
                                }
@@ -250,6 +265,7 @@
                                state.CurrentAction = "PickFinished";
                            }
                            state.LastPickPositions = positions;
                            task.RobotTaskState = TaskRobotStatusEnum.RobotPickFinish.GetHashCode();
                            await _latestRobotTaskService.Repository.UpdateDataAsync(task);
                        }
@@ -262,8 +278,9 @@
                                var stockDTO = BuildStockDTO(state, positions);
                                var configKey = state.CurrentTask?.RobotTaskType == RobotTaskTypeEnum.ChangePallet.GetHashCode()
                                    ? nameof(ConfigKey.ChangePalletAsync) : nameof(ConfigKey.GroupPalletAsync);
                                var result = await HttpRequestHelper.HTTPPostAsync(nameof(Category.WMS), stockDTO.ToJsonString(), configKey);
                                putSuccess = result.Status;
                                var result = _httpClientHelper.Post<WebResponseContent>(configKey, stockDTO.ToJson());
                                putSuccess = result.Data.Status && result.IsSuccess;
                            }
                            if (putSuccess)
@@ -276,17 +293,18 @@
                            task.RobotTaskState = TaskRobotStatusEnum.RobotPutFinish.GetHashCode();
                            await _latestRobotTaskService.Repository.UpdateDataAsync(task);
                        }
                        await _TcpSocket.SendMessageAsync(client, message);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"RobotJob MessageReceived Error: {ex.Message}");
                }
                await _TcpSocket.SendMessageAsync(client, message);
                return null;
            }
            // 更新缓存中的状态
            _cache.TryUpdateIfChanged($"{RedisPrefix.Code}:{RedisName.SocketDevices}:{state.IPAddress}", state);
            return null;
        }
@@ -297,7 +315,7 @@
        /// <param name="message"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        private static async Task<bool> IsSimpleCommandAsync(string message, RobotSocketState state)
        private async Task<bool> IsSimpleCommandAsync(string message, RobotSocketState state)
        {
            switch (message)
            {
@@ -378,7 +396,7 @@
            }
        }
        private static async Task HandleInboundTaskAsync(RobotSocketState state, bool useSourceAddress)
        private async Task HandleInboundTaskAsync(RobotSocketState state, bool useSourceAddress)
        {
            var currentTask = state.CurrentTask;
            if (currentTask == null)
@@ -399,9 +417,8 @@
                PalletType = 1,
                TaskType = 4
            };
            var result = await HttpRequestHelper.HTTPPostAsync(nameof(Category.WMS), taskDto.ToJsonString(), nameof(ConfigKey.CreateTaskInboundAsync));
            if (!result.Status)
            var result = _httpClientHelper.Post<WebResponseContent>(nameof(ConfigKey.CreateTaskInboundAsync), taskDto.ToJson());
            if (!result.Data.Status && result.IsSuccess)
            {
                return;
            }
@@ -433,20 +450,21 @@
        private static StockDTO BuildStockDTO(RobotSocketState state, int[] positions)
        {
            string sss = state.ToJson();
            return new StockDTO
            {
                SourceLineNo = state.CurrentTask?.RobotSourceAddressLineCode,
                SourcePalletNo = state.CurrentTask?.RobotSourceAddressPalletCode,
                TargetPalletNo = state.CurrentTask?.RobotTargetAddressPalletCode,
                TargetLineNo = state.CurrentTask?.RobotTargetAddressLineCode,
                SourceLineNo = state.CurrentTask.RobotSourceAddressLineCode,
                SourcePalletNo = state.CurrentTask.RobotSourceAddressPalletCode,
                TargetPalletNo = state.CurrentTask.RobotTargetAddressPalletCode,
                TargetLineNo = state.CurrentTask.RobotTargetAddressLineCode,
                Details = positions
                    .Where(x => x > 0)
                    .OrderBy(x => x)
                    .Select((x, idx) => new StockDetailDTO
                    {
                        Quantity = state.CurrentTask?.RobotTaskTotalNum ?? 1,
                        Quantity = state.RobotTaskTotalNum > 0 ? state.RobotTaskTotalNum + positions.Length : positions.Length,
                        Channel = x,
                        CellBarcode = !state.CellBarcode.IsNullOrEmpty() ? state.CellBarcode[idx] : ""
                        CellBarcode = state.CellBarcode?.Count > 0 ? state.CellBarcode[x - 1] : ""
                    })
                    .ToList()
            };
@@ -455,6 +473,27 @@
        private Dt_RobotTask? GetTask(RobotCraneDevice robotCrane)
        {
            return _robotTaskService.QueryRobotCraneTask(robotCrane.DeviceCode);
        }
        /// <summary>
        /// 发送机械手取货命令
        /// </summary>
        /// <param name="task"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        private async Task SendSocketRobotPickAsync(Dt_RobotTask task, RobotSocketState state)
        {
            string taskString = $"Pickbattery,{task.RobotSourceAddress}";
            // 发送任务指令
            bool result = await _TcpSocket.SendToClientAsync(state.IPAddress, taskString);
            if (result)
            {
                // TODO 处理成功发送任务指令后的逻辑
                task.RobotTaskState = TaskRobotStatusEnum.RobotExecuting.GetHashCode();
                result = await _robotTaskService.UpdateRobotTaskAsync(task);
                // 更新缓存中的状态
                _cache.TryUpdateIfChanged($"{RedisPrefix.Code}:{RedisName.SocketDevices}:{state.IPAddress}", state);
            }
        }
    }
@@ -510,7 +549,7 @@
        /// <summary>
        /// 抓取位置条码
        /// </summary>
        public List<string> CellBarcode { get; set; } = new();
        public List<string> CellBarcode { get; set; }
        /// <summary>
        /// 当前抓取任务