场景管理 Cluster(SceneManagement)
Cluster ID: 0x0062 |
所在 Endpoint: 通常在 Endpoint 1(功能端点)
SceneManagement 是 Matter 中的场景管理 Cluster —— 负责将多个 Cluster 的属性值打包成一个「快照」, 然后通过一条命令一键恢复到这组状态。 比如「观影模式」可以同时把灯调暗、色温调暖、窗帘关上,这些动作就是一个场景。
每个场景由 GroupID + SceneID 唯一标识,属于某个组(Group), 组内可以包含多个场景。场景的核心数据结构是 ExtensionFieldSets —— 一组「Cluster ID + 属性值列表」的快照,定义了这个场景要把哪些 Cluster 的哪些属性设成什么值。
SceneManagement(0x0062)是 Matter 1.4 引入的新 Cluster,取代了旧版 Scenes(0x0005)。 新版本引入了 Fabric 级隔离(每个 Fabric 独立管理自己的场景表)和 FabricSceneInfo 结构体,解决了旧版多 Fabric 共享场景表的安全问题。 新项目应直接使用 0x0062,旧版 0x0005 已标记为弃用。
命令(Commands)
SceneManagement Cluster 共有 8 个命令,覆盖场景的增删改查、一键召回和跨组复制。 其中 AddScene 和 RecallScene 是日常开发最常用的两个。 点击下方表格中的命令 ID 可跳转到对应的详细说明。
| ID | 名称 | 说明 | 响应命令 |
|---|---|---|---|
0x00 |
AddScene | 添加或更新一个场景 | AddSceneResponse |
0x01 |
ViewScene | 查看指定场景的完整数据 | ViewSceneResponse |
0x02 |
RemoveScene | 删除指定场景 | RemoveSceneResponse |
0x03 |
RemoveAllScenes | 删除指定组内的所有场景 | RemoveAllScenesResponse |
0x04 |
StoreScene | 捕获当前状态存为场景 | StoreSceneResponse |
0x05 |
RecallScene | 一键恢复指定场景 | 无 |
0x06 |
GetSceneMembership | 查询组内已有的场景列表 | GetSceneMembershipResponse |
0x40 |
CopyScene | 在组之间复制场景 | CopySceneResponse |
AddScene —— 添加场景(0x00)
向设备的场景表中添加一个新场景,或更新已有场景。
场景的核心数据通过 ExtensionFieldSets 传入 —— 它定义了这个场景要控制哪些 Cluster 的哪些属性值。
如果指定的 GroupID + SceneID 已存在,会覆盖更新。
| 参数 | 类型 | 说明 |
|---|---|---|
| GroupID | group-id | 场景所属的组 ID。0x0000 表示不属于任何组 |
| SceneID | uint8 | 场景 ID,在组内唯一(0x00 ~ 0xFF) |
| TransitionTime | uint32 | 过渡时间,单位 0.1 秒(毫秒的十分之一)。例如 10 = 1.0 秒 |
| SceneName | string | 场景名称(最长 16 字节)。需要设备支持 SN 特性 |
| ExtensionFieldSets | list | 各 Cluster 的属性快照列表(详见数据结构说明) |
AddSceneResponse 返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
| Status | status | 操作结果状态码 |
| GroupID | group-id | 场景所属的组 ID |
| SceneID | uint8 | 场景 ID |
使用场景
用户在 App 中创建「观影模式」:灯光调到 10%、色温设为暖白、窗帘关闭。 App 将这些属性值封装进 ExtensionFieldSets,通过 AddScene 存入设备, 之后用 RecallScene 一键恢复。
ViewScene —— 查看场景(0x01)
读取指定场景的完整数据,包括过渡时间、场景名称和 ExtensionFieldSets。 用于在 App 界面上展示场景详情或编辑前获取当前配置。
| 参数 | 类型 | 说明 |
|---|---|---|
| GroupID | group-id | 场景所属的组 ID |
| SceneID | uint8 | 要查看的场景 ID |
ViewSceneResponse 返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
| Status | status | 操作结果状态码 |
| GroupID | group-id | 组 ID |
| SceneID | uint8 | 场景 ID |
| TransitionTime | uint32 | 过渡时间(0.1 秒) |
| SceneName | string | 场景名称 |
| ExtensionFieldSets | list | 各 Cluster 的属性快照 |
使用场景
App 场景编辑页面加载时,先用 ViewScene 读取当前配置,展示给用户, 用户修改后再通过 AddScene 更新。
RemoveScene —— 删除场景(0x02)
从设备的场景表中删除指定的一个场景。删除后该 SceneID 可以被重新使用。
| 参数 | 类型 | 说明 |
|---|---|---|
| GroupID | group-id | 场景所属的组 ID |
| SceneID | uint8 | 要删除的场景 ID |
RemoveSceneResponse 返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
| Status | status | 操作结果状态码 |
| GroupID | group-id | 组 ID |
| SceneID | uint8 | 场景 ID |
使用场景
用户在 App 中删除不再需要的场景,如删掉旧的「派对模式」。
RemoveAllScenes —— 删除组内所有场景(0x03)
一次性删除指定组内的全部场景。适合重置或清空某个区域的场景配置。
| 参数 | 类型 | 说明 |
|---|---|---|
| GroupID | group-id | 要清空场景的组 ID |
RemoveAllScenesResponse 返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
| Status | status | 操作结果状态码 |
| GroupID | group-id | 组 ID |
使用场景
用户重新装修后,清空「客厅」组的所有旧场景,准备重新配置。
StoreScene —— 捕获当前状态(0x04)
将设备当前的实际状态「拍快照」保存为一个场景。设备会自动读取自身各 Cluster 的当前属性值, 打包成 ExtensionFieldSets 存入场景表。相比 AddScene 需要手动指定每个属性值, StoreScene 更像一个「保存当前状态」的快捷操作。
| 参数 | 类型 | 说明 |
|---|---|---|
| GroupID | group-id | 场景所属的组 ID |
| SceneID | uint8 | 场景 ID(如果已存在则覆盖) |
StoreSceneResponse 返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
| Status | status | 操作结果状态码 |
| GroupID | group-id | 组 ID |
| SceneID | uint8 | 场景 ID |
使用场景
用户通过滑块把灯光调到自己喜欢的状态后,点击「保存为场景」按钮, App 发送 StoreScene 命令,设备自动将当前亮度、色温等属性值存入场景表。 不需要 App 逐个读取属性值再用 AddScene 传入。
RecallScene —— 恢复场景(0x05)
一键恢复指定场景。设备会读取场景中保存的 ExtensionFieldSets, 将各 Cluster 的属性值设置到场景记录的目标值。 如果指定了 TransitionTime,设备会在过渡时间内平滑切换(如灯光渐变)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| GroupID | group-id | 是 | 场景所属的组 ID |
| SceneID | uint8 | 是 | 要恢复的场景 ID |
| TransitionTime | uint32 | 否 | 覆盖场景自带的过渡时间(0.1 秒)。省略则使用场景存储时的值 |
TransitionTime 的单位是 0.1 秒(100 毫秒),不是秒也不是毫秒。
例如值为 10 表示 1.0 秒,30 表示 3.0 秒。
这与旧版 Scenes Cluster 的秒级单位不同,新版精度更高。
使用场景
用户点击 App 中的「观影模式」按钮,App 发送 RecallScene, 灯在 1 秒内从当前亮度渐暗到 10%,色温渐变为暖白,窗帘缓缓关闭。 所有设备同步执行,过渡自然流畅。
GetSceneMembership —— 查询场景列表(0x06)
查询指定组内有哪些场景。返回该组下所有已存储的 SceneID 列表和剩余容量。 用于在 App 界面展示场景列表或判断还能创建多少个场景。
| 参数 | 类型 | 说明 |
|---|---|---|
| GroupID | group-id | 要查询的组 ID |
GetSceneMembershipResponse 返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
| Status | status | 操作结果状态码 |
| Capacity | uint8 / null | 剩余可存场景数量。null 表示未知 |
| GroupID | group-id | 组 ID |
| SceneList | list<uint8> | 该组内已存储的 SceneID 列表 |
使用场景
App 打开「场景管理」页面时,先调用 GetSceneMembership 获取当前组的所有场景 ID, 再逐个调用 ViewScene 拿到场景详情展示列表。
CopyScene —— 复制场景(0x40)
在组之间复制场景。可以复制单个场景,也可以一次性复制源组的全部场景到目标组。 适合在不同房间之间共享相同的场景配置。
| 参数 | 类型 | 说明 |
|---|---|---|
| Mode | CopyModeBitmap | Bit 0: CopyAllScenes —— 为 1 时复制源组的全部场景 |
| GroupIdentifierFrom | group-id | 源组 ID |
| SceneIdentifierFrom | uint8 | 源场景 ID(CopyAllScenes = 1 时忽略) |
| GroupIdentifierTo | group-id | 目标组 ID |
| SceneIdentifierTo | uint8 | 目标场景 ID(CopyAllScenes = 1 时忽略) |
CopySceneResponse 返回字段
| 字段 | 类型 | 说明 |
|---|---|---|
| Status | status | 操作结果状态码 |
| GroupIdentifierFrom | group-id | 源组 ID |
| SceneIdentifierFrom | uint8 | 源场景 ID |
使用场景
用户在客厅配置好了「阅读模式」场景,想要在书房也用同样的配置。 通过 CopyScene 把客厅组的场景复制到书房组,不需要重新设置每个属性值。
属性详解
SceneManagement Cluster 有 3 个属性。场景数据本身不通过属性暴露, 而是通过 ViewScene / GetSceneMembership 命令读取。 属性提供的是场景表的容量、当前状态等元信息。
| ID | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0000 |
LastConfiguredBy 新版已移除 | node-id / null | 最后修改场景表的节点 ID |
0x0001 |
SceneTableSize | uint16 | 场景表总容量 |
0x0002 |
FabricSceneInfo | list<FabricSceneInfo> | 各 Fabric 的场景概况信息 |
LastConfiguredBy(0x0000) 新版已移除
LastConfiguredBy 已不在较新版本的 Matter 规范中(本站对照的 connectedhomeip v1.6 官方定义里已没有它)。按新版本开发的设备不会实现它,这里保留说明仅供对接旧设备时参考。新版本不再提供「最后配置者」信息,场景概况改由 FabricSceneInfo 按 Fabric 分别提供。
记录最后一次修改场景表的节点 ID(Node ID)。
可以用来排查「是谁改了场景配置」的问题。
值为 null 表示场景表从未被修改,或设备不支持追踪此信息。
| ID | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0000 |
LastConfiguredBy 新版已移除 | node-id / null | Nullable。记录最后一次通过 AddScene / RemoveScene / StoreScene 等命令修改场景表的节点。null = 未记录或从未修改 |
SceneTableSize(0x0001)
设备场景表的最大容量,即最多能存储多少个场景。 这是所有 Fabric 共享的总容量。典型设备值在 8~16 之间。
| ID | 名称 | 类型 | 说明 |
|---|---|---|---|
0x0001 |
SceneTableSize | uint16 | 场景表总容量。多个 Fabric 共享这个容量上限,例如值为 16 表示所有 Fabric 加起来最多 16 个场景 |
FabricSceneInfo(0x0002)
每个 Fabric 独立维护的场景状态信息。这是一个列表,每个元素对应一个 Fabric。 通过它可以知道当前 Fabric 有多少个场景、当前激活的是哪个场景、还能再存多少个。
SceneManagement 的一个重要设计是 Fabric 级隔离: 每个 Fabric(可以理解为每个智能家居平台,如 Apple Home、Google Home)只能看到和操作自己的场景, 无法读取或修改其他 Fabric 的场景数据。FabricSceneInfo 也只返回当前 Fabric 自己的信息。
| 字段 | 类型 | 说明 |
|---|---|---|
| SceneCount | uint8 | 当前 Fabric 已存储的场景数量 |
| CurrentScene | uint8 | 当前激活的场景 ID(最后一次 RecallScene / StoreScene 的场景) |
| CurrentGroup | group-id | 当前激活场景所属的组 ID |
| SceneValid | bool | 当前场景状态是否仍然有效。如果设备属性被手动修改(不通过场景),会变为 false |
| RemainingCapacity | uint8 | 当前 Fabric 还能再存储多少个场景 |
| FabricIndex | fabric-idx | 此记录对应的 Fabric 索引 |
当通过 RecallScene 恢复了一个场景后,SceneValid 变为 true。
但如果之后用户手动调节了亮度或色温(不通过场景操作),设备的实际状态就与场景记录不一致了,
SceneValid 会变回 false。
可以用这个字段判断当前设备状态是否仍然匹配某个场景。
核心数据结构
ExtensionFieldSets(扩展字段集)
ExtensionFieldSets 是场景的核心数据 —— 它记录了「这个场景要把哪些 Cluster 的哪些属性设成什么值」。 结构是一个列表,每个元素包含一个 Cluster ID 和该 Cluster 下要设置的属性值列表。
| 层级 | 字段 | 类型 | 说明 |
|---|---|---|---|
| ExtensionFieldSet | ClusterID | cluster-id | 要控制的 Cluster ID,如 0x0006(OnOff) |
| AttributeValueList | list | 该 Cluster 下的属性值列表 | |
| AttributeValuePair | AttributeID | attrib-id | 属性 ID,如 0x0000(OnOff 的开关状态) |
| ValueUnsigned8/16/... | 各类型 | 属性值,类型取决于该属性的定义 |
举个例子,一个「观影模式」场景的 ExtensionFieldSets 可能包含:
- OnOff(0x0006):开关 = 开启
- LevelControl(0x0008):亮度 = 25(约 10%)
- ColorControl(0x0300):色温 X = 370,色温 Y = 300(暖白光)
设备执行 RecallScene 时,会逐个读取这些属性对,调用对应 Cluster 的逻辑设置属性值。
每个 Cluster 需要实现 ScenesManagement 的回调接口来支持场景存取。
Feature 位图
SceneManagement Cluster 通过 FeatureMap(0xFFFC)声明设备支持的高级能力:
SN 特性是可选的。不支持 SN 的设备在 AddScene 时会忽略 SceneName 参数, ViewScene 返回的 SceneName 也会是空字符串。 如果 App 需要展示场景名称,可以在 App 本地存储,不依赖设备端。
示例数据
属性读取示例
读取 SceneManagement Cluster 属性时的返回数据:
{
// --- 场景表信息 ---
"0x0001": 16, // SceneTableSize = 16(最多存储 16 个场景)
// --- Fabric 场景信息 ---
"0x0002": [ // FabricSceneInfo(当前 Fabric 的场景概况)
{
"SceneCount": 3, // 当前 Fabric 已存储 3 个场景
"CurrentScene": 1, // 当前激活的场景 ID
"CurrentGroup": 0, // 当前激活场景所属的组 ID
"SceneValid": true, // 当前场景状态有效
"RemainingCapacity": 13, // 还能再存 13 个场景
"FabricIndex": 1 // 所属 Fabric 索引
}
]
}
AddScene 命令示例
创建一个「观影模式」场景,包含 OnOff、LevelControl、ColorControl 三个 Cluster 的属性快照:
{
"invokeRequests": [{
"commandPath": {
"endpointId": 1,
"clusterId": "0x0062",
"commandId": "0x00" // AddScene
},
"commandFields": {
"GroupID": 0, // 组 ID(0 = 不属于任何组)
"SceneID": 1, // 场景 ID
"TransitionTime": 10, // 过渡时间 = 1.0 秒(单位 0.1 秒)
"SceneName": "Movie", // 场景名称(需 SN 特性)
"ExtensionFieldSets": [ // 各 Cluster 的属性快照
{
"ClusterID": "0x0006", // OnOff Cluster
"AttributeValueList": [
{ "AttributeID": "0x0000", "ValueUnsigned8": 1 }
]
},
{
"ClusterID": "0x0008", // LevelControl Cluster
"AttributeValueList": [
{ "AttributeID": "0x0000", "ValueUnsigned8": 25 }
]
},
{
"ClusterID": "0x0300", // ColorControl Cluster
"AttributeValueList": [
{ "AttributeID": "0x0003", "ValueUnsigned16": 370 },
{ "AttributeID": "0x0004", "ValueUnsigned16": 300 }
]
}
]
}
}]
}
实际开发中,ExtensionFieldSets 里应该只包含设备实际支持的 Cluster。 发送前可以先通过 Descriptor Cluster(0x001D)的 ServerList 确认设备有哪些 Cluster, 避免传入设备不支持的 Cluster 导致命令失败。
常见场景
场景 1:观影模式 —— 一键调暗灯光
目标:用户点击「观影模式」按钮,灯光在 2 秒内渐变到暗暖光。
- 创建场景时,用
AddScene (0x00)设置 ExtensionFieldSets:- OnOff:开启
- LevelControl:亮度 = 25(约 10%)
- ColorControl:色温设为暖白
- 日常使用时,App 发送
RecallScene (0x05),传入 GroupID 和 SceneID - 设备在 2 秒内平滑切换到目标状态,灯光自然变暗变暖
- 如果用户想快速切换不要渐变,在 RecallScene 中覆盖 TransitionTime = 0
场景 2:起床模式 —— 清晨自然唤醒
目标:每天早上 7:00 灯光从关闭渐亮到明亮冷白光,模拟日出。
- 用
AddScene (0x00)创建「起床」场景:- OnOff:开启
- LevelControl:亮度 = 254(100%)
- ColorControl:色温设为冷白(日光色)
- 在自动化规则中设定:每天 07:00 触发
RecallScene (0x05) - 灯光在 1 分钟内从关闭状态缓缓亮起到日光白,自然唤醒
- 可配合 OnOff Cluster 的 OnWithTimedOff 做防忘关灯:起床 30 分钟后自动关闭
场景 3:一键场景切换 —— 物理按钮触发
目标:墙壁开关的单击 / 双击分别切换不同场景。
- 预先配置两个场景:
- SceneID = 1「日常」:亮度 80%,自然白光
- SceneID = 2「观影」:亮度 10%,暖白光
- 在绑定规则(Binding)中配置:
- 开关单击 → RecallScene(GroupID=0, SceneID=1)
- 开关双击 → RecallScene(GroupID=0, SceneID=2)
- 场景切换完全在本地执行(通过 Group 组播),不依赖云端,响应速度极快
-
用
StoreScene (0x04)可以让用户自定义:把灯调到喜欢的状态, 长按开关触发 StoreScene,当前状态就保存为该按键对应的场景