其他深度

Odoo IoT 配对为什么不只是“扫个码”:pairing code、session 事件、设备发现与 driver 生命周期讲透

很多人第一次接触 Odoo IoT 只看到配对码界面,但 connection_manager、event_manager、interface 和 driver 源码说明,它真正难的是“盒子如何被数据库接管、设备如何被发现、动作如何防重并回流事件”。看懂这条链,IoT 才不会停留在表面连通性。

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

先说结论

Odoo IoT 最难的部分,不是“盒子能不能联网”,而是这四件事如何连续成立:

  • 盒子如何先拿到 pairing code 并绑定数据库
  • 前端监听 session 如何等到正确设备事件
  • 新硬件插上后如何被 interface 发现并匹配 driver
  • 某个动作如何执行一次、回一条结果、避免重复触发

/home/ubuntu/odoo-temp/addons/iot_drivers/connection_manager.pyevent_manager.pyinterface.pydriver.py 看,官方真正建的是一条 注册 → 发现 → 执行 → 回流 的设备生命周期。

第一层:配对码为什么不是装饰性验证码

ConnectionManager 启动后,会在满足条件时持续轮询:

  • 本地还没配置 Odoo server URL
  • 设备有 IP
  • 不是热点模式阻塞态
  • pairing code 还没过期

随后它会向 iot-proxy.odoo.com 请求:

  • pairing_code
  • pairing_uuid
  • 再轮询是否拿到 url / token / db_uuid / enterprise_code

这说明 pairing code 不是一次性 UI 展示,而是整条“盒子注册到数据库”链的临时凭证。

也就是说,用户扫到的不是一个可爱数字,而是让云端代理暂时识别这台盒子的引导令牌。

第二层:为什么配对成功后要立刻重启

_connect_to_server() 在拿到数据库信息后会做三件很关键的事:

  1. 保存 server URL 与 token
  2. 把已检测到的设备一次性发送给数据库
  3. 检查 git branch 后重启 Odoo IoT 服务

很多人会觉得“都配对成功了,为什么还要重启”,但从架构上看这是合理的。

因为配对成功不等于系统状态已经完整切换。重启的意义在于:

  • 重新带证书启动
  • 正式加载对应 handler / 配置
  • 让盒子进入绑定后的稳定运行态

所以这一步更像“接管完成后的切换”,而不是简单刷新页面。

第三层:为什么事件管理器要维护 session

EventManager 内部有:

  • events
  • sessions
  • add_request()
  • _delete_expired_sessions()
  • device_changed()

前端长轮询或监听请求进来时,会创建一个 session,绑定:

  • session_id
  • 关注的 devices
  • 一个线程事件 Event()
  • result 容器
  • 最近请求时间

这意味着 IoT 事件不是“广播给所有监听者”,而是按 session 与目标设备路由。

这样设计很重要,因为同一台 IoT Box 可能同时服务多个页面或组件:

  • POS 在等扫码枪
  • 厨显在等打印反馈
  • 某个设置页在等设备状态变更

如果没有 session 路由,事件很容易串台。

第四层:设备事件为什么既要回 controller,又要喂 WebRTC

device_changed() 在生成 event 后会:

  • send_to_controller()
  • 如果存在 webrtc_client,继续 send(event)
  • 追加到本地 events
  • 再逐个 session 看谁应该收到结果

这说明 Odoo 并没有把事件回流只理解成“给当前页面返回 JSON”。

它实际上准备了多条消费路径:

  • controller / longpolling
  • webrtc 通道
  • 本地 session 等待队列

这代表官方面对的是复杂前端设备交互,而不是简单同步 RPC。

第五层:为什么 Interface 是“发现层”,Driver 是“执行层”

Interface 线程会周期执行 get_devices(),然后:

  • 算出新接入设备 added
  • 算出已移除设备 removed
  • 找到对应 connection type 下、按 priority 排序的 drivers
  • 用第一个 supported(device) 为真的 driver 来实例化设备线程

这里架构分层非常清楚:

  • Interface 负责看“现在插着什么设备”
  • Driver 负责看“这类设备能做什么动作”

如果只写 Driver 没有 Interface,你就无法稳定发现插拔变化;如果只有 Interface 没有 Driver,发现了设备也不知道怎么操作。

第六层:动作为什么要做防重复

Driver.action() 里有个很关键的细节:action_unique_id

如果同一个唯一 ID 的动作重复到来,系统会直接忽略并记 warning。

这类设计看似小,实际非常重要。因为在 IoT 场景里,最怕的不是按钮点了没反应,而是:

  • 网络重试导致重复打印
  • 重复下发导致同一设备执行两次
  • 用户误以为失败又点一次

所以 Odoo 在 driver 层就做幂等防重,是非常正确的架构位置。

第七层:为什么不是所有设备都通过统一事件回调

Driver.action() 里还有一个判断:

  • 打印机和 payment 设备不走通用 event_manager.device_changed() 回流
  • 它们自己处理低纸、刷卡等待等特殊事件

这说明官方并没有为了统一而强行统一,而是承认某些设备类型的交互时序更复杂,需要专门处理。

这反而体现架构成熟:

  • 通用链路覆盖大多数设备
  • 特殊设备保留专门时序模型

最容易误解的三个点

误区一:IoT 配对成功就代表系统稳定了

不是。配对只是注册入口,后面还有配置落地、设备上报和服务重启。

误区二:发现设备就等于可用了

也不是。还得有匹配成功的 driver,设备线程真正跑起来才算进入可执行状态。

误区三:动作回调就是普通 RPC 返回

不是。它同时涉及 session 路由、controller 通知、可能的 WebRTC 分发,以及动作防重。

实战上怎么理解最稳

如果你在做 Odoo IoT 排障或集成,最稳的排查顺序是:

  1. 先看盒子是否已完成 pairing 并保存 server URL/token
  2. 再看 interface 有没有发现设备
  3. 再看是否成功挑中对应 driver
  4. 再看 action 是否有唯一 ID、是否被幂等拦截
  5. 最后再看 session 有没有收到正确事件

最后总结

Odoo IoT 的真正价值,不在“能显示配对码”,而在它把 数据库接管、设备发现、驱动执行和事件回流 串成了完整生命周期。

只有把这条链看完整,你才会明白 Odoo 为什么能把 ERP 前端动作真正落到现场硬件上。

DISCUSSION

评论区

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