2. LwM2M对象模型与资源设计
LwM2M 的核心思想是把设备能力抽象成一棵可寻址、可发现、可读写的对象树。理解这棵树的结构,是后续做设备接入、数据上报、远程控制和固件升级的基础。LwM2M 定义了四个基本概念:Object(对象)、Object Instance(对象实例)、Resource(资源)和 Resource Instance(资源实例)。它们之间是层层包含的关系,最终通过一个 URI 唯一定位到某个具体数据点。
Object 是对某一类功能的抽象描述,例如“设备信息”“温度传感器”“连接监控”“固件升级”。每个对象由 OMA 分配一个数字 ID,比如设备对象是 3,连接监控对象是 4,固件升级对象是 5,温度传感器对象是 3303。Object 本身不存储数据,它定义的是“这一类设备应该有哪些资源”。Object Instance 是对象的具体实现,比如一台网关上有两个温度探头,就对应两个温度传感器对象实例,编号为 0 和 1。Resource 是对象实例中真正承载数据的字段,例如温度值、单位、最小值、最大值。Resource Instance 则用于资源本身是数组或多值的情况,比如一个资源表示“支持的多条频段列表”,每个频段就是一个资源实例。
把四层关系落到 URI 上,LwM2M 使用类似 /ObjectID/ObjectInstanceID/ResourceID/ResourceInstanceID 的路径。例如 /3303/0/5700 表示第 0 个温度传感器实例的“传感器值”资源;/3/0/0 表示设备对象的制造商资源。客户端注册到服务器后,服务器就是通过这样的路径去读、写、执行或观察资源的。路径中的层级不能随意跳写,资源实例只在资源被定义为多实例时才出现。
在实际开发中,我们并不需要从零设计所有对象。OMA 维护了一份公开的 LwM2M 对象注册表(OMA Object Registry),里面列出了标准对象的 ID、名称、版本、资源定义、资源编号、数据类型、操作权限和是否多实例。使用注册表时,先按功能检索对象,例如要上报电池电量就查“Battery”对象,得到 ID 为 6,再查它的资源表,知道 0 号资源是电量百分比、1 号资源是电压。这样服务器和客户端就能基于同一份定义通信,避免各自造字段导致互不兼容。注册表还标注了对象版本,例如 1.0 与 1.1 的资源差异,选型时要确认设备端和平台端支持的版本一致。
当标准对象无法覆盖业务需求时,就需要设计自定义对象。自定义对象不能占用 OMA 已分配的 ID,通常使用 32768~42767 这一段保留区间,或者由企业向 OMA 申请正式编号。设计自定义对象时,建议按以下思路推进:先明确这个对象要解决什么业务问题,再列出需要暴露给平台的字段,然后为每个字段确定资源编号、数据类型、操作权限和是否多实例,最后确定对象 ID 和版本号。
下面以一个“智能灌溉控制器”为例,说明自定义对象的设计过程。该设备需要上报土壤湿度、阀门状态、灌溉时长,并支持远程开关阀门。我们定义一个自定义对象,ID 取 33000,版本 1.0,名称 Irrigation Controller。资源设计如下表所示。
| 资源 ID | 资源名称 | 数据类型 | 操作权限 | 多实例 | 说明 |
|---|---|---|---|---|---|
| 0 | 土壤湿度 | Float | R | 否 | 百分比,0~100 |
| 1 | 阀门状态 | Boolean | R | 否 | true 表示开启 |
| 2 | 灌溉时长 | Integer | RW | 否 | 单位秒,可远程设置 |
| 3 | 阀门控制 | — | E | 否 | 执行资源,触发开/关 |
| 4 | 灌溉计划 | String | RW | 是 | 多条计划,每条为一个资源实例 |
设计完成后,客户端在注册时把该对象实例挂到对象树上,例如 /33000/0/0 表示土壤湿度,/33000/0/3 表示阀门控制执行资源。服务器读取 /33000/0/0 即可获得湿度值,向 /33000/0/2 写入 600 表示把灌溉时长设为 600 秒,向 /33000/0/3 发起 Execute 操作即可触发阀门动作。如果灌溉计划有多条,则通过 /33000/0/4/0、/33000/0/4/1 分别访问。
最后需要强调的是,对象模型不是静态的文档,而是设备与平台之间的契约。无论是使用标准对象还是自定义对象,都应把对象 ID、版本、资源编号、数据类型和权限写入设备端模型文件和平台端物模型配置,并在联调时用 Read、Write、Execute、Observe 四类操作逐一验证。只有路径、类型和权限三者完全对齐,后续的数据采集和远程控制才能稳定运行。