plc_control/docs/superpowers/plans/2026-03-24-control-engine.md

3.3 KiB

控制引擎实现计划

当前状态

该计划对应的核心功能已经落地,且在后续修复中做了几次重要收敛。当前代码状态以仓库实现为准,下面记录的是最新有效设计。

已完成范围

  • 已实现 ControlRuntimeStoreUnitRuntime
  • 已实现单元自动控制状态机
  • 已实现故障锁定、通信锁定、人工确认流程
  • 已实现自动控制相关 API
  • 已实现 UnitRuntimeChanged WebSocket 推送
  • 已实现前端单元运行时展示
  • 已实现手动控制前的运行时阻断校验

关键实现更新

1. 时长配置约束

控制单元时长字段现在统一要求:

  • run_time_sec > 0
  • stop_time_sec > 0
  • acc_time_sec > 0
  • bl_time_sec > 0
  • acc_time_sec > run_time_sec

这些约束已在创建和更新接口中统一校验。

2. 自动控制启动条件统一

单个启动和批量启动现在使用同一套阻断规则。以下任一条件成立时都不能启动自动控制:

  • fault_locked = true
  • comm_locked = true
  • manual_ack_required = true

3. 设备映射刷新策略已调整

最初计划里是“单元任务启动时加载一次设备映射”。这个方案已经被修正。

当前实现:

  • 控制引擎在每轮单元循环中重新读取设备和角色映射
  • 设备或点位的控制相关配置发生变化后,会主动唤醒对应单元任务
  • 因此不再依赖“等下一个 supervisor 周期重启任务”来刷新映射

这解决了运行中的单元长期使用旧 equipment.kindsignal_roleequipment_id 绑定的问题。

当前引擎行为

supervisor

  • 周期性扫描已启用单元
  • 确保每个启用单元都有对应任务在运行
  • 单元被禁用或删除后,其任务会自行退出

unit_task

每轮循环都会执行:

  1. 重读单元配置
  2. 重读设备和角色映射
  3. 检查故障与通信状态
  4. 根据 auto_enabled、锁定状态和当前状态机状态推进流程

wait_phase

  • 使用 sleep_until(deadline) 控制阶段结束时间
  • 中途通过 fault_ticknotify 打断
  • 打断后重新检查故障、通信和自动控制开关

运行时结构

当前 UnitRuntime 字段:

pub struct UnitRuntime {
    pub unit_id: Uuid,
    pub state: UnitRuntimeState,
    pub auto_enabled: bool,
    pub accumulated_run_sec: i64,
    pub display_acc_sec: i64,
    pub fault_locked: bool,
    pub flt_active: bool,
    pub comm_locked: bool,
    pub manual_ack_required: bool,
}

说明:

  • accumulated_run_secdisplay_acc_sec 单位都是毫秒
  • 运行时状态保存在内存中,不持久化

配置变更后的唤醒链路

以下操作现在都会通知相关控制单元尽快刷新配置:

  • 更新设备
  • 批量调整设备所属单元
  • 删除设备
  • 更新点位的 equipment_id / signal_role
  • 批量调整点位设备绑定
  • 删除点位

相关文件

  • src/control/runtime.rs
  • src/control/engine.rs
  • src/control/validator.rs
  • src/handler/control.rs
  • src/handler/equipment.rs
  • src/handler/point.rs
  • src/service/control.rs
  • src/event.rs
  • src/websocket.rs

验证状态

当前仓库内已补的相关测试包括:

  • 时长字段校验测试
  • comm_locked 阻止自动启动测试
  • 设备映射重载反映最新角色绑定测试

最近一次相关修改完成后,cargo testcargo check 均已通过。