其他深度

Odoo IoT Box 断网后为什么不会立刻变砖:Wi‑Fi 重连、热点回退与二维码入网链路讲透

很多人研究 Odoo IoT 时只盯着驱动和设备发现,但真正决定 IoT Box 能不能“活着回来”的,往往是 iot_drivers 里的网络恢复逻辑。wifi.py 明确把“先恢复可接入性”放在“再恢复业务连接”之前:能连上旧 Wi‑Fi 就复用,连不上就切回 AP,用户还能通过二维码重新入网。理解这套容错链,现场部署才不会一断网就全盘重来。

其他
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 4 阅读

先说结论

Odoo IoT Box 的网络设计重点,不是“尽量一直在线”,而是一旦掉线,设备还能重新被人接管

这也是为什么 addons/iot_drivers/tools/wifi.py 里最关键的逻辑,不是驱动发现,而是:

  • 怎么识别当前网络状态
  • 怎么尝试恢复旧连接
  • 失败后什么时候切回热点模式
  • 怎么把重新接入这件事尽量降低门槛

换句话说,IoT Box 最核心的生存能力不是“联网”,而是“掉网后还能重新入网”。

第一层:为什么 get_available_ssids() 会在必要时重载 NetworkManager

get_available_ssids() 并不是简单跑一次 nmcli 就结束。

它先调用 _scan_network(),如果发现结果异常到只剩“当前已连接网络”这一种,就会尝试 _reload_network_manager() 再扫一次。

这说明官方很清楚:现场网络问题不一定真是 Wi‑Fi 没了,有时候只是 NetworkManager 自己状态不可靠。

所以 Odoo 的思路不是一上来就让用户重启盒子,而是先把网络管理服务本身当成可恢复对象。

第二层:为什么 reconnect() 先等 10 秒,不急着抢连 Wi‑Fi

reconnect() 开头有一段容易被忽略的逻辑:在不是 force_update 的情况下,它会先等最多 10 秒,看设备是否已经拿到 IP。

这背后的判断很成熟:

  • 设备刚启动时,网络栈可能还没稳定
  • 有线网也可能已经可用
  • 如果此时立刻重连 Wi‑Fi,反而可能把现有正常网络打断

所以 Odoo 先问的是:我是不是已经有可用网络了?

如果已经有 IP,而且当前还处在 AP 模式,系统甚至会顺手把 AP 关掉,避免设备同时暴露不必要的热点入口。

第三层:为什么没有 SSID 时直接回 AP,而不是报失败

reconnect() 如果拿不到目标 ssid,并不会抛一个“无法连接”的错误就完事,而是直接 toggle_access_point(START)

这个选择非常关键。

因为对现场部署来说,最糟糕的状态不是“暂时没网”,而是“没人能重新配网”。

只要热点还能起来,部署人员就还能:

  • 连接到 IoT Box 自身
  • 打开本地管理页
  • 重新输入 Wi‑Fi 配置
  • 继续做后续配对

所以 AP 模式本质上是 IoT Box 的自救入口

第四层:为什么 _connect() 要先关 AP,再尝试持久化配置

_connect() 会先检查两个前提:

  1. 目标 SSID 是否真的在可见网络列表里
  2. 能否成功停掉 AP 模式

只有这样才会继续执行 nmcli device wifi connect

连接成功后,它还会调用 _validate_configuration(),把网络配置同步到 /root_bypass_ramdisks

这个细节非常 Odoo IoT:

  • 临时连上网还不够
  • 关键是重启之后还能自动回来

官方注释也说得很明确:IoT Box 的根文件系统里有些内容重启会丢,所以必须把网络配置额外落到保留区域。

这就是“现场恢复”和“重启后持续可用”之间的区别。

第五层:为什么失败时是否回 AP,要看原来有没有退路

reconnect() 里还有个很精细的变量:should_start_access_point_on_failure

它不是一刀切地说“失败就开热点”,而是根据当前状态判断:

  • 如果原本就在 AP 模式,失败后当然应该继续回 AP
  • 如果当前没有任何 IP,也该回 AP
  • 但如果还有别的网络通路,未必需要强行开热点

这种判断避免了两种坏结果:

  • 完全失联
  • 不必要地暴露热点接口

这是典型的运维思维,而不是单纯的开发思维。

第六层:为什么二维码生成属于网络恢复链的一部分

get_qr_data_for_wifi()generate_network_qr_codes() 看起来像 UI 小功能,其实它们属于恢复链的重要一环。

逻辑很直接:

  • 如果当前在 AP 模式,就生成 IoT Box 热点的二维码
  • 如果已经配置了 Wi‑Fi,就生成目标 Wi‑Fi 的二维码
  • 同时再生成一个本地管理页 URL 的二维码

这等于把“找盒子、连盒子、打开盒子”三件事用最少输入动作串起来。

在仓库、门店、展会这种现场环境里,这比让运维手打 SSID、密码和 IP 地址稳定得多。

第七层:为什么 disconnect() 也会顺手开 AP

disconnect() 并不是简单地断掉当前网络。

它在断开后会检查 get_ip(),如果设备已经没有网络入口,就会切回 AP。

这说明在 IoT Box 的世界里,“主动断网”也必须保留回退路径。

否则你今天点了断开,明天可能连设备在哪个网段都找不到。

实战部署最容易踩的坑

1. 只验证连接成功,不验证配置持久化

如果 _validate_configuration() 没做好,设备可能这次连上、下次重启就失联。

2. 把 AP 模式当成异常状态

实际上它是恢复链的重要保底,不是简单的失败标志。

3. 忽略已有有线网络

reconnect() 明确会先观察是否已有 IP,说明 Wi‑Fi 恢复不应该破坏已有可用网络。

4. 现场只给文字说明,不给二维码入口

现场环境里,二维码往往比文档步骤更可靠。

结论

Odoo IoT Box 的网络逻辑真正聪明的地方,不是连接 Wi‑Fi 这件事本身,而是它把“恢复接入能力”摆在了第一优先级。

所以理解这块源码时,最值得盯住的不是某个驱动,而是这条容错链:

  • get_available_ssids():尽量拿到可信网络视图
  • reconnect():优先复用现有连通性
  • _connect():建立连接并落地持久配置
  • toggle_access_point():兜底恢复可接入入口
  • generate_network_qr_codes():降低重新入网门槛

这也是为什么真正稳定的 IoT 部署,靠的从来不只是“第一次配成功”,而是“出问题后还回得来”。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。