3. Matter数据模型

Matter 的数据模型是整套协议能够跨厂商互操作的根基。它把一台设备抽象成一棵严格分层的树:最上层是节点(Node),节点下挂若干端点(Endpoint),端点下挂若干集群(Cluster),集群内部再细分为属性(Attribute)、命令(Command)和事件(Event)。理解这六层对象的从属关系,以及每一层“由谁定义、在哪里定义、如何被寻址”,是后续编写固件、生成代码、调试配网的前提。

六层对象的层次关系

节点代表一个可被 Matter 网络寻址的独立设备实体,它拥有唯一的 Node ID,并承载一个“根端点”。根端点固定为 Endpoint 0,它不面向用户功能,而是承载设备级信息:基本信息集群(Basic Information)、通用诊断集群、网络调试集群、访问控制集群等。真正对应用户功能的部分挂在 Endpoint 1 及之后的端点上。例如一盏可调光调色温的灯,可以设计为:Endpoint 0 放设备管理类集群,Endpoint 1 放 On/Off、Level Control、Color Control 三个功能集群。

端点本身是一个“逻辑功能容器”,它把一组协同工作的集群打包在一起,使同一设备可以对外呈现多个独立功能单元。集群是功能的最小语义单位,由 Matter 规范统一定义,例如 On/Off 集群的 ID 是 0x0006,Level Control 是 0x0008,Temperature Measurement 是 0x0402。集群内部的三类元素分工明确:属性描述状态(如当前亮度、当前色温),命令触发动作(如开、关、调亮度),事件上报历史或瞬时发生的事实(如开关被按下、设备重启)。

节点 Node Node ID = 0x0000000000000001 端点 Endpoint 0 根端点 · 设备管理 端点 Endpoint 1 功能端点 · 灯控 Basic Info 0x0028 Network Comm. 0x0031 On/Off 0x0006 Level Control 0x0008 属性 Attribute OnOff (0x0000) bool 命令 Command Toggle (0x02) 事件 Event SwitchLatched 层次速查 节点:设备唯一标识,承载全部端点 端点:逻辑功能容器,Endpoint 0 为根端点 集群:规范定义的功能单元,含属性/命令/事件 属性:描述状态,可读可订阅 命令:触发动作,由控制器下发 事件:上报历史或瞬时事实

寻址路径:从节点到具体属性

Matter 使用“路径(Path)”来唯一定位任意一个可操作对象。一条完整路径由四段组成:Node ID / Endpoint ID / Cluster ID / Attribute ID 或 Command ID 或 Event ID。例如要读取 Endpoint 1 上 On/Off 集群的 OnOff 属性,路径写作 1/1/0x0006/0x0000(节点 ID 在会话上下文中确定,因此常省略)。要下发 Toggle 命令,则写作 1/1/0x0006/0x02。这种“四元组”寻址方式使得任何符合规范的控制器都能以统一方式访问任意厂商的设备,无需私有协议适配。

定义方法:从规范到代码

在实际开发中,数据模型的定义通常分两步走。第一步是设备类型选择:Matter 规范预定义了标准设备类型(Device Type),例如“Dimmable Light”要求必须实现 On/Off、Level Control 集群,可选实现 Color Control。开发者根据产品功能选择最接近的设备类型,从而获得一份“必须实现集群清单”。第二步是集群实现:对清单中的每个集群,逐一实现其属性、命令和事件。属性需要提供读取回调,可写属性还需提供写入回调;命令需要实现对应的处理函数;事件则在特定条件触发时上报。

以 On/Off 集群为例,规范要求实现 OnOff 属性(布尔型,0x0000)和 Off、On、Toggle 三个命令。在代码中,这通常映射为一个结构体或类,包含属性存储、命令处理函数和事件触发接口。下面是一段示意性的伪代码,展示集群实现的基本骨架:

// 示意性伪代码:On/Off 集群实现骨架
Cluster OnOffCluster {
    Attribute OnOff = false;          // 0x0000, bool, 可读可订阅

    Command Off()   { OnOff = false; } // 0x00
    Command On()    { OnOff = true;  } // 0x01
    Command Toggle() { OnOff = !OnOff; } // 0x02

    // 属性变化时自动上报,无需手动触发
}

需要注意的是,属性值的变化并不需要开发者手动“发送通知”。Matter 采用订阅机制:控制器订阅某个属性后,设备在属性值变化时会自动上报。因此实现的重点是保证属性值在命令执行后正确更新,订阅上报由协议栈处理。

端点设计中的常见取舍

一个设备应该设计几个端点,是实际开发中经常遇到的问题。基本原则是:功能上独立可控的单元应放在不同端点。例如一个双路开关面板,两路灯可以独立开关,就应设计为 Endpoint 1 和 Endpoint 2,各自拥有独立的 On/Off 集群。如果两路必须同步动作,也可以合并为一个端点,但灵活性会降低。另一个常见做法是把传感器和執行器放在同一节点的不同端点上,例如 Endpoint 1 放温度传感器集群,Endpoint 2 放开关集群,这样控制器可以分别订阅和操作。

根端点 Endpoint 0 是强制存在的,且必须实现 Basic Information 集群。很多初学者会忽略这一点,导致设备无法通过认证测试。Basic Information 集群中的 VendorID、ProductID、NodeLabel 等属性是配网和识别设备的关键信息,必须在固件中正确填写。

属性、命令、事件的协作关系

三者不是孤立存在的,而是围绕“状态”形成闭环。属性是状态的载体,命令是改变状态的入口,事件是状态变化的记录。以调光开关为例:控制器下发 MoveToLevel 命令(Level Control 集群,命令 ID 0x00),设备执行后更新 CurrentLevel 属性(0x0000),如果配置了订阅,属性变化会自动上报给控制器;同时,如果设备支持 SwitchLatched 事件,在物理按键被按下时也会上报事件。控制器通过订阅属性获得实时状态,通过事件获得瞬时动作记录,两者互补。

层次 作用 示例 是否可订阅
节点 Node 设备唯一标识与寻址入口 Node ID 0x0001 —
端点 Endpoint 逻辑功能容器 Endpoint 1(灯控) —
集群 Cluster 功能语义单元 On/Off (0x0006) —
属性 Attribute 描述状态 OnOff (0x0000) 是
命令 Command 触发动作 Toggle (0x02) 否
事件 Event 上报事实 SwitchLatched 是