uniapp 小程序低功耗蓝牙配网 ble配网 物联网

server/2024/10/18 18:23:54/

 1.获取蓝牙列表  bleList.vue

<template><view><button @touchstart="startSearch">获取蓝牙列表</button><scroll-view :scroll-top="scrollTop" scroll-y class="content-pop"><viewclass="bluetoothItem"v-for="(item, index) in bluetoohList":key="index"@click="openControl(item)"><view class="textItem">蓝牙:{{ item.name }}</view><view>{{ item.deviceId }}</view></view></scroll-view></view>
</template><script>
export default {data() {return {bluetoohList: [],};},onLoad: function (options) {this.startSearch();},methods: {// 连接蓝牙startSearch() {let that = this;that.$ble.openBluetoothAdapter((res) => {that.$ble.getBluetoothAdapterState((res) => {if (res.available) {if (res.discovering) {that.$ble.stopBluetoothDevicesDiscovery();} else {that.getBluetoothDevices();}that.checkPemission();} else {that.$tip.toast("本机蓝牙不可用");}});},(err) => {that.openSetting();});},openSetting() {let params = {title: "检测到您没打开蓝牙权限,是否去设置打开?",showCancel: true,};this.$tip.showModal(params, (res) => {if (res.confirm) {this.$ble.openSetting();}});},checkPemission() {//android 6.0以上需授权地理位置权限var that = this;const sys = uni.getSystemInfoSync();if (sys.platform == "ios") {that.getBluetoothDevices();} else if (sys.platform == "android") {console.log(app.getSystem().substring(app.getSystem().length - (app.getSystem().length - 8),app.getSystem().length - (app.getSystem().length - 8) + 1));if (app.globalData.getSystem().substring(app.globalData.getSystem().length -(app.globalData.getSystem().length - 8),app.globalData.getSystem().length -(app.globalData.getSystem().length - 8) +1) > 5) {uni.getSetting({success: (res) => {console.log(res);if (!res.authSetting["scope.userLocation"]) {uni.authorize({scope: "scope.userLocation",complete: (res) => {that.getBluetoothDevices();},});} else {that.getBluetoothDevices();}},});}}},//获取蓝牙设备信息getBluetoothDevices() {that.$tip.loading("蓝牙搜索中");this.$ble.getBluetoothDevices((res) => {this.bluetoohList = res;this.$tip.loaded();});},// 连接蓝牙 跳转到连接页面openControl(item) {let params = {list: this.bluetoohList,info: item,};this.$tip.redirectTo("/pagesA/bleDevice/bleWifiSuccess", params);},},
};
</script><style scoped>
.content-pop {width: 100vw;max-height: 55vh;padding: 0 30rpx;
}
.bluetoothItem {padding: 20rpx 0;font-weight: 400;font-size: 28rpx;border-bottom: 1rpx solid #f4f4f4;text-align: left;
}
.textItem {display: block;margin-bottom: 10rpx;
}
</style>

2.选择蓝牙进行连接  blefi.vue

<script>
export default {data() {return {bluInfo: {},services: [],bleServiceId: "",serviceId: 0,writeCharacter: false,readCharacter: false,notifyCharacter: false,BLEInformation: {serveiceId: "",config_write_char_id: "",cmd_write_char_id: "",config_read_char_id: "",cmd_read_char_id: "",},};},onLoad(option) {// 接收页面传递的数据this.bluInfo = JSON.parse(decodeURIComponent(option.info));this.bluetooh(this.bluInfo.info.deviceId);},methods: {bluetooh(deviceId) {var that = this;that.$ble.stopBluetoothDevicesDiscovery();that.$ble.createBLEConnection(deviceId,(res) => {that.getSeviceId(deviceId);},(err) => {console.log(err, "11111111");that.bluetoothFail();});},// 连接成功后保存连接状态getSeviceId(deviceId) {var that = this;that.$ble.getBLEDeviceServices(deviceId,(res) => {that.services = res.services;that.bleServiceId = res.services[0].uuid;this.BLEInformation.serveiceId = res.services[0].uuid;that.getCharacteristics(deviceId);},(err) => {console.log(err, "2222222");that.bluetoothFail();});},getCharacteristics(deviceId) {var that = this;var list = that.services;var num = that.serviceId;var write = that.writeCharacter;var read = that.readCharacter;var notify = that.notifyCharacter;that.$ble.getBLEDeviceCharacteristics(deviceId,that.bleServiceId,(res) => {for (var i = 0; i < res.characteristics.length; ++i) {var properties = res.characteristics[i].properties;if (!notify) {if (properties.notify) {notify = true;}}if (!write) {if (properties.write) {this.BLEInformation.config_write_char_id =res.characteristics[2].uuid;this.BLEInformation.cmd_write_char_id =res.characteristics[0].uuid;write = true;}}if (!read) {if (properties.read) {this.BLEInformation.config_read_char_id =res.characteristics[3].uuid;this.BLEInformation.cmd_read_char_id =res.characteristics[1].uuid;read = true;}}}if (!write || !notify || !read) {num++;(that.writeCharacter = write),(that.readCharacter = read),(that.notifyCharacter = notify),(that.serviceId = num);if (num == list.length) {// console.log("找不到该读写的特征值")that.bluetoothFail();} else {that.getCharacteristics(deviceId);}} else {that.bluetoothSuccess(res);}},(err) => {console.log(err, "4444444");that.bluetoothFail();});},// 蓝牙连接打印机bluetoothSuccess(res) {uni.setStorageSync("blefiInfo", this.BLEInformation);let params = {title: "连接成功",confirmText: "继续",showCancel: false,};this.$tip.showModal(params, (res) => {if (res.confirm) {// 蓝牙连接成功this.$tip.redirectTo("/pages/ble/bleWifi");}});},bluetoothFail() {// 蓝牙连接失败this.$tip.redirectTo("/pages/ble/bleFail");},},
};
</script><style scoped>
.zai-box {padding: 0;margin: 0;height: 100%;background-color: #fff;
}.container {padding: 30rpx;margin: 0;font-size: 28rpx;color: #20212b;background-color: #fff;text-align: left;font-weight: 400;
}image {width: 362rpx;height: 362rpx;margin-top: 30rpx;
}.textTitle {display: block;font-size: 36rpx;font-weight: bold;color: #20212b;display: block;margin-bottom: 30rpx;
}.textItem {display: block;font-size: 24rpx;font-weight: 400;color: #999999;line-height: 36rpx;
}
</style>

3. 低功耗蓝牙连接WiFi  blefiWifi.vue

<template><view><text>{{ SSID }}</text><input type="text" placeholder="请输入密码" v-model="password" /><button @click="settiing">连接</button></view></template><script>import APToast from "@/util/APToast.js";export default {data() {return {SSID: "your SSID",password: "",connected: true,wifiCountDown: 0,wifiCountInterval: null, // 定时器blefiInfo: {},};},// 二级页面清除onUnload() {this.$ble.offBLEConnectionStateChange();this.clearIntervalWifi();},onLoad(options) {this.blefiInfo = uni.getStorageSync("blefiInfo");let sys = uni.getStorageSync("phoneInfo");if (sys.platform == "android") {// this.$ble.onBLEMTUChange((res) => {//   console.log(res, "androidMTU");// });// this.$ble.getBLEMTU(this.blefiInfo.deviceId, (res) => {//   console.log(res, "mtu");// });const mtu = 512;this.$ble.setBLEMTU(this.blefiInfo.deviceId,mtu,(res) => {console.log(res, "512");},(err) => {console.log(err, "000");});}this.$ble.getBLEDeviceServices(this.blefiInfo.deviceId, (res) => {this.$ble.getBLEDeviceCharacteristics(this.blefiInfo.deviceId,this.blefiInfo.serveiceId,(res) => {this.$ble.notifyBLECharacteristicValueChange(true,this.blefiInfo.deviceId,this.blefiInfo.serveiceId,this.blefiInfo.readCharId,(res) => {console.log("启用notify成功");});});});this.$ble.onBLEConnectionStateChange((res) => {this.connected = res.connected;if (!res.connected) {this.$tip.loaded();// 蓝牙连接失败,跳转到失败页面this.$tip.redirectTo("/pages/ble/bleFail");}});// 接收配网打印机回传的数据this.$ble.onBLECharacteristicValueChange((res) => {if (!res || res.value.byteLength == 0) return;this.clearIntervalWifi();this.$tip.loaded();let num = new Int32Array(res.value)[0];console.log(num, "NUM");let tip = APToast.find((item) => item.id == num);if (num == 0) {// 连接wifi成功this.$tip.redirectTo("/pages/ble/WifiSuccess");} else {// 连接WiFi失败this.$tip.redirectTo("/pages/ble/WifiFile");}});},methods: {settiing() {this.startSMSTimer("60");this.$tip.loading("连接中");if (this.connected) {this.sendWifi();} else {this.$tip.loaded();// 蓝牙连接失败,跳转到失败页面this.$tip.redirectTo("/pages/ble/bleFail");}},// 转UTF-8sendWifi() {let msg = {event: "network",data: { ssid: this.SSID, password: this.password, authmode: 4 },};let buffer = this.stringToUint8Array(JSON.stringify(msg));this.bleSendWifi(buffer);},// json字符串数据转Uint8ArraystringToUint8Array(str) {// 方法一// var arr = [];// for (var i = 0, j = str.length; i < j; ++i) {//   arr.push(str.charCodeAt(i));// }// var tmpUint8Array = new Uint8Array(arr);// return tmpUint8Array.buffer;// 方法二let buffer = new ArrayBuffer(str.length);let dataView = new DataView(buffer);for (var i = 0; i < str.length; i++) {dataView.setUint8(i, str.charCodeAt(i));}return buffer;},bleSendWifi(payload) {if (this.connected) {this.$ble.writeBLECharacteristicValueOnce(this.blefiInfo.deviceId,this.blefiInfo.serveiceId,this.blefiInfo.writecharId,payload);if (this.blefiInfo.readCharId) {this.$ble.readBLECharacteristicValue(this.blefiInfo.deviceId,this.blefiInfo.serveiceId,this.blefiInfo.readCharId);}}},startSMSTimer(val) {this.wifiCountDown = val;this.wifiCountInterval = setInterval(() => {this.wifiCountDown--;// console.log(this.wifiCountDown);if (this.wifiCountDown <= 0) {clearInterval(this.wifiCountInterval);this.wifiCountInterval = null;this.$tip.loaded();// 连接WiFi失败this.$tip.redirectTo("/pages/ble/WifiFile");}}, 1000);},clearIntervalWifi() {this.wifiCountDown = 0;if (this.wifiCountInterval) {clearInterval(this.wifiCountInterval);this.wifiCountInterval = null;}},},};</script>

4. 手机连接蓝牙失败、蓝牙连接WiFi成功/失败(关闭蓝牙连接)

<script>
export default {onLoad() {// 使用完成后在合适的时机断开连接和关闭蓝牙适配器this.$ble.closeBLEConnection(this.deviceId);this.$ble.closeBluetoothAdapter();},
};
</script>

5.ble.js

let data = {devices: [],log: [],connected: true, //原本是falsechs: [],deviceId: "",writeDeviceId: "",writeServiceId: "",writeCharacteristicId: "",packData: [], // 分包数据cmd: null, // 命令码statusCode: null, // 状态码datalength: null, // 数据长度checkSums: null, // 校验和req_key_id: "",
};class ble {openBluetoothAdapter(success, failure) {uni.openBluetoothAdapter({success: (res) => {success(res);},fail: (err) => {failure(err);},});}getBluetoothAdapterState(success) {uni.getBluetoothAdapterState({success: (res) => {success(res);},});}//停止搜寻附近的蓝牙外围设备stopBluetoothDevicesDiscovery() {uni.stopBluetoothDevicesDiscovery();}//获取蓝牙设备信息getBluetoothDevices(success) {// 开始搜寻附近的蓝牙外围设备uni.startBluetoothDevicesDiscovery({success: (res) => {setTimeout(() => {// 获取搜索到的设备信息uni.getBluetoothDevices({success: (res) => {let bluetoohList = [];var num = 0;for (var i = 0; i < res.devices.length; ++i) {if (res.devices[i].name != "未知设备") {bluetoohList[num] = res.devices[i];num++;}}this.stopBluetoothDevicesDiscovery();success(bluetoohList);},});}, 5000);// that.onBluetoothDeviceFound();},});}openSetting() {uni.openSetting({//opensetting是调起设置页面的success: (res) => {if (res.authSetting == true) {//判断res.authsetting的值是true还是falseuni.openBluetoothAdapter();}},});}//断开与低功耗蓝牙设备的连接closeBLEConnection(deviceId) {uni.closeBLEConnection({deviceId: deviceId,});}offBLEConnectionStateChange() {wx.offBLEConnectionStateChange();}//连接低功耗蓝牙设备createBLEConnection(deviceId, success, failure) {uni.createBLEConnection({deviceId: deviceId,success: (res) => {success(res);},fail: (err) => {failure(err);},});}//获取蓝牙设备所有服务getBLEDeviceServices(deviceId, success, failure) {wx.getBLEDeviceServices({deviceId: deviceId,success: (res) => {success(res);},fail(err) {failure(err);},});}//获取蓝牙设备某个服务中所有特征值getBLEDeviceCharacteristics(deviceId, serviceId, success, failure) {wx.getBLEDeviceCharacteristics({deviceId: deviceId,serviceId: serviceId,success: (res) => {success(res);},fail(err) {failure(err);},});}notifyBLECharacteristicValueChange(state,deviceId,serviceId,characteristicId,success) {wx.notifyBLECharacteristicValueChange({state: state,deviceId: deviceId,serviceId: serviceId,characteristicId: characteristicId,success: function (res) {success(res);},});}onBLEConnectionStateChange(success) {wx.onBLEConnectionStateChange((res) => {success(res);});}// 接收配网打印机回传的数据onBLECharacteristicValueChange(success) {wx.onBLECharacteristicValueChange((res) => {success(res);});}//关闭蓝牙模块closeBluetoothAdapter() {wx.closeBluetoothAdapter();}// 不分包写入蓝牙writeBLECharacteristicValueOnce(deviceId,serviceId,characteristicId,value) {wx.writeBLECharacteristicValue({deviceId: deviceId,serviceId: serviceId,characteristicId: characteristicId,value: value,});}readBLECharacteristicValue(deviceId, serviceId, characteristicId) {wx.readBLECharacteristicValue({deviceId: deviceId,serviceId: serviceId,characteristicId: characteristicId,});}getBLEMTU(deviceId, success) {wx.getBLEMTU({deviceId: deviceId,writeType: "write",success(res) {success(res.mtu);},});}onBLEMTUChange(success) {wx.onBLEMTUChange(function (res) {success(res.mtu);});}setBLEMTU(deviceId, mtu, success, failure) {wx.setBLEMTU({deviceId: deviceId,mtu: mtu,success: (res) => {success(res);},fail: (res) => {failure(res);},});}
}
const bleDevice = new ble();
export default bleDevice;

6.APToast.js

const message = [{id:0,type:"WIFI_REASON_SUCCESS",message:"打印机连接成功"},{id:2,type:"WIFI_REASON_AUTH_EXPIRE",message:"身份验证超时"},{id:3,type:"WIFI_REASON_AUTH_LEAVE",message:"连接中断"},{id:8,type:"WIFI_REASON_ASSOC_LEAVE",message:"连接中断"},{id:15,type:"WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT",message:"密码错误"},{id:201,type:"WIFI_REASON_NO_AP_FOUND",message:"未找到可用的网络"},{id:202,type:"WIFI_REASON_AUTH_FAIL",message:"密码错误或身份验证超时"},{id:203,type:"WIFI_REASON_ASSOC_FAIL",message:"设备无法与WiFi成功关联"},{id:204,type:"WIFI_REASON_HANDSHAKE_TIMEOUT",message:"密码错误"},{id:205,type:"WIFI_REASON_CONNECTION_FAIL",message:"连接失败"}, 
]export default message;

7.tip.js

export default class Tips { /*** 弹出提示框*/static success(title, duration = 1000) {setTimeout(() => {uni.showToast({title: title,icon: "success",mask: true,duration: duration,});}, 300);if (duration > 0) {return new Promise((resolve, reject) => {setTimeout(() => {resolve();}, duration);});}}/*** 弹出加载提示*/static loading(title = "加载中") {if (Tips.isLoading) {return;}Tips.isLoading = true;uni.showLoading({title: title,mask: true,});}/*** 加载完毕*/static loaded() {if (Tips.isLoading) {Tips.isLoading = false;uni.hideLoading();}}/*** 关闭当前页面,跳转到新页面*/static redirectTo(urls, item) {uni.redirectTo({url: item? urls + "?info=" + encodeURIComponent(JSON.stringify(item)): urls, //  JSON.parse(decodeURIComponent(option.info));});}/*** 弹出确认窗口*/static showModal(val, success) {uni.showModal({title: val.title ? val.title : "",content: val.content ? val.content : "",showCancel: val.showCancel,confirmText: val.confirmText ? val.confirmText : "确定",cancelText: val.cancelText ? val.cancelText : "取消",cancelColor: "#999999", //取消按钮颜色confirmColor: "#00A0E9", //确定按钮颜色success: (res) => {success(res);},});}
}/*** 静态变量,是否加载中*/
Tips.isLoading = false;

8.main.js

import ble from "./common/util/ble.js";
import tip from "./common/util/tip.js";// ble
Vue.prototype.$ble = ble;
// tip
Vue.prototype.$tip = tip;


http://www.ppmy.cn/server/38497.html

相关文章

【MySQL】事务及其隔离性/隔离级别

目录 一、事务的概念 1、事务的四种特性 2、事务的作用 3、存储引擎对事务的支持 4、事务的提交方式 二、事务的启动、回滚与提交 1、准备工作&#xff1a;调整MySQL的默认隔离级别为最低/创建测试表 2、事务的启动、回滚与提交 3、启动事务后未commit&#xff0c;但是…

ansible—playbook的template、tags、roles模块

目录 一、template 1、简介 2、template模块实例 1.先准备一个以.j2结尾的template模板文件&#xff0c;设置引用的变量&#xff0c;ansible上要先安装httpd 2、修改主机清单文件&#xff0c;使用主机变量定义一个变量名相同而值不同的变量 3、主机添加hosts 4、编写pla…

Flutter笔记:Widgets Easier组件库(11)- 使用提示吐丝(Tip Toasts)

Flutter笔记 Widgets Easier组件库&#xff08;11&#xff09;使用提示吐丝 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this …

ARP欺骗使局域网内设备断网

一、实验准备 kali系统&#xff1a;可使用虚拟机软件模拟 kali虚拟机镜像链接&#xff1a;https://www.kali.org/get-kali/#kali-virtual-machines 注意虚拟机网络适配器采用桥接模式 局域网内存在指定断网的设备 二、实验步骤 打开kali系统命令行&#xff1a;ctrlaltt可快…

修改el-checkbox样式

一定要在最外层&#xff1b; //未选中框/deep/ .el-checkbox__inner{border-color: #0862a3;}//选中框/deep/ .el-checkbox__input.is-checked .el-checkbox__inner{background-color: #0862a3;border-color: #0862a3;}//未选中框时右侧文字/deep/ .el-checkbox__label{}//选中…

洛谷 P4148:简单题 ← KD-Tree模板题

【题目来源】https://www.luogu.com.cn/problem/P4148【题目描述】 你有一个 NN 的棋盘&#xff0c;每个格子内有一个整数&#xff0c;初始时的时候全部为 0&#xff0c;现在需要维护两种操作&#xff1a; ● 1 x y A → 1≤x,y≤N&#xff0c;A 是正整数。将格子 (x,y) 里的数…

【C语言】static关键字用法

目录 一、static修饰局部变量 二、static修饰全局变量 三、static修饰函数 一、static修饰局部变量 首先我们来看两段代码: 代码1&#xff08;不加static&#xff09; #include <stdio.h> void test() {int i 0;i;printf("%d ", i); } int main() {int i…

视频封面一键提取:从指定时长中轻松获取您想要的帧图片

在数字媒体时代&#xff0c;视频已成为人们获取信息、娱乐和沟通的主要形式之一。而一个好的视频封面&#xff0c;往往能够吸引观众的眼球&#xff0c;增加视频的点击率和观看量。然而&#xff0c;对于很多视频创作者和编辑者来说&#xff0c;如何从视频中快速、准确地提取出合…