合宙的设备,需要一个通用的报文协议,使得合宙的设备,能够按照这个通用协议,把设备采集的各种数据上报到合宙云平台做记录。
同时,该协议,也能够支持接收下发的指令。
该协议必须是基于连接的承载,可以是 TCP,也可以是 MQTT,以方便进行鉴权。
协议采用二进制方式,节约通信流量,降低功耗。
同时,该协议要足够简单,看完报文协议后,无需查阅,就可以理解报文的含义。
上行和下行,采用同样的报文格式。
报文分为消息头和消息体两部分。
消息头只有一个,在报文开头,固定12个字节,分为设备ID,消息长度,版本标志三个字段。
消息体可以有多个,采用TLV的形式。
除了特殊约定外,报文的各个字节采用大端对齐的方式。
消息头一共 16 字节。
1, 设备 ID - 8 字节
其中第一个字节,代表设备类型,4G,WiFi,BLE,等;
剩余 7 字节为设备 ID,可以是 IMEI,也可以是 MAC, 也可以是 Chip ID,不做特殊约定。
设备 ID 采用 BCD 编码方式。
设备 ID 长度不足 7 字节的,自动在高位补 0.
2,流水号 - 2 字节
3,消息长度 - 2 字节
从版本标识开始的消息长度,最长不能大于 1400字节。
4,消息标识-4 字节
用来做协议和消息约定的32个bit。
bit0-3: 协议版本号;
bit4: 是否需要回复
bit5: 是否携带鉴权 key
其余26个bit 为0.
消息体有多个 TLV 组成: T-字段类型,L-字段长度,V-字段取值,可以任意多个 TLV, 只要消息长度不超过 1400 字节即可。
1, 字段类型 - 2 字节
前面 12 个 bit, 代表字段含义,比如温度,湿度,转速,工作或者停止,等等;
后面 4bit,代表数据类型(整数,浮点,bool,ascii,binary)
2, 长度 - 2 字节
字段取值的长度
3, 字段值
实际的值。
| 字段 | **字段名** | **长度** | 含义 |
| 消息头 | 设备ID | 8 | 第一个字节,代表设备类型,4G,WiFi,BLE,等; 剩余7字节为设备ID,可以是IMEI,也可以是MAC, 也可以是Chip ID,不做特殊约定。 |
| 消息头 | 流水号 | 2 | |
| 消息头 | 消息长度 | 2 | 从消息标识开始的消息长度,最长不能大于 1400字节。 |
| 消息头 | 消息标识 | 4 | bit0-3: 协议版本号; bit4: 是否需要回复 bit5: 是否携带鉴权 key 其余26个bit 为0. |
| 认证key(可选) | key | 64 | 用于 UDP 报文的鉴权 |
| TLV1 | 字段类型 | 2 | 前面12个bit, 代表字段含义,比如温度,湿度,转速,工作或者停止,等等; 后面4bit,代表数据类型(整数,浮点,bool,ascii,binary) |
| TLV1 | 长度 | 2 | |
| TLV1 | 字段值 | N | |
| TLV2 | 字段类型 | 2 | |
| TLV2 | 长度 | 2 | |
| TLV2 | 字段值 | N | |
| ...... | |||
在设备建立连接之前,需要发送鉴权消息。
鉴权的方式是,通过 TLV 传递用户的 key+IMEI(或者 MAC)+MUID,由服务器判断是否合法,如果不合法的话,服务器主动发起断链操作。
报文 value:用户 key+"-"+imei(或 mac)+"-"+muid(或 unique_id)
字段类型: 0003 - ASCII 可打印字符串
示例: 对于 4g 模组:
例如:
完整报文就是:X1zBmxSd1H2Gy69DtAyNytmUe7dudGXm-862419074073247-20250605190426A662704A3771265005
对于 wifi 模组:
用户 key:客户在平台创建项目的时候生成的字符串,可打印字符
Sta mac:wifi 模组的 sta mac,获取的 hex 格式的 mac 地址,为 16 进制可见字符串
muid:等待适配
例如:
用户 key 参考 iot 平台的如:X1zBmxSd1H2Gy69DtAyNytmUe7dudGXm
Sta mac:C8C2C68E12E6
完整报文:X1zBmxSd1H2Gy69DtAyNytmUe7dudGXm-C8C2C68E12E6-muid(等待适配)
对于以太网模组(mcu+ 网口):
用户 key:客户在平台创建项目的时候生成的字符串,可打印字符
以太网 mac:以太网的 mac,需要转为十六进制可见字符串
unique_id:muc 通过 mcu.unique_id()获取的唯一 id,需要转为十六进制可见字符串
示例:用户 key 参考 iot 平台的如:X1zBmxSd1H2Gy69DtAyNytmUe7dudGXm
服务器收到鉴权消息后解析出 key、imei(mac)、muid,并校验 imei 和 muid 是不是匹配,然后通过 key 找到对应的项目,在项目中查找是否存在该 imei(mac)设备,存在就返回鉴权成功,不存在就返回失败,并断开链接
服务器需要注意,生成的用户 key 不能有 "-"符号。
服务器校验成功后,需要下发"ok"或者"success"通知模组,字段类型为 17
设备主动向云平台报告在线状态、维持连接活性。
心跳规则:
字段类型一共 2 字节,分为两部分: 字段含义和数据类型,其中字段含义 12bit,数据类型 4bit。
数据类型占用 4 个 bit,理论上支持 16 种数据类型。
0000 - 整数
0001 - 浮点数
0002 - 布尔值
0003 - ASCII 字符串
0004 - binary 字符串
0005 - UNICODE 字符串
字段含义占用 12bit,理论上支持 4096 种字段含义。
其中,
(1) 0 - 15 为预留值,
(2) 16-255 为控制信令类型,
(3) 256-2047 为业务字段类型,分为传感类,资产管理类,设备参数类,其他每个类别 256 种字段。
(4) 2048-4095 为预留值。
16 - 鉴权请求 - 上行
17 - 鉴权回复 - 下行
18 - 上报回应 - 下行,用于服务器对设备的上报的回应
19 - 控制命令 - 下行, 用于服务器对设备下发的控制命令
20 - 控制回应 - 上行, 用于对服务器发送的控制命令的回应
21 - iRTU 下行命令,
22 - iRTU 上行回复,
256 - 温度
257 - 湿度
258 - 颗粒数
259 - 酸度
260 - 碱度
261 - 海拔
262 - 水位
263 - CPU 温度/环境温度
264 - 电量计量
512- GNSS 经度
513 - GNSS 维度
514 - 行驶速度
515 - 最强的 4 颗 GNSS 卫星的 4 个 CN
516 - 搜到的所有卫星数
517 - 可见卫星数
518 - 航向角
519 - 基站定位/GNSS 定位标识
520 - GNSS 芯片型号和固件版本号
521- 方向
768 - 高度
769 - 宽度
770 - 转速
771 - 电量(mV)
772 - 驻留小区
773 - 驻留小区和临区
774 - 元器件型号
775 - GPIO 高低电平
776 - 开机原因
777 - 开机次数
778 - 休眠模式
779- 定时唤醒间隔
780 - 设备入网的 IPV4/IPV6 标志
781 - 当前联网方式(4G/WiFi/以太网)
1024 - Lua 核心库错误上报(用于 LuatOS 自动化测试)
1025 - Lua 扩展卡错误上报(用于 LuatOS 自动化测试)
1026 - Lua 业务错误上报(用于 LuatOS 自动化测试)
1027 - 固件版本号
1028 - SMS 转发
1029 - 来电转发
1280 - 时间
1281 - 无意义数据
T: 21
L: 消息的长度
V:实际的 iRTU 下行命令的全文
举例:
T: 0x0017 ----- 信令类型 21
L: 0x000B ---- 11 个字节
V: 字符串: “rrpc,getcsq”
T: 22
L: 消息的长度
V:实际的 iRTU 上行命令全文
举例:
T: 0x0017 ----- 信令类型 22
L: 0x000B ---- 14 个字节
V: 字符串: “rrpc,getcsq,17”
遥测的目的是检测设备的 mobile 信息,证明设备还活着,还具备通信能力;
airCloud 协议,目的是合宙设备驱动的业务,都有被记录到数据库的机会。
TCP server 收到数据后,直接发起写入数据库动作。
TCP server 在接受了 socket 连接后,等待设备的鉴权请求,如果超时或者鉴权请求不通过,主动发起断链。
有三个角色: 设备,Broker,ServClient。
ServClient 订阅所有主题,设备只订阅跟自己相关的主题。
设备的主题名字为: /AirPro/DeviceID/ServType
其中, AirPro 是固定字符串;
DeviceID 是设备的 ID, 内容和消息头的 设备 ID 相同;
ServType 包括两种:
(1)auth
(2)all
其中, auth 是指鉴权报文, all 是指所有其他报文。
设备和Broker建立MQTT 连接后,首先设备要发起鉴权,Broker把鉴权请求转发给ServClient,ServClient审核后,回复鉴权通过或者鉴权失败。
如果回复的是鉴权失败,ServClent需要在10秒钟之内通知Broker,把发起鉴权的设备进行断链处理。
如果设备超时没有发起鉴权,ServClient也要通知Broker,把设备断链。
airCloud 当前不推荐 UDP 协议。
如果必须要用 UDP 的话,需要在消息标识的第 6 个 bit 设为 1, 并在消息头和 TLV 中间,放置 64 字节的 key。
服务器需要对每个 UDP 消息,进行 key 的合法性检查。
airCloud 当前不支持 HTTP UDP 协议。
所有上报的数据,都记录到数据库
提供 web 表单查询日志,并且可以导出到文件。
可视化展现,和数据存储做分离的实现。
提供 web 后台的查询接口,后端和前端的实现可以分离。
合宙的开发板,默认都使用一个 key, 上报当前的驻留小区,可以在后台查询日志。
合宙的量产小板,用 airCloud 批量挂测,做压力测试。
IRTU 取消对第三方云平台的支持, 只内置合宙 airCloud 协议。
客户可以用这个协议,搭建自己的后台;
也可以上报合宙的后台,合宙按照套餐收费。
合宙平台收费标准如下:
| 免费版 | 标准版 | VIP版 | |
| 年费 | 0 | ¥3000 | ¥10000 |
| 设备数 | 3 | 100(可扩容) | 1000(可扩容) |
| 每日上行消息限量 | 1000 | 1.5万 | 150万 |
| 数据保存时间 | 7天 | 6个月 | 12个月 |
| API 云端对接 | 不支持 | 支持 | 支持 |
| 日志导出文件 | 不支持 | 支持 | 支持 |
| 二级用户 | 不支持 | 10 | 100 |
扩容费用:
| 扩容量 | 价格 | |
| 设备数扩容 | 100 | 500 |
| 每日消息量扩容 | 10万 | 500 |
| 二级用户 | 100 | 200 |
| 数据存储 | 1亿报文1年 | 1000 |
exiot 扩展库, 调用 socket 核心库,mqtt 核心库,exnetif 扩展库。
扩展卡包含如下成员函数:
1, init(): 初始化参数,设备 ID,流水号初始化,指定协议版本,
2, auth_req(), 携带对收到鉴权回复的回调,以及超时的回调。
3, data_report(), 上报设备数据。