设备 Wi-Fi 配网总失败?一份可脚本化的排查清单

设备 Wi-Fi 配网总失败?一份可脚本化的排查清单

一、密码明明对了,却配网失败

去年帮一个连锁客户做门店监控,实施同事在群里连发三张图:机身二维码、路由器贴纸、App 报错「添加失败」。

店长站在旁边问:「是不是你们摄像机坏了?」

我远程让他做一件事:在开发者后台调 「未绑定设备信息」 接口,把返回里的 wifiConfigModewifiTransferMode 截图发来——三十秒就定位了:机型只支持 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,是现场失败排名第一的原因。

架构:谁干什么

开发者 OpenAPI

现场

SmartConfig/SoftAP

online

实施 App / OpenSDK

IPC 待配网

unBindDeviceInfo

bindDevice

listDeviceDetailsByPage

currentDeviceWifi / wifiAround


三、四层排查 + 代码

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 含 SoftAPSmartConfig 失败时改 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 密码
后台查不到设备私人账号绑定开发者主账号重绑
换网后离线未 controlDeviceWifiwifiAround → 切换

五、收尾

配网失败很少是「摄像机坏了」,更多是 模式、频段、权限、绑定码 四件事里有一件没对齐。我们把现场流程收成:

unBindDeviceInfo(能力)
→ SDK 配网(SmartConfig / SoftAP / 声波)
→ 轮询 online → bindDevice(正确 code)
→ listDeviceDetailsByPage 验收

脚本化 preflight 之后,那个连锁项目配网失败率从大约 40% 降到 8%——剩下的多半是现场路由器策略(MAC 过滤、访客网络隔离),就需要网络同事协同了。

如果你也在做云 IPC 批量实施,建议把 01-preflight.js 嵌进实施 App:扫码后先出能力报告,再让用户选配网方式,比反复试错省太多时间。具体接口名与字段以你所对接平台的 Wi-Fi 配置 / 设备接入 文档为准;不同区域网关域名务必按文档填写,填错区域的表现和「配网失败」很像。

你在现场见过最离谱的配网乌龙是什么?欢迎评论区交流。


说明:本文为个人项目实践笔记;接口名称与字段以所对接平台的当前开发者文档为准。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值