编辑 | blame | 历史 | 原始文档

堆垛机 TargetAddress 输送线站台空闲检查 实施计划

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal:StackerCraneTaskSelector.TrySelectOutboundTask 中新增 TargetAddress 输送线站台空闲检查(CV_State == 2 表示空闲),不可用则返回 null。

Architecture:StackerCraneTaskSelector 类中新增 IsTargetAddressConveyorStationAvailable 私有方法,通过 _routerService.QueryNextRoute 获取路由信息,从 Storage.Devices 找到输送线设备,调用 GetValue<ConveyorLineStatus, byte> 读取 CV_State 判断是否空闲。

Tech Stack: C# / .NET 6+,SqlSugar ORM,Serilog


涉及文件

  • 修改: WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs

Task 1: 新增 IsTargetAddressConveyorStationAvailable 方法

Files:
- Modify: WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs

  • [ ] Step 1: 确认现有 using 命名空间

打开 StackerCraneTaskSelector.cs,检查是否已包含以下 using:
- WIDESEAWCS_QuartzJob.ConveyorLine.Enum.ConveyorLineStatus
- WIDESEAWCS_Model.Models.Dt_Router

如缺少,添加:
csharp using WIDESEAWCS_QuartzJob.ConveyorLine.Enum; using WIDESEAWCS_Model.Models;

  • [ ] Step 2: 在类末尾(IsOutTaskStationAvailable 方法之后,} 之前)新增方法
/// <summary>
/// 判断 TargetAddress 输送线站台是否空闲
/// </summary>
/// <param name="task">出库任务</param>
/// <returns>站台空闲(CV_State == 2)返回 true</returns>
private bool IsTargetAddressConveyorStationAvailable([NotNull] Dt_Task task)
{
    // 确定任务类型
    int taskType = task.TaskType == (int)TaskOutboundTypeEnum.OutEmpty
        ? StackerCraneConst.EmptyPalletTaskType
        : task.TaskType;

    // 通过路由查找 TargetAddress 对应的设备信息
    Dt_Router? router = _routerService.QueryNextRoute(task.Roadway, task.TargetAddress, taskType);
    if (router == null)
    {
        QuartzLogHelper.LogWarn(_logger, "IsTargetAddressConveyorStationAvailable:未找到 TargetAddress 路由信息,TargetAddress: {TargetAddress},任务号: {TaskNum}",
            $"IsTargetAddressConveyorStationAvailable:未找到 TargetAddress 路由信息,TargetAddress: {task.TargetAddress}", task.Roadway, task.TargetAddress, task.TaskNum);
        return false;
    }

    // 查找输送线设备
    IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == router.ChildPosiDeviceCode);
    if (device == null)
    {
        QuartzLogHelper.LogWarn(_logger, "IsTargetAddressConveyorStationAvailable:未找到输送线设备,ChildPosiDeviceCode: {ChildPosiDeviceCode},任务号: {TaskNum}",
            $"IsTargetAddressConveyorStationAvailable:未找到输送线设备,ChildPosiDeviceCode: {router.ChildPosiDeviceCode}", task.Roadway, router.ChildPosiDeviceCode, task.TaskNum);
        return false;
    }

    // 转换为输送线设备
    CommonConveyorLine conveyorLine = (CommonConveyorLine)device;

    // 读取 CV_State,CV_State == 2 表示空闲
    byte cvState = conveyorLine.GetValue<ConveyorLineStatus, byte>(ConveyorLineStatus.CV_State, task.TargetAddress);
    bool isAvailable = cvState == 2;
    QuartzLogHelper.LogInfo(_logger, "IsTargetAddressConveyorStationAvailable:TargetAddress: {TargetAddress},CV_State: {CV_State},是否空闲: {IsAvailable},任务号: {TaskNum}",
        $"IsTargetAddressConveyorStationAvailable:TargetAddress: {task.TargetAddress},CV_State: {cvState},是否空闲: {isAvailable}", task.Roadway, task.TargetAddress, cvState, isAvailable, task.TaskNum);

    return isAvailable;
}
  • [ ] Step 3: Commit
git add WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs
git commit -m "feat(StackerCraneTaskSelector): 新增 TargetAddress 输送线站台空闲检查方法

IsTargetAddressConveyorStationAvailable 通过路由查找输送线设备,读取 CV_State 判断是否空闲(CV_State == 2)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>"

Task 2: 在 TrySelectOutboundTask 中调用新方法

Files:
- Modify: WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs

  • [ ] Step 1: 找到 TrySelectOutboundTask 方法中的 return 语句

当前方法末尾(line ~210):
csharp return IsOutTaskStationAvailable(taskAfterTransferCheck) ? taskAfterTransferCheck : null;

  • [ ] Step 2: 在 return 语句之前插入 TargetAddress 检查逻辑

return IsOutTaskStationAvailable(...) 之前插入:
csharp // 判断 TargetAddress 输送线站台是否空闲 if (!IsTargetAddressConveyorStationAvailable(taskAfterTransferCheck)) { return null; }

修改后:
```csharp
// 判断 TargetAddress 输送线站台是否空闲
if (!IsTargetAddressConveyorStationAvailable(taskAfterTransferCheck))
{
return null;
}

// 判断出库站台是否可用
return IsOutTaskStationAvailable(taskAfterTransferCheck) ? taskAfterTransferCheck : null;
```

  • [ ] Step 3: 验证修改位置正确

确认修改后的 TrySelectOutboundTask 方法末尾逻辑为:
```csharp
// 判断 TargetAddress 输送线站台是否空闲
if (!IsTargetAddressConveyorStationAvailable(taskAfterTransferCheck))
{
return null;
}

// 判断出库站台是否可用
return IsOutTaskStationAvailable(taskAfterTransferCheck) ? taskAfterTransferCheck : null;
```

  • [ ] Step 4: Commit
git add WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs
git commit -m "feat(StackerCraneTaskSelector): 在 TrySelectOutboundTask 中调用 TargetAddress 站台空闲检查

检查顺序:先检查 NextAddress 出库站台,再检查 TargetAddress 输送线站台
若 TargetAddress 站台不空闲(CV_State != 2),任务不可选

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>"

Task 3: 验证构建

  • [ ] Step 1: 执行构建验证
cd D:/Git/ShanMeiXinNengYuan/Code
dotnet build WCS/WIDESEAWCS_Server/WIDESEAWCS_Server.sln

预期:无编译错误

  • [ ] Step 2: 如有错误,分析并修复

常见错误:
- 缺少 using → 添加命名空间
- 类型转换异常 → 确认设备类型为 CommonConveyorLine
- 方法未找到 → 确认方法签名正确


验证清单

  • [ ] IsTargetAddressConveyorStationAvailable 方法已添加在 IsOutTaskStationAvailable 方法之后
  • [ ] TrySelectOutboundTask 方法在判断 IsOutTaskStationAvailable 之前,先判断 IsTargetAddressConveyorStationAvailable
  • [ ] 新增方法包含完整的日志记录(Warn 和 Info)
  • [ ] CV_State == 2 作为空闲判断条件
  • [ ] task.TargetAddress 直接作为 GetValue 的设备子编号
  • [ ] 构建通过,无编译错误
  • [ ] 已提交两个 commit(方法新增 + 调用点)