| | |
| | | using Serilog; |
| | | using SqlSugar; |
| | | using WIDESEA_Core; |
| | | using WIDESEAWCS_Common.HttpEnum; |
| | | using WIDESEAWCS_Common.TaskEnum; |
| | | using WIDESEAWCS_Core; |
| | | using WIDESEAWCS_Core.Helper; |
| | |
| | | private readonly ILogger _logger; |
| | | |
| | | /// <summary> |
| | | /// 目标地址到设备类型的映射 |
| | | /// 目标地址到设备类型的映射(入库站台) |
| | | /// </summary> |
| | | /// <remarks> |
| | | /// </remarks> |
| | | private static List<string> AddressToDeviceType = new List<string> { "11020", "11028" }; |
| | | private static List<string> AddressToDeviceType = new List<string> { "11020", "11028", "2125" }; |
| | | |
| | | /// <summary> |
| | | /// 托盘检查位置的最近执行时间(用于30秒间隔限制) |
| | |
| | | return Task.CompletedTask; |
| | | } |
| | | |
| | | // 创建并行选项,限制最大并发数 |
| | | //var parallelOptions = new ParallelOptions |
| | | //{ |
| | | // // 限制并发数:子设备数量和 CPU 核心数*2 的较小值 |
| | | // MaxDegreeOfParallelism = Math.Min(childDeviceCodes.Count, Environment.ProcessorCount * 2), |
| | | //}; |
| | | |
| | | // 并行处理每个子设备 |
| | | //Parallel.For(0, childDeviceCodes.Count, parallelOptions, i => |
| | | foreach (var childDeviceCode in childDeviceCodes) |
| | | { |
| | | //string childDeviceCode = childDeviceCodes[i]; |
| | |
| | | if (command.CV_State == 2) |
| | | { |
| | | // 检查该位置是否已有任务 |
| | | var existingTask = _taskService.Db.Queryable<Dt_Task>().First(x => x.TargetAddress == childDeviceCode); |
| | | if (existingTask.IsNullOrEmpty()) |
| | | var existingTask = _taskService.Db.Queryable<Dt_Task>().Count(x => x.TargetAddress == childDeviceCode); |
| | | if (existingTask < 5) |
| | | { |
| | | // 没有任务,向 WMS 请求出库托盘任务 |
| | | var position = checkPalletPositions.FirstOrDefault(x => x.Code == childDeviceCode); |
| | | //QuartzLogHelper.LogInfo(_logger, "Execute:检查托盘位置 {ChildDeviceCode},请求WMS出库托盘任务", $"检查托盘位置 {childDeviceCode},请求WMS出库托盘任务", conveyorLine.DeviceCode, childDeviceCode); |
| | | |
| | | var responseResult = _httpClientHelper.Post<WebResponseContent>("GetOutBoundTrayTaskAsync", new CreateTaskDto() |
| | | string configKey = "GetOutBoundTrayTaskAsync"; |
| | | string requestParam = new CreateTaskDto() |
| | | { |
| | | WarehouseId = position.WarehouseId, |
| | | TargetAddress = childDeviceCode |
| | | }.Serialize()); |
| | | }.Serialize(); |
| | | DateTime startTime = DateTime.Now; |
| | | |
| | | var responseResult = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam); |
| | | |
| | | _lastPalletCheckTime[childDeviceCode] = DateTime.Now; |
| | | |
| | | // 如果请求成功,接收 WMS 返回的任务 |
| | | if (responseResult.IsSuccess && responseResult.Data.Status) |
| | | { |
| | | QuartzLogHelper.LogInfo(_logger, $"调用WMS接口成功,接口:【{configKey}】,请求参数:【{requestParam}】,响应数据:【{responseResult.Data?.Data}】,耗时:{(DateTime.Now - startTime).TotalMilliseconds}ms", conveyorLine.DeviceCode); |
| | | var wmsTask = JsonConvert.DeserializeObject<WMSTaskDTO>(responseResult.Data.Data.ToString()); |
| | | List<WMSTaskDTO> taskDTOs = new List<WMSTaskDTO> { wmsTask }; |
| | | if (wmsTask != null) |
| | | _taskService.ReceiveWMSTask(taskDTOs); |
| | | } |
| | | else |
| | | { |
| | | QuartzLogHelper.LogError(_logger, $"调用WMS接口失败,接口:【{configKey}】,请求参数:【{requestParam}】,错误信息:【{responseResult.Data?.Message}】", conveyorLine.DeviceCode); |
| | | } |
| | | } |
| | | } |
| | |
| | | var task = _taskService.QueryManualInboundTask(childDeviceCode); |
| | | if (task != null) |
| | | { |
| | | var handler = new ManualInboundTaskHandler(_taskService); |
| | | QuartzLogHelper.LogInfo(_logger, $"获取到输送线开始任务,任务号:{task.TaskNum},状态: {task.TaskStatus},当前地址:{conveyorLine.DeviceCode}", conveyorLine.DeviceCode); |
| | | var handler = new ManualInboundTaskHandler(_taskService, _logger); |
| | | handler.WriteTaskToPlc(conveyorLine, childDeviceCode, task); |
| | | } |
| | | } |
| | |
| | | Dt_Task task = _taskService.QueryExecutingConveyorLineTask(command.TaskNo, childDeviceCode); |
| | | if (!task.IsNullOrEmpty()) |
| | | { |
| | | QuartzLogHelper.LogInfo(_logger, "Execute:子设备 {ChildDeviceCode} 处理任务 {TaskNum},状态: {Status}", $"处理任务 {task.TaskNum},状态: {task.TaskStatus}", conveyorLine.DeviceCode, childDeviceCode, task.TaskNum, task.TaskStatus); |
| | | QuartzLogHelper.LogInfo(_logger, $"处理任务 {task.TaskNum},状态: {task.TaskStatus}", conveyorLine.DeviceCode); |
| | | // 处理任务状态(根据状态分发到不同方法) |
| | | ProcessTaskState(conveyorLine, command, task, childDeviceCode); |
| | | return Task.CompletedTask; |
| | | continue; |
| | | } |
| | | else if (command.TaskNo == 1 && !command.Barcode.IsNullOrEmpty() && childDeviceCode == "11068") |
| | | // Todo: 下面的逻辑主要处理没有查询到任务但有条码的情况,可能是需要生成机械手任务或者调用 WMS 创建入库任务 (临时使用) |
| | | else if (!command.Barcode.IsNullOrEmpty() && childDeviceCode == "11068") |
| | | { |
| | | if (_robotTaskService.Db.Queryable<Dt_RobotTask>().Any(x => x.RobotTargetAddressPalletCode == command.Barcode)) |
| | | var isWcsTask = _taskService.Db.Queryable<Dt_Task>().Any(x => x.PalletCode == command.Barcode && (x.TaskStatus == (int)TaskOutStatusEnum.OutNew || x.TaskStatus == (int)TaskInStatusEnum.InNew)); |
| | | var isRobotTask = _robotTaskService.Db.Queryable<Dt_RobotTask>().Any(x => x.RobotTargetAddressPalletCode == command.Barcode || x.RobotRoadway == "注液组盘机械手"); |
| | | if (isWcsTask || isRobotTask) |
| | | { |
| | | return Task.CompletedTask; |
| | | continue; |
| | | } |
| | | |
| | | Random rnd = new Random(); |
| | | int num = rnd.StrictNext();//产生真随机数 |
| | | // 没有任务号但有条码并且在11068位置,直接添加机械手组盘任务 |
| | | // 直接添加机械手组盘任务 |
| | | Dt_RobotTask robotTask = new Dt_RobotTask |
| | | { |
| | | RobotTargetAddressPalletCode = command.Barcode, |
| | |
| | | RobotGrade = 1, |
| | | RobotRoadway = "注液组盘机械手", |
| | | RobotTargetAddressLineCode = childDeviceCode, |
| | | RobotTaskNum = num, // 生成任务号 |
| | | RobotTaskNum = Random.Shared.StrictNext(), // 生成任务号 |
| | | RobotDispatchertime = DateTime.Now, |
| | | }; |
| | | if (_robotTaskService.AddData(robotTask).Status) |
| | | { |
| | | QuartzLogHelper.LogInfo(_logger, $"生产机械手任务成功, {robotTask.RobotTaskNum},状态: {robotTask.RobotTaskState},当前地址:{conveyorLine.DeviceCode}", conveyorLine.DeviceCode); |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode); |
| | | } |
| | | } |
| | | else if (!command.Barcode.IsNullOrEmpty() && (childDeviceCode == "11001" || childDeviceCode == "11010")) |
| | | { |
| | | var isWcsTask = _taskService.Db.Queryable<Dt_Task>().Any(x => x.PalletCode == command.Barcode && (x.TaskStatus == (int)TaskOutStatusEnum.OutNew || x.TaskStatus == (int)TaskInStatusEnum.InNew)); |
| | | var isRobotTask = _robotTaskService.Db.Queryable<Dt_RobotTask>().Any(x => x.RobotTargetAddressPalletCode == command.Barcode); |
| | | if (isWcsTask || isRobotTask) |
| | | { |
| | | continue; |
| | | } |
| | | |
| | | // 调用 WMS 创建空托盘入库任务 |
| | | string configKey = nameof(ConfigKey.CreateTaskInboundAsync); |
| | | string requestParam = new CreateTaskDto() |
| | | { |
| | | PalletCode = command.Barcode, |
| | | SourceAddress = childDeviceCode, |
| | | TargetAddress = "GWSC1", // 目标地址 |
| | | Roadway = "GWSC1", // 巷道 |
| | | WarehouseId = 1, // 仓库 ID |
| | | PalletType = 1, // 托盘类型(默认为1) |
| | | TaskType = TaskTypeEnum.InEmpty.GetHashCode() // 任务类型(入库/空托盘入库) |
| | | }.Serialize(); |
| | | DateTime startTime = DateTime.Now; |
| | | |
| | | var responseResult = _httpClientHelper.Post<WebResponseContent>(configKey, requestParam); |
| | | |
| | | if (responseResult.IsSuccess && responseResult.Data.Status) |
| | | { |
| | | QuartzLogHelper.LogInfo(_logger, $"调用WMS接口成功,接口:【{configKey}】,请求参数:【{requestParam}】,响应数据:【{responseResult.Data?.Data}】,耗时:{(DateTime.Now - startTime).TotalMilliseconds}ms", conveyorLine.DeviceCode); |
| | | var wmsTask = JsonConvert.DeserializeObject<WMSTaskDTO>(responseResult?.Data?.Data?.ToString()); |
| | | List<WMSTaskDTO> taskDTOs = new List<WMSTaskDTO> { wmsTask }; |
| | | if (wmsTask == null) continue; |
| | | |
| | | if (_taskService.ReceiveWMSTask(taskDTOs).Status) |
| | | { |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | QuartzLogHelper.LogError(_logger, $"调用WMS接口失败,接口:【{configKey}】,请求参数:【{requestParam}】,错误信息:【{responseResult.Data?.Message}】", conveyorLine.DeviceCode); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | catch (Exception innerEx) |