合宙 IOT 通用报文协议 AirCloud -- 1.0
五、AirCloud 和遥测的关系
遥测的目的是检测设备的 mobile 信息,证明设备还活着,还具备通信能力;
airCloud 协议,目的是合宙设备驱动的业务,都有被记录到数据库的机会。
六、支持的通信承载
6.1、getip:
通信协议要求
- 协议需要兼容老设备, 同时兼容负载均衡
- 便于扩展到更多二进制数据的上传
- 要包含鉴权, 上传后要自动归入设备对应的数据里
通信逻辑
- 负载均衡服务器,支持生成图片上传的 url 和额外参数
- 设备通过调用 getip 接口, 获取图片上传所需要的 url 和参数列表
- 设备在指定条件下(定时/按键触发),使用上述参数执行上传
- 设备平台收到数据后, 需要展示到页面中
通信接口设计
请求(https)
URL device.openluat.com/getip?key="....."
METHOD GET
key 表示用户的 key 通过 sha256 加密后的值
响应(json 格式)
补充后的考虑如下:
{
//设备连接信息 (MQTT/TCP)
"conninfo": {
"host": "xxx", // 服务器地址
"port": xxx, // 端口
"user_name": "xxx", // 用户名
"password": "xxxxxxxx", // 密码
"transport": "tcp", //连接方式"tcp"或者"mqtt"
},
//图片上传信息
"imgupurl": "https://image.openluat.com/iot/upload/file",
"imgbody": {
"{data}": "f",
"auth": true,
"dir": "upload_image",
"mon": true,
"prefix": "123456789012_",
"index": true,
"thumb": "thumb",
"tip": "图片说明",
"rpt": false
},
"imgheader": {
"token": "2xb3….",
"salt": "80…",
"tu": 1
},
//音频上传信息
"audupurl": "https://audio.openluat.com/iot/upload/file",
** //下面具体字段还需要建栋确认。**
"audbody": {
"{data}": "audio_file", // 音频文件的字段名
"auth": true,
"dir": "upload_audio", // 服务端存储音频的目录
"mon": true,
"prefix": "123456789012_",
"index": true,
"size": 300, // 文件大小
"rpt": false//上传后成功是否返回详细信息。
},
"audheader": {
"token": "3yc4….",
"salt": "81…",
"tu": 1
}
}
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(), 上报设备数据。