Skip to content

业务流程与状态机设计(V10)

内容类型:任务分流 + 状态机设计难度:进阶适合:按钮使能、测试流程、告警/停机、恢复、联锁和跨阶段状态问题阅读时间:约 12 分钟

上位机里的按钮不等于设备动作,设备报警也不等于软件一定停机。真正需要设计的是:什么事件在什么条件下发生,系统采取什么后果,状态如何变化,什么时候复位,以及留下什么证据。

V10 不要求每次改一个状态条件都重新画完整状态机。

1. 先分任务

当前任务推荐路径
“现在这个按钮什么时候可用?”Read-Only Trace
“连续 5 次才报警,但流程继续”Execution / BehaviorPatch
“以前停止后能回 Ready,最近回不去了”RegressionFix
“新增一个测试阶段/恢复流程”Discovery / State Design
状态分散、同类 Bug 长期反复显式 Architecture Hotspot Review

现有系统只改一条明确 transition 时,优先最小 BehaviorPatch;新主流程才需要完整状态表和状态图。

2. Behavior Contract 是最小状态修改单元

涉及运行规则时先写:

text
Trigger:
Condition:
Action:
Reset:
Record:
NonGoals:

例如:

text
Trigger: 停机窗口残余电流检测
Condition: 连续 5 个有效样本达到阈值
Action: AlarmOnly,当前测试继续
Reset: 任意正常样本清零;下一停机窗口重新计数
Record: 保存 5 个 Raw/工程值、阈值、时间戳
NonGoals: 不修改下一测试窗口启动条件,不改高压控制

这六行比“增加一个报警状态”更不容易被误实现。

3. 事件后果先分类,再谈状态

类型是否改变主流程典型表现
Information通常不改变状态展示/记录
Advisory不应硬阻断提示,必要时用户确认
AlarmOnly流程继续报警 + 记录
InterlockFault阻断/停止故障状态 + 明确恢复

重要:通信超时没有固定后果

旧式设计常写:

text
通信超时 → FaultStop

这是不安全的默认假设。

同一个“通信超时”在不同设备/阶段可能是:

text
Information   → 一次后台轮询失败,下一周期再试
AlarmOnly     → 辅助设备离线,但当前测试继续
Advisory      → 用户确认是否继续
InterlockFault→ 关键安全设备失联,必须停止

后果必须来自业务规则,而不是由异常类型自动决定。

4. 软件状态、设备状态、事件后果不要混成一个枚举

建议至少区分概念:

text
WorkflowState
DeviceState
EventConsequence

例如:

text
WorkflowState = Running
ScopeState = Disconnected
EventConsequence = AlarmOnly

这在某些项目完全可能成立:示波器掉线被记录报警,但其它本地流程继续。

如果把所有东西都塞进 FaultStop,后续会出现状态组合爆炸。

5. 新流程的状态列表

只有新流程/大改版时才建议建立完整表。

状态业务含义允许操作禁止操作进入条件退出条件
Idle无活动测试连接、配置危险运行命令初始化完成准备任务
Ready设备/参数满足启动条件启动、允许参数修改未授权危险动作前置检查通过Start/Fault
Running正在执行核心流程停止、查看状态修改关键参数Start 成功Complete/Stop/Fault
Stopping正在有序停止只允许必要查看再次启动Stop 请求Stopped/Fault
Completed本轮完成保存、复盘、新任务改写已冻结结果正常完成新任务
Faulted已被 InterlockFault 阻断查看原因、恢复自动继续危险动作联锁故障Reset/Recovery

状态名可按项目调整。关键不是名字统一,而是含义和后果一致。

6. Transition 表要显式写后果和证据

CurrentTriggerConditionActionConsequenceNextReset/Record
Ready用户 Start参数合法且关键设备 Ready开始流程InformationRunning记录参数版本
Running用户 Stop任意运行阶段发起有序停止InformationStopping记录停止来源
Running辅助设备超时本项目定义可继续提示+记录AlarmOnlyRunning记录原始错误
Running安全联锁断开联锁条件成立停危险动作InterlockFaultFaulted保存联锁证据
FaultedReset原因已解除且满足恢复条件清故障InformationReady记录人工确认

不要只写 Running → Faulted,否则很难 Review “为什么会去 Faulted”。

7. 按钮使能是状态机的投影,不是第二套业务规则

例如启动按钮:

text
CanStart
= WorkflowState == Ready
  && RequiredDevicesReady
  && ParametersValid
  && NoBlockingInterlock

UI 可以基于这个结果禁用按钮,但后端真实 Start 入口仍应保护关键业务条件。

反模式:

text
UI 禁用了按钮
→ 认为系统安全
→ 其它调用入口仍能直接执行 Start

危险动作不能只靠 UI 控制。

8. 连续 N 次、窗口和 Reset 是状态,不是普通 if

例如“连续 5 次超阈值”至少要明确:

text
ResetOnGood?
InvalidSamplePolicy?
ReportOnce?
ResetBoundary?

可能需要状态:

text
ConsecutiveCount
ReportedThisWindow
WindowId

但不要为了这三个状态就创建一个全新状态机框架;如果现有逻辑有稳定 owner,局部实现即可。

9. 运行窗口/阶段切换要定义边界

工业测试常见:

text
Prepare
→ TestWindow
→ StopWindow
→ TestWindow
→ ...
→ Complete

跨窗口状态必须明确:

  • 哪些计数清零;
  • 哪些缓存保留;
  • 哪些健康查询暂停;
  • 哪些设备状态只读缓存;
  • 哪些告警每窗口只报一次;
  • 下一窗口由什么条件启动。

否则“上一窗口留下的状态”会成为非常隐蔽的回归源。

10. Stop / Fault / EmergencyStop 不要混用

Normal Stop

用户主动停止,通常要求:

  • 有序停止任务;
  • 保存必要数据;
  • 资源回到可再次运行状态。

Interlock Fault

业务/安全条件触发,需要:

  • 立即或受控终止特定动作;
  • 明确故障原因;
  • 明确 Reset 条件。

Emergency Stop

如果项目存在真正急停,需要单独按设备安全规范设计;不要简单等同于普通 StopAsync()

软件文档必须写清它能做什么、不能替代什么硬件安全措施。

11. Recovery 是一等流程

需要回答:

text
故障原因解除后自动恢复还是人工确认?
恢复到 Ready、Idle 还是回到原阶段?
未完成的数据如何处理?
设备是否需要重新同步参数?
旧 session/task 是否已结束?

“清掉红色提示”不是恢复完成。

恢复后的软件状态、设备状态和业务数据必须重新一致。

12. RegressionFix:状态行为以前正常时先比较 transition delta

用户说:

text
以前点停止后可以再次启动,现在不行

先比较:

  • Stop 后 NextState 是否变化;
  • 新增了哪个 guard;
  • Reset 是否少清一个 flag;
  • 设备状态是否新增缓存;
  • 最近是否引入新的 Fault 后果;
  • Timer/session 是否仍然占用资源。

建立:

text
KnownGood transition
vs
Current transition

不要先把所有状态机代码重构一遍。

13. 操作员状态与维护状态分层

主界面通常展示:

text
待机 / 自检中 / 就绪 / 测试中 / 停止中 / 已完成 / 故障

维护诊断可以有更细:

text
ScopeDisconnected
RawRecoveryPending
MESRetrying
StopAwaitingDeviceAck

不要让实验人员面对几十个内部枚举值;也不要为了界面简洁把底层诊断证据丢掉。

详见 操作员界面与维护诊断分层

14. 验证按状态风险选

BehaviorPatch

如果只改连续次数/提示后果:

text
边界前不触发
达到条件触发
Reset 正确
NonGoals 未改变

V3 状态机/联锁

至少关注:

text
Normal Start
Normal Stop
Fault Enter
Fault Reset
Stop during running
Repeated Start blocked
Window/Stage transition
Recovery
WorkflowSmoke

危险真实设备动作仍需人工授权。

15. 两个可复制 Prompt

查当前状态行为

text
$host-computer-dev
只做 Read-Only Trace。

我想确认:
【例如:示波器通信超时后当前测试到底会不会停止】

请追踪最短链并输出:
Trigger / Condition / Action / NextState / Reset / Record。
如果 UI 状态和后端真实后果不同,请明确指出。
不要修改代码或重画整个状态机。

明确状态规则修改

text
$host-computer-dev
这是一个已确认的 BehaviorPatch,不需要重新做完整需求分析。

Trigger:
Condition:
Action:
Reset:
Record:
NonGoals:

请定位当前 transition owner,做最小修改。
如果 Action 会改变 AlarmOnly / InterlockFault 或 Stop/Continue 后果,按 V3 做 focused workflow 验证。
不要顺手重构整个状态机。

16. 常见反模式

反模式后果
所有异常都 FaultStop非关键故障意外阻断流程
“报警”没有 Action实现只能猜后果
UI 按钮禁用就是唯一联锁其它入口可绕过
连续 N 次不定义 Reset状态跨窗口残留
Stop/Fault/EStop 共用一个语义恢复和安全边界混乱
只清 UI 红色,不恢复真实状态看起来恢复、实际不能运行
改一条 transition 重画全状态机小改成本失控

下一步

一句话原则

状态机先定义业务后果,再定义新状态;明确的一条规则只改一条规则,新主流程才做完整状态设计。

别来无恙 · C# 上位机 AI 实战站 · 从零到交付 · QQ 群:1016188499