| | |
| | | using MapsterMapper; |
| | | using Microsoft.Extensions.Configuration; |
| | | using Microsoft.Extensions.Logging; |
| | | using Newtonsoft.Json; |
| | | using Quartz; |
| | | using SqlSugar; |
| | | using System.Text.Json; |
| | | using WIDESEA_Core; |
| | | using WIDESEAWCS_Common.TaskEnum; |
| | | using WIDESEAWCS_Core; |
| | |
| | | private readonly ILogger<CommonConveyorLineNewJob> _logger; |
| | | |
| | | /// <summary> |
| | | /// 目标地址到设备类型的映射 |
| | | /// </summary> |
| | | /// <remarks> |
| | | /// </remarks> |
| | | private static List<string> AddressToDeviceType = new List<string> { "11020", "11028" }; |
| | | |
| | | /// <summary> |
| | | /// 构造函数 |
| | | /// </summary> |
| | | /// <param name="taskService">任务服务</param> |
| | |
| | | } |
| | | |
| | | // 创建并行选项,限制最大并发数 |
| | | var parallelOptions = new ParallelOptions |
| | | { |
| | | // 限制并发数:子设备数量和 CPU 核心数*2 的较小值 |
| | | MaxDegreeOfParallelism = Math.Min(childDeviceCodes.Count, Environment.ProcessorCount * 2), |
| | | }; |
| | | //var parallelOptions = new ParallelOptions |
| | | //{ |
| | | // // 限制并发数:子设备数量和 CPU 核心数*2 的较小值 |
| | | // MaxDegreeOfParallelism = Math.Min(childDeviceCodes.Count, Environment.ProcessorCount * 2), |
| | | //}; |
| | | |
| | | _logger.LogDebug("Execute:开始并行处理输送线 {DeviceCode},子设备数量: {Count}", conveyorLine.DeviceCode, childDeviceCodes.Count); |
| | | QuartzLogger.Debug($"开始并行处理输送线,子设备数量: {childDeviceCodes.Count}", conveyorLine.DeviceCode); |
| | | //_logger.LogDebug("Execute:开始并行处理输送线 {DeviceCode},子设备数量: {Count}", conveyorLine.DeviceCode, childDeviceCodes.Count); |
| | | //QuartzLogger.Debug($"开始并行处理输送线,子设备数量: {childDeviceCodes.Count}", conveyorLine.DeviceCode); |
| | | |
| | | // 并行处理每个子设备 |
| | | Parallel.For(0, childDeviceCodes.Count, parallelOptions, i => |
| | | //Parallel.For(0, childDeviceCodes.Count, parallelOptions, i => |
| | | foreach (var childDeviceCode in childDeviceCodes) |
| | | { |
| | | string childDeviceCode = childDeviceCodes[i]; |
| | | //string childDeviceCode = childDeviceCodes[i]; |
| | | var correlationId = Guid.NewGuid().ToString("N"); |
| | | try |
| | | { |
| | |
| | | { |
| | | _logger.LogDebug("Execute:子设备 {ChildDeviceCode} 命令为空,跳过", childDeviceCode); |
| | | QuartzLogger.Debug($"子设备 {childDeviceCode} 命令为空,跳过", conveyorLine.DeviceCode); |
| | | return; |
| | | continue; |
| | | } |
| | | |
| | | // 如果 WCS_ACK 为 1,先清除(表示处理过上一次请求) |
| | | if (command.WCS_ACK == 1) |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 0, childDeviceCode); |
| | | |
| | | // ========== 检查特定位置是否有托盘 ========== |
| | | // 从配置中读取需要检查托盘的位置列表 |
| | |
| | | if (checkPalletPositions.Any(x => x.Code == childDeviceCode)) |
| | | { |
| | | // 检查输送线状态(是否有托盘) |
| | | if (command.CV_State.ObjToBool()) |
| | | if (command.CV_State == 2) |
| | | { |
| | | // 检查该位置是否已有任务 |
| | | var existingTask = _taskService.Repository.QueryFirst(x => x.TargetAddress == childDeviceCode); |
| | | var existingTask = _taskService.Db.Queryable<Dt_Task>().First(x => x.TargetAddress == childDeviceCode); |
| | | if (existingTask.IsNullOrEmpty()) |
| | | { |
| | | // 没有任务,向 WMS 请求出库托盘任务 |
| | |
| | | // 如果请求成功,接收 WMS 返回的任务 |
| | | if (responseResult.IsSuccess && responseResult.Data.Status) |
| | | { |
| | | var wmsTask = JsonSerializer.Deserialize<List<WMSTaskDTO>>(responseResult.Data.Data.Serialize()); |
| | | var wmsTask = JsonConvert.DeserializeObject<WMSTaskDTO>(responseResult.Data.Data.ToString()); |
| | | List<WMSTaskDTO> taskDTOs = new List<WMSTaskDTO> { wmsTask }; |
| | | if (wmsTask != null) |
| | | _taskService.ReceiveWMSTask(wmsTask); |
| | | _taskService.ReceiveWMSTask(taskDTOs); |
| | | } |
| | | } |
| | | } |
| | |
| | | // 只有当 PLC_STB 为 1 时才处理任务 |
| | | if (command.PLC_STB != 1) |
| | | { |
| | | _logger.LogDebug("Execute:子设备 {ChildDeviceCode} PLC_STB 不为1,跳过", childDeviceCode); |
| | | QuartzLogger.Debug($"子设备 {childDeviceCode} PLC_STB 不为1,跳过", conveyorLine.DeviceCode); |
| | | return; |
| | | // 如果 WCS_ACK 为 1,先清除(表示处理过上一次请求) |
| | | if (command.WCS_ACK == 1) |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 0, childDeviceCode); |
| | | continue; |
| | | } |
| | | |
| | | // ========== 处理无托盘条码的情况 ========== |
| | |
| | | _logger.LogDebug("Execute:子设备 {ChildDeviceCode} 无托盘条码,请求出库任务", childDeviceCode); |
| | | QuartzLogger.Debug($"子设备 {childDeviceCode} 无托盘条码,请求出库任务", conveyorLine.DeviceCode); |
| | | _conveyorLineDispatch.RequestOutbound(conveyorLine, command, childDeviceCode); |
| | | return; |
| | | continue; |
| | | } |
| | | |
| | | // ========== 处理已有任务号的情况 ========== |
| | | if (command.TaskNo > 0) |
| | | if (command.TaskNo > 0 && !command.Barcode.IsNullOrEmpty()) |
| | | { |
| | | // 查询正在执行的任务 |
| | | Dt_Task task = _taskService.QueryExecutingConveyorLineTask(command.TaskNo, childDeviceCode); |
| | |
| | | QuartzLogger.Info($"处理任务 {task.TaskNum},状态: {task.TaskStatus}", conveyorLine.DeviceCode); |
| | | // 处理任务状态(根据状态分发到不同方法) |
| | | ProcessTaskState(conveyorLine, command, task, childDeviceCode); |
| | | return; |
| | | return Task.CompletedTask; |
| | | } |
| | | } |
| | | } |
| | |
| | | _logger.LogError(innerEx, "Execute:子设备 {ChildDeviceCode} 处理异常,CorrelationId: {CorrelationId}", childDeviceCode, correlationId); |
| | | QuartzLogger.Error($"子设备处理异常: {innerEx.Message}", conveyorLine.DeviceCode, innerEx); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | |
| | | { |
| | | case InExecuting: |
| | | // 入库执行中,调用下一地址处理 |
| | | _conveyorLineDispatch.RequestInNextAddress(conveyorLine, command, childDeviceCode); |
| | | |
| | | if (AddressToDeviceType.Contains(childDeviceCode)) |
| | | // 到达目标地址,调用入库完成 |
| | | _conveyorLineDispatch.ConveyorLineInFinish(conveyorLine, command, childDeviceCode); |
| | | else |
| | | // 未到达目标地址,调用入库下一地址处理 |
| | | _conveyorLineDispatch.RequestInNextAddress(conveyorLine, command, childDeviceCode); |
| | | break; |
| | | |
| | | case OutExecuting: |
| | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |