智能设备WiFi配网实战:从踩坑到一键连接的完整解决方案

97 阅读3分钟

在智能家居开发中,设备配网是用户接触产品的第一个技术环节,其体验直接影响用户对产品的第一印象。经过多个项目的实战积累,我总结出一套高成功率的配网方案,在此分享关键实现思路和技术细节。

功能流程

智能设备配网主要包含以下核心流程:

graph TD
    A[设备信息获取] --> B[热点连接检测]
    B --> C[WiFi列表选择]
    C --> D[配置信息下发]
    D --> E{状态检查}
    E -->|成功| F[配网完成]
    E -->|失败| G[错误重试/备选方案]
    G --> H[蓝牙配网]

一、设备信息获取:双二维码策略

为兼顾便捷性与灵活性,我们采用两种二维码方案:

1. 小程序普通链接二维码

适用场景:快速上线,用户体验统一

普通链接二维码内容:https://域名/bind?deviceId=xxx&deviceWifiName=xxx...

配置要点

  • 需在小程序后台配置业务域名(开发管理-扫普通链接二维码打开小程序)

保存后需要确认发布,否则即使是开发者账号也是无法打开的

  • 支持参数传递,便于设备识别
  • 生成简单,用户扫码直接进入小程序体验更好

2. JSON格式二维码

适用场景:需要传递复杂参数或跨平台使用

// 二维码内容结构
{
  "appId": "小程序APPID",
  "path": "pages/connect/index",
  "extra": {
    "deviceType": "smart_plug_v2",
    "deviceWifiName": "SmartDevice_XXXX",
    "firmwareVersion": "1.2.3"
  }
}

优势

  • 支持复杂数据结构
  • 便于设备厂商预置二维码
  • 可扩展性强,便于后续功能迭代

推荐方案:生产环境建议同时支持两种方式,让用户和设备厂商按需选择。

二、热点连接检测

选择使用WiFi配网来作为我们的配网方案,设备配网的核心前提是手机必须连接到设备自身的热点。这里需要精确判断网络状态:

// 监听WiFi连接状态变化
uni.onWifiConnected((res) => {
  const currentWifi = res.wifi;
  
  // 关键判断:当前连接WiFi是否为第一步获取到的设备热点
  if (currentWifi.SSID !== deviceWifiName) {
    // 显示引导弹窗,提示用户切换WiFi
    showGuideModal({
      title: '请连接设备热点',
      content: `检测到您当前连接的是"${currentWifi.SSID}",请前往手机WiFi设置中连接"${deviceWifiName}"热点`,
      deviceWifiName: deviceWifiName,
    });
  } else {
    // 已连接设备热点,进入下一步
    proceedToWifiConfig();
  }
});

// 主动获取当前WiFi状态(兼容性处理)
async function checkCurrentWifi() {
  try {
    const wifiInfo = await uni.getConnectedWifi();
    return wifiInfo;
  } catch (error) {
    // iOS等系统可能无法直接获取,需要用户手动操作
    console.warn('获取当前WiFi信息失败,需要用户手动确认', error);
    showManualGuide();
  }
}

技术要点

  • 多端兼容:iOS与Android在WiFi API权限上的差异需要妥善处理
  • 用户引导:清晰的提示信息配合可视化指引,降低用户操作门槛
  • 异常处理:网络权限被拒绝时的降级方案

三、WiFi列表获取与处理

可以参考上一篇文章一键搞定UniApp WiFi连接!这个Vue 3 Hook让你少走弯路来获取wifi列表,然后提示让用户选择并提供WiFi密码

四、配置信息下发

设备热点通常会启动一个本地HTTP服务器用于接收配置,配置下发后需要硬件端通知验证设备是否成功连接目标网络,如果成功断开设备热点,失败提示用户重连:

// 向设备发送WiFi配置
async function sendWifiConfigToDevice(ssid, password, deviceIp = '192.168.4.1') {
  const configData = {
    ssid: ssid,
    password: password,
    timestamp: Date.now(),
  };

  try {
    const result = await uni.request({
      url: `http://${deviceIp}/config`,
      method: 'POST',
      data: configData,
      timeout: 30000, // 关键:超时设置30秒
      header: {
        'Content-Type': 'application/json'
      }
    });
    
    // 处理设备响应及错误处理
    ...
  }
}

五、备选方案实现

如果硬件端支持蓝牙协议,也可以改为使用蓝牙配网,主要流程跟WiFi配网基本一致