| | |
| | | using MapsterMapper; |
| | | using Microsoft.Extensions.Logging; |
| | | using Serilog; |
| | | using System.Threading.Tasks; |
| | | using WIDESEAWCS_Common.TaskEnum; |
| | | using WIDESEAWCS_Core; |
| | | using WIDESEAWCS_Core.Helper; |
| | | using WIDESEAWCS_Core.LogHelper; |
| | | using WIDESEAWCS_ITaskInfoService; |
| | | using WIDESEAWCS_Model.Models; |
| | | using WIDESEAWCS_QuartzJob; |
| | | using WIDESEAWCS_QuartzJob.Models; |
| | | using WIDESEAWCS_QuartzJob.Service; |
| | | |
| | | namespace WIDESEAWCS_Tasks |
| | |
| | | { |
| | | // 清除任务号,表示当前空闲 |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.TaskNo, 0, childDeviceCode); |
| | | _logger.LogDebug("HeartBeat:子设备 {ChildDeviceCode} 心跳", childDeviceCode); |
| | | QuartzLogger.Debug($"HeartBeat:子设备 {childDeviceCode} 心跳", conveyorLine.DeviceCode); |
| | | QuartzLogHelper.LogDebug(_logger, $"HeartBeat:子设备 {childDeviceCode} 心跳", conveyorLine.DeviceCode); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// <param name="childDeviceCode">子设备编码</param> |
| | | public void RequestInbound(CommonConveyorLine conveyorLine, ConveyorLineTaskCommandNew command, string childDeviceCode) |
| | | { |
| | | _logger.LogInformation("RequestInbound:子设备 {ChildDeviceCode} 请求入库", childDeviceCode); |
| | | QuartzLogger.Info($"请求入库,子设备: {childDeviceCode}", conveyorLine.DeviceCode); |
| | | QuartzLogHelper.LogInfo(_logger, $"请求入库,子设备: {childDeviceCode}", conveyorLine.DeviceCode); |
| | | |
| | | // 向 WMS 请求新任务(基于条码) |
| | | if (_taskFilter.RequestWmsTask(command.Barcode, childDeviceCode)) |
| | |
| | | // 更新任务状态到下一阶段 |
| | | _taskService.UpdateTaskStatusToNext(task); |
| | | |
| | | _logger.LogInformation("RequestInbound:入库任务已下发,任务号: {TaskNum},子设备: {ChildDeviceCode}", task.TaskNum, childDeviceCode); |
| | | QuartzLogger.Info($"入库任务已下发,任务号: {task.TaskNum},子设备: {childDeviceCode}", conveyorLine.DeviceCode); |
| | | QuartzLogHelper.LogInfo(_logger, $"入库任务已下发,任务号: {task.TaskNum},子设备: {childDeviceCode}", conveyorLine.DeviceCode); |
| | | } |
| | | } |
| | | } |
| | |
| | | Dt_Task? task = _taskFilter.QueryExecutingTask(command.TaskNo, childDeviceCode); |
| | | if (task == null) |
| | | { |
| | | _logger.LogDebug("RequestInNextAddress:任务 {TaskNo} 不存在", command.TaskNo); |
| | | QuartzLogger.Debug($"RequestInNextAddress:任务 {command.TaskNo} 不存在", conveyorLine.DeviceCode); |
| | | QuartzLogHelper.LogDebug(_logger, $"RequestInNextAddress:任务 {command.TaskNo} 不存在", conveyorLine.DeviceCode); |
| | | return; |
| | | } |
| | | |
| | | _logger.LogInformation("RequestInNextAddress:入库下一地址,任务号: {TaskNum},子设备: {ChildDeviceCode}", task.TaskNum, childDeviceCode); |
| | | QuartzLogger.Info($"RequestInNextAddress:入库下一地址,任务号: {task.TaskNum},子设备: {childDeviceCode}", conveyorLine.DeviceCode); |
| | | QuartzLogHelper.LogInfo(_logger, $"RequestInNextAddress:入库下一地址,任务号: {task.TaskNum},子设备: {childDeviceCode}", conveyorLine.DeviceCode); |
| | | |
| | | // 如果不是空托盘任务,处理目标地址(与拘束机/插拔钉机交互) |
| | | if (task.TaskType != (int)TaskOutboundTypeEnum.OutEmpty) |
| | | bool isEmptyTask = task.TaskType == (int)TaskOutboundTypeEnum.OutEmpty; |
| | | |
| | | // 确定目标地址 |
| | | string targetAddress; |
| | | if (isEmptyTask) |
| | | { |
| | | _targetAddressSelector.HandleInboundNextAddress(conveyorLine, task.NextAddress, childDeviceCode); |
| | | targetAddress = "2125"; |
| | | QuartzLogHelper.LogDebug(_logger, $"子设备: {childDeviceCode},入库下一目标地址: {2125}", conveyorLine.DeviceCode); |
| | | } |
| | | else |
| | | { |
| | | Dt_Router routers = _routerService.QueryNextRoute(task.NextAddress, task.TargetAddress); |
| | | if (routers == null) throw new Exception($"未找到设备路由信息"); |
| | | targetAddress = routers.ChildPosi; |
| | | } |
| | | |
| | | // 更新任务当前位置 |
| | | _ = _taskService.UpdatePosition(task.TaskNum, task.CurrentAddress); |
| | | // 处理目标地址:ChildPosi == "2125" 时跳过 HandleInboundNextAddress |
| | | if (targetAddress == "2125") |
| | | { |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.Target, "2125", childDeviceCode); |
| | | } |
| | | else if (!_targetAddressSelector.HandleInboundNextAddress(conveyorLine, targetAddress, childDeviceCode)) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | // 设置 WCS_STB 标志,表示 WCS 已处理 |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_STB, 1, childDeviceCode); |
| | | // 更新任务当前位置和 WCS_ACK |
| | | if (isEmptyTask) |
| | | { |
| | | _ = _taskService.UpdatePosition(task.TaskNum, task.CurrentAddress, "2125"); |
| | | } |
| | | else |
| | | { |
| | | _ = _taskService.UpdatePosition(task.TaskNum, task.CurrentAddress); |
| | | } |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | Dt_Task? task = _taskFilter.QueryExecutingTask(command.TaskNo, childDeviceCode); |
| | | if (task != null) |
| | | { |
| | | // 回复 ACK 确认 |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 1, childDeviceCode); |
| | | |
| | | // 更新任务状态到下一阶段(通常是完成) |
| | | WebResponseContent content = _taskService.UpdateTaskStatusToNext(task); |
| | | |
| | | _logger.LogInformation("ConveyorLineInFinish:入库完成,任务号: {TaskNum},子设备: {ChildDeviceCode}", task.TaskNum, childDeviceCode); |
| | | QuartzLogger.Info($"入库完成,任务号: {task.TaskNum}", conveyorLine.DeviceCode); |
| | | if (_taskService.UpdateTaskStatusToNext(task).Status) |
| | | { |
| | | // 回复 ACK 确认 |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode); |
| | | QuartzLogHelper.LogInfo(_logger, $"入库完成,任务号: {task.TaskNum},子设备:{childDeviceCode}", conveyorLine.DeviceCode); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | /// <param name="conveyorLine">输送线设备对象</param> |
| | | /// <param name="command">PLC 命令数据</param> |
| | | /// <param name="childDeviceCode">子设备编码</param> |
| | | public void RequestOutbound(CommonConveyorLine conveyorLine, ConveyorLineTaskCommandNew command, string childDeviceCode) |
| | | public Task RequestOutbound(CommonConveyorLine conveyorLine, ConveyorLineTaskCommandNew command, string childDeviceCode) |
| | | { |
| | | // 查询待处理任务 |
| | | Dt_Task? task = _taskFilter.QueryPendingTask(conveyorLine.DeviceCode, childDeviceCode); |
| | | if (task != null) |
| | | if (task == null) return Task.CompletedTask; |
| | | |
| | | // 确定目标地址:空托盘任务使用 "2201",其他任务使用 NextAddress |
| | | var isEmptyTask = task.TaskType == (int)TaskOutboundTypeEnum.OutEmpty; |
| | | var targetAddress = task.CurrentAddress == "2217" ? (isEmptyTask ? "2201" : task.NextAddress) : task.NextAddress; |
| | | |
| | | // 处理特殊地址 2217,需要调用目标地址选择器 |
| | | if (task.CurrentAddress == "2217" && !_targetAddressSelector.HandleOutboundNextAddress(conveyorLine, targetAddress, childDeviceCode)) |
| | | { |
| | | // 设置任务号 |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.TaskNo, task.TaskNum, childDeviceCode); |
| | | |
| | | // 设置托盘条码 |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.Barcode, task.PalletCode, childDeviceCode); |
| | | |
| | | // 设置目标地址 |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.Target, task.NextAddress, childDeviceCode); |
| | | |
| | | // 回复 ACK 确认 |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 1, childDeviceCode); |
| | | |
| | | // 更新任务状态 |
| | | _taskService.UpdateTaskStatusToNext(task); |
| | | |
| | | _logger.LogInformation("RequestOutbound:出库任务已下发,任务号: {TaskNum},子设备: {ChildDeviceCode}", task.TaskNum, childDeviceCode); |
| | | QuartzLogger.Info($"出库任务已下发,任务号: {task.TaskNum}", conveyorLine.DeviceCode); |
| | | return Task.CompletedTask; ; |
| | | } |
| | | |
| | | // 设置任务号、托盘条码、目标地址、WCS_ACK |
| | | var isTaskNoSet = conveyorLine.SetValue(ConveyorLineDBNameNew.TaskNo, task.TaskNum, childDeviceCode); |
| | | |
| | | Thread.Sleep(100); // 确保 PLC 能正确读取任务号后再写入条码 |
| | | var isPalletSet = conveyorLine.SetValue(ConveyorLineDBNameNew.Barcode, task.PalletCode, childDeviceCode); |
| | | |
| | | bool isTargetSet = true; |
| | | if (targetAddress == "2217" && !isEmptyTask) |
| | | { |
| | | QuartzLogHelper.LogDebug(_logger, $"子设备: {childDeviceCode},出库目标地址: {targetAddress}", conveyorLine.DeviceCode); |
| | | Thread.Sleep(100); // 确保 PLC 能正确读取任务号后再写入条码 |
| | | isTargetSet = conveyorLine.SetValue(ConveyorLineDBNameNew.Target, targetAddress, childDeviceCode); |
| | | } |
| | | if (!isTargetSet || !isTaskNoSet || !isPalletSet) |
| | | { |
| | | QuartzLogHelper.LogError(_logger, $"RequestOutbound:下发出库任务失败,任务号: {task.TaskNum},子设备: {childDeviceCode}", conveyorLine.DeviceCode); |
| | | return Task.CompletedTask; |
| | | } |
| | | |
| | | bool isWmsResult = false; |
| | | // 更新任务状态或位置 |
| | | if (isEmptyTask && task.NextAddress == "2217") |
| | | { |
| | | task.TaskStatus = task.TaskStatus.GetNextNotCompletedStatus<TaskOutStatusEnum>(); |
| | | task.NextAddress = "2201"; |
| | | isWmsResult = _taskService.Repository.UpdateData(task); |
| | | } |
| | | else |
| | | { |
| | | isWmsResult = _taskService.UpdateTaskStatusToNext(task).Status; |
| | | } |
| | | |
| | | if(!isWmsResult) |
| | | { |
| | | QuartzLogHelper.LogError(_logger, $"RequestOutbound:更新任务状态失败,任务号: {task.TaskNum},子设备: {childDeviceCode}", conveyorLine.DeviceCode); |
| | | return Task.CompletedTask; |
| | | } |
| | | |
| | | Thread.Sleep(100); // 确保 PLC 能正确读取任务号后再写入条码 |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode); |
| | | |
| | | QuartzLogHelper.LogInfo(_logger, "RequestOutbound:出库任务已下发,任务号: {TaskNum},子设备: {ChildDeviceCode}", $"出库任务已下发,任务号: {task.TaskNum}", conveyorLine.DeviceCode, task.TaskNum, childDeviceCode); |
| | | return Task.CompletedTask; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// </summary> |
| | | /// <remarks> |
| | | /// 当出库任务执行到某个中间站点时调用。 |
| | | /// 根据下一地址判断是否需要与拘束机/插拔钉机等设备交互。 |
| | | /// </remarks> |
| | | /// <param name="conveyorLine">输送线设备对象</param> |
| | | /// <param name="command">PLC 命令数据</param> |
| | |
| | | Dt_Task? task = _taskFilter.QueryExecutingTask(command.TaskNo, childDeviceCode); |
| | | if (task == null) |
| | | { |
| | | _logger.LogDebug("RequestOutNextAddress:任务 {TaskNo} 不存在", command.TaskNo); |
| | | QuartzLogger.Debug($"RequestOutNextAddress:任务 {command.TaskNo} 不存在", conveyorLine.DeviceCode); |
| | | QuartzLogHelper.LogDebug(_logger, $"RequestOutNextAddress:任务 {command.TaskNo} 不存在", conveyorLine.DeviceCode); |
| | | return; |
| | | } |
| | | |
| | | _logger.LogInformation("RequestOutNextAddress:出库下一地址,任务号: {TaskNum},子设备: {ChildDeviceCode}", task.TaskNum, childDeviceCode); |
| | | QuartzLogger.Info($"RequestOutNextAddress:出库下一地址,任务号: {task.TaskNum},子设备: {childDeviceCode}", conveyorLine.DeviceCode); |
| | | QuartzLogHelper.LogInfo(_logger, $"RequestOutNextAddress:出库下一地址,任务号: {task.TaskNum},子设备: {childDeviceCode}", conveyorLine.DeviceCode); |
| | | |
| | | // 如果不是空托盘任务,处理目标地址 |
| | | if (task.TaskType != (int)TaskOutboundTypeEnum.OutEmpty) |
| | | { |
| | | _targetAddressSelector.HandleOutboundNextAddress(conveyorLine, task.NextAddress, childDeviceCode); |
| | | } |
| | | //if (task.TaskType != (int)TaskOutboundTypeEnum.OutEmpty) |
| | | //{ |
| | | Dt_Router routers = _routerService.QueryNextRoute(task.NextAddress, task.TargetAddress); |
| | | if (routers == null) throw new Exception($"未找到设备路由信息"); |
| | | |
| | | _targetAddressSelector.HandleOutboundNextAddress(conveyorLine, routers.ChildPosi, childDeviceCode); |
| | | //} |
| | | |
| | | // 更新任务当前位置 |
| | | _ = _taskService.UpdatePosition(task.TaskNum, task.CurrentAddress); |
| | | |
| | | // 回复 ACK 确认 |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 1, childDeviceCode); |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | // 更新任务状态到下一阶段(通常是完成) |
| | | WebResponseContent content = _taskService.UpdateTaskStatusToNext(task); |
| | | |
| | | // 回复 ACK 确认 |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, 1, childDeviceCode); |
| | | if (content.Status) |
| | | { |
| | | // 回复 ACK 确认 |
| | | conveyorLine.SetValue(ConveyorLineDBNameNew.WCS_ACK, (short)1, childDeviceCode); |
| | | } |
| | | |
| | | _logger.LogInformation("ConveyorLineOutFinish:出库完成,任务号: {TaskNum},子设备: {ChildDeviceCode}", task.TaskNum, childDeviceCode); |
| | | QuartzLogger.Info($"出库完成,任务号: {task.TaskNum}", conveyorLine.DeviceCode); |
| | | QuartzLogHelper.LogInfo(_logger, $"出库完成,完成结果:{content.Status},任务号: {task.TaskNum},错误消息:{content.Message}", conveyorLine.DeviceCode); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |