一、开机联网的完整顺序
设备上电后不能立刻发请求,必须按顺序来:
- 等待网络就绪(SIM 注网加 PDP 激活)
- 请求 OTA 接口,换取 WebSocket 连接参数
- 建立长连接,进入业务主循环
任何一步操之过急,都会拿到"网络不可用",而且现象是超时,很难查。
二、坑 1:网络没就绪就发请求
用 checkNet.waitNetworkReady(timeout) 阻塞等待,返回 (stage, state),只有 (3, 1) 才代表网络就绪:
stage, state = checkNet.waitNetworkReady(60)
if stage == 3 and state == 1:
print("网络就绪")
判断当前是否可用的轻量写法:
st = net.getState()
data_state = st[1][0] # 数据域注网状态
info = dataCall.getInfo(1, 0) # profileID=1, IPv4
pdp_state = info[2][0] # 0 未激活,1 已激活
ok = data_state in (1, 5) and pdp_state == 1
注意 getState() 失败会返回 -1,要先判空再取下标,否则直接抛异常。
三、坑 2:设备没注册,会拿到一个六位注册码
OTA 接口对未注册设备不返回连接参数,而是返回 activation.code。这个六位码要单独、醒目地打印出来,方便去控制台绑定:
activation = info.get("activation")
if activation is not None:
print("注册码:", activation.get("code", "??????"))
控制台绑定后重新运行即可。别把它当成"请求失败"直接忽略。
四、坑 3:建链顺序会影响内存成败
这一点很隐蔽。设备上同时有两条 TLS 长连接(语音服加阿里云)和一路摄像头预览。这三样都吃内存,而预览的帧缓冲最大。
正确顺序是:先建两条 TLS 连接,最后再开预览。
原因:TLS 握手和收发缓冲需要连续的大块内存。如果预览先开、把内存打散,握手就可能失败。反过来,预览放最后,即使内存更紧也不会影响已建立的连接。
五、坑 4:断线只降级,不整机退出
小智连接断开后,如果直接让整个程序退出,那相机、云端这些还正常的功能就全废了。
做法是只降级语音:
voice_ok = False # 只停语音
# 相机与云端主循环继续运行
然后每隔 15 秒尝试重连一次:
重连流程: OTA 取参 -> connect() -> hello 握手 -> 重新绑定连接对象
重连成功就恢复语音能力,失败就静默等待下一轮,不要刷屏。
六、小结
- 联网必须等"就绪",别抢跑。
- 未注册设备拿到的是注册码,不是错误。
- 建链顺序:先 TLS,后预览。
- 断线只降级语音,主循环不退出。
- 重连要有节奏(如 15 秒),失败也别慌。