合宙 IOT 通用报文协议 AirCloud -- 1.0
五、AirCloud 和遥测的关系
遥测的目的是检测设备的 mobile 信息,证明设备还活着,还具备通信能力;
airCloud 协议,目的是合宙设备驱动的业务,都有被记录到数据库的机会。
六、支持的通信承载
6.1、负载均衡 getip:
通信协议要求
- 协议需要兼容老设备, 同时兼容负载均衡
- 便于扩展到更多二进制数据的上传
- 要包含鉴权, 上传后要自动归入设备对应的数据里
通信逻辑
- 负载均衡服务器,支持生成图片上传的 url 和额外参数
- 设备通过调用 getip 接口, 获取图片上传所需要的 url 和参数列表
- 设备在指定条件下(定时/按键触发),使用上述参数执行上传
- 设备平台收到数据后, 需要展示到页面中
通信接口设计
请求(https)
URL device.openluat.com/getip
METHOD POST
BODY {
"key": "用户key-imei",
"type": 1
}
参数说明:
key:用户 key + "-" + imei(或 mac) + "-" + muid(或 unique_id);string 格式
type:0 或不携带:定位产品
1:拍照上传的产品
2:音频上传
3:表示 aircloud 业务基于 tcp 协议上报数据;
响应(json 格式)
正常返回码 200, 其他均是错误返回。
注:对于 400,408 响应码需要在设备端考虑网络质量不稳定的处理。
失败响应:
首先判断非 200 的。对于 200 响应时,需要检查响应中的 msg 参数是否”ok”,如果不是”ok”,则描述的是失败原因。举例:
{
"msg": "invalid client"
}
成功响应:
首先判断 200 的,然后检查 msg 参数,如果结果是“ok”,则是成功响应。响应的具体内容与 type 有关。
当 type 为 0 时,表示 gps 位置上报类的业务,响应格式为:
{
"ipv4": "124.xx.xx.xx", "tcp",7808,
"ipv6": "2407:xxxx:xxxx:xxxx::xxxx:xxxx",
"udp": 7809,
"msg": "ok"
}
注意:可以提供ipv4及ipv6地址,且每类地址均可提供tcp及udp连接。
type 为 1,表示拍照上传类的业务,响应格式为:
{
"imgupurl": "https://xxx.xxx.com/api",
"imgbody": {"{data}","f", "auth", true, "dir",
"upload_image", "mon", true, "thumb", "t", "index", true,
"prefix", "86……"},
"imgheader":{……},//这一段无论返回什么数据,都作为post数据上报
"msg": "ok"
}
说明:
1、需要以form-data方式上传POST数据。
2、url是imgupurl返回的值。
3、imgheader,需要作为post的header部分,无论返回哪些数据都需携带。不需要包含imgheader这个字段。
4、imgbody需要作为post的body参数。“f”:是要上传的二进制图片文件数据。
auth为true表示取图片时需要鉴权,false表示不需要鉴权;
dir表示上传图片的归档目录;
mon表示按月归档;
thumb如果的值表示生成的缩略图会有改文字;
index为true表示数据归档入库(这个必须使用true,否则数据不入库,从管理台无法查询到);
prefix表示图片文件名前缀。
注意:imgbody部分返回新的支持如下方式。建议新的代码使用如下参数。
"imgbody": {"{data} ":"f", "param":"xxxxxx"}
表示数据使用f这个字段传输,另外一个字段使用param,携带的值为xxxx。该值包含了之前所有的key,简化操作。
当 type 为 3、4、5 的时候,都表示基于 aircloud 的业务,返回格式相同,相应格式举例:
{
"msg": "ok"
"conninfo":{
"ipv4": "124.xx.xx.xx",
"port": 9109,
"user_name": "",//mqtt才会有
"password": "",
},
"imginfo":{
"url": " https://xxx.xxx.com/api ",
"data_key":"f",
"data_param":{"key":"xxxxxx"}
},
"audinfo":{
"url": " https://xxx.xxx.com/api ",
"data_key":"f",
"data_param":{"key":"xxxxxx"}
}
}
说明:
conninfo段表示连接信息。其中:
ipv4表示分配到的上传服务器ip,port表示上传端口。
imageinfo和audioinfo分别表示图片上传及音频上传的服务器信息。其中:
url是上传的api,上传时需要以form-data方式POST数据;
data_key表示数据部分的参数(示例为”f”,按实际返回值填写),需要注意数据上传时,使用的名字即需要服务器保存的文件名,如果多次上传使用相同的文件名,后面的文件会覆盖前面的文件。
data_param里面作为其它参数(示例里表示需要额外加一个”key”,值为”xxxxx”,如果有其他参数,都作为POST参数携带)。
AirCloud 的调用 getip 的时机参考:
1、首次没有获取 ip 前调用
2、连接获取 ip 端口后,如果 TCP 断连先进行重连,如果 3 次重连失败就去调用 getip 重新获取 ip 及端口。
3、更异常的情况:若 getip 如果失败,也应该尝试 3 次。
6.2 TCP
TCP server 收到数据后,直接发起写入数据库动作。
TCP server 在接受了 socket 连接后,等待设备的鉴权请求,如果超时或者鉴权请求不通过,主动发起断链。
6.3 MQTT
6.3.1 MQTT 角色
有三个角色: 设备,Broker,ServClient。
6.3.2 MQTT 主题
ServClient 订阅所有主题,设备只订阅跟自己相关的主题。
设备的主题名字为: /AirCloud/direction/DeviceID/ServType
其中, AirCloud 是固定字符串;
direction 是传输方向:
(1)up:上行方向,表示从设备到服务器的通信
(2)down:下行方向,表示从服务器到设备的通信
DeviceID 是设备的 ID, 内容和消息头的 设备 ID 相同;
ServType 包括两种:
(1)auth
(2)all
其中, auth 是指鉴权报文, all 是指所有其他报文。
目前的 topic 主题如下:
设备鉴权上报:
/AirCloud/up/DeviceID/auth
设备数据上报:
/AirCloud/up/DeviceID/all
服务器鉴权响应下发:
/AirCloud/down/DeviceID/auth
服务器数据下发:
/AirCloud/down/DeviceID/all
6.3.3 鉴权
设备和Broker建立MQTT 连接后,首先设备要发起鉴权,Broker把鉴权请求转发给ServClient,ServClient审核后,回复鉴权通过或者鉴权失败。
如果回复的是鉴权失败,ServClent需要在10秒钟之内通知Broker,把发起鉴权的设备进行断链处理。
如果设备超时没有发起鉴权,ServClient也要通知Broker,把设备断链。
6.4 UDP
AirCloud 当前不推荐 UDP 协议。
如果必须要用 UDP 的话,需要在消息标识的第 6 个 bit 设为 1, 并在消息头和 TLV 中间,放置 64 字节的 key。
服务器需要对每个 UDP 消息,进行 key 的合法性检查。
6.5 HTTP
通过 getip 获取的上报 url
设备上传流程:
设备上传图片文件流程如下:
请求(https)
URL "https://image.openluat.com/iot/upload/file" , 根据getip的返回的数据决定,不能写死
METHOD POST
HEADERS 根据getip的返回数据进行填充,对应"imgheader"
BODY mulitpart格式
其中, body中文件的key 要使用 {data} 对应的值
响应(json 格式)
正常返回码 200, 其他一律作为错误
响应内容
{
"code":0,//code为0表示成功
"value": {//这个是rpt请求参数为true的返回。如果没有携带rpt,则value返回"上传成功"
"uri": "/vsna/luatos/336677/upload_image/2025-09/86453607261497520250908144614.png",
"size": "26.00KB",
"thumb": "/vsna/luatos/336677/upload_image/2025-09/86453607261497520250908144614s.png"
}
}
设备上传音频文件流程如下:
请求(https)
URL "https://audio.openluat.com/iot/upload/file" , 根据getip的返回的数据决定,不能写死
METHOD POST
HEADERS 根据getip的返回数据进行填充,对应"audheader"
BODY mulitpart格式
其中, body中文件的key 要使用 {data} 对应的值
响应(json 格式)
正常返回码 200, 其他一律作为错误
响应内容
{
"code":0,//code为0表示成功
"value": {//这个是rpt请求参数为true的返回。如果没有携带rpt,则value返回"上传成功"
"uri": "/vsna/luatos/336677/upload_image/2025-09/xxx.mp3",
"size": "26.00KB",
"thumb": "/vsna/luatos/336677/upload_image/2025-09/xxx.mp3"
}
}
调用时机
按业务逻辑而定
Aircloud 协议 http 文件上传:
上传控制信令:
23 - 文件上传开始通知 - 上行(设备通知服务器开始上传文件)
24 - 文件上传完成通知 - 上行(上传完成后通知服务器结果)
增加业务字段类型:
784 - 文件上传类型(图片/音频)
785 - 文件名称
786 - 文件大小
787 - 上传结果状态
http 文件上传的逻辑大概是:

七、云端后台实现
7.1 云端后台记录
所有上报的数据,都记录到数据库
7.2 日志查询
提供 web 表单查询日志,并且可以导出到文件。
7.3 可视化展现
可视化展现,和数据存储做分离的实现。
7.4 API 查询
提供 web 后台的查询接口,后端和前端的实现可以分离。
八,扩展库实现
excloud 扩展库, 调用 socket 核心库,mqtt 核心库,exnetif 扩展库。
扩展卡包含如下成员函数:
1, init(): 初始化参数,设备 ID,流水号初始化,指定协议版本,
2, auth_req(), 携带对收到鉴权回复的回调,以及超时的回调。
3, data_report(), 上报设备数据。