3. 数据上报与属性设置:设备属性上报、平台下发属性、数据格式解析
好,咱们进入第三个核心环节。这一节我打算把「设备怎么把数据报上来」和「平台怎么把指令发下去」这两条路彻底讲透。
你想想看,IoT 系统说白了就两件事:数据上行和指令下行。上行是设备告诉平台「我现在怎么样了」,下行是平台告诉设备「你给我做什么」。这两条路走不通,整个系统就是摆设。
3.1 设备属性上报:设备在「说话」
设备属性上报,就是设备主动向平台报告自己的状态。比如温度传感器每隔 5 秒上报一次当前温度,或者智能门锁在开门瞬间上报一个「门已打开」的事件。
上报的两种方式:
- 定时上报:设备按固定周期上报数据。我习惯在低功耗场景下把周期拉长到 30 秒以上,省电。
- 事件触发上报:只有状态变化时才上报。比如门锁从「关」变成「开」,立刻上报一次。
核心要点:上报的数据格式必须与产品模型中定义的属性一致。你在产品模型里定义了「temperature」是 int 类型,上报时就不能传字符串。
举个例子,一个温湿度传感器上报数据,典型的 JSON 格式是这样的:
{
"service_id": "temperature_humidity",
"data": {
"temperature": 25.6,
"humidity": 68.3
},
"event_time": "2025-01-15T10:30:00Z"
}
这里有个细节——service_id 必须和产品模型里定义的服务 ID 完全一致。我在项目中遇到过有人把 service_id 写成了驼峰命名,结果平台死活不认,排查了半天才发现是大小写问题。
3.2 平台下发属性:平台在「下指令」
下行就更有意思了。平台下发属性,说白了就是平台告诉设备「你把某个参数改成 XXX」。比如远程调整空调的目标温度,或者修改传感器的上报频率。
下发的典型场景:
- 远程配置:修改设备的工作参数,比如上报间隔、阈值等。
- 远程控制:直接控制设备执行某个动作,比如打开继电器、切换模式。
平台下发属性的消息格式长这样:
{
"object_device_id": "device_001",
"services": [
{
"service_id": "temperature_humidity",
"properties": {
"target_temperature": 26.0,
"mode": "cool"
}
}
]
}
注意:设备收到下发的属性后,必须回复一个响应。如果设备不回复,平台会认为下发失败,并且会重试。我曾经在项目中因为设备端没写响应逻辑,导致平台疯狂重试,把设备搞死机了。
3.3 数据格式解析:别让格式坑了你
嗯,这里要重点说一下数据格式。华为云 IoT 平台支持两种主流格式:JSON 和 二进制。
| 格式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| JSON | 资源丰富的设备(如 Linux 网关、Android 设备) | 可读性强、调试方便 | 数据量大、解析开销大 |
| 二进制 | 资源受限设备(如 MCU、低功耗传感器) | 数据量小、传输效率高 | 可读性差、需要编解码插件 |
我个人习惯是:能用 JSON 就用 JSON。为什么?因为调试太方便了。你在 MQTT 客户端里直接看到明文数据,一眼就能看出问题。二进制格式虽然省流量,但一旦出问题,你得拿着十六进制数据对着协议文档一个一个字节对,那叫一个痛苦。
但如果你做的是 NB-IoT 或者 LoRa 这种低带宽场景,二进制就是唯一选择了。这时候你需要写一个编解码插件,把二进制数据转换成平台能理解的 JSON。
我的经验:编解码插件最好在设备端和平台端各写一份。设备端编码时,把数据按协议打包成二进制;平台端解码时,用插件还原成 JSON。两边对着一份协议文档开发,能减少很多沟通成本。
3.4 避坑指南:我踩过的三个坑
- 属性名大小写不一致:产品模型里定义的是「temperature」,设备上报的是「Temperature」,平台直接丢弃。我曾经因为这个排查了整整一天。
- 忘记回复平台下发:设备收到下发的属性后,必须回复一个空响应。不回复的话,平台会一直重试,直到超时。
- 时间戳格式不对:平台要求的时间戳是 ISO 8601 格式,比如 "2025-01-15T10:30:00Z"。有人传了时间戳整数,平台解析失败。
好了,这一节的内容就这些。数据上报和属性下发是 IoT 系统最基础的两个操作,但也是最容易出问题的地方。你只要把格式、响应、时间戳这三个点盯住了,基本不会翻车。