操作状态 Cluster(OperationalState)
Cluster ID: 0x0060 |
所在 Endpoint: 通常在 Endpoint 1(功能端点)
OperationalState 是 Matter 中用于描述家电运行状态的通用状态机 Cluster。 它为洗衣机、烘干机、烤箱、扫地机器人等需要「启动/暂停/停止/恢复」操作的设备提供统一的控制接口。 作为基础 Cluster,设备特定的变体(如 OvenCavityOperationalState、RVCOperationalState)都继承自它。
OperationalState 定义了通用的状态和错误枚举。设备特定的 Cluster(如烤箱、扫地机器人)
会继承这些基础定义,并在此基础上扩展自己的状态值和错误码。
例如,扫地机器人(RVC)会增加 SeekingCharger、Charging 等状态,
以及 StuckAtObstacle、DustBinFull 等错误。
命令(Commands)
OperationalState Cluster 共有 4 个命令,对应家电操作的基本动作。
所有命令执行后都会返回 OperationalCommandResponse,包含一个
ErrorStateStruct 用于指示操作是否成功。
点击下方表格中的命令 ID 可跳转到对应的详细说明。
| ID | 名称 | 说明 | 响应 |
|---|---|---|---|
0x00 |
Pause | 暂停当前操作 | OperationalCommandResponse |
0x01 |
Stop | 停止操作 | OperationalCommandResponse |
0x02 |
Start | 启动操作 | OperationalCommandResponse |
0x03 |
Resume | 恢复暂停的操作 | OperationalCommandResponse |
Pause —— 暂停(0x00)
暂停设备当前正在进行的操作。执行成功后,OperationalState 属性变为
Paused (2)。设备会保留当前进度,可以通过 Resume 命令恢复。
不需要参数。
只有当设备处于 Running (1) 状态时才能暂停。
如果在 Stopped (0) 或 Error (3) 状态下调用,
会返回 CommandInvalidInState (3) 错误。
使用场景
洗衣机正在洗涤时,用户需要临时打开门添加衣物。App 发送 Pause 命令, 洗衣机暂停洗涤、排水解锁门。添加衣物后发送 Resume 继续。
Stop —— 停止(0x01)
完全停止设备的当前操作。执行成功后,OperationalState 属性变为
Stopped (0)。与 Pause 不同,Stop 会放弃当前进度,
需要重新 Start 才能开始新的操作周期。不需要参数。
使用场景
烤箱正在烤制食物,用户发现设置有误需要完全取消。发送 Stop 命令终止烤制, 之后可以重新配置参数再发送 Start 开始新的烤制周期。
Start —— 启动(0x02)
启动设备的操作。执行成功后,OperationalState 属性变为
Running (1)。通常在设备处于 Stopped (0) 状态时调用。
不需要参数。
使用场景
用户在洗衣机上选好洗涤程序和温度后,点击 App 上的启动按钮, App 发送 Start 命令开始洗涤周期。
Resume —— 恢复(0x03)
恢复之前被 Pause 暂停的操作。执行成功后,OperationalState 属性变为
Running (1),设备从暂停的位置继续执行。不需要参数。
只有当设备处于 Paused (2) 状态时才能恢复。
如果在 Stopped (0) 状态下调用,会返回
CommandInvalidInState (3) 错误 —— 此时应该用 Start 而不是 Resume。
使用场景
洗衣机在暂停状态下,用户关上门后点击继续按钮。 App 发送 Resume 命令,洗衣机从暂停位置继续洗涤。
OperationalCommandResponse —— 命令响应
所有四个命令(Pause/Stop/Start/Resume)执行后都会返回此响应。 它包含一个 ErrorStateStruct,用于指示命令是否成功。
| 字段 | 类型 | 说明 |
|---|---|---|
| CommandResponseState | ErrorStateStruct | 命令执行结果。ErrorStateID = 0 (NoError) 表示成功 |
属性详解
OperationalState Cluster 共有 6 个应用属性。点击下方汇总表中的属性 ID 可跳转到对应的详细说明。
| ID | 名称 | 类型 | 分组 | 说明 |
|---|---|---|---|---|
0x0000 |
PhaseList | list<string> / null | 阶段信息 | 操作阶段列表 |
0x0001 |
CurrentPhase | uint8 / null | 阶段信息 | 当前所处阶段索引 |
0x0002 |
CountdownTime | elapsed_s / null | 阶段信息 | 剩余时间(秒) |
0x0003 |
OperationalStateList | list<OperationalStateStruct> | 运行状态 | 设备支持的所有状态 |
0x0004 |
OperationalState | OperationalStateEnum | 运行状态 | 当前运行状态 |
0x0005 |
OperationalError | ErrorStateStruct | 运行状态 | 当前错误信息 |
阶段信息(0x0000, 0x0001, 0x0002)
描述设备当前操作的阶段进度和剩余时间。对于支持多阶段流程的设备(如洗衣机、烘干机),这些属性可以让 App 展示精确的进度信息。
| ID | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0000 |
PhaseList(阶段列表) | list<string> / null |
设备操作的有序阶段名称列表。例如洗衣机可能是 ["浸泡", "洗涤", "漂洗", "脱水"]。
Nullable —— null 表示设备不支持阶段概念(如简单的开关设备)。
列表最多 32 项
|
0x0001 |
CurrentPhase(当前阶段) | uint8 / null |
当前所处阶段在 PhaseList 中的索引(从 0 开始)。
Nullable —— 当 PhaseList 为 null 时,此值也为 null
|
0x0002 |
CountdownTime(剩余时间) | elapsed_s / null |
当前操作的预计剩余时间,单位秒。设备会定期更新此值。
Nullable —— null 表示设备无法预估剩余时间
|
CountdownTime 是整个操作周期的剩余时间,不是单个阶段的剩余时间。
当设备从一个阶段进入下一个阶段时,CurrentPhase 会更新,
而 CountdownTime 则持续倒数直到整个操作完成。
运行状态(0x0003, 0x0004, 0x0005)
描述设备的运行状态和错误信息。这是 App 上展示设备状态的核心数据源。
| ID | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0003 |
OperationalStateList(状态列表) | list<OperationalStateStruct> | 设备支持的所有运行状态。每个条目包含状态 ID 和可选的本地化标签。 标准状态(0~3)之外,设备可以定义自己的扩展状态(ID ≥ 0x80) |
0x0004 |
OperationalState(运行状态) | OperationalStateEnum | 设备当前的运行状态,取值范围见 OperationalStateEnum。 这是 App 展示设备状态的核心属性 |
0x0005 |
OperationalError(当前错误) | ErrorStateStruct |
设备当前的错误状态。当 OperationalState 为
Error (3) 时,此属性包含具体的错误信息。
无错误时 ErrorStateID = 0 (NoError)
|
枚举定义
OperationalStateEnum —— 运行状态
设备的运行状态枚举。标准定义了 4 个基础值,设备特定的 Cluster 可以在 0x80~0xBF 范围内扩展。
ErrorStateEnum —— 错误类型
错误状态枚举。标准定义了 4 个通用错误码,设备特定的 Cluster 可以在 0x40~0x7F 范围内扩展。
数据结构
ErrorStateStruct —— 错误状态结构
用于描述设备的错误信息。既用于 OperationalError 属性,也用于命令响应。
包含错误码、可选的本地化标签和详细描述。
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| ErrorStateID | ErrorStateEnum | 是 | 错误类型编码。0 表示无错误 |
| ErrorStateLabel | string | 否 | 可选的本地化错误标签,供 App 直接展示。当 ErrorStateID 在标准范围之外时,此字段必须提供 |
| ErrorStateDetails | string | 否 | 可选的错误详细描述,提供更多诊断信息 |
OperationalStateStruct —— 操作状态结构
用于 OperationalStateList 属性中,描述设备支持的每一个运行状态。
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| OperationalStateID | uint8 | 是 | 状态编码。0~3 为标准状态,0x80~0xBF 为设备特定扩展状态 |
| OperationalStateLabel | string | 否 | 可选的本地化状态标签。对于标准状态(0~3),此字段可以省略;对于扩展状态(≥0x80),此字段必须提供 |
事件(Events)
OperationalState Cluster 定义了 2 个事件,用于通知控制端设备的重要状态变化。
OperationalError 事件
当设备进入错误状态时触发此事件。事件优先级为 CRITICAL, 确保控制端能及时收到错误通知。
| 字段 | 类型 | 说明 |
|---|---|---|
| ErrorState | ErrorStateStruct | 当前的错误信息 |
OperationCompletion 事件
当设备完成一个完整操作周期时触发此事件。事件优先级为 INFO。 该事件携带操作的时间统计信息,方便 App 展示操作报告。
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| CompletionErrorCode | ErrorStateEnum | 是 | 操作完成时的错误码。0 (NoError) 表示正常完成 |
| TotalOperationalTime | elapsed_s / null | 否 | 操作总耗时(秒),包含暂停时间。null 表示设备不支持统计 |
| PausedTime | elapsed_s / null | 否 | 暂停累计时长(秒)。null 表示设备不支持统计 |
如果需要计算实际工作时间(不含暂停),可以用
TotalOperationalTime - PausedTime。
例如洗衣机总耗时 90 分钟,其中暂停了 10 分钟,则实际洗涤时间为 80 分钟。
示例数据
一台正在运行中的洗衣机的 OperationalState Cluster 读取结果:
{
// --- 阶段信息 ---
"0x0000": ["浸泡", "洗涤", "漂洗", "脱水"], // PhaseList(操作阶段列表)
"0x0001": 1, // CurrentPhase = 1(当前处于「洗涤」阶段)
"0x0002": 1620, // CountdownTime = 1620 秒(剩余 27 分钟)
// --- 运行状态 ---
"0x0003": [ // OperationalStateList(设备支持的状态列表)
{ "OperationalStateID": 0, "OperationalStateLabel": "已停止" },
{ "OperationalStateID": 1, "OperationalStateLabel": "运行中" },
{ "OperationalStateID": 2, "OperationalStateLabel": "已暂停" },
{ "OperationalStateID": 3, "OperationalStateLabel": "错误" }
],
"0x0004": 1, // OperationalState = Running(正在运行)
"0x0005": { // OperationalError(当前无错误)
"ErrorStateID": 0,
"ErrorStateLabel": "",
"ErrorStateDetails": ""
}
}
PhaseList、CurrentPhase、CountdownTime
都是 Nullable 类型。简单的设备可能不支持阶段和倒计时,这些值会返回 null。
App 在渲染界面时需要处理 null 的情况 —— 当值为 null 时,
隐藏对应的 UI 元素即可。
常见场景
场景 1:洗衣机完整洗涤生命周期
- 用户选好洗涤程序,App 发送
Start (0x02)命令 - 洗衣机状态变为
Running (1),PhaseList返回["浸泡", "洗涤", "漂洗", "脱水"],CurrentPhase = 0(浸泡) - App 订阅
CurrentPhase和CountdownTime属性变化,实时更新进度条和倒计时 - 洗衣机依次进入各阶段,
CurrentPhase从 0 → 1 → 2 → 3 - 操作完成后,设备状态变为
Stopped (0),触发OperationCompletion事件 - App 收到事件,展示完成通知:「洗涤完成,总耗时 65 分钟」
场景 2:错误处理与恢复
- 洗衣机正在运行,突然检测到进水管异常
- 设备状态变为
Error (3),OperationalError更新为:ErrorStateID = 1 (UnableToStartOrResume)ErrorStateLabel = "进水异常"ErrorStateDetails = "进水流量低于阈值,请检查水龙头是否打开"
- 设备触发
OperationalError事件(CRITICAL 优先级),App 弹出错误通知 - 用户检查并修复进水管后,发送
Stop (0x01)清除错误状态 - 设备回到
Stopped (0),用户重新发送Start (0x02)开始新周期
场景 3:进度追踪与界面展示
- App 读取
PhaseList,根据阶段数量渲染进度指示器(如 4 个步骤的进度条) - 订阅
CurrentPhase属性,收到变化后高亮对应的阶段步骤 - 订阅
CountdownTime属性,实时更新倒计时显示 - 订阅
OperationalState属性,根据不同状态切换界面:Stopped (0)—— 显示「启动」按钮Running (1)—— 显示「暂停」和「停止」按钮,展示进度和倒计时Paused (2)—— 显示「继续」和「停止」按钮,倒计时暂停Error (3)—— 显示错误信息和「停止」按钮
- 注意处理
PhaseList = null的情况 —— 不显示阶段进度,仅显示状态和倒计时