阅读 184

智能家居小程序softAP配网和BLE配网功能实现

上一个项目一直在做智能家居的小程序和后台管理系统,现在整理一下其中最关键的配网步骤。

softAP的配网原理

配网流程图:

softAP配网原理.png

softAP配网,即利用设备的无线芯片,将设备进入到softAP模式,开启一个无线局域网,手机(或其它移动设备)通过连入设备开启的无线局域网后,向设备发送路由器的ssid及password等信息,让设备在无屏幕的情况下,获取到路由器的ssid信息,达到联网的目的。

上面的流程图简单的画了一下,下面我大概讲一下具体的配网步骤\

配网步骤总共需要4步

  1. 智能家居设备需要长按特定的按键进入配网模式,这个时候设备会启动wifi模块释放wifi(不同的设备进入配网的方式不一样)

WechatIMG745.png 2. 小程序进入配网界面,输入当前家庭连接的wifi密码,记录家庭wifi的名字和密码(可以直接通过小程序的API直接获取到当前手机连接的wifi名字) WechatIMG746.png 3. 手机进行网络切换,连接设备释放的wifi,然后进行UDP通信,把wifi名字和密码发送给设备端,设备端通过名字密码连接家庭wifi和服务器进行通信(UDP通信发送名字密码可以做自定义的加密处理降低抓包风险) WechatIMG747.png 4.小程序通过调服务器接口查询智能设备是否配网成功(查询参数加密MD5、设备devId、userId)

softAP实现的代码

// 配网 async getDevice() {     let that = this;     this.setData({       isOnload: false     })     wx.showToast({       title: '配网时长在1-2分钟,请耐心等待!',       icon: 'none',       duration: 2000     })     setTimeout(() => {       wx.showLoading({         title: '配网中',       })     }, 2000)     // 开始配网     let ASCIIStr = `${String.fromCharCode(util.prefixInteger(that.data.SSID.length, 2))}${that.data.SSID}${String.fromCharCode(util.prefixInteger(that.data.password.length, 2))}${that.data.password}`       let ASCIIStrMi = 0;       for (var i = ASCIIStr.length - 1; i >= 0; i--) {         var str = ASCIIStr.charAt(i);         var code = str.charCodeAt();         ASCIIStrMi += code;       }       that.UDPSocketHandler = wx.createUDPSocket(),       that.UDPSocketHandler.bind();       var times = setInterval(() => {         try {           that.UDPSocketHandler.send({             address: "10.10.100.000",             port: 12414,             message: `${ASCIIStr}${String.fromCharCode(ASCIIStrMi % 256)}`,             offset: 0,             // length: message.byteLength           })         } catch (e) { }       }, 1000); //1000:每1秒轮询一次       that.UDPSocketHandler.onListening(function (res) {         console.log(res, '监听中...')       })       that.UDPSocketHandler.onMessage(function (res) {         let str = util.newAb2Str(res.message);         that.setData({           udpCode: str.replace("RECVDONE", "")         });         console.log('str===' + str)         if (str.indexOf("RECVDONE") !== -1) {           clearInterval(times);           that.UDPSocketHandler.close();           that.distributionNetwork();           console.log('RECVDONE !== 1','配网中');         }       })       that.UDPSocketHandler.onError(function (res) {         console.log(res, 'error');       })   },   getuserDev(index) {     let that = this;     if (index > 19) {       wx.hideLoading();       wx.showToast({         title: '配网超时',         icon: 'none',         duration: 2000       });       return;     }     index++;     let md5Str = md5.md5(`${that.data.SSID}${that.data.password}${that.data.udpCode}`)     let data = {       userId: app.globalData.unionId,       wifiMd5: md5Str,       devId: that.data.udpCode,     }     console.log("配网",data)     global.api.devNetwork(data).then(res => {       console.log("res", res);       if (res.code == 200 && res.rows !== null) {         clearInterval(that.data._time);         wx.hideLoading();         wx.showToast({           title: '配网成功',           icon: 'none',           duration: 2000         });         wx.navigateTo({           url: '/xxxx/xxxx/xxxx/xxxx/xxxxxx/index?data=' + JSON.stringify(res.rows) + '&equipment=' + that.data.equipment + '&ps=' + that.data.ps,         });       } else {         setTimeout(() => {           that.getuserDev(index);         }, 5000)       }     })       .catch(err => {         setTimeout(() => {           that.getuserDev(index);         }, 5000)       })   },   distributionNetwork() {     var that = this;     wx.showLoading({       title: '配网中',     });     that.getuserDev(0);   }, 复制代码

上面这部分只是具体的逻辑实现,像调用的小程序获取wifi信息的API就不往上放了。

BLE配网功能

BLE配网就是低功耗蓝牙配网

WechatIMG748.png

// 获取当前设备信息   getSystemInfo() {     var that = this;     wx.getSystemInfo({       success: function (res) {         console.log(res, "获取当前设备信息");         that.setData({           windowHeight: res.windowHeight,         });       },     });   },   // 初始化蓝牙模块   openBluetooth() {     var that = this;     wx.openBluetoothAdapter({       success: function (res) {         console.log("初始化蓝牙适配器成功" + JSON.stringify(res));         that.setData({           msg: "初始化蓝牙适配器成功",         });         wx.showModal({           title: "蓝牙适配情况",           content: "初始化蓝牙适配器成功",         });       },       fail() {         that.setData({           msg: "初始化蓝牙适配器失败",         });         wx.showModal({           title: "蓝牙适配情况",           content: "蓝牙适配失败,请检查手机蓝牙和定位功能是否打开",         });       },       complete() {         console.log("初始化蓝牙适配器完成");       },     });   },   // 开启蓝牙设备搜索   switchChange() {     var that = this;     if (!that.data.searchDevice) {       that.setData({         searchDevice: !that.data.searchDevice,       });       console.log("打开蓝牙设备搜索");       wx.getBluetoothAdapterState({         success(res) {           console.log("getBluetoothAdapterState", res);         },       });       wx.onBluetoothAdapterStateChange(function (res) {         console.log("onBluetoothAdapterStateChange", res.available);       });       wx.startBluetoothDevicesDiscovery({         success(res) {           console.log("startBluetoothDevicesDiscovery", res);         },       });       wx.onBluetoothDeviceFound(function (devices) {         console.error(devices, "devices");         if (!devices.devices[0]) return;         let result = that.data.deviceList.some((item) => {           console.log(item, "item");           if (item.deviceId === devices.devices[0].deviceId) return true;         });         if (!result) {           that.setData({             deviceList: [...that.data.deviceList, devices.devices[0]],           });         }         // console.log('onBluetoothDeviceFound', that.data.deviceList)       });       wx.getBluetoothDevices({         success(res) {           console.log("getBluetoothDevices", res);         },       });     } else {       // that.deviceList = []       // that.currentDevice = {}       wx.stopBluetoothDevicesDiscovery({         success(res) {           that.setData({             searchDevice: !that.data.searchDevice,           });           console.log("关闭蓝牙设备搜索", res);         },       });     }   },   // 点击蓝牙设备   chooseDevice(event) {     console.log(event.currentTarget.dataset.item, "item");     var that = this;     that.setData({       currentDevice: event.currentTarget.dataset.item,       nowDevice: true,     });     wx.pageScrollTo({       scrollTop: that.data.windowHeight,       duration: 100,     });   },   //   confirmConnect(event) {     console.log(event.currentTarget, "aaaaaa");     var that = this;     wx.showModal({       title: "连接当前蓝牙设备",       success(res) {         if (res.confirm) {           that.connectTo(event.currentTarget.dataset.deviceid);         } else if (res.cancel) {           console.log("用户点击取消");         }       },     });   },   //   connectTo(deviceId) {     var that = this;     console.log("连接蓝牙设备搜索", deviceId);     wx.stopBluetoothDevicesDiscovery({       success(res) {         console.log("关闭蓝牙设备搜索", res);         that.setData({           searchDevice: !that.data.searchDevice,         });       },     });     wx.showLoading({       title: "连接蓝牙设备中...",     });     wx.createBLEConnection({       deviceId: deviceId,       success(res) {         console.log("蓝牙设备连接成功", res);         wx.hideLoading();         wx.getBLEDeviceServices({           deviceId: deviceId,           success(res) {             that.setData({               deviceService: res.services,             });             for (var t = 0; t < that.data.deviceService.length; t++) {               var service = that.data.deviceService[t];               var serviceId = service.uuid.substring(4, 8);               console.log(service.uuid, "serviceId1111111");               if (serviceId === "FFE0") {                 that.setData({                   serviceId: service.uuid,                 });               }             }             that.setData({               nowDevice: !that.nowDevice,               nowService: !that.nowService,             });             console.log("获取蓝牙设备Service" + res.errMsg);           },           fail(res) {             wx.showModal({               title: "设备Service信息",               content:                 "蓝牙设备连接成功" + "\n" + "设备信息获取错误" + res.errMsg,             });           },         });       },       fail(res) {         console.log("蓝牙设备连接失败,请稍后重试");         wx.hideLoading();         wx.showModal({           title: "提示",           content: "蓝牙设备连接失败,请稍后重试",           duration: 2000,         });       },       complete() {         console.log("蓝牙设备连接完成");         wx.hideLoading();       },     });   },   // 发送数据   sendMessage() {     let that = this;     console.log(that.data.sendData);     let data = that.data.sendData.split(",");     let dataBuffer = new ArrayBuffer(data.length);     let dataView = new DataView(dataBuffer);     for (let j = 0; j < data.length; j++) {       dataView.setUint8(j, "0x" + data[j]);     }     that.setData({       deviceId: that.data.currentDevice.deviceId,     });     console.log(that.data.serviceId, "serviceId");     console.log(that.data.deviceId, "deviceId");     wx.getBLEDeviceCharacteristics({       deviceId: that.data.deviceId,       serviceId: that.data.serviceId,       success(res) {         console.log(res.characteristics);         that.deviceCharacteristics = res.characteristics;         for (var i = 0; i < that.deviceCharacteristics.length; i++) {           that.characteristic = that.deviceCharacteristics[i];           that.characteristicProperties = that.characteristic.properties;           if (that.characteristicProperties.notify === true) {             that.characteristicId = that.characteristic.uuid;             wx.notifyBLECharacteristicValueChange({               state: true, // 启用 notify 功能               deviceId: that.deviceId,               serviceId: that.serviceId,               characteristicId: that.characteristicId,               success(res) {                 console.log("开启notify成功" + that.characteristic.uuid);                 for (let i = 0; i < dataView.byteLength; i++) {                   var writeData = "0x" + dataView.getUint8(i).toString(16);                   that.writeDatas = that.writeDatas + "\n" + writeData;                 }                 wx.writeBLECharacteristicValue({                   deviceId: that.deviceId,                   serviceId: that.serviceId,                   characteristicId: that.characteristicId,                   value: dataBuffer,                   success(res) {                     console.log("发送的数据:" + that.writeDatas);                     console.log("message发送成功");                     wx.showModal({                       title: "数据发送成功",                       content: that.writeDatas,                     });                     wx.readBLECharacteristicValue({                       deviceId: that.deviceId,                       serviceId: that.serviceId,                       characteristicId: that.characteristicId,                       success(res) {                         console.log("读取数据成功");                       },                     });                   },                   fail(res) {                     // fail                     console.log("message发送失败" + that.characteristicIdw);                     wx.showToast({                       title: "数据发送失败,请稍后重试",                       icon: "none",                     });                   },                   complete(res) {                     // fail                     console.log("message发送完成");                   },                 });               },               fail() {                 console.log("开启notify失败" + that.characteristicId);               },             });             // that.writeMessage(that.deviceId, that.serviceId, that.characteristicIdw, that.characteristicIdr, that.characteristicIdn)           }         }       },       fail() {         console.log("获取characteristic失败");       },     });     that.writeDatas = [];   },   receiveMessage() {     let that = this;     that.deviceId = this.currentDevice.deviceId;     that.serviceId = that.serviceId;     wx.getBLEDeviceCharacteristics({       deviceId: that.deviceId,       serviceId: that.serviceId,       success(res) {         console.log(res.characteristics);         that.deviceCharacteristics = res.characteristics;         for (var i = 0; i < that.deviceCharacteristics.length; i++) {           that.characteristic = that.deviceCharacteristics[i];           that.characteristicProperties = that.characteristic.properties;           if (that.characteristicProperties.notify === true) {             that.characteristicId = that.characteristic.uuid;             wx.notifyBLECharacteristicValueChange({               state: true, // 启用 notify 功能               deviceId: that.deviceId,               serviceId: that.serviceId,               characteristicId: that.characteristicId,               success(res) {                 console.log("开启notify成功" + that.characteristic.uuid);                 console.log(that.characteristicProperties.write);                 console.log(that.characteristicProperties.read);                 wx.readBLECharacteristicValue({                   deviceId: that.deviceId,                   serviceId: that.serviceId,                   characteristicId: that.characteristicId,                   success(res) {                     console.log("接收数据成功");                   },                 });                 wx.onBLECharacteristicValueChange(function (res) {                   console.log("接收数据:", that.ab2hex(res.value));                   var recMessage = that.ab2hex(res.value);                   that.reMessage.push(recMessage);                 });               },               fail() {                 console.log("开启notify失败" + that.characteristicId);                 console.log(that.characteristicProperties.write);                 console.log(that.characteristicProperties.read);               },               complete() {                 console.log("开启完成");               },             });           }         }       },       fail() {         console.log("获取characteristic失败");       },     });   },   disconnect() {     var that = this;     that.setData({       deviceId: that.data.currentDevice.deviceId,     });     wx.closeBLEConnection({       deviceId: that.data.deviceId,       success(res) {         wx.showModal({           title: "设备连接情况",           content: "蓝牙设备已经断开",         });         that.setData({           nowDevice: false,           currentDevice: {},           nowService: false,           deviceService: {},         });       },     });   },   ab2hex(buffer) {     var hexArr = Array.prototype.map.call(       new Uint8Array(buffer),       function (bit) {         return ("00" + bit.toString(16)).slice(-2);       }     );     return hexArr.join("");   },   /**    * 生命周期函数--监听页面加载    */   onLoad: function (options) {     console.log(this.data.deviceList, "deviceList");     this.getSystemInfo();     this.openBluetooth();   },   /**    * 生命周期函数--监听页面显示    */   onShow: function () {     var that = this;     // 监听蓝牙适配器状态变化事件     wx.onBluetoothAdapterStateChange(function (res) {       console.log(`蓝牙设备状态更改`, res.available);       that.openBluetooth();     });   },


作者:王小辉
链接:https://juejin.cn/post/7020596289146454047


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐