背景
本次公司新开发出来一款温湿度无线设备,需要支持WIFI配网操作;主要使用人员为:客户以及生产人员。
功能
可通过微信小程序进行配网,满足:
- 用户可以配置设备连接自有的WIFI,进行数据上传
- 可将数据上传至公司平台或第三方服务器
- 可指定设备连接的ip,若不指定则自动分配
开发环境以及使用技术
- 微信小程序以及微信开发者工具
- uniapp以及HBuilder X
具体实现的思路
通过与硬件工程师进行沟通,确定配网主要流程为:
- 设备进入配网模式
- 链接设备WIFI
- UDP发送要让设备连接的WIFI名称以及密码等信息
- 设备配网成功后,退出AP模式
配网知识拓展(物联网部分)
实现流程
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以及密码有部分的限制,更深层次的原因希望有大佬能为我解惑。
注意事项:
在进行后续测试的过程中,发现部分机型存在问题
- 手机应当开启定位功能(否则无法获取用户当前连接的WiFi名称)
- 需要关闭手机流量:
该问题在小米手机上发现的,如果用户流量与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传输过程中 数据丢失
*/
}
}
总结:
- 微信小程序自动连接WiFi,当设备WiFi存在密码的时候,部分手机会无法自动连接成功,需要
wx.connectWifi
配置maunal: true
,跳转到手机WiFi列表进行手动连接诶;反之如果设备WiFi设置为开放模式该问题出现概率下降。 - 用户需要打开手机定位才能获取当前连接的WiFi名称
- 部分机型(例如:小米)在进行设备配网前,需要关闭手机流量,否则由于设备WiFi无法联网,会自动使用手机流量导致无法进行UDP数据传输。
至此,本次WIFI设备AP配网功能实现;在此进行一下记录,希望各位如果有更好的方法或者了解为何WiFi开放则不会出现自动连接失败的原因,能帮我解惑。