| | |
| | | using Microsoft.Extensions.Logging; |
| | | using Quartz; |
| | | using System; |
| | | using System.Diagnostics.CodeAnalysis; |
| | | using System.IO; |
| | | using System.Threading.Tasks; |
| | | using WIDESEAWCS_Common.TaskEnum; |
| | | using WIDESEA_Core; |
| | | using WIDESEAWCS_Core; |
| | | using WIDESEAWCS_Core.LogHelper; |
| | | using WIDESEAWCS_ITaskInfoRepository; |
| | | using WIDESEAWCS_ITaskInfoService; |
| | | using WIDESEAWCS_Model.Models; |
| | | using WIDESEAWCS_QuartzJob; |
| | | using WIDESEAWCS_QuartzJob.StackerCrane; |
| | | using WIDESEAWCS_Tasks.StackerCraneJob; |
| | | using WIDESEA_Core; |
| | | using WIDESEAWCS_QuartzJob.Service; |
| | | using WIDESEAWCS_QuartzJob.StackerCrane; |
| | | using WIDESEAWCS_QuartzJob.StackerCrane.Enum; |
| | | using WIDESEAWCS_Common.Constants; |
| | | using WIDESEAWCS_Tasks.StackerCraneJob; |
| | | |
| | | namespace WIDESEAWCS_Tasks |
| | | { |
| | |
| | | private readonly StackerCraneCommandBuilder _commandBuilder; |
| | | |
| | | /// <summary> |
| | | /// 日志记录器 |
| | | /// </summary> |
| | | private readonly ILogger<CommonStackerCraneJob> _logger; |
| | | |
| | | /// <summary> |
| | | /// 堆垛机设备编码 |
| | | /// </summary> |
| | | private string _deviceCode = string.Empty; |
| | | |
| | | /// <summary> |
| | | /// 构造函数 |
| | | /// </summary> |
| | | /// <param name="taskService">任务服务</param> |
| | |
| | | /// <param name="taskRepository">任务仓储</param> |
| | | /// <param name="routerService">路由服务</param> |
| | | /// <param name="httpClientHelper">HTTP 客户端帮助类</param> |
| | | /// <param name="logger">日志记录器</param> |
| | | public CommonStackerCraneJob( |
| | | ITaskService taskService, |
| | | ITaskExecuteDetailService taskExecuteDetailService, |
| | | ITaskRepository taskRepository, |
| | | IRouterService routerService, |
| | | HttpClientHelper httpClientHelper) |
| | | HttpClientHelper httpClientHelper, |
| | | ILogger<CommonStackerCraneJob> logger) |
| | | { |
| | | _taskService = taskService; |
| | | _taskExecuteDetailService = taskExecuteDetailService; |
| | | _taskRepository = taskRepository; |
| | | _logger = logger; |
| | | |
| | | // 加载配置文件 |
| | | _config = LoadConfig(); |
| | | |
| | | // 初始化任务选择器 |
| | | _taskSelector = new StackerCraneTaskSelector(taskService, routerService, httpClientHelper); |
| | | _taskSelector = new StackerCraneTaskSelector(taskService, routerService, httpClientHelper, _logger); |
| | | |
| | | // 初始化命令构建器 |
| | | _commandBuilder = new StackerCraneCommandBuilder(taskService, routerService, _config); |
| | | _commandBuilder = new StackerCraneCommandBuilder(taskService, routerService, _config, _logger); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | { |
| | | // 从 JobDataMap 获取堆垛机设备参数 |
| | | bool flag = context.JobDetail.JobDataMap.TryGetValue("JobParams", out object? value); |
| | | if (!flag || value is not IStackerCrane commonStackerCrane) |
| | | if (!flag || value is not CommonStackerCrane commonStackerCrane) |
| | | { |
| | | // 参数无效,直接返回 |
| | | _logger.LogWarning("Execute:参数无效"); |
| | | QuartzLogger.Warn("Execute:参数无效", "CommonStackerCraneJob"); |
| | | return Task.CompletedTask; |
| | | } |
| | | |
| | | _deviceCode = commonStackerCrane.DeviceCode; |
| | | |
| | | // ========== 订阅任务完成事件(全局只订阅一次) ========== |
| | | if (!commonStackerCrane.IsEventSubscribed) |
| | | { |
| | | // 绑定任务完成事件处理方法 |
| | | commonStackerCrane.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler; |
| | | _logger.LogInformation("Execute:订阅任务完成事件,设备: {DeviceCode}", _deviceCode); |
| | | QuartzLogger.Info($"订阅任务完成事件", _deviceCode); |
| | | } |
| | | |
| | | // ========== 检查堆垛机任务完成状态 ========== |
| | | commonStackerCrane.CheckStackerCraneTaskCompleted(); |
| | | //_logger.LogDebug("Execute:检查任务完成状态,设备: {DeviceCode}", _deviceCode); |
| | | //QuartzLogger.Debug($"检查任务完成状态,设备: {_deviceCode}", _deviceCode); |
| | | |
| | | // ========== 检查是否可以发送新任务 ========== |
| | | if (!commonStackerCrane.IsCanSendTask(commonStackerCrane.Communicator, commonStackerCrane.DeviceProDTOs, commonStackerCrane.DeviceProtocolDetailDTOs)) |
| | | //if (!commonStackerCrane.IsCanSendTask(commonStackerCrane.Communicator, commonStackerCrane.DeviceProDTOs, commonStackerCrane.DeviceProtocolDetailDTOs)) |
| | | if (commonStackerCrane.StackerCraneStatusValue != StackerCraneStatus.Normal) |
| | | { |
| | | // 堆垛机不可用(如正在执行上一任务),直接返回 |
| | | _logger.LogDebug("Execute:堆垛机不可用,设备: {DeviceCode}", _deviceCode); |
| | | QuartzLogger.Debug($"堆垛机不可用,设备: {_deviceCode}", _deviceCode); |
| | | return Task.CompletedTask; |
| | | } |
| | | |
| | |
| | | if (task == null) |
| | | { |
| | | // 没有可用任务 |
| | | //_logger.LogDebug("Execute:没有可用任务,设备: {DeviceCode}", _deviceCode); |
| | | //QuartzLogger.Debug($"没有可用任务,设备: {_deviceCode}", _deviceCode); |
| | | return Task.CompletedTask; |
| | | } |
| | | |
| | | //_logger.LogInformation("Execute:选择任务,设备: {DeviceCode},任务号: {TaskNum}", _deviceCode, task.TaskNum); |
| | | //QuartzLogger.Info($"选择任务,任务号: {task.TaskNum}", _deviceCode); |
| | | |
| | | // ========== 构建命令 ========== |
| | | // 命令构建下沉到专用构建器 |
| | |
| | | if (stackerCraneTaskCommand == null) |
| | | { |
| | | // 命令构建失败 |
| | | _logger.LogWarning("Execute:命令构建失败,设备: {DeviceCode},任务号: {TaskNum}", _deviceCode, task.TaskNum); |
| | | QuartzLogger.Warn($"命令构建失败,任务号: {task.TaskNum}", _deviceCode); |
| | | return Task.CompletedTask; |
| | | } |
| | | |
| | |
| | | bool sendFlag = SendStackerCraneCommand(commonStackerCrane, stackerCraneTaskCommand); |
| | | if (sendFlag) |
| | | { |
| | | Task.Delay(1000).Wait(); |
| | | commonStackerCrane.SetValue(StackerCraneDBName.WorkAction, (short)StackerCraneWorkActionEnum.StartTask); |
| | | // 发送成功,更新状态 |
| | | commonStackerCrane.LastTaskType = task.TaskType; |
| | | _taskService.UpdateTaskStatusToNext(task.TaskNum); |
| | | |
| | | _logger.LogInformation("Execute:命令发送成功,设备: {DeviceCode},任务号: {TaskNum}", _deviceCode, task.TaskNum); |
| | | QuartzLogger.Info($"命令发送成功,任务号: {task.TaskNum}", _deviceCode); |
| | | } |
| | | else |
| | | { |
| | | _logger.LogError("Execute:命令发送失败,设备: {DeviceCode},任务号: {TaskNum}", _deviceCode, task.TaskNum); |
| | | QuartzLogger.Error($"命令发送失败", _deviceCode); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | // 记录异常 |
| | | Console.WriteLine($"CommonStackerCraneJob Error: {ex.Message}"); |
| | | _logger.LogError(ex, "Execute:执行异常,设备: {DeviceCode}", _deviceCode); |
| | | QuartzLogger.Error($"执行异常: {ex.Message}", _deviceCode, ex); |
| | | } |
| | | |
| | | return Task.CompletedTask; |
| | |
| | | if (stackerCrane != null) |
| | | { |
| | | // 记录日志 |
| | | Console.Out.WriteLine("TaskCompleted" + e.TaskNum); |
| | | _logger.LogInformation("CommonStackerCrane_StackerCraneTaskCompletedEventHandler:任务完成,任务号: {TaskNum}", e.TaskNum); |
| | | QuartzLogger.Info($"任务完成,任务号: {e.TaskNum}", stackerCrane.DeviceCode); |
| | | |
| | | // 更新任务状态为完成 |
| | | _taskService.StackCraneTaskCompleted(e.TaskNum); |
| | | |
| | | // 清除堆垛机的作业指令(设置为 2,表示空闲) |
| | | stackerCrane.SetValue(StackerCraneDBName.WorkAction, 2); |
| | | if (_taskService.StackCraneTaskCompleted(e.TaskNum).Status) |
| | | { |
| | | // 清除堆垛机的作业指令(设置为空闲) |
| | | stackerCrane.SetValue(StackerCraneDBName.WorkAction, (short)StackerCraneWorkActionEnum.TaskComplete); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | }; |
| | | } |
| | | } |
| | | } |
| | | } |