01 数据上报和命令下发
AirCloud 数据上报功能
作者:孟伟
一、功能概述
AirCloud 是 LuatOS 物联网设备云服务通信协议,提供设备连接、数据上报、远程控制和文件上传等核心功能。excloud 扩展库是 AirCloud 协议的实现,通过该库设备可以快速接入aircloud云服务平台(iot.luatos.com),实现远程监控和管理。
1.1 数据上报功能介绍
数据上报是 AirCloud 的核心功能之一,允许设备将各种状态数据、传感器数据等信息定期或触发式地传输到云端平台,实现:
- 设备状态实时监控
- 传感器数据采集与分析
- 设备运行历史记录
- 基于数据的业务决策
1.2 支持上报的具体数据类型
AirCloud 支持上报多种类型的数据,通过 excloud.FIELD_MEANINGS 常量定义,主要包括以下几大类:
1.2.1 传感器数据
| 数据类型 | 字段含义 | 建议数据类型 | 描述 |
| `TEMPERATURE` | 温度 | FLOAT | 设备或环境温度值 |
| `HUMIDITY` | 湿度 | FLOAT | 环境湿度百分比 |
| `PARTICULATE` | 颗粒物浓度 | INTEGER | 空气中颗粒物含量 |
| `ACIDITY` | 酸度(pH值) | FLOAT | 溶液酸碱度 |
| `ALKALINITY` | 碱度 | FLOAT | 溶液碱度值 |
| `ALTITUDE` | 海拔 | FLOAT | 设备当前海拔高度 |
| `WATER_LEVEL` | 水位 | FLOAT | 水位高度或液位 |
| `ENV_TEMPERATURE` | 环境温度 | FLOAT | 外部环境温度 |
| `POWER_METERING` | 电量计量 | FLOAT | 电力消耗或发电量 |
1.2.2 定位与运动数据
| 数据类型 | 字段含义 | 建议数据类型 | 描述 |
| `GNSS_LONGITUDE` | GNSS经度 | FLOAT | 设备经度坐标 |
| `GNSS_LATITUDE` | GNSS纬度 | FLOAT | 设备纬度坐标 |
| `SPEED` | 行驶速度 | FLOAT | 设备移动速度 |
| `GNSS_CN` | GNSS卫星信噪比 | INTEGER | 卫星信号质量 |
| `SATELLITES_TOTAL` | 搜索到的卫星总数 | INTEGER | 可见卫星数量 |
| `SATELLITES_VISIBLE` | 可见卫星数 | INTEGER | 实际使用的卫星数 |
| `HEADING` | 航向角 | FLOAT | 设备行驶方向角 |
| `LOCATION_METHOD` | 定位方式标识 | INTEGER | 0=基站定位, 1=GNSS定位, 2=混合定位 |
| `DIRECTION` | 方向角 | FLOAT | 设备朝向角度 |
1.2.3 设备状态数据
| 数据类型 | 字段含义 | 建议数据类型 | 描述 |
| `BATTERY_LEVEL` | 电池电压 | INTEGER | 电池电压值(mV) |
| `SIGNAL_STRENGTH_4G` | 4G信号强度 | INTEGER | 4G网络信号质量 |
| `SIM_ICCID` | SIM卡ICCID | ASCII | SIM卡唯一标识 |
| `NETWORK_TYPE` | 网络类型 | INTEGER | 当前联网方式(4G/WiFi/以太网) |
| `NETWORK_IP_TYPE` | 网络IP类型 | INTEGER | 0=IPv4, 1=IPv6 |
| `GPIO_LEVEL` | GPIO高低电平 | INTEGER | 设备GPIO状态 |
| `BOOT_REASON` | 开机原因 | INTEGER | 设备启动原因代码 |
| `BOOT_COUNT` | 开机次数 | INTEGER | 设备累计启动次数 |
| `SLEEP_MODE` | 设备休眠模式 | INTEGER | 0=正常, 1=轻休眠, 3=深度休眠 |
| `WAKE_INTERVAL` | 定时唤醒间隔 | INTEGER | 休眠唤醒时间间隔 |
1.2.4 设备参数数据
| 数据类型 | 字段含义 | 建议数据类型 | 描述 |
| `HEIGHT` | 设备物理高度 | FLOAT | 设备安装高度或物理尺寸 |
| `WIDTH` | 设备物理宽度 | FLOAT | 设备宽度尺寸 |
| `ROTATION_SPEED` | 转速 | INTEGER | 设备旋转速度 |
| `SERVING_CELL` | 驻留小区 | INTEGER | 当前服务基站信息 |
| `CELL_INFO` | 小区信息 | BINARY | 服务小区+邻区信息 |
| `COMPONENT_MODEL` | 元器件型号 | ASCII | 设备中具体元器件型号 |
1.2.5 软件与系统数据
| 数据类型 | 字段含义 | 建议数据类型 | 描述 |
| `FIRMWARE_VERSION` | 固件版本号 | ASCII | 设备固件版本信息 |
| `LUA_CORE_ERROR` | Lua核心库错误 | ASCII | Lua核心库错误信息 |
| `LUA_EXT_ERROR` | Lua扩展库错误 | ASCII | Lua扩展库错误信息 |
| `LUA_APP_ERROR` | Lua业务错误 | ASCII | 业务逻辑错误信息 |
| `SMS_FORWARD` | 短信转发 | ASCII | 转发的短信内容 |
| `CALL_FORWARD` | 来电转发 | ASCII | 来电信息 |
1.2.6 通用数据
| 数据类型 | 字段含义 | 建议数据类型 | 描述 |
| `TIMESTAMP` | 时间戳 | INTEGER | 数据采集时间戳 |
| `RANDOM_DATA` | 无意义数据 | BINARY | 测试或占位数据 |
1.2.7 控制与响应数据
| 数据类型 | 字段含义 | 建议数据类型 | 描述 |
| `CONTROL_COMMAND` | 控制命令 | 不限制 | 平台下发的控制指令 |
| `CONTROL_RESPONSE` | 控制回应 | 不限制 | 设备执行命令的响应 |
| `AUTH_REQUEST` | 鉴权请求 | BINARY | 设备身份认证请求 |
| `AUTH_RESPONSE` | 鉴权回复 | BINARY | 平台认证结果回复 |
二、准备环境
2.1 硬件环境
-
Air780EPM V1.3 版本开发板一块 + 可上网的 sim 卡一张 +4g 天线一根 :
-
sim 卡插入开发板的 sim 卡槽
- 天线装到开发板上
-
TYPE-C USB 数据线一根 ,Air780EPM V1.3 版本开发板和数据线的硬件接线方式为:
-
Air780EPM V1.3 版本开发板通过 TYPE-C USB 口供电;(外部供电/USB 供电 拨动开关 拨到 USB 供电一端)
- TYPE-C USB 数据线直接插到核心板的 TYPE-C USB 座子,另外一端连接电脑 USB 口;
2.2 软件环境
在开始实践本示例之前,先筹备一下软件环境:
- 烧录工具: Luatools 工具;
- 本demo开发测试时使用的固件为Air780EPM V2018 版本固件,本demo对固件版本没有什么特殊要求,所以你如果要测试本demo时,可以直接使用最新版本的内核固件Air780EPM固件,Air780EHM固件;如果发现最新版本的内核固件测试有问题,可以使用我们开发本demo时使用的内核固件版本来对比测试
- LuatOS 需要的脚本和资源文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air780EPM/demo/aircloud
三、API 接口说明
详细 API 文档请参考:https://docs.openluat.com/osapi/ext/excloud/
四、数据上报功能实现
4.1 核心代码示例
--[[
本demo演示了excloud扩展库的数据上报功能,包括:
1. 设备连接与认证
2. 数据定时上报
3. 心跳保活机制
]]
-- 导入excloud库
local excloud = require("excloud")
-- 注册回调函数
function on_excloud_event(event, data)
log.info("用户回调函数", event, json.encode(data))
if event == "connect_result" then
if data.success then
log.info("连接成功")
sys.publish("aircloud_connected")
else
log.info("连接失败: " .. (data.error or "未知错误"))
end
elseif event == "auth_result" then
if data.success then
log.info("认证成功")
else
log.info("认证失败: " .. data.message)
end
elseif event == "message" then
log.info("收到消息, 流水号: " .. data.header.sequence_num)
-- 处理服务器下发的消息
for _, tlv in ipairs(data.tlvs) do
log.info("TLV字段", "含义:", tlv.field, "类型:", tlv.type, "值:", tlv.value)
if tlv.field == excloud.FIELD_MEANINGS.CONTROL_COMMAND then
log.info("收到控制命令: " .. tostring(tlv.value))
-- 处理控制命令并发送响应
local response_ok, err_msg = excloud.send({
{
field_meaning = excloud.FIELD_MEANINGS.CONTROL_RESPONSE,
data_type = excloud.DATA_TYPES.UNICODE,
value = "命令执行成功"
}
}, false)
if not response_ok then
log.info("发送控制响应失败: " .. err_msg)
end
end
end
elseif event == "disconnect" then
log.warn("与服务器断开连接")
elseif event == "reconnect_failed" then
log.info("重连失败,已尝试 " .. data.count .. " 次")
elseif event == "send_result" then
if data.success then
log.info("发送成功,流水号: " .. data.sequence_num)
else
log.info("发送失败: " .. data.error_msg)
end
end
end
-- 注册回调
excloud.on(on_excloud_event)
-- 主任务函数
function excloud_task_func()
-- 如果当前时间点设置的默认网卡还没有连接成功,一直在这里循环等待
while not socket.adapter(socket.dft()) do
log.warn("excloud_task_func", "wait IP_READY", socket.dft())
-- 在此处阻塞等待默认网卡连接成功的消息"IP_READY"
-- 或者等待1秒超时退出阻塞等待状态;
-- 注意:此处的1000毫秒超时不要修改的更长;
-- 因为当使用exnetif.set_priority_order配置多个网卡连接外网的优先级时,会隐式的修改默认使用的网卡
-- 当exnetif.set_priority_order的调用时序和此处的socket.adapter(socket.dft())判断时序有可能不匹配
-- 此处的1秒,能够保证,即使时序不匹配,也能1秒钟退出阻塞状态,再去判断socket.adapter(socket.dft())
sys.waitUntil("IP_READY", 1000)
end
-- 配置excloud参数
local ok, err_msg = excloud.setup({
use_getip = true, -- 使用getip服务
device_type = 1, -- 4G设备
auth_key = "VmhtOb81EgZau6YyuuZJzwF6oUNGCbXi",
transport = "tcp", -- 使用TCP传输
auto_reconnect = true, -- 自动重连
reconnect_interval = 10, -- 重连间隔(秒)
max_reconnect = 5, -- 最大重连次数
mtn_log_enabled = true, -- 启用运维日志
mtn_log_blocks = 2, -- 日志文件块数
mtn_log_write_way = excloud.MTN_LOG_CACHE_WRITE -- 缓存写入方式
})
if not ok then
log.info("初始化失败: " .. err_msg)
return
end
log.info("excloud初始化成功")
-- 开启excloud服务
local ok, err_msg = excloud.open()
if not ok then
log.info("开启excloud服务失败: " .. err_msg)
return
end
log.info("excloud服务已开启")
-- 启动自动心跳,默认5分钟一次的心跳
excloud.start_heartbeat()
log.info("自动心跳已启动")
-- 启动3分钟一次的心跳,可配置自定义内容
-- excloud.start_heartbeat(180, {
-- { field_meaning = excloud.FIELD_MEANINGS.TIMESTAMP,
-- data_type = excloud.DATA_TYPES.INTEGER,
-- value = os.time() }
-- })
-- 停止自动心跳
--excloud.stop_heartbeat()
-- 主循环:定期上报数据
while true do
-- 每30秒上报一次数据
sys.wait(30000)
-- 检查连接状态
local status = excloud.status()
if not status.is_connected then
log.warn("设备未连接,跳过数据上报")
else
-- 上报基础状态数据
local ok, err_msg = excloud.send({
{
field_meaning = excloud.FIELD_MEANINGS.SIGNAL_STRENGTH_4G,
data_type = excloud.DATA_TYPES.INTEGER,
value = 22 -- 信号强度
},
{
field_meaning = excloud.FIELD_MEANINGS.SIM_ICCID,
data_type = excloud.DATA_TYPES.ASCII,
value = "89860118801012345678" -- SIM卡ICCID
},
{
field_meaning = excloud.FIELD_MEANINGS.TIMESTAMP,
data_type = excloud.DATA_TYPES.INTEGER,
value = os.time()
}
}, false)
if ok then
log.info("基础数据上报成功")
else
log.error("基础数据上报失败:", err_msg)
end
end
end
end
-- 启动主任务
sys.taskInit(excloud_task_func)
4.2 代码解析
4.2.1 回调函数注册
回调函数用于处理 AirCloud 的各种事件,包括连接结果、认证结果、消息接收、发送结果等。特别是 send_result 事件,可以用于确认数据上报是否成功。
4.2.2 设备连接与认证
使用 excloud.setup() 配置设备参数,包括:
use_getip: 是否使用 getip 服务(推荐使用,支持负载均衡)device_type: 设备类型(1 表示 4G 设备)auth_key: 设备认证密钥(从云平台获取项目 key)transport: 传输协议(支持 "tcp" 和 "mqtt"、"tcp")auto_reconnect: 是否自动重连
4.2.3 数据上报实现
数据上报的核心是 excloud.send() 函数,它接受两个参数:
- 数据数组:包含多个 TLV(Type-Length-Value)格式的数据项
- 是否需要响应:布尔值,true 表示需要服务器响应
TLV 每个数据项包含三个字段:
field_meaning: 字段含义(使用 excloud.FIELD_MEANINGS 中的常量)data_type: 数据类型(使用 excloud.DATA_TYPES 中的常量)value: 数据值
4.2.4 心跳机制
心跳机制用于维持设备与云端的连接状态,可通过 excloud.start_heartbeat() 启动,默认每 5 分钟发送一次心跳。
五、GetIP 服务
5.1 GetIP 服务简介
GetIP 服务是 AirCloud 提供的负载均衡服务,用于:
- 为设备分配最优的服务器节点
- 返回图片/音频文件上传所需的 URL 和参数,以及运维日志上报的 URL 和参数
- 确保上传数据的安全性和可靠性
- 此服务在 excloud 扩展库中自动运行,用户脚本无需干预
六、云平台配置
6.1 平台配置步骤
- 需要先登录合宙 IOT 平台,如下图所示,没有账号的,可以先注册一个。客户向合宙采购 4G 模块时,如果采购人员没有告知合宙这批模块放在 iot 平台 上的哪个产品下,则合宙会以采购人的手机号为账号,默认密码 888888,创建一个"合宙标准模块"的项目,此次采购的所有模块都会放在这个项目下。
- 创建新项目或选择现有项目并获取项目 key (auth_key),并将获取的项目 key 配置在代码中。

代码中配置过程如下:

- 然后同样的账号登录 iot.luatos.com 平台中查看设备上报报文。

七、功能验证
7.1 Luatools 日志查看
通过 Luatools 工具可以查看设备的运行日志,确认数据上报是否正常:
- getip 设备日志:

- 数据上报设备日志:

7.2 云平台数据查看
云平台接收到的设备数据展示:

7.3 远程下发测试
通过云平台下发控制命令或数据,观察设备响应:
下发界面:

设备接收并响应控制命令的日志:

八、常见问题与解决方案
8.1 数据上报失败
原因分析:
- 网络连接不稳定
- 设备未成功认证
- 数据格式错误
- 云平台配置问题
解决方案:
- 检查网络连接状态
- 确认 auth_key 配置正确
- 验证数据格式是否符合要求
- 检查云平台设备状态
8.2 数据上报延迟
原因分析:
- 网络延迟
- 设备处理速度慢
- 上报频率过高
解决方案:
- 优化网络连接
- 减少单次上报的数据量
- 调整上报频率
九、总结
数据上报功能是 AirCloud 的核心能力之一,通过简单的 API 调用,设备可以轻松实现与云端的数据交互。合理使用数据上报功能,可以:
- 实现设备的远程监控与管理
- 为业务决策提供数据支持
- 及时发现设备异常情况
- 优化设备运行状态
通过本教程的学习,用户可以快速掌握 AirCloud 数据上报功能的使用方法,为物联网应用开发打下坚实的基础。