3. 通信协议与数据上云:MQTT协议详解、JSON数据格式设计、设备接入阿里云IoT/华为云IoT平台流程

好,咱们进入第三章。这一章我估计是很多同学最关心的——数据怎么从电梯里跑出来,又怎么稳稳当当地送到云端。

说实话,我在做第一个电梯物联网项目时,最头疼的就是通信这块。电梯在井道里,信号时好时坏,数据丢了都不知道。后来我选定了MQTT,才算是把这块硬骨头啃下来了。

3.1 MQTT协议——为什么是它?

MQTT,全称是Message Queuing Telemetry Transport。名字挺长,但你记住三个关键词就行:轻量、发布/订阅、可靠

为什么电梯物联网要用MQTT?我跟你分析一下:

  • 带宽小——电梯控制器一般就几十K的内存,跑HTTP太重了。MQTT的报文头最小只有2个字节,你想想看,这得多省。
  • 支持断线重连——电梯在运行中,信号可能瞬间丢失。MQTT有遗嘱消息(Last Will)和保留消息(Retained Message),设备掉线了,云端能第一时间知道。
  • QoS质量等级——你可以选择数据要不要确认到达。电梯报警这种关键数据,我一般用QoS 1,确保至少送达一次。

核心概念速览:

  • Broker:消息代理,就是云端那个中转站。阿里云、华为云都提供。
  • Topic:主题,数据发到哪个“频道”。比如 /elevator/status/001
  • Publish/Subscribe:发布者发数据,订阅者收数据。电梯是发布者,监控平台是订阅者。

3.2 JSON数据格式设计——别小看这一步

数据格式设计,我吃过亏。早期项目里,大家各写各的,有人用XML,有人用自定义二进制。结果对接时,光解析就花了两周。

后来我统一用JSON,简单、可读性强、解析快。但JSON也不是随便写的,我总结了一套规范:

3.2.1 基础结构

{
  "deviceId": "ELV-001",
  "timestamp": 1712563200000,
  "dataType": "status",
  "payload": {
    "floor": 12,
    "speed": 1.5,
    "doorState": "open",
    "load": 680,
    "faultCode": 0
  }
}

注意几个要点:

  • deviceId:唯一标识,我习惯用“ELV-”前缀加编号,方便筛选。
  • timestamp:用毫秒时间戳,别用字符串。云端处理时,数值比字符串快一个数量级。
  • dataType:区分数据类型。status是状态,alarm是报警,config是配置。这样订阅时可以直接过滤。

3.2.2 报警数据示例

{
  "deviceId": "ELV-001",
  "timestamp": 1712563205000,
  "dataType": "alarm",
  "payload": {
    "alarmCode": "E102",
    "alarmDesc": "门锁回路故障",
    "severity": 2
  }
}

我的小技巧:severity字段用数字表示严重等级。1是致命,2是严重,3是警告。这样在云端做告警分级时,直接比较数值就行,不用解析字符串。

3.3 设备接入阿里云IoT平台

阿里云IoT平台,我用得最多。它的设备接入流程很清晰,我一步步说:

3.3.1 创建产品和设备

  1. 登录阿里云IoT控制台,创建产品。产品类型选“自定义”,节点类型选“设备”。
  2. 定义功能。比如添加“当前楼层”、“运行速度”等属性。这一步其实就是定义JSON里的字段。
  3. 注册设备。系统会生成三元组:ProductKey、DeviceName、DeviceSecret。这三个东西,一定要保存好。

我曾经踩过的坑:DeviceSecret泄露了,结果有人冒充设备往云端发假数据。后来我强制要求所有设备出厂前,必须把三元组烧录到安全芯片里,不能明文存储。

3.3.2 MQTT连接参数

阿里云的MQTT连接地址格式是:

${ProductKey}.iot-as-mqtt.${Region}.aliyuncs.com:1883

比如:a1B2cD3eF4.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883

连接时,用户名和密码的生成规则:

  • 用户名${DeviceName}&${ProductKey}
  • 密码:用DeviceSecret对时间戳做HMAC-SHA1加密。具体算法阿里云文档有,我建议直接用官方SDK,省心。

3.3.3 发布和订阅Topic

阿里云的Topic规则:

  • 上报属性/sys/${ProductKey}/${DeviceName}/thing/event/property/post
  • 接收指令/sys/${ProductKey}/${DeviceName}/thing/service/property/set

说白了,设备往第一个Topic发数据,云端就能收到。云端想控制设备,就往第二个Topic发指令。

3.4 设备接入华为云IoT平台

华为云的流程和阿里云大同小异,但有几个细节不一样:

3.4.1 设备认证方式

华为云支持两种:

  • 密钥认证:和阿里云类似,用设备ID和密钥。
  • 证书认证:用X.509证书。安全性更高,但管理成本也高。我一般只在金融、政务类项目里用证书。

3.4.2 MQTT连接参数

华为云的连接地址:

${DeviceId}.iot-mqtts.${Region}.huaweicloud.com:8883

注意,华为云默认用8883端口,走TLS加密。如果要用1883明文端口,得在控制台手动开启。

3.4.3 Topic设计

华为云的Topic格式:

  • 数据上报$oc/devices/${DeviceId}/sys/properties/report
  • 命令下发$oc/devices/${DeviceId}/sys/commands/#

对比总结:

特性 阿里云IoT 华为云IoT
认证方式 密钥(默认) 密钥/证书
默认端口 1883 8883(TLS)
Topic格式 /sys/${PK}/${DN}/... $oc/devices/${DN}/...
设备影子 支持 支持

3.5 避坑指南与实战建议

最后,我分享几个实战中总结的经验:

  • 心跳包别太频繁——我见过有人设成1秒一次,结果设备电量撑不过一天。建议30秒到60秒一次,足够了。
  • QoS别乱用——QoS 2虽然最可靠,但网络开销大。电梯状态数据用QoS 0或1就行,报警数据用QoS 1。
  • 数据压缩——如果设备上报频率高,比如每100毫秒报一次,建议用Gzip压缩JSON。我在一个项目里,压缩后流量减少了70%。
  • 离线缓存——电梯信号不好时,数据先存本地。等网络恢复,再批量上传。我一般用环形缓冲区,存最近1000条数据。

嗯,这一章的内容就这些。MQTT和JSON看着简单,但真正用好,还是得在项目里磨。下一章,咱们聊聊边缘计算——数据在电梯本地怎么预处理,怎么减轻云端的压力。