跳转至

合宙 IOT 通用报文协议 AirCloud -- 1.0

五、AirCloud 和遥测的关系

遥测的目的是检测设备的 mobile 信息,证明设备还活着,还具备通信能力;

airCloud 协议,目的是合宙设备驱动的业务,都有被记录到数据库的机会。

六、支持的通信承载

6.1、负载均衡 getip:

通信协议要求

  1. 协议需要兼容老设备, 同时兼容负载均衡
  2. 便于扩展到更多二进制数据的上传
  3. 要包含鉴权, 上传后要自动归入设备对应的数据里

通信逻辑

  1. 负载均衡服务器,支持生成图片上传的 url 和额外参数
  2. 设备通过调用 getip 接口, 获取图片上传所需要的 url 和参数列表
  3. 设备在指定条件下(定时/按键触发),使用上述参数执行上传
  4. 设备平台收到数据后, 需要展示到页面中

通信接口设计

请求(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(), 上报设备数据。