Appearance
案例 B-05:试验流程、状态机与事件后果
设备按钮不应直接等于硬件动作,但“发生异常”也不应自动等于“进入故障停机”。V10 把两个问题分开:
text
State
= 当前流程处于什么阶段
Event Consequence
= 某个事件发生后到底提示、报警、阻断还是停机1. 试验流程中的状态
一个典型周期试验可以包含:
text
Idle
→ SelfTest
→ Ready
→ Testing
→ Resting
→ Testing ...
→ Completed根据项目需要还可能有:
Paused:人工暂停,可按规则恢复;Stopping:正在执行受控停止;InterlockStop:安全联锁导致的阻断状态;RecoveryRequired:需要人工处理后才能继续。
不要为了模板完整强行加入所有状态。只保留能表达真实业务阶段的状态。
2. Testing / Resting 是业务窗口,不只是计时器
案例中的运行窗口与停机窗口具有不同设备职责:
Testing
可能允许:
- 指定输出;
- 数据采集;
- 流程计数;
- 运行期状态监视。
Resting
可能要求:
- 关闭某些危险输出;
- 保留必要状态和日志;
- 执行停机窗口专属检查;
- 等待下一轮重新进入 Testing。
哪些检查在哪个窗口执行必须由业务定义,不能因为函数名带 HealthCheck 就默认两个窗口都运行。
3. 事件后果单独分类
同一个状态中可以发生不同等级事件:
| 类型 | 示例 | 是否改变主流程 |
|---|---|---|
| Information | 一轮完成、设备状态刷新 | 通常不改变 |
| Advisory | 磁盘空间偏低、维护提醒 | 默认继续 |
| AlarmOnly | 连续 N 次残余值异常但业务规定继续 | 报警记录,主流程继续 |
| InterlockFault | 高压保护、急停、明确安全联锁 | 阻断/停止 |
因此不要写:
text
CommunicationError → FaultStop
AnyAlarm → FaultStop除非需求明确规定它们属于 InterlockFault。
4. BehaviorPatch 应只修改相关 transition
如果现有系统只是把:
text
单帧越限 → FaultStop改成:
text
连续 5 帧越限 → AlarmOnly → Testing/Resting 继续这属于 BehaviorPatch,不需要重新设计整套状态机。
先固定:
text
Trigger
Condition
Action
Reset
Record
NonGoals然后只检查相关状态、计数器、告警记录和停止调用是否仍被触发。
5. 参数、派生量和窗口不要混在一起
试验软件常同时存在:
- 用户输入参数;
- 软件计算派生参数;
- 安全延时;
- 设备下发参数;
- Testing/Resting 窗口;
- 循环次数或目标时长。
设计时应明确 Source of Truth 和单位。特别是时间、频率、电流、电压等字段,避免 UI 改了一个数字,内部状态机或设备下发仍用旧值。
涉及正式约束变化时转到 业务约束跨层传播。
6. 状态机和硬件动作之间必须有边界
状态迁移不能只是:
text
Ready → Testing还要明确迁移过程需要的软件条件,例如:
text
Ready
→ 参数有效
→ 必要设备已连接
→ 软件侧自检完成
→ 等待需要的人工确认
→ 执行设备动作
→ 确认软件状态
→ Testing但真机高压、运动、阀门等危险动作不能因为状态机图上有一条边,就变成 Agent 自动测试动作。
相关规则见 真实设备操作与验证安全边界。
7. 验收不要写成“一套全部都测”
按实际修改风险选择:
V1
纯页面状态显示、按钮样式。
V2
普通设备状态映射、参数传播、通信状态。
V3
Testing/Resting 转换、连续计数、告警后果、Stop/Recovery、联锁、并发和资源释放。
HardwarePending
需要真实设备确认的危险动作、保护链和现场恢复。
所以“危险输出已经关闭”只有在有实际设备证据时才能写成验证结论;Fake/Simulation 只能证明软件下发逻辑和状态判断。
8. 本案例推荐的状态表
| 当前状态 | 事件 | 条件 | 后果 | 下一状态 |
|---|---|---|---|---|
| Idle | StartRequested | 参数/连接满足 | 准备自检 | SelfTest |
| SelfTest | SelfTestPassed | 软件侧条件满足 | 等待启动条件 | Ready |
| Ready | StartConfirmed | 需要的人工确认完成 | 启动当前试验窗口 | Testing |
| Testing | WindowElapsed | 正常结束窗口 | 关闭本窗口动作 | Resting |
| Resting | RestElapsed | 仍有剩余循环 | 准备下一轮 | Testing |
| Testing/Resting | AlarmOnly | 业务规定不阻断 | 记录/告警 | 原状态继续 |
| 任意运行态 | InterlockFault | 联锁条件成立 | 阻断并执行安全停止 | InterlockStop |
| 任意运行态 | UserStop | 用户请求停止 | 受控停止 | Stopping |
| Stopping | StopCompleted | 软件停止步骤完成 | 结束任务 | Completed/Idle |
这张表只是结构示例,具体状态名和后果必须以项目实际业务为准。
9. 本案例最值得保留的经验
- 状态和事件后果分开。 Alarm 不自动等于 FaultStop。
- Testing / Resting 是业务语义。 不要只当计时器标签。
- BehaviorPatch 改局部 transition。 明确规则变化不重新设计整套系统。
- UI Disable 不是安全联锁。 后端仍要验证真实前置条件。
- 软件验证和真机验证分开。 没有现场证据就保持
HardwarePending。 - 停止流程本身也是状态机。 Stop、Cancellation、Dispose 和设备安全动作不能混成一个按钮回调。