微信小程序实现物联网WIFI设备AP配网

1,715 阅读4分钟

背景

本次公司新开发出来一款温湿度无线设备,需要支持WIFI配网操作;主要使用人员为:客户以及生产人员。

功能

可通过微信小程序进行配网,满足:

  1. 用户可以配置设备连接自有的WIFI,进行数据上传
  2. 可将数据上传至公司平台或第三方服务器
  3. 可指定设备连接的ip,若不指定则自动分配

开发环境以及使用技术

  1. 微信小程序以及微信开发者工具
  2. uniapp以及HBuilder X

具体实现的思路

通过与硬件工程师进行沟通,确定配网主要流程为:

  1. 设备进入配网模式
  2. 链接设备WIFI
  3. UDP发送要让设备连接的WIFI名称以及密码等信息
  4. 设备配网成功后,退出AP模式

配网知识拓展(物联网部分)

2f2a8281e390bcd7d650c5dd127d354.png

实现流程

1、链接WiFi

/**
 * 判断手机版本 是否支持   */
function checkPhoneVersion() {
    //检测手机型号
    wx.getSystemInfo({
	success: function(res) {
            var system = '';
            if (res.platform == 'android') system = parseInt(res.system.substr(8));
            if (res.platform == 'ios') system = parseInt(res.system.substr(4));
            if (res.platform == 'android' && system < 6) {
                wx.showToast({
                        title: '手机版本不支持',
                })
                return
            }
            if (res.platform == 'ios' && system < 11.2) {
                wx.showToast({
                    title: '手机版本不支持',
                })
                return
            }
			
            isOpenWifi(); // 自定义判断用户是否打开了WiFi
        }
    })
}
wx.connectWifi({
    SSID,
    password,
    success(res) {
        console.log('连接wifi成功 res', res);
        wx.showLoading({
            title: '设置中...'
        })
        // 链接成功,发送配置信息
        sendCfg();
    },
    fail(err) {
        // 链接失败
    }
})

问题:

在配网过程中,发现部分手机会出现自动连接指定WiFi失败的情况(有可能报 err.errCode 12010,系统错误),这种问题查看社区说无法确定具体问题
解决方法:

wx.connectWifi({
    SSID,
    password,
    maunal: true, // 重点**
    success: (res) => {
        console.log('手动链接完毕 res', res);
    },
    fail(err) {
    
    }
})

当出现该问题后,再次调用链接WiFi maunal: true 配置,可以从小程序直接跳转到手机的WiFi列表页面,用户可以手动的连接WiFi;然后再返回小程序,进行后续操作;
在实际项目中我在小程序中的onShow与onHide生命周期进行判断,用户是否跳转到手机WiFi列表进行手动连接;然后再校验当前连接的WiFi,再进行后续的UDP信息传输。

新发现:

在后续使用过程中,发现一个有意思的,当设备WiFi设置为开放网络(即设备配网模式下的WiFi 不设置密码)的时候,在华为、荣耀等个别机型上,不会再出现自动连接WiFi失败的现象。
这个问题我感觉有可能在这部分机型上,或许对自动连接WiFi以及密码有部分的限制,更深层次的原因希望有大佬能为我解惑。

注意事项:

在进行后续测试的过程中,发现部分机型存在问题

  1. 手机应当开启定位功能(否则无法获取用户当前连接的WiFi名称)
  2. 需要关闭手机流量:
    该问题在小米手机上发现的,如果用户流量与WiFi同时打开,当连接到设备WiFi的时候,由于设备配网WiFi无法上网,真机模拟下会自动使用流量而不会切到WiFi;导致后续的UDP信息无法传输

2、UDP连接传输信息

这一部分就相对来说问题少了,只需要创建UDP连接,并按照约定的地址进行信息传输即可。

// 如果设备使用环境(医院等内部)需要指定ip ,在jo中增加对应的信息即可
let jo = {
    "ssid": ssid, // 指定设备连接的WiFi
    "pwd": pwd,
    "url": url, // 设备数据上传的服务器地址
};
udp = wx.createUDPSocket();
udp.bind();

udp.send({
    address,
    port,
    message: JSON.stringify(jo);
});
if(!sendTimer) {
    sendTimer = setInterval(() => {
        // 周期发送UDP消息
        if(connectUdpNum > maxUdp) {
            initCfgSign();
            wx.showToast({
                    title: 'UDP连接超时,请重新配置网络',
                    icon: 'none',
                    duration: 3000
            })
            return;
        }
        udp.send({
            address,
            port,
            message: js
        });
        connectUdpNum ++ 
    }, 1000);
}
udp.onMessage(onUdpMessage); // 监听UDP连接返回的信息
function onUdpMessage(res) {
    if (res.remoteInfo.size > 0) {
        // 将 ArrayBuffer类型的res.message取出来
        let unit8Arr = new Uint8Array(res.message)
        let encodedString = String.fromCharCode.apply(null, unit8Arr);
        // 没有这一步中文会乱码
        let decodedString = decodeURIComponent(escape((encodedString)))
        let jo = JSON.parse(decodedString);
        /**
         * 判断返回的连接信息与设备接收到的是否一致
         * 防止 UDP传输过程中 数据丢失
         */
         
     }
}

总结:

  1. 微信小程序自动连接WiFi,当设备WiFi存在密码的时候,部分手机会无法自动连接成功,需要wx.connectWifi配置 maunal: true,跳转到手机WiFi列表进行手动连接诶;反之如果设备WiFi设置为开放模式该问题出现概率下降。
  2. 用户需要打开手机定位才能获取当前连接的WiFi名称
  3. 部分机型(例如:小米)在进行设备配网前,需要关闭手机流量,否则由于设备WiFi无法联网,会自动使用手机流量导致无法进行UDP数据传输。
    至此,本次WIFI设备AP配网功能实现;在此进行一下记录,希望各位如果有更好的方法或者了解为何WiFi开放则不会出现自动连接失败的原因,能帮我解惑。