340 lines
10 KiB
JavaScript
Raw Normal View History

2025-04-16 18:15:18 +08:00
import Taro from "@tarojs/taro";
2025-04-18 09:09:09 +08:00
import { handshake1, handshake2 } from "./sendOrder";
2025-04-16 18:15:18 +08:00
import TASK from "./taskQueue";
const errMsg = {
0: "正常",
10000: "未初始化蓝牙适配器",
10001: "请检查手机蓝牙是否打开或微信是否授权蓝牙",
10002: "没有找到指定设备",
10003: "连接失败",
10004: "没有找到指定服务",
10005: "没有找到指定特征",
10006: "当前连接已断开",
10007: "当前特征不支持此操作",
10008: "其余所有系统上报的异常",
10009: "Android系统版本低于4.3不支持蓝牙功能",
10012: "连接超时",
10013: "连接超时",
1509008: "请检查手机定位是否打开或微信是否授权定位",
};
class Bluetooth {
config = {
2025-04-21 18:27:42 +08:00
// serviceId: "4E31BF4A-8507-3A2B-7344-C7EDACD38104", //设备服务id
// NotifyUUID: "4E31BF4B-8507-3A2B-7344-C7EDACD38104",
// WriteUUID: "4E31BF4C-8507-3A2B-7344-C7EDACD38104",
serviceId: 'C7E6FAE0-E966-1000-8000-BEF9C723DF6A', //设备服务id
NotifyUUID: 'C7E6FAE1-E966-1000-8000-BEF9C723DF6A',
WriteUUID: 'C7E6FAE2-E966-1000-8000-BEF9C723DF6A',
2025-04-16 18:15:18 +08:00
};
// 连接状态
linkFlag = false;
// 蓝牙是否可用
available = true;
// 蓝牙初始化
isInit = false;
timeout = null;
timeout1 = null;
// 判断是否搜索到设备
isFindBt = null;
platform = Taro.getSystemInfoSync().platform;
appAuthorize = Taro.getAppAuthorizeSetting();
2025-04-21 18:27:42 +08:00
deviceInfo = Taro.getStorageSync('deviceInfo') || {}
2025-04-16 18:15:18 +08:00
callBack = () => { };
searchBack = () => { };
constructor() {
this.onBluetoothAdapterStateChange();
this.onBLEConnectionStateChange();
this.onBluetoothDeviceFound();
}
// 错误
fail(res) {
this.linkFlag = false;
if (!res.errCode) return;
let starIde = res.errMsg.indexOf("fail") + 5;
Taro.showToast({ title: errMsg[res.errCode] || errMsg[res.errno] || res.errMsg.substring(starIde), icon: "none", duration: 3000 });
}
// 监测手机蓝牙状态
onBluetoothAdapterStateChange() {
Taro.onBluetoothAdapterStateChange(({ available, discovering }) => {
this.available = available;
// 手机蓝牙开启
if (this.available && !this.isInit) {
Taro.closeBluetoothAdapter({
success: (res) => {
this.openBluetoothAdapter();
},
});
console.log("手机蓝牙开启");
}
// 手机蓝牙关闭
if (!available) {
this.isInit = false;
this.deviceInfo.state = false;
this.linkFlag = false;
this.callBack(this.deviceInfo);
console.log("手机蓝牙关闭");
}
});
}
// 初始化蓝牙模块
openBluetoothAdapter() {
return Taro.openBluetoothAdapter({
success: () => {
console.log("初始化蓝牙模块");
this.isInit = true;
},
fail: (err) => {
this.isInit = false;
this.fail(err);
},
});
}
// 开始搜寻附近的蓝牙外围设备
startBluetoothDevicesDiscovery() {
console.log("搜索蓝牙");
if (this.appAuthorize.locationAuthorized != "authorized" && this.platform == "android")
return Taro.showToast({ title: "请打开微信定位权限", icon: "none", duration: 3000 });
Taro.startBluetoothDevicesDiscovery({
allowDuplicatesKey: true,
powerLevel: "high",
success: (res) => {
this.isFindBt = setTimeout(() => {
if (this.platform == "android") {
this.stopBluetoothDevicesDiscovery();
Taro.showModal({
title: "未搜索到设备",
content: "1、请检查设备是否在附近或者设备是否被其他应用连接。2、请检查手机微信应用权限中的附近的设备权限是否打开。",
showCancel: false,
success: () => {
const pages = Taro.getCurrentPages();
if (pages?.length > 1) {
Taro.navigateBack();
}
},
});
}
2025-04-18 09:09:09 +08:00
console.log("未搜索到设备");
2025-04-16 18:15:18 +08:00
this.isFindBt && this.clearTimeoutFn("isFindBt");
}, 6000);
},
fail: (err) => {
this.fail(err);
this.stopBluetoothDevicesDiscovery();
},
});
}
// 监听搜索到新设备的事件
// 定义一个方法用于处理蓝牙设备发现事件
2025-04-21 18:27:42 +08:00
onBluetoothDeviceFound(fn) {
2025-04-16 18:15:18 +08:00
Taro.onBluetoothDeviceFound((res) => {
const devices = res.devices[0];
const advertisData = this.ab2hex(devices.advertisData);
const mac = this.strInsert(String(advertisData).substring(4, 16)).toLocaleUpperCase();
// 判断是否有搜索到设备
this.isFindBt && this.clearTimeoutFn("isFindBt");
2025-04-21 18:27:42 +08:00
if (devices.name && devices.name == "W53A") {
// if (devices.name && devices.name == "LE-AB2020") {
2025-04-16 18:15:18 +08:00
const item = {
deviceId: devices.deviceId,
mac: mac,
name: devices.name,
};
2025-04-21 18:27:42 +08:00
// this.deviceInfo = { ...this.deviceInfo, ...item }
// this.stopBluetoothDevicesDiscovery();
// this.createBleConnection();
fn && fn(item)
2025-04-16 18:15:18 +08:00
}
});
}
// 蓝牙连接
createBleConnection() {
if (!this.available || this.linkFlag) return;
this.linkFlag = true;
Taro.setStorageSync("deviceInfo", this.deviceInfo);
console.log("正在连接设备");
Taro.createBLEConnection({
timeout: 8000,
deviceId: this.deviceInfo.deviceId,
success: () => {
this.deviceInfo.state = true;
this.getBLEDeviceServices();
// this.getBLEDeviceCharacteristics();
},
fail: (res) => {
this.linkFlag = false;
console.log(res, this.deviceInfo, "连接错误");
this.callBack({ ...this.deviceInfo, errCode: 10003 });
if (!this.deviceInfo.deviceId) return this.timeout && this.clearTimeoutFn("timeout");
if (this.timeout) return;
if (res.errno == "1509007") {
this.closeBluetoothAdapter();
} else {
this.timeout = setTimeout(() => {
this.timeout && this.clearTimeoutFn("timeout");
this.createBleConnection();
}, 10000);
}
},
});
}
// 获取蓝牙多个service
getBLEDeviceServices() {
Taro.getBLEDeviceServices({
deviceId: this.deviceInfo.deviceId,
success: (res) => {
console.log(JSON.stringify(res), 'JSON.stringify(res)');
this.getBLEDeviceCharacteristics();
},
fail: (err) => this.fail(err),
});
}
// 获取蓝牙低功耗设备某个服务中所有特征
getBLEDeviceCharacteristics() {
Taro.getBLEDeviceCharacteristics({
deviceId: this.deviceInfo.deviceId,
serviceId: this.config.serviceId,
success: (res) => {
this.notifyBLECharacteristicValueChange();
},
fail: (err) => this.fail(err),
});
}
// 启用蓝牙低功耗设备特征值变化时的 notify 功能
notifyBLECharacteristicValueChange() {
Taro.notifyBLECharacteristicValueChange({
deviceId: this.deviceInfo.deviceId,
serviceId: this.config.serviceId,
characteristicId: this.config.NotifyUUID,
state: true,
success: (res) => {
console.log("连接成功");
2025-04-21 18:27:42 +08:00
Taro.setStorageSync("deviceInfo", this.deviceInfo);
2025-04-18 09:09:09 +08:00
handshake1()
2025-04-16 18:15:18 +08:00
this.callBack(this.deviceInfo);
},
fail: (err) => this.fail(err),
});
}
//监听设备返回的数据
onBLECharacteristicValueChange(fn) {
Taro.onBLECharacteristicValueChange((data) => {
let bytes = new Uint8Array(data.value);
let value = String(this.ab2hex(bytes));
2025-04-18 09:09:09 +08:00
// 第二次握手
if (bytes[2] == 0xea && bytes[3] == 0x01) {
handshake2()
2025-04-16 18:15:18 +08:00
}
2025-04-18 09:09:09 +08:00
console.log(`设备回复====>${value}`);
2025-04-16 18:15:18 +08:00
TASK.executeTask();
2025-04-18 09:09:09 +08:00
fn && fn(bytes, value);
2025-04-16 18:15:18 +08:00
});
}
// 向蓝牙写入数据
writeBleValue(value) {
2025-04-18 09:09:09 +08:00
if (!this.deviceInfo.state) {
console.log("蓝牙未连接")
return
}
2025-04-16 18:15:18 +08:00
console.log("发送指令====>" + String(this.ab2hex(value)).toLocaleUpperCase());
return Taro.writeBLECharacteristicValue({
deviceId: this.deviceInfo.deviceId,
serviceId: this.config.serviceId,
characteristicId: this.config.WriteUUID,
writeType: "writeNoResponse",
value: value,
});
}
//蓝牙断开
onBLEConnectionStateChange() {
Taro.onBLEConnectionStateChange((res) => {
if (!res.connected) {
console.log(res, "蓝牙断开");
this.deviceInfo.state = res.connected;
this.callBack(this.deviceInfo);
this.linkFlag = false;
if (!this.available || this.timeout || !this.isInit || !this.deviceInfo.deviceId) return;
this.timeout = setTimeout(() => {
this.timeout && this.clearTimeoutFn("timeout");
this.createBleConnection();
}, 1000);
}
});
}
//停止搜寻附近的蓝牙外围设备
stopBluetoothDevicesDiscovery() {
Taro.stopBluetoothDevicesDiscovery();
2025-04-18 09:09:09 +08:00
this.isFindBt && this.clearTimeoutFn("isFindBt");
2025-04-16 18:15:18 +08:00
console.log("停止搜寻");
}
// 断开与蓝牙低功耗设备的连接
closeBluetoothAdapter() {
return new Promise((resolve, reject) => {
this.linkFlag = false;
this.deviceInfo = { state: false };
wx.removeStorageSync("deviceInfo");
this.callBack(this.deviceInfo);
Taro.closeBluetoothAdapter({
success: (res) => {
this.openBluetoothAdapter().then(resolve).catch(reject);
},
});
})
}
// 设备响应回调
deviceCallBack(fn) {
this.callBack = fn;
}
// 转换二进制数据
ab2hex(buffer) {
if (!buffer) return;
const hexArr = Array.prototype.map.call(new Uint8Array(buffer), function (bit) {
return ("00" + bit.toString(16)).slice(-2);
});
return hexArr.join("").toLocaleLowerCase();
}
2025-04-21 18:27:42 +08:00
unBindDevice() {
this.deviceInfo = {}
wx.removeStorageSync('deviceInfo')
this.closeBluetoothAdapter()
}
2025-04-16 18:15:18 +08:00
/**
* 字符串插入字符
* @param {*} str 字符串
* @param {*} length 间隔多少个插入
* @param {*} fmt 插入符号
* @returns
*/
strInsert(str, length = 2, fmt = ":") {
if (!str || !str.length) return "";
var reg = new RegExp("\\w{1," + length + "}", "g");
let ma = str.match(reg);
return ma.join(fmt).toLocaleLowerCase();
}
// 清除计时器
clearTimeoutFn(name) {
clearTimeout(this[name]);
this[name] = null;
}
}
export default new Bluetooth();