设备 Wi-Fi 配网总失败?一份可脚本化的排查清单
一、密码明明对了,却配网失败
去年帮一个连锁客户做门店监控,实施同事在群里连发三张图:机身二维码、路由器贴纸、App 报错「添加失败」。
店长站在旁边问:「是不是你们摄像机坏了?」
我远程让他做一件事:在开发者后台调 「未绑定设备信息」 接口,把返回里的 wifiConfigMode、wifiTransferMode 截图发来——三十秒就定位了:机型只支持 2.4GHz + 声波配网,现场手机连的是 5G Wi-Fi,还强行走了 SmartConfig。
换 2.4G 频段、改声波配网,第四遍成功。密码从未错,模式和频段错了。
二、配网、上线、绑定是三件事
很多工单把「配网失败」和「绑定失败」写在一起,技术上是两条链路:
| 阶段 | 完成标志 | 常见接口/动作 |
|---|---|---|
| 配网 | 设备连上目标 Wi-Fi,能访问互联网 | App / OpenSDK:SmartConfig、SoftAP、声波等 |
| 上线 | 平台侧 status 为 online | 轮询「未绑定设备信息」或分页查详情 |
| 绑定 | 设备进入开发者资产池 | bindDevice + 正确 code |
┌─ SmartConfig / SoftAP / 声波 …
手机 ────┤
└─ 把 SSID+密码交给设备
│
▼
设备连 Wi-Fi 上网
│
▼
unBindDeviceInfo.status = online
│
▼
bindDevice(验证码/密码)
│
▼
listDeviceDetailsByPage 能查到且 online
OpenAPI 不会替你发 Wi-Fi 广播——配网动作在 客户端 SDK 或官方 App 完成;HTTP 接口负责 查能力、查状态、绑定、换热点。集成商要把分工写进 SOP,避免后端同学被拉去「写配网协议」。
配网模式速查(接口字段wifiConfigMode)
平台「未绑定设备信息」接口会返回设备支持的模式(多值逗号分隔,常见如下):
| 模式 | 适用 | 现场注意 |
|---|---|---|
| SmartConfig | 一键传 Wi-Fi 密码 | 手机需近场;Android 常要定位权限;2.4G |
| SoftAP | 设备开热点,手机连上去配 | 先连设备 AP,再回路由器 SSID |
| SoundWave | 声波传密码 | 环境别太吵;音量要够 |
| LAN | 有线 | 网线直插,无无线步骤 |
| QRCode | 扫码传参 | 按机型说明扫特定码 |
另有 wifiTransferMode:不少 IPC 仅 2.4Ghz。门店 5G 优先、双频合一的 SSID,是现场失败排名第一的原因。
架构:谁干什么
三、四层排查 + 代码
0. 公共调用壳(全文复用)
// lib/platform-call.js — 网关域名、appId、appSecret 放环境变量
import crypto from 'node:crypto';
import { randomUUID } from 'node:crypto';
export function calcSign(time, nonce, appSecret) {
const raw = `time:${time},nonce:${nonce},appSecret:${appSecret}`;
return crypto.createHash('md5').update(raw, 'utf8').digest('hex');
}
export async function platformCall(method, params = {}) {
const appId = process.env.APP_ID;
const appSecret = process.env.APP_SECRET;
const base = process.env.OPENAPI_BASE; // 文档中的区域网关 + /openapi
const time = Math.floor(Date.now() / 1000);
const nonce = randomUUID();
const body = {
system: { ver: '1.0', appId, sign: calcSign(time, nonce, appSecret), time, nonce },
id: randomUUID(),
params,
};
const res = await fetch(`${base}/${method}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
const json = await res.json();
if (json.result?.code !== '0') throw new Error(`[${json.result.code}] ${json.result.msg}`);
return json.result.data;
}
export async function adminToken() {
const data = await platformCall('accessToken', {});
return data.accessToken;
}
第一层:配网前 — 查能力,别盲试
先调「未绑定设备信息」,再决定 App 里点哪种配网方式:
// scripts/01-preflight.js
import 'dotenv/config';
import { platformCall, adminToken } from '../lib/platform-call.js';
const deviceId = process.env.TARGET_DEVICE_ID;
const token = await adminToken();
const info = await platformCall('unBindDeviceInfo', {
token,
deviceId,
// 扫码可得,可选:deviceCodeModel, deviceModelName, ncCode
});
console.log({
support: info.support,
deviceExist: info.deviceExist,
status: info.status,
bindStatus: info.bindStatus,
wifiConfigMode: info.wifiConfigMode,
wifiConfigModeOptional: info.wifiConfigModeOptional,
wifiTransferMode: info.wifiTransferMode,
catalog: info.catalog,
});
决策表(贴实施手册):
| 返回值 | 动作 |
|---|---|
deviceExist: notExist | 核对序列号、是否假机/未烧录 |
support: false | 机型不在平台支持列表 |
bindStatus 已绑定 | 勿重复配网,走解绑或换账号 |
wifiTransferMode 仅 2.4Ghz | 路由器必须开 2.4G,勿只连 5G |
wifiConfigMode 含 SoftAP | SmartConfig 失败时改 SoftAP |
踩坑 1:不查 wifiConfigMode,全系门店用 SmartConfig——声波机型成功率能差 五倍以上。
第二层:配网中 — SDK 流程要点
HTTP 不能替代配网,但实施 App 里建议固定顺序(与常见 OpenSDK 文档一致):
SmartConfig 路径
1. unBindDeviceInfo → 确认未绑定、支持 SmartConfig
2. 手机连 2.4G Wi-Fi(与目标 SSID 同频段)
3. SDK 发起无线配对,传入 SSID / 密码
4. 局域网搜索设备 / 轮询 status 直到 online
5. bindDevice
SoftAP 路径
1. unBindDeviceInfo → 确认支持 SoftAP
2. 手机连接设备热点(机身标签有 SSID 提示)
3. SDK SoftAP 配对,下发家里路由器密码
4. 手机切回正常 Wi-Fi,轮询 online
5. bindDevice
Android 权限清单(缺一项可能「永远配网中」):
<!-- 配网常见所需权限,按 SDK 文档裁剪 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
踩坑 2:Android 10+ 未开定位,SmartConfig 静默失败——界面还在转圈,log 里没有任何异常。
踩坑 3:双频合一 SSID,部分设备只认 2.4G 隐藏 BSSID。我们现场改 单独 2.4G _guest 专给摄像机,成功率明显上去。
第三层:配网后 — 轮询上线 + 绑定
// scripts/02-wait-online-and-bind.js
import 'dotenv/config';
import { platformCall, adminToken } from '../lib/platform-call.js';
const deviceId = process.env.TARGET_DEVICE_ID;
const deviceCode = process.env.DEVICE_CODE; // 8 位安全码或设备密码
const token = await adminToken();
async function waitOnline(maxTry = 30, intervalMs = 2000) {
for (let i = 0; i < maxTry; i++) {
const info = await platformCall('unBindDeviceInfo', { token, deviceId });
if (info.status === 'online') return info;
if (info.status === 'upgrading') throw new Error('设备升级中,稍后再绑');
await new Promise((r) => setTimeout(r, intervalMs));
}
throw new Error('超时:设备未上线,检查 Wi-Fi/密码/频段');
}
await waitOnline();
await platformCall('bindDevice', { token, deviceId, code: deviceCode });
console.log('bindDevice OK');
code 对照(绑定失败第二大坑):
| 情况 | code 传什么 |
|---|---|
| 未改密码,标签有 8 位安全码 | 8 位安全码 |
| 已改设备密码 | 设备密码 |
| 无 8 位安全码且未改密 | 空字符串 |
code 与加密字段 encryptCode 同时传时,以 code 为准。
踩坑 4:配网明明成功,bindDevice 报验证码错误——实施把 路由器 Wi-Fi 密码 填进了 code 字段。
第四层:验收 — 分页列表 + 信号
// scripts/03-verify-asset.js
import 'dotenv/config';
import { platformCall, adminToken } from '../lib/platform-call.js';
const deviceId = process.env.TARGET_DEVICE_ID;
const token = await adminToken();
const page = await platformCall('listDeviceDetailsByPage', {
token,
pageSize: 50,
page: 1,
source: 'bindAndShare',
});
const dev = page.deviceList?.find((d) => d.deviceId === deviceId);
if (!dev || dev.deviceStatus !== 'online') {
throw new Error('资产池未验收:设备不在线或不在本开发者账号');
}
console.log('验收通过', dev.deviceName, dev.deviceStatus);
try {
const wifi = await platformCall('currentDeviceWifi', { token, deviceId });
console.log('当前 Wi-Fi', wifi.ssid, '信号', wifi.intensity, '/5');
if (Number(wifi.intensity) <= 2) {
console.warn('信号偏弱,后续预览可能卡顿,建议换 AP 或 wifiAround 选热点');
}
} catch {
console.log('跳过 Wi-Fi 查询(可能为有线设备)');
}
配网成功 vs 接入成功:
✗ App 能预览,但 listDeviceDetailsByPage 无此序列号 → 绑在私人账号,非开发者主账号
✓ 分页接口 deviceStatus=online → 才算项目接入完成
第五层:已绑定设备换 Wi-Fi(售后场景)
设备已进资产池,门店换路由器后离线——用 周边 Wi-Fi 查询 + 切换热点(切换接口耗时长,文档建议超时 ≥75s):
// scripts/04-switch-wifi.js
import 'dotenv/config';
import { platformCall, adminToken } from '../lib/platform-call.js';
const deviceId = process.env.TARGET_DEVICE_ID;
const token = await adminToken();
const around = await platformCall('wifiAround', { token, deviceId });
console.log('周边热点', around.wLan?.map((w) => ({
ssid: w.ssid,
intensity: w.intensity,
linkStatus: w.linkStatus,
})));
const target = around.wLan?.find((w) => w.ssid === process.env.NEW_SSID);
if (!target) throw new Error('目标 SSID 不在周边列表中');
// 该接口耗时长,fetch 建议 signal/timeout ≥ 75s
await platformCall('controlDeviceWifi', {
token,
deviceId,
ssid: target.ssid,
bssid: target.bssid,
linkEnable: true,
password: process.env.NEW_WIFI_PASSWORD,
});
console.log('切换指令已下发,等待 online 后验收');
踩坑 5:未先 wifiAround 直接 controlDeviceWifi,平台返回参数错误——BSSID 必须从周边列表取。
现场 Checklist(可打印)
□ unBindDeviceInfo:support=true,bindStatus=unbind
□ wifiTransferMode 与路由器频段一致(2.4G 机型禁 5G-only)
□ 配网模式与 wifiConfigMode 匹配
□ Android 定位 / Wi-Fi 权限已开
□ 轮询 status=online 后再 bindDevice
□ code 用安全码/设备密码,非 Wi-Fi 密码
□ listDeviceDetailsByPage 验收 online
□ 可选:currentDeviceWifi intensity ≥ 3
四、进阶:边界与生产
| 话题 | 建议 |
|---|---|
| OpenAPI 边界 | 配网广播在 SDK;HTTP 管查、绑、换网 |
| 批量门店 | 统一 2.4G SSID 规范;实施 App 内置 preflight 脚本 |
| 安全 | appSecret 仅服务端;encryptCode 绑定接口可选 |
| 超时 | controlDeviceWifi 长耗时;前端勿 30s 断请求 |
| 旧接口 | 列表用分页查详情,勿抄文档里已标注停维护的旧协议 |
| 有线路径 | LAN 模式设备跳过无线步骤,插线上线即绑 |
排错速查
| 现象 | 高概率原因 | 动作 |
|---|---|---|
| 一直「搜索设备」 | 2.4G/5G 搞错 | 查 wifiTransferMode |
| SmartConfig 无反应 | 缺定位权限 | Android 权限 |
| online 后 bind 失败 | code 填错 | 安全码 vs 密码 |
| 后台查不到设备 | 私人账号绑定 | 开发者主账号重绑 |
| 换网后离线 | 未 controlDeviceWifi | wifiAround → 切换 |
五、收尾
配网失败很少是「摄像机坏了」,更多是 模式、频段、权限、绑定码 四件事里有一件没对齐。我们把现场流程收成:
unBindDeviceInfo(能力)
→ SDK 配网(SmartConfig / SoftAP / 声波)
→ 轮询 online → bindDevice(正确 code)
→ listDeviceDetailsByPage 验收
脚本化 preflight 之后,那个连锁项目配网失败率从大约 40% 降到 8%——剩下的多半是现场路由器策略(MAC 过滤、访客网络隔离),就需要网络同事协同了。
如果你也在做云 IPC 批量实施,建议把 01-preflight.js 嵌进实施 App:扫码后先出能力报告,再让用户选配网方式,比反复试错省太多时间。具体接口名与字段以你所对接平台的 Wi-Fi 配置 / 设备接入 文档为准;不同区域网关域名务必按文档填写,填错区域的表现和「配网失败」很像。
你在现场见过最离谱的配网乌龙是什么?欢迎评论区交流。
说明:本文为个人项目实践笔记;接口名称与字段以所对接平台的当前开发者文档为准。
335

被折叠的 条评论
为什么被折叠?



