场景管理 Cluster(SceneManagement)

Cluster ID: 0x0062  |  所在 Endpoint: 通常在 Endpoint 1(功能端点)

SceneManagement 是 Matter 中的场景管理 Cluster —— 负责将多个 Cluster 的属性值打包成一个「快照」, 然后通过一条命令一键恢复到这组状态。 比如「观影模式」可以同时把灯调暗、色温调暖、窗帘关上,这些动作就是一个场景。

每个场景由 GroupID + SceneID 唯一标识,属于某个组(Group), 组内可以包含多个场景。场景的核心数据结构是 ExtensionFieldSets —— 一组「Cluster ID + 属性值列表」的快照,定义了这个场景要把哪些 Cluster 的哪些属性设成什么值。

Matter 1.4+ 替代旧版 Scenes(0x0005)

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 返回字段

字段类型说明
Statusstatus操作结果状态码
GroupIDgroup-id场景所属的组 ID
SceneIDuint8场景 ID
使用场景

用户在 App 中创建「观影模式」:灯光调到 10%、色温设为暖白、窗帘关闭。 App 将这些属性值封装进 ExtensionFieldSets,通过 AddScene 存入设备, 之后用 RecallScene 一键恢复。

ViewScene —— 查看场景(0x01)

读取指定场景的完整数据,包括过渡时间、场景名称和 ExtensionFieldSets。 用于在 App 界面上展示场景详情或编辑前获取当前配置。

参数类型说明
GroupIDgroup-id场景所属的组 ID
SceneIDuint8要查看的场景 ID

ViewSceneResponse 返回字段

字段类型说明
Statusstatus操作结果状态码
GroupIDgroup-id组 ID
SceneIDuint8场景 ID
TransitionTimeuint32过渡时间(0.1 秒)
SceneNamestring场景名称
ExtensionFieldSetslist各 Cluster 的属性快照
使用场景

App 场景编辑页面加载时,先用 ViewScene 读取当前配置,展示给用户, 用户修改后再通过 AddScene 更新。

RemoveScene —— 删除场景(0x02)

从设备的场景表中删除指定的一个场景。删除后该 SceneID 可以被重新使用。

参数类型说明
GroupIDgroup-id场景所属的组 ID
SceneIDuint8要删除的场景 ID

RemoveSceneResponse 返回字段

字段类型说明
Statusstatus操作结果状态码
GroupIDgroup-id组 ID
SceneIDuint8场景 ID
使用场景

用户在 App 中删除不再需要的场景,如删掉旧的「派对模式」。

RemoveAllScenes —— 删除组内所有场景(0x03)

一次性删除指定组内的全部场景。适合重置或清空某个区域的场景配置。

参数类型说明
GroupIDgroup-id要清空场景的组 ID

RemoveAllScenesResponse 返回字段

字段类型说明
Statusstatus操作结果状态码
GroupIDgroup-id组 ID
使用场景

用户重新装修后,清空「客厅」组的所有旧场景,准备重新配置。

StoreScene —— 捕获当前状态(0x04)

将设备当前的实际状态「拍快照」保存为一个场景。设备会自动读取自身各 Cluster 的当前属性值, 打包成 ExtensionFieldSets 存入场景表。相比 AddScene 需要手动指定每个属性值, StoreScene 更像一个「保存当前状态」的快捷操作。

参数类型说明
GroupIDgroup-id场景所属的组 ID
SceneIDuint8场景 ID(如果已存在则覆盖)

StoreSceneResponse 返回字段

字段类型说明
Statusstatus操作结果状态码
GroupIDgroup-id组 ID
SceneIDuint8场景 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 界面展示场景列表或判断还能创建多少个场景。

参数类型说明
GroupIDgroup-id要查询的组 ID

GetSceneMembershipResponse 返回字段

字段类型说明
Statusstatus操作结果状态码
Capacityuint8 / null剩余可存场景数量。null 表示未知
GroupIDgroup-id组 ID
SceneListlist<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 返回字段

字段类型说明
Statusstatus操作结果状态码
GroupIdentifierFromgroup-id源组 ID
SceneIdentifierFromuint8源场景 ID
使用场景

用户在客厅配置好了「阅读模式」场景,想要在书房也用同样的配置。 通过 CopyScene 把客厅组的场景复制到书房组,不需要重新设置每个属性值。

属性详解

SceneManagement Cluster 有 3 个属性。场景数据本身不通过属性暴露, 而是通过 ViewScene / GetSceneMembership 命令读取。 属性提供的是场景表的容量、当前状态等元信息。

ID 名称 类型 说明
0x0000 LastConfiguredBy 新版已移除 node-id / null 最后修改场景表的节点 ID
0x0001 SceneTableSize uint16 场景表总容量
0x0002 FabricSceneInfo list<FabricSceneInfo> 各 Fabric 的场景概况信息

LastConfiguredBy(0x0000) 新版已移除

新版 Matter 已移除

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 有多少个场景、当前激活的是哪个场景、还能再存多少个。

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 索引
SceneValid 的含义

当通过 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)声明设备支持的高级能力:

Bit 0
SN(SceneNames) 场景名称 —— 启用后 AddScene 可以设置 SceneName 字段,ViewScene 返回场景名称
SN 特性是否必须

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 秒内渐变到暗暖光。

  1. 创建场景时,用 AddScene (0x00) 设置 ExtensionFieldSets:
    • OnOff:开启
    • LevelControl:亮度 = 25(约 10%)
    • ColorControl:色温设为暖白
    TransitionTime = 20(即 2.0 秒渐变)
  2. 日常使用时,App 发送 RecallScene (0x05),传入 GroupID 和 SceneID
  3. 设备在 2 秒内平滑切换到目标状态,灯光自然变暗变暖
  4. 如果用户想快速切换不要渐变,在 RecallScene 中覆盖 TransitionTime = 0
场景 2:起床模式 —— 清晨自然唤醒

目标:每天早上 7:00 灯光从关闭渐亮到明亮冷白光,模拟日出。

  1. 用 AddScene (0x00) 创建「起床」场景:
    • OnOff:开启
    • LevelControl:亮度 = 254(100%)
    • ColorControl:色温设为冷白(日光色)
    TransitionTime = 600(即 60 秒渐变,1 分钟日出效果)
  2. 在自动化规则中设定:每天 07:00 触发 RecallScene (0x05)
  3. 灯光在 1 分钟内从关闭状态缓缓亮起到日光白,自然唤醒
  4. 可配合 OnOff Cluster 的 OnWithTimedOff 做防忘关灯:起床 30 分钟后自动关闭
场景 3:一键场景切换 —— 物理按钮触发

目标:墙壁开关的单击 / 双击分别切换不同场景。

  1. 预先配置两个场景:
    • SceneID = 1「日常」:亮度 80%,自然白光
    • SceneID = 2「观影」:亮度 10%,暖白光
  2. 在绑定规则(Binding)中配置:
    • 开关单击 → RecallScene(GroupID=0, SceneID=1)
    • 开关双击 → RecallScene(GroupID=0, SceneID=2)
  3. 场景切换完全在本地执行(通过 Group 组播),不依赖云端,响应速度极快
  4. 用 StoreScene (0x04) 可以让用户自定义:把灯调到喜欢的状态, 长按开关触发 StoreScene,当前状态就保存为该按键对应的场景