libfota3-远程升级
一、概述
libfota3 是合宙面向合宙主流产品(Air780Exx、Air8000、Air8101、Air1601 等系列)推出的 LuatOS 脚本方式 FOTA 远程升级扩展库。扩展库内部完成「检测新版本 → 下载升级包 → 校验 → 写入升级分区 → 重启生效 → 结果上报」的完整升级闭环,仅对接合宙 IoT 平台,不支持自建升级服务器。 使用前需在合宙 IoT 平台创建项目并获取 project_key(详见第六章操作演示),随后在脚本中 require 并调用 request() 完成一次配置,扩展库内部会自动完成等待网络、时间同步、定时检测、下载、刷写与重启。主要特性:
- 自动/手动双模式:auto+interval 定时检测,重启后按时间戳续算不漏检;check_update() 可随时手动触发。
- 运行期动态配置:config() 支持不重启调整参数,并自动同步定时器启停。
- 全过程状态回调与结果闭环:on_status 覆盖检测、下载(含百分比)、刷写、重启等环节;on_confirm 可为带屏设备提供下载前、重启前确认;升级结果会在重启后自动比对并上报服务器。
二、核心示例
local libfota3 = require("libfota3")
-- 一站式启动(自动检测 + 下载 + 重启)
libfota3.request({
project_key = "your_project_key", -- 项目密钥,用于FOTA服务认证
script_name = "fota3_temp", -- 脚本名称
script_version = "001.999.000", -- 脚本版本
auto = true, -- 启用自动定时检测
interval = 86400, -- 自动检测间隔(秒),默认24小时
on_status = function(status, msg, percent)
log.info("fota_temp", status, msg, percent)
end,
on_confirm = function(action, info, callback)
if action == "download" then
-- true 表示用户确认下载
callback(true)
elseif action == "reboot" then
-- true 表示用户确认重启升级
callback(true)
end
end,
})
-- 手动触发检测更新
libfota3.check_update()
-- 动态修改配置
libfota3.config({auto = false})
libfota3.config({auto = true, interval = 3600})
三、常量详解
libfota3 库没有常量。
四、函数详解
4.1 libfota3.request(new_opts)
功能
启动 FOTA 升级流程,是“自动检测 + 下载 + 重启”的一站式入口。
调用 request() 后,库会保存本次配置,并等待网络就绪、完成时间同步;随后按 auto / interval 配置自动定时检测更新,发现新版本时依次完成“下载升级包 → 校验 → 刷写 → 重启”的升级闭环。
request() 可多次调用,用于在开机后重新下发整套配置;运行过程中也可通过 check_update() 手动触发检测、通过 config() 动态修改配置。
注意事项
-
配置整体替换,非合并:每次调用 request() 都会用本次传入的 new_opts 整体覆盖上一次保存的全部配置(含 project_key、on_status 等)。只修改单个或部分参数时,请使用 config()。
-
运行互斥:FOTA 流程(等待网络、时间同步、检测、下载等任意阶段)执行期间,重复调用 request() 或 check_update() 会被忽略,请等待上一轮流程结束(如收到 download_done / rebooting 等状态)后再发起。
-
自动检测依赖时间同步:时间同步成功后才会按 auto / interval 启动自动定时检测;若同步失败(网络差、NTP 超时),本次不会自动检测,可通过 check_update() 手动检测或稍后重试 request()。
-
网络未就绪提示:网络等待上限 60 秒,未就绪期间会每秒回调一次 "network_fail",业务侧如需提示请自行节流。
-
开机自动上报上次升级结果:若上次检测到新版本且确认下载过,设备重启后开机时库会先回调 "boot_report",再根据版本比对结果回调 "upgrade_success" 或 "upgrade_fail"。
-
on_confirm 确认回调:不传时默认允许所有操作(自动下载、自动重启);传入后,每次收到回调都必须调用一次 callback(true) / callback(false) 表示确认或取消,否则流程会一直等待。
-
interval 取值:单位秒,默认 86400(24 小时);interval \<= 0 视为未启用自动检测;请勿设置过短(如小于 60 秒),避免频繁请求服务器。
参数
new_opts
参数含义:fota升级参数配置;参数为 table 类型,table 内容格式说明如下:
{
参数含义:项目密钥,此处为合宙 iot 平台上 Turnkey 标题栏中的项目密钥,详细说明请看下方的操作说明;
数据类型:string;
取值范围:无;
是否必选:必须传入此参数;
注意事项:无;
参数示例:"your_project_key";
project_key = ,
参数含义:脚本名称,此处指的是 main.lua 中的 PROJECT;
数据类型:string;
取值范围:无;
是否必选:可选传入此参数,不填时默认为 _G.PROJECT(需要代码中的 PROJECT 为全局变量);
注意事项:无;
参数示例:"fota3_temp";
script_name = ,
参数含义:脚本版本号,此处指的是 main.lua 中的 VERSION;
数据类型:string;
取值范围:无;
是否必选:可选传入此参数,不填时默认为 _G.VERSION(需要代码中的 VERSION 为全局变量);
注意事项:无;
参数示例:"001.999.000";
script_version = ,
参数含义:是否启动定时检测,默认为开启;
数据类型:boolean;
取值范围:true/false;
是否必选:可选传入此参数,不填时默认为 true,表示开启;
注意事项:设备第一次开机(不包含重启)时会自动进行一次检测;
参数示例:true;
auto = ,
参数含义:自动检测间隔,单位秒;
数据类型:number;
取值范围:无,以定时器支持的最大时间为主;
是否必选:可选传入此参数,不填时默认为 86400(24 小时);
注意事项:不要设置过短,避免频繁触发;
参数示例:86400;
interval = ,
参数含义:状态回调函数,内含三个参数,格式如下:
status
参数含义:状态码,用于表示整个 FOTA 过程中的状态;
数据类型:string;
取值范围:"network_fail" -- 网络连接失败
"boot_report" -- 正在检测上次升级结果
"checking" -- 正在检测更新
"check_fail" -- 检测失败
"no_new_version" -- 当前已是最新版本
"new_version" -- 发现新版本
"download_start" -- 开始下载升级包
"downloading" -- 正在下载(包含进度)
"download_fail" -- 下载失败
"download_done" -- 升级包已就绪
"rebooting" -- 正在重启
"upgrade_success" -- 升级成功
"upgrade_fail" -- 升级失败/无变化
是否必选:可选传入此参数;
注意事项:无;
参数示例:-- 如下方所示,定义了一个函数 fota_cb 就可以做为此参数传入
local function fota_cb(status, msg, percent)
if status == "network_fail" then
-- 网络连接失败,可记录日志或提示用户检查网络
log.warn("fota", "网络连接失败:", msg)
elseif status == "boot_report" then
-- 正在检测上次升级结果,启动时自动触发
log.info("fota", "检测升级结果:", msg)
elseif status == "checking" then
-- 正在检测更新
log.info("fota", "检测更新:", msg)
elseif status == "check_fail" then
-- 检测失败,可能是网络问题或服务器异常
log.warn("fota", "检测失败:", msg)
elseif status == "no_new_version" then
-- 当前已是最新版本,无需升级
log.info("fota", "已是最新版本:", msg)
elseif status == "new_version" then
-- 发现新版本,准备下载
log.info("fota", "发现新版本:", msg)
elseif status == "download_start" then
-- 开始下载升级包
log.info("fota", "开始下载:", msg)
elseif status == "downloading" then
-- 正在下载,显示进度(percent 为 0-100 的整数)
log.info("fota", "下载进度:", msg, percent .. "%")
elseif status == "download_fail" then
-- 下载失败,可能是网络中断或存储空间不足
log.warn("fota", "下载失败:", msg)
elseif status == "download_done" then
-- 升级包已就绪,等待用户确认重启
log.info("fota", "下载完成:", msg)
elseif status == "rebooting" then
-- 正在重启,准备应用升级
log.info("fota", "重启升级:", msg)
elseif status == "upgrade_success" then
-- 升级成功,版本已更新
log.info("fota", "升级成功:", msg)
elseif status == "upgrade_fail" then
-- 升级失败或无变化
log.warn("fota", "升级失败:", msg)
end
end
msg
参数含义:状态描述信息,参考状态码说明;
数据类型:string;
取值范围:参考 status 状态码说明;
是否必选:可选传入此参数;
注意事项:无;
参数示例:参考上方 status 参数示例;
percent
参数含义:下载进度百分比(0~100),仅在 status == "downloading" 时有效,其他状态为 nil;
数据类型:number;
取值范围:0-100;
注意事项:无;
参数示例:参考上方 status 参数示例;
数据类型:function;
取值范围:无;
是否必选:可选传入此参数;
注意事项:无;
参数示例:参考上方 status 参数示例;
on_status = ,
参数含义:确认回调函数,内含三个参数,格式如下:
action
参数含义:确认操作类型;
数据类型:string;
取值范围:"download" -- 确认下载
"reboot" -- 确认重启
是否必选:是;
注意事项:无;
参数示例:参考下方 on_confirm 参数示例;
info
参数含义:确认操作的详细信息,当 action == "download" 时:包含以下字段:
info.version
参数含义:升级包的脚本版本号;
数据类型:string;
取值范围:由FOTA服务端返回;
是否必选:是;
注意事项:仅 action == "download" 时存在;
参数示例:"001.999.000"
info.size
参数含义:升级包大小(字节);
数据类型:number;
取值范围:大于0的整数;
是否必选:是;
注意事项:仅 action == "download" 时存在;
参数示例:102400
info.fota_sn
参数含义:FOTA序列号,用于标识本次升级任务;
数据类型:string;
取值范围:由FOTA服务端返回;
是否必选:是;
注意事项:仅 action == "download" 时存在;
参数示例:"202606201234567890"
数据类型:table 或 nil;
取值范围:当 action == "download" 时:包含以上字段;
当 action == "reboot" 时:为 nil;
是否必选:可选传入此参数;
注意事项:无;
参数示例:参考下方 on_confirm 参数示例;
callback
参数含义:确认结果回调函数,用于通知库用户的选择;
数据类型:function;
取值范围:无;
是否必选:可选传入此参数;
注意事项:调用 callback(true) 表示确认,callback(false) 表示取消;
参数示例:参考下方 on_confirm 参数示例;
数据类型:function;
取值范围:无;
是否必选:可选传入此参数;
注意事项:不传入时默认允许所有操作;
参数示例:-- 如下方所示,定义了一个函数 fota_confirm 就可以做为此参数传入
local function fota_confirm(action, info, callback)
if action == "download" then
-- 确认下载,info 包含版本、大小、序列号
log.info("fota", "收到下载请求:")
log.info("fota", " 版本:", info.version)
log.info("fota", " 大小:", info.size, "字节")
log.info("fota", " 序列号:", info.fota_sn)
-- true 表示用户确认下载
callback(true)
elseif action == "reboot" then
-- 确认重启,info 为 nil
log.info("fota", "收到重启请求")
-- true 表示用户确认重启升级
callback(true)
end
end
}
返回值
无;
示例
libfota3.request({
project_key = "your_project_key", -- 项目密钥,用于FOTA服务认证
script_name = "fota3_temp", -- 脚本名称
script_version = "001.999.000", -- 脚本版本
auto = true, -- 启用自动定时检测
interval = 86400, -- 自动检测间隔(秒),默认24小时
on_status = function(status, msg, percent)
log.info("fota_temp", status, msg, percent)
end,
on_confirm = function(action, info, callback)
if action == "download" then
log.info("fota_temp", "download", info.version, info.size, info.fota_sn)
-- true 表示用户确认下载
callback(true)
elseif action == "reboot" then
-- true 表示用户确认重启升级
callback(true)
end
end,
})
4.2 libfota3.check_update()
功能
手动触发一次更新检测,与自动定时检测走同一套完整升级闭环:
等待网络就绪 → 向 FOTA 服务器查询是否有新版本 →(发现新版本)on_confirm 确认下载 → 下载升级包并做校验 → 写入 FOTA 分区 → on_confirm 确认重启 → 重启设备。
一般用于设备运行过程中由用户主动触发的场景(如按键、云平台指令、业务定时器等)。
注意事项
-
使用前必须先调用 request() 完成初始化配置(至少包含 project_key),否则检测会因缺少 project_key 而失败。
-
与 request() 共用运行互斥:任意 FOTA 流程执行期间调用 check_update() 会被忽略。
-
无返回值,检测结果通过 on_status 回调获知(依次可能收到 checking / check_fail / no_new_version / new_version;确认下载后还会收到下载与重启相关状态)。
参数
无。
返回值
无;
示例
-- 启动 FOTA 升级功能
libfota3.request({
project_key = "your_project_key", -- 项目密钥,用于FOTA服务认证
script_name = "fota3_temp", -- 脚本名称
script_version = "001.999.000", -- 脚本版本
auto = true, -- 启用自动定时检测
interval = 86400, -- 自动检测间隔(秒),默认24小时
on_status = function(status, msg, percent)
log.info("fota_temp", status, msg, percent)
end,
on_confirm = function(action, info, callback)
if action == "download" then
log.info("fota_temp", "download", info.version, info.size, info.fota_sn)
-- true 表示用户确认下载
callback(true)
elseif action == "reboot" then
-- true 表示用户确认重启升级
callback(true)
end
end,
})
-- 间隔一段时间后。。。。。。。
-- 手动执行检测更新
libfota3.check_update()
4.3 libfota3.config(new_opts)
功能
动态修改 FOTA 配置,并自动处理自动检测定时器的启停。支持只传需要修改的部分字段,未传字段保持原值(与 request() 的整体替换不同),例如:
-
关闭自动定时检测:
libfota3.config({auto = false}); -
调整检测间隔:
libfota3.config({auto = true, interval = 3600}); -
修改 project_key / script_name / script_version / on_status / on_confirm 等字段,将在后续检测流程中生效。
注意事项
-
使用之前必须先调用 request() 完成初始化后再使用 config();单独使用 config() 不会启动时间同步与任何 FOTA 流程。
-
修改 auto / interval 会按新配置重新安排自动检测定时器;config() 不会打断正在执行的检测/下载流程,新配置从下一轮检测开始生效。
-
修改 project_key / on_status / on_confirm 等非定时器字段时立即生效,不影响自动检测节奏。
参数
new_opts
参数含义:fota升级参数配置;参数为 table 类型,table 内容格式说明如下:
{
参数含义:项目密钥,此处为合宙 iot 平台上 Turnkey 标题栏中的项目密钥,详细说明请看下方的操作说明;
数据类型:string;
取值范围:无;
是否必选:必须传入此参数;
注意事项:无;
参数示例:"your_project_key";
project_key = ,
参数含义:脚本名称,此处指的是 main.lua 中的 PROJECT;
数据类型:string;
取值范围:无;
是否必选:可选传入此参数,不填时默认为 _G.PROJECT(需要代码中的 PROJECT 为全局变量);
注意事项:无;
参数示例:"fota3_temp";
script_name = ,
参数含义:脚本版本号,此处指的是 main.lua 中的 VERSION;
数据类型:string;
取值范围:无;
是否必选:可选传入此参数,不填时默认为 _G.VERSION(需要代码中的 VERSION 为全局变量);
注意事项:无;
参数示例:"001.999.000";
script_version = ,
参数含义:是否启动定时检测,默认为开启;
数据类型:boolean;
取值范围:true/false;
是否必选:可选传入此参数,不填时默认为 true,表示开启;
注意事项:设备第一次开机(不包含重启)时会自动进行一次检测;
参数示例:true;
auto = ,
参数含义:自动检测间隔,单位秒;
数据类型:number;
取值范围:无,以定时器支持的最大时间为主;
是否必选:可选传入此参数,不填时默认为 86400(24 小时);
注意事项:不要设置过短,避免频繁触发;
参数示例:86400;
interval = ,
参数含义:状态回调函数,内含三个参数,格式如下:
status
参数含义:状态码,用于表示整个 FOTA 过程中的状态;
数据类型:string;
取值范围:"network_fail" -- 网络连接失败
"boot_report" -- 正在检测上次升级结果
"checking" -- 正在检测更新
"check_fail" -- 检测失败
"no_new_version" -- 当前已是最新版本
"new_version" -- 发现新版本
"download_start" -- 开始下载升级包
"downloading" -- 正在下载(包含进度)
"download_fail" -- 下载失败
"download_done" -- 升级包已就绪
"rebooting" -- 正在重启
"upgrade_success" -- 升级成功
"upgrade_fail" -- 升级失败/无变化
是否必选:可选传入此参数;
注意事项:无;
参数示例:-- 如下方所示,定义了一个函数 fota_cb 就可以做为此参数传入
local function fota_cb(status, msg, percent)
if status == "network_fail" then
-- 网络连接失败,可记录日志或提示用户检查网络
log.warn("fota", "网络连接失败:", msg)
elseif status == "boot_report" then
-- 正在检测上次升级结果,启动时自动触发
log.info("fota", "检测升级结果:", msg)
elseif status == "checking" then
-- 正在检测更新
log.info("fota", "检测更新:", msg)
elseif status == "check_fail" then
-- 检测失败,可能是网络问题或服务器异常
log.warn("fota", "检测失败:", msg)
elseif status == "no_new_version" then
-- 当前已是最新版本,无需升级
log.info("fota", "已是最新版本:", msg)
elseif status == "new_version" then
-- 发现新版本,准备下载
log.info("fota", "发现新版本:", msg)
elseif status == "download_start" then
-- 开始下载升级包
log.info("fota", "开始下载:", msg)
elseif status == "downloading" then
-- 正在下载,显示进度(percent 为 0-100 的整数)
log.info("fota", "下载进度:", msg, percent .. "%")
elseif status == "download_fail" then
-- 下载失败,可能是网络中断或存储空间不足
log.warn("fota", "下载失败:", msg)
elseif status == "download_done" then
-- 升级包已就绪,等待用户确认重启
log.info("fota", "下载完成:", msg)
elseif status == "rebooting" then
-- 正在重启,准备应用升级
log.info("fota", "重启升级:", msg)
elseif status == "upgrade_success" then
-- 升级成功,版本已更新
log.info("fota", "升级成功:", msg)
elseif status == "upgrade_fail" then
-- 升级失败或无变化
log.warn("fota", "升级失败:", msg)
end
end
msg
参数含义:状态描述信息,参考状态码说明;
数据类型:string;
取值范围:参考 status 状态码说明;
是否必选:可选传入此参数;
注意事项:无;
参数示例:参考上方 status 参数示例;
percent
参数含义:下载进度百分比(0~100),仅在 status == "downloading" 时有效,其他状态为 nil;
数据类型:number;
取值范围:0-100;
注意事项:无;
参数示例:参考上方 status 参数示例;
数据类型:function;
取值范围:无;
是否必选:可选传入此参数;
注意事项:无;
参数示例:参考上方 status 参数示例;
on_status = ,
参数含义:确认回调函数,内含三个参数,格式如下:
action
参数含义:确认操作类型;
数据类型:string;
取值范围:"download" -- 确认下载
"reboot" -- 确认重启
是否必选:是;
注意事项:无;
参数示例:参考下方 on_confirm 参数示例;
info
参数含义:确认操作的详细信息,当 action == "download" 时:包含以下字段:
info.version
参数含义:升级包的脚本版本号;
数据类型:string;
取值范围:由FOTA服务端返回;
是否必选:是;
注意事项:仅 action == "download" 时存在;
参数示例:"001.999.000"
info.size
参数含义:升级包大小(字节);
数据类型:number;
取值范围:大于0的整数;
是否必选:是;
注意事项:仅 action == "download" 时存在;
参数示例:102400
info.fota_sn
参数含义:FOTA序列号,用于标识本次升级任务;
数据类型:string;
取值范围:由FOTA服务端返回;
是否必选:是;
注意事项:仅 action == "download" 时存在;
参数示例:"202606201234567890"
数据类型:table 或 nil;
取值范围:当 action == "download" 时:包含以上字段;
当 action == "reboot" 时:为 nil;
是否必选:可选传入此参数;
注意事项:无;
参数示例:参考下方 on_confirm 参数示例;
callback
参数含义:确认结果回调函数,用于通知库用户的选择;
数据类型:function;
取值范围:无;
是否必选:可选传入此参数;
注意事项:调用 callback(true) 表示确认,callback(false) 表示取消;
参数示例:参考下方 on_confirm 参数示例;
数据类型:function;
取值范围:无;
是否必选:可选传入此参数;
注意事项:不传入时默认允许所有操作;
参数示例:-- 如下方所示,定义了一个函数 fota_confirm 就可以做为此参数传入
local function fota_confirm(action, info, callback)
if action == "download" then
-- 确认下载,info 包含版本、大小、序列号
log.info("fota", "收到下载请求:")
log.info("fota", " 版本:", info.version)
log.info("fota", " 大小:", info.size, "字节")
log.info("fota", " 序列号:", info.fota_sn)
-- true 表示用户确认下载
callback(true)
elseif action == "reboot" then
-- 确认重启,info 为 nil
log.info("fota", "收到重启请求")
-- true 表示用户确认重启升级
callback(true)
end
end
}
返回值
无;
示例
-- 启动 FOTA 升级功能
libfota3.request({
project_key = "your_project_key", -- 项目密钥,用于FOTA服务认证
script_name = "fota3_temp", -- 脚本名称
script_version = "001.999.000", -- 脚本版本
auto = true, -- 启用自动定时检测
interval = 86400, -- 自动检测间隔(秒),默认24小时
on_status = function(status, msg, percent)
log.info("fota_temp", status, msg, percent)
end,
on_confirm = function(action, info, callback)
if action == "download" then
log.info("fota_temp", "download", info.version, info.size, info.fota_sn)
-- true 表示用户确认下载
callback(true)
elseif action == "reboot" then
-- true 表示用户确认重启升级
callback(true)
end
end,
})
-- 间隔一段时间后。。。。。。。
-- 手动执行检测更新
libfota3.check_update()
-- 间隔一段时间后。。。。。。。
-- 动态修改自动检测参数
libfota3.config({auto = true, interval = 86400})
4.4 libfota3.version()
功能
获取当前 libfota3 扩展库自身的版本号,返回值为字符串形式的“年月日时分”(格式:YYYYMMDDHHmm),可用于确认设备上实际运行的扩展库版本。
注意事项
-
该接口为纯查询接口,不依赖 request() 初始化,可在脚本任意位置随时调用。
-
返回的是扩展库自身的版本号,与脚本版本(script_version)、核心固件版本无关,扩展库更新后返回值才会随之变化。
-
扩展库加载时会自动通过 log.debug 打印一次版本号(格式为 “libfota3 version -> 版本号”),便于排查设备上运行的库版本。
参数
无。
返回值
local version = libfota3.version()
version
含义说明:库文件版本信息,string 类型的年月日时分;
数据类型:string;
取值范围:12 位数字;
返回示例:"202609151040"
示例
local libfota3 = require("libfota3")
-- 获取扩展库版本号并打印
log.info("fota", "libfota3版本:", libfota3.version()) -- 输出:libfota3版本: 202609151040
五、版本更新说明
版本号:202609151040
1、更新时间:2026-09-15 10:40
2、更新内容(首版发布)
- 新增 request() 接口,等待时间同步后启动自动检测定时器,支持基于时间戳的跨重启延续检测
- 新增 check_update() 接口,手动触发检测更新,复用 running 互斥标志
- 新增 config() 接口,动态修改配置参数并自动同步定时器启停
- 新增 version() 接口,返回库版本号
- 支持 HTTP 检测更新,自动向 FOTA 服务器查询新版本
- 支持 HTTP 下载升级包,自动选择 PSRAM 或内部 Flash 存储临时文件
- 支持 SHA256 校验,确保升级包完整性
- 支持下载进度回调,实时反馈下载百分比
- 支持用户确认回调,有屏设备可交互确认下载和重启操作
- 支持升级结果上报,自动将升级成功/失败结果发送给 FOTA 服务器
- 支持开机版本比对,重启后自动检测升级是否成功并上报
- 支持多平台设备标识获取(IMEI/MAC/unique_id),覆盖 Air780E/Air8000/Air8101/Air1601/Air1602/Air1780 等系列
六、产品支持说明
支持 LuatOS 开发的所有产品都支持 libfota3 扩展库。
七、操作演示说明
待补充