绑定 Cluster(Binding)

Cluster ID: 0x001E  |  所在 Endpoint: 功能端点(如 Endpoint 1) |  角色: Client 侧配置(无命令,通过写属性配置)

Binding 是 Matter 中定义设备间「接线关系」的 Cluster。它解决的核心问题是: 一个设备发出的命令,应该发给谁?

举个例子:你有一个智能开关和一个智能灯泡。按下开关时,开关怎么知道该控制哪盏灯? 答案就是 Binding —— 在开关的 Binding 属性里写入灯泡的地址,开关就「认识」了这盏灯。

核心概念:Binding 是 Client 侧的配置

Binding 配置在发送命令的一方(Client),而不是接收命令的一方(Server)。 比如开关控灯的场景:Binding 写在开关上,不是写在灯泡上。

可以把 Binding 理解为「通讯录」—— 开关的通讯录里记着灯泡的地址, 按下按钮时就按照通讯录里的地址发送 OnOff 命令。灯泡自己不需要知道是谁在控制它。

没有命令,只有属性写入

Binding Cluster 没有任何命令。所有配置都通过 Write Attribute 操作完成 —— 直接写入 Binding 属性。 这意味着每次写入都是全量替换整个绑定列表,不是追加。 修改绑定时,先读取当前列表,修改后整体写回。

属性

Binding Cluster 只有一个属性,且是必须支持的。

ID 名称 类型 读写 说明
0x00 Binding list<TargetStruct> 读写 绑定目标列表

Binding(绑定目标列表)

一个 TargetStruct 的列表,每个条目描述一个绑定目标。 设备会按照这个列表中的地址发送命令。列表为空表示没有绑定任何目标。

写入时是全量替换 —— 新写入的列表会完全覆盖旧的。 如果只想添加一个绑定,需要先读取现有列表,追加新条目后整体写回。

TargetStruct 字段

ID 字段 类型 必填 说明
0 Node node-id 可选 目标节点 ID(单播绑定时使用)
1 Group group-id 可选 目标群组 ID(组播绑定时使用)
2 Endpoint endpoint-no 可选 目标端点(单播绑定时与 Node 配合使用)
3 Cluster cluster-id 可选 绑定到目标的哪个 Cluster
254 FabricIndex fabric-idx 是 此绑定所属的 Fabric
单播 vs 组播:二选一

每个 TargetStruct 要么是单播绑定(指定 Node + Endpoint), 要么是组播绑定(指定 Group)。两者不能同时出现在同一个条目中。

  • 单播:控制一台特定设备的特定端点,如「这个开关控制卧室床头灯」
  • 组播:控制一个群组内的所有设备,如「这个开关控制客厅所有灯」

Cluster 字段可选 —— 省略时表示绑定目标上的所有 Cluster, 填写时表示只绑定到特定 Cluster(如只绑定 OnOff,不绑定 LevelControl)。

示例数据

读取绑定列表

{
  // 读取绑定列表
  "attributeRequests": [{
    "endpointId": 1,
    "clusterId": "0x001E",
    "attributeId": "0x00"          // Binding
  }]
}

单播绑定(开关 → 灯泡)

将开关(Endpoint 1)绑定到 Node 2 上的灯泡(Endpoint 1)的 OnOff Cluster:

{
  // 单播绑定:开关 → 灯泡
  // 写入 Endpoint 1 的 Binding 属性
  "writeRequests": [{
    "attributePath": {
      "endpointId": 1,
      "clusterId": "0x001E",
      "attributeId": "0x00"        // Binding
    },
    "dataVersion": 0,
    "data": [
      {
        "0": 2,                    // Node = 2(目标灯泡的 Node ID)
        "2": 1,                    // Endpoint = 1(目标灯泡的功能端点)
        "3": "0x0006",             // Cluster = OnOff(绑定到 OnOff Cluster)
        "254": 1                   // FabricIndex = 1
      }
    ]
  }]
}

组播绑定(开关 → 灯群组)

将开关绑定到群组 1,按下时群组内所有灯一起响应:

{
  // 组播绑定:开关 → 一组灯
  "writeRequests": [{
    "attributePath": {
      "endpointId": 1,
      "clusterId": "0x001E",
      "attributeId": "0x00"        // Binding
    },
    "dataVersion": 0,
    "data": [
      {
        "1": 1,                    // Group = 1(目标群组 ID)
        "3": "0x0006",             // Cluster = OnOff(绑定到 OnOff Cluster)
        "254": 1                   // FabricIndex = 1
      }
    ]
  }]
}

多重绑定(一个开关控制多个目标)

同一个开关同时绑定两盏灯和一个群组 —— 列表中的每个条目都是一个独立的绑定目标:

{
  // 多重绑定:一个开关同时控制多个目标
  "writeRequests": [{
    "attributePath": {
      "endpointId": 1,
      "clusterId": "0x001E",
      "attributeId": "0x00"
    },
    "dataVersion": 0,
    "data": [
      {
        "0": 2, "2": 1, "3": "0x0006",   // 灯泡 A(Node 2, Endpoint 1, OnOff)
        "254": 1
      },
      {
        "0": 3, "2": 1, "3": "0x0006",   // 灯泡 B(Node 3, Endpoint 1, OnOff)
        "254": 1
      },
      {
        "1": 1, "3": "0x0006",            // 群组 1(客厅所有灯)
        "254": 1
      }
    ]
  }]
}

常见场景

场景 1:开关控制灯泡(单播绑定)

最经典的 Binding 场景。一个墙壁开关控制一盏特定的灯。

  1. 开关和灯泡都已配网到同一个 Fabric
  2. 确认灯泡的 Node ID(如 2)和功能端点(如 Endpoint 1)
  3. 在开关的 Endpoint 1 写入 Binding 属性,添加一条 Node=2, Endpoint=1, Cluster=0x0006(OnOff) 的记录
  4. 按下开关 → 开关自动向 Node 2 / Endpoint 1 发送 OnOff Toggle 命令 → 灯泡响应

这个过程不需要 Hub 或云端中转 —— 开关和灯泡在本地 Fabric 内直接通信。

场景 2:开关控制一组灯(组播绑定)

客厅有 3 盏灯,用户希望一个开关同时控制它们。

  1. 先通过 Groups Cluster 将 3 盏灯加入同一个群组(如 Group ID = 1)
  2. 在开关的 Binding 属性写入一条 Group=1, Cluster=0x0006 的记录
  3. 按下开关 → 开关向群组 1 发送组播 OnOff 命令 → 3 盏灯同时响应

组播比逐个发送单播命令更高效,延迟更低,所有灯几乎同时响应。

场景 3:多重绑定(一个开关控制多个不同目标)

一个场景开关需要同时控制不同类型的设备。

  1. Binding 列表中写入多条记录,每条指向不同的目标
  2. 可以混合使用单播和组播 —— 比如一条指向卧室灯(单播),一条指向客厅灯组(组播)
  3. 按下开关时,设备会遍历 Binding 列表,向每个目标都发送命令

注意:多重绑定时,所有目标收到的是相同的命令。 如果需要对不同设备发送不同命令(比如开灯的同时关空调),应该使用自动化规则而不是 Binding。

开发建议

App 中管理 Binding 的典型流程:

  1. 先读取当前 Binding 列表(Read Attribute)
  2. 在 App UI 中展示已绑定的目标设备
  3. 用户添加或移除绑定目标
  4. 将修改后的完整列表写回(Write Attribute)—— 注意是全量替换

写入时需要提供正确的 FabricIndex,通常从当前连接的 Fabric 信息中获取。 跨 Fabric 的绑定条目不会被写入操作影响 —— 每个 Fabric 只能管理自己的绑定。