plc_control/docs/投煤器布料机功能实现方案.md

15 KiB
Raw Permalink Blame History

投煤器布料机远程监控与控制功能实现方案

最后更新2026-03-24基于当前代码重新审阅

1. 目标

基于当前 plc_control 项目,扩展出面向投煤器与布料机的业务化远程监控与控制能力,满足以下目标:

  • 实时监控投煤器、布料机运行状态
  • 支持远程手动启停
  • 支持投煤器自动定时运行
  • 支持投煤累计触发布料机自动运行
  • 支持故障锁定、人工复位、通讯异常冻结
  • 支持通过配置适配不同现场,不改代码完成项目复用

2. 当前系统能力盘点

2.1 通用平台基础(已有)

  • OPC UA 数据源接入与自动重连(connection.rs
  • 节点浏览、批量建点、点位实时订阅(handler/point.rs, handler/source.rs
  • 点位批量写入能力(connection.rs: write_point_values_batch
  • WebSocket 实时推送(websocket.rs
  • 前端设备、点位、日志、趋势图基础界面
  • 页面配置 page 能力
  • 进程内事件总线 event.rscontrol + telemetry 双通道)
  • HTTP 中间件、鉴权、分页等工具链

2.2 业务模型(已有)

  • unit 表(migrations/20260324090000_add_unit_and_event.sql
    • 包含 run_time_sec, stop_time_sec, acc_time_sec, bl_time_sec, require_manual_ack_after_fault
  • event 表(同上迁移),含 unit_id, equipment_id, source_id, level, payload
  • equipment.unit_id FK
  • equipment.kindpoint.signal_role
  • ControlUnit, EventRecord 模型(model.rs

2.3 业务逻辑(已有)

  • Unit CRUD 接口:GET/POST/PUT/DELETE /api/unit, GET /api/unit/{id}
  • 设备手动控制接口:POST /api/control/equipment/{id}/start|stop
    • 内置脉冲写入(写 1 → 等 300ms → 写 0
    • 前置校验:rem == 1, flt == 0, 通讯质量 goodcontrol/validator.rs
  • AppEvent::EquipmentStartCommandSent/EquipmentStopCommandSent,自动持久化 event 表并推送 WebSocket
  • 内存运行态结构体(control/runtime.rs
    • UnitRuntimeState: Stopped / Running / DistributorRunning / FaultLocked / CommLocked
    • UnitRuntime:含 accumulated_run_sec, fault_locked, comm_locked, manual_ack_required 等全部字段
    • ControlRuntimeStore:全局 HashMap<Uuid, UnitRuntime>,已注册到 AppState
  • control/validator.rs:独立的控制前置校验模块
  • control/engine.rs:模块骨架已建立,start() 函数为空桩
  • 前端Unit 列表(units.js),事件列表(events.js),设备 Unit 绑定(equipment.js
  • 事件列表接口:GET /api/event(支持 unit_id, event_type 过滤)

3. 与需求的差距(当前真实状态)

需求项 状态 说明
Unit / 设备 / 点位数据模型 已完成 迁移、模型、CRUD 全部到位
脉冲写入封装 已完成 内置在 handler/control.rs
手动控制前置校验 已完成 validator.rs 实现 REM/FLT/quality 检查
手动启停接口 已完成 start/stop 接口含脉冲写入和事件持久化
运行态内存模型 已完成 runtime.rs 数据结构完整,已注入 AppState
事件持久化与查询 已完成 event 表 + 事件处理 + GET /api/event
自动控制状态机 未实现 engine.rs 是空桩,无任何调度逻辑
自动控制接口 未实现 start-auto, stop-auto 接口
故障锁定联动 未实现 runtime.fault_locked 有字段但无联动逻辑
通讯冻结联动 未实现 runtime.comm_locked 有字段但无联动逻辑
人工确认解锁接口 未实现 ack-fault 接口
手动控制检查运行态 未实现 validator.rs 未读取 ControlRuntimeStore
运行态 WebSocket 推送 未实现 单元状态变更未推送前端
运行态查询接口 未实现 GET /api/unit/{id}/runtime
前端设备控制面板 未实现 缺 REM/RUN/FLT 展示和手动启停按钮
前端单元详情/总览 未实现 缺状态机状态展示、自动/手动切换
前端参数在线编辑 🔶 部分 Unit 编辑 Modal 有表单,但无运行态反馈

4. 推荐实现思路

继续在现有平台上"增量扩展"

  • 现有 unit / equipment / point / event 底座不动
  • 填充 control/engine.rs 实现状态机调度
  • 新增自动控制和 ack-fault 接口
  • validator.rs 增加对运行态的检查
  • 扩展 AppEvent 业务事件,通过 WebSocket 推送运行态变更
  • 前端增加业务控制页面

5. 命名与模型设计(已落地,确认)

5.1 设备分类(equipment.kind

  • coal_feeder:投煤器
  • distributor:布料机

5.2 点位角色规范(point.signal_role

  • 状态点:rem run flt ii q
  • 控制点:start_cmd stop_cmd
  • 可选扩展:estop mode_auto mode_manual reset_cmd

5.3 Unit 运行态放内存(已确认)

运行态字段已在 control/runtime.rs:UnitRuntime 中定义完整,不落库。 服务重启后重新从 REM/RUN/FLT/Q 重建运行态,不自动补发命令。

5.4 统一 event 表,预留 alarm 表(已落地)

  • event:记录"发生了什么",已上线
  • alarm:记录"需要被告警管理的异常",第二阶段实现

6. 控制逻辑设计

6.1 手动控制(已实现,待补充运行态检查)

当前已实现:

  • rem == 1 检查
  • flt == 0 检查
  • 通讯质量检查
  • 脉冲写入300ms

待补充:在 validator.rs 中增加对 ControlRuntimeStore 的检查:

  • fault_locked == true → 拒绝
  • comm_locked == true → 拒绝
  • manual_ack_required == true → 拒绝(等待人工确认)

6.2 自动控制状态机(待实现)

每个 unit 独立维护状态机,在 control/engine.rs 中以后台任务驱动。

STOPPED

  • 累计停止时间 current_stop_elapsed_sec
  • stop_elapsed >= StopTime → 校验投煤器 REM/FLT/质量 → 发启动命令 → 切换到 RUNNING

RUNNING

  • 累计运行时间 current_run_elapsed_sec
  • accumulated_run_sec += delta
  • run_elapsed >= RunTime → 停止投煤器 → 切换回 STOPPED
  • accumulated_run_sec >= AccTime → 进入 DISTRIBUTOR_RUNNING

DISTRIBUTOR_RUNNING

  • 校验布料机 REM/FLT/质量
  • 启动布料机,等待 RUN == 1
  • 计时 BLTime
  • 停止布料机
  • 清零 accumulated_run_sec
  • 切回 STOPPED 或自动节拍起点

6.3 故障机制(待实现)

任意设备检测到 FLT == 1

  • 停止该单元自动控制
  • state = FaultLocked, fault_locked = true
  • 发送并持久化 FaultLocked 事件

FLT1 → 0 恢复:

  • 不自动解锁
  • manual_ack_required = true
  • 等待人工调用 POST /api/control/unit/{id}/ack-fault

6.4 通讯异常机制(待实现)

当 OPC UA 质量位异常或连接中断:

  • state = CommLocked, comm_locked = true
  • 冻结全部控制动作
  • 前端按钮灰化

通讯恢复后:

  • 重新读取 REM/RUN/FLT
  • 重同步运行态
  • 不自动补发控制命令
  • 持久化恢复事件
  • 等待人工操作或下一次自动触发

7. 事件体系设计

7.1 继续复用 src/event.rs

当前 AppEvent 已有:

  • SourceCreate/Update/Delete
  • PointCreateBatch/PointDeleteBatch
  • EquipmentStartCommandSent/EquipmentStopCommandSent
  • PointNewValue(遥测)

待扩展

AutoControlStarted { unit_id }
AutoControlStopped { unit_id }
FaultLocked { unit_id, equipment_id }
FaultAcked { unit_id }
CommLocked { unit_id }
CommRecovered { unit_id }
UnitStateChanged { unit_id, from_state, to_state }

7.2 哪些事件适合落库

  • 适合:所有手动/自动启停、故障、通讯、参数变更、状态切换
  • 不适合:PointNewValue、高频遥测、内部轮询过程

8. 后端改造方案

8.1 已有模块(确认现状)

模块 文件 状态
HTTP 控制接口 src/handler/control.rs 有 Unit CRUD + start/stop + event list
控制前置校验 src/control/validator.rs REM/FLT/质量检查,待加运行态检查
内存运行态 src/control/runtime.rs 数据结构完整
自动控制引擎 src/control/engine.rs 空桩,待实现
服务层 Unit src/service/ CRUD 完整

8.2 待新增接口

POST /api/control/unit/{id}/start-auto    启动自动控制
POST /api/control/unit/{id}/stop-auto     停止自动控制
POST /api/control/unit/{id}/ack-fault     人工确认故障解锁
GET  /api/unit/{id}/runtime               查询运行态state, elapsed, fault_locked 等)

说明:

  • start/stop-auto 修改运行态 auto_enabled,引擎轮询时读取
  • ack-fault 仅在 manual_ack_required == true 时允许操作,否则返回 400

8.3 控制引擎运行方式(待实现)

control/engine.rs: start() 中实现后台任务:

每 500ms 扫描所有 enabled unit
  ↓
从 ControlRuntimeStore 读取运行态
  ↓
从 connection_manager.get_point_monitor_data_read_guard() 取实时点值
  ↓
检查质量位 → 更新 comm_locked
  ↓
检查 FLT → 更新 fault_locked
  ↓
驱动状态机 tick
  ↓
有状态变化 → 更新 ControlRuntimeStore → 发 AppEvent → 推 WebSocket

8.4 手动控制补充运行态检查

control/validator.rs: validate_manual_control() 中增加:

let runtime = state.control_runtime.get(unit_id).await;
if let Some(runtime) = runtime {
    if runtime.fault_locked {
        return Err(ApiErr::Forbidden("Unit is fault locked", ...));
    }
    if runtime.comm_locked {
        return Err(ApiErr::Forbidden("Unit is comm locked", ...));
    }
    if runtime.manual_ack_required {
        return Err(ApiErr::Forbidden("Fault ack required before control", ...));
    }
}

8.5 关键复用点

可直接复用当前已有能力:

  • connection_manager.get_point_monitor_data_read_guard() → 读取实时点值
  • connection_manager.write_point_values_batch() → 写点(自动控制也走此接口)
  • event_manager.send() → 统一事件入口
  • ws_manager.send_to_public() → 推送运行态变更
  • unit_id + equipment.kind + point.signal_role 三元组 → 业务映射

9. 前端改造方案

9.1 已有页面(确认现状)

页面/功能 状态
Unit 列表(含 CRUD Modal 基础实现
事件列表 基础实现
设备列表(含 Unit 归属绑定) 实现
点位绑定equipment/signal_role 实现
趋势图 实现

9.2 待新增页面/功能

设备控制面板(单台投煤器/布料机):

  • REM / RUN / FLT / Q / II 实时显示
  • 启动 / 停止按钮灰化逻辑comm_locked / fault_locked / manual_ack_required
  • 通讯异常、故障锁定提示
  • 最近控制事件

单元总览Unit 卡片增强):

  • 当前状态机状态STOPPED / RUNNING / DISTRIBUTOR_RUNNING / FAULT_LOCKED / COMM_LOCKED
  • 自动/手动切换按钮
  • 故障确认按钮(manual_ack_required == true 时显示)
  • 累计运行时间进度
  • 投煤器 + 布料机运行状态摘要

参数在线编辑

  • 现有 Unit Modal 已有表单
  • 需补充:保存后通知引擎重新加载(或引擎每次 tick 从 DB 读取配置)

WebSocket 运行态更新

  • 新增 WsMessage::UnitRuntimeChanged { unit_id, runtime } 消息类型
  • 前端收到后实时更新 Unit 卡片状态,无需轮询

10. 分阶段实施建议

第一阶段:补全控制闭环(当前阶段)

目标:让自动控制可以跑起来,故障/通讯保护机制生效。

待完成工作:

  1. 补充运行态检查到 validator.rs

    • 手动控制时检查 fault_locked, comm_locked, manual_ack_required
  2. 实现 control/engine.rs

    • 后台 500ms 轮询任务
    • 质量检查 → comm_locked 更新
    • FLT 检测 → fault_locked 更新
    • 状态机 tickSTOPPED / RUNNING / DISTRIBUTOR_RUNNING
  3. 新增接口

    • POST /api/control/unit/{id}/start-auto
    • POST /api/control/unit/{id}/stop-auto
    • POST /api/control/unit/{id}/ack-fault
    • GET /api/unit/{id}/runtime
  4. 扩展 AppEvent

    • FaultLocked, FaultAcked, CommLocked, CommRecovered, UnitStateChanged, AutoControlStarted, AutoControlStopped
  5. WebSocket 运行态推送

    • WsMessage::UnitRuntimeChanged
  6. 前端设备控制面板

    • REM/RUN/FLT 展示 + 启停按钮 + 灰化逻辑
  7. 前端 Unit 卡片增强

    • 状态机状态展示、自动/手动切换、故障确认

交付后可验证:

  • 单台设备手动启停(含故障/通讯拦截)
  • 单元自动定时启停
  • 累计触发布料机运行
  • 故障恢复后人工确认才能操作
  • 通讯异常冻结后恢复自动同步

第二阶段:增强版

  • 单元详情页(运行趋势、事件时间线、参数在线编辑)
  • 更丰富的趋势图(电流 II、运行状态变化曲线
  • 报警规则与 alarm
  • 报警确认与恢复流程

第三阶段:现场适配版

  • 导入导出配置
  • 项目模板
  • 配置校验工具
  • 启停联锁自检
  • 操作权限控制

11. 当前优先落地顺序

从当前代码基础出发,第一阶段建议按下面顺序开发:

  1. validator.rs 补充运行态检查
  2. engine.rs 实现质量检查与 comm_locked 更新
  3. engine.rs 实现 FLT 检测与 fault_locked 更新
  4. engine.rs 实现状态机主循环
  5. handler/control.rs 新增 start-auto, stop-auto, ack-fault
  6. handler/control.rs 新增 GET /api/unit/{id}/runtime
  7. 扩展 AppEvent 业务事件类型并落库
  8. websocket.rs 新增 UnitRuntimeChanged 消息
  9. 前端设备控制面板
  10. 前端 Unit 卡片增强
  11. 第二阶段再引入独立 alarm

12. 对当前代码的具体落点

文件 改动内容
src/control/engine.rs 填充后台轮询任务,实现状态机 tick
src/control/validator.rs 增加运行态检查fault/comm/ack
src/handler/control.rs 新增 start-auto, stop-auto, ack-fault, runtime 接口
src/event.rs 扩展 AppEvent 业务事件枚举
src/websocket.rs 新增 WsMessage::UnitRuntimeChanged
web/js/units.js Unit 卡片增加状态机状态、auto 切换、fault ack 按钮
web/js/equipment.js 增加设备控制面板REM/RUN/FLT + 启停)
web/js/app.js 绑定新按钮事件,处理 WebSocket 运行态消息

不需要改动的:

  • src/model.rs(数据模型完整)
  • src/control/runtime.rs(运行态结构体完整)
  • 所有迁移文件schema 已完整)
  • src/handler/point.rs(保留底层写点,不承载业务控制)

13. 本次结论

当前项目已经完成了业务底座的建设(数据模型、脉冲写入、手动控制、事件持久化、运行态数据结构),具备了较好的基础。

下一步核心工作集中在:

  1. 填充 control/engine.rs——这是最核心的缺口,所有自动控制、故障保护、通讯冻结都需要它来驱动
  2. 前端业务控制面板——让操作员看到并操作设备状态

其余部分接口、事件、WebSocket属于连接层工作量相对可控。