|
@@ -5,12 +5,8 @@ class bleManager {
|
|
|
constructor() {
|
|
|
this.hasPermission = false;
|
|
|
this.isAvailable = false;
|
|
|
- // this.devices = [];
|
|
|
- this.connectedDeviceId = null;
|
|
|
- // this.services = [];
|
|
|
- this.serviceId = null;
|
|
|
- this.deviceId = null;
|
|
|
- this.characteristicId = null;
|
|
|
+ this.scanDevices = [];
|
|
|
+ this.device = null;
|
|
|
}
|
|
|
|
|
|
// 检查蓝牙权限
|
|
@@ -22,20 +18,26 @@ class bleManager {
|
|
|
success(res) {
|
|
|
if (res.authSetting["scope.bluetooth"]) {
|
|
|
_this.globalData.scopeBluetooth = true;
|
|
|
+ this.hasPermission = true;
|
|
|
+ // console.log('checkBluetoothPermission success, now is', res)
|
|
|
+
|
|
|
resolve(true);
|
|
|
|
|
|
} else if (res.authSetting["scope.bluetooth"] === undefined) {
|
|
|
_this.globalData.scopeBluetooth = false;
|
|
|
+ this.hasPermission = false;
|
|
|
wx.authorize({
|
|
|
scope: "scope.bluetooth",
|
|
|
complete() {
|
|
|
- _this.getBluetoothStatus();
|
|
|
+
|
|
|
+ resolve(_this.checkBluetoothPermission());
|
|
|
+
|
|
|
}
|
|
|
});
|
|
|
- resolve(false);
|
|
|
|
|
|
} else {
|
|
|
_this.globalData.scopeBluetooth = false;
|
|
|
+ this.hasPermission = false;
|
|
|
|
|
|
wx.showModal({
|
|
|
title: '请打开系统蓝牙进行配网',
|
|
@@ -65,14 +67,24 @@ class bleManager {
|
|
|
|
|
|
// 初始化蓝牙适配器
|
|
|
initBluetoothAdapter() {
|
|
|
+ let _this = this;
|
|
|
+ wx.onBluetoothAdapterStateChange(function (res) {
|
|
|
+ console.log('adapterState changed, now is', res)
|
|
|
+ _this.isAvailable = res.available ?? false
|
|
|
+
|
|
|
+ })
|
|
|
return new Promise((resolve, reject) => {
|
|
|
wx.openBluetoothAdapter({
|
|
|
success: (res) => {
|
|
|
- this.isAvailable = true;
|
|
|
+ _this.isAvailable = true;
|
|
|
+ // console.log('adapterState success, now is', res)
|
|
|
+
|
|
|
resolve(true);
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
- this.isAvailable = false;
|
|
|
+ _this.isAvailable = false;
|
|
|
+ // console.log('adapterState fail, now is', err)
|
|
|
+
|
|
|
reject(false);
|
|
|
}
|
|
|
});
|
|
@@ -81,23 +93,56 @@ class bleManager {
|
|
|
|
|
|
// 获取已连接的蓝牙设备
|
|
|
getConnectedDevices() {
|
|
|
+ if (!this.isAvailable && !this.hasPermission) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
return new Promise((resolve, reject) => {
|
|
|
wx.getConnectedBluetoothDevices({
|
|
|
- services: ["ffc0", "ab00", "ffe5"],
|
|
|
- // services: ["0000ab00-0000-1000-8000-00805f9b34fb"
|
|
|
- // , "0000ffc0-0000-1000-8000-00805f9b34fb"
|
|
|
+ // services: ["FFC0", "ffc0", "FFC1", "FFC2", "ffc1", "ffc2", "AB00", "ab00", "AB01", "AB02", "FFF1", "fff1", "FFE2", "FFE5",],
|
|
|
+ services: ["ab00", "0000AB00-0000-1000-8000-00805F9B34FB", "ffe5", "1111"],
|
|
|
+ // services: [
|
|
|
+ // "0000ab00-0000-1000-8000-00805f9b34fb",
|
|
|
+ // "0000ffc0-0000-1000-8000-00805f9b34fb",
|
|
|
+ // "0000FFF0-0000-1000-8000-00805F9B34FB",
|
|
|
+ // "0000FFF1-0000-1000-8000-00805F9B34FB",
|
|
|
+ // "0000FFE5-0000-1000-8000-00805F9B34FB",
|
|
|
// ],
|
|
|
success: (res) => {
|
|
|
// const connectedDevices = res.devices.map(device => ({
|
|
|
// deviceId: device.deviceId,
|
|
|
// name: device.name || device.localName
|
|
|
// }));
|
|
|
- console.log('已连接的蓝牙设备:', res.devices);
|
|
|
- resolve(res.devices);
|
|
|
+ console.log('已连接的蓝牙设备:', res);
|
|
|
+ resolve(res);
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
console.error('获取已连接的蓝牙设备失败:', err);
|
|
|
- reject(new Error('获取已连接的蓝牙设备失败'));
|
|
|
+ reject([]);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取获取在蓝牙模块生效期间所有搜索到的蓝牙设备。包括已经和本机处于连接状态的设备。
|
|
|
+ getAllConnectedDevices() {
|
|
|
+ if (!this.isAvailable && !this.hasPermission) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ wx.getBluetoothDevices({
|
|
|
+ success: (res) => {
|
|
|
+ // const connectedDevices = res.devices.map(device => ({
|
|
|
+ // deviceId: device.deviceId,
|
|
|
+ // name: device.name || device.localName
|
|
|
+ // }));
|
|
|
+ console.log('已扫描过的蓝牙设备:', res);
|
|
|
+ let newDevices = this.fiterDevice(res)
|
|
|
+
|
|
|
+ resolve(newDevices);
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ console.error('已扫描过的蓝牙设备失败:', err);
|
|
|
+ reject([]);
|
|
|
}
|
|
|
});
|
|
|
});
|
|
@@ -131,9 +176,9 @@ class bleManager {
|
|
|
}
|
|
|
|
|
|
wx.writeBLECharacteristicValue({
|
|
|
- deviceId: this.deviceId,
|
|
|
- serviceId: this.serviceId,
|
|
|
- characteristicId: this.characteristicId,
|
|
|
+ deviceId: this.device.deviceId,
|
|
|
+ serviceId: this.device.serviceId,
|
|
|
+ characteristicId: this.device.characteristicId,
|
|
|
value: buffer,
|
|
|
success: (res) => {
|
|
|
console.log('数据发送成功:', res);
|
|
@@ -147,47 +192,72 @@ class bleManager {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- getSetting() {
|
|
|
+ async getSetting() {
|
|
|
const _this = this;
|
|
|
- wx.getSetting({
|
|
|
- success(res) {
|
|
|
- if (res.authSetting["scope.userFuzzyLocation"]) {
|
|
|
- // 成功
|
|
|
- _this.getBluetoothStatus();
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
|
|
- } else if (res.authSetting["scope.userFuzzyLocation"] === undefined) {
|
|
|
+ wx.getSetting({
|
|
|
+ success(res) {
|
|
|
+ if (res.authSetting["scope.userFuzzyLocation"]) {
|
|
|
+ // 成功
|
|
|
+ // _this.getBluetoothStatus();
|
|
|
+ console.log("有定位权限")
|
|
|
+ resolve(true);
|
|
|
+
|
|
|
+ } else if (res.authSetting["scope.userFuzzyLocation"] === undefined) {
|
|
|
+
|
|
|
+ wx.authorize({
|
|
|
+ scope: "scope.userFuzzyLocation",
|
|
|
+ success() {
|
|
|
+ console.log("再次获取定位权限")
|
|
|
+ resolve(_this.getSetting());
|
|
|
|
|
|
- wx.authorize({
|
|
|
- scope: "scope.userFuzzyLocation",
|
|
|
- success() {
|
|
|
- _this.getSetting();
|
|
|
- }
|
|
|
- });
|
|
|
- } else {
|
|
|
-
|
|
|
- wx.showModal({
|
|
|
- title: '请打开系统位置获取',
|
|
|
- success(res) {
|
|
|
- if (res.confirm) {
|
|
|
- console.log('用户点击确定')
|
|
|
- wx.openSetting({
|
|
|
- complete() {
|
|
|
- // _this.getSetting();
|
|
|
- }
|
|
|
- })
|
|
|
- } else if (res.cancel) {
|
|
|
- console.log('用户点击取消');
|
|
|
}
|
|
|
- }
|
|
|
- })
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+
|
|
|
+ wx.showModal({
|
|
|
+ title: '请打开系统位置获取定位权限',
|
|
|
+ success(res) {
|
|
|
+ if (res.confirm) {
|
|
|
+ console.log('用户点击确定')
|
|
|
+ wx.openSetting({
|
|
|
+ complete() {
|
|
|
+ // _this.getSetting();
|
|
|
+ // resolve(_this.getSetting());
|
|
|
+
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else if (res.cancel) {
|
|
|
+ console.log('用户点击取消');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ console.log("没有有定位权限")
|
|
|
+ reject(false);
|
|
|
+
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- })
|
|
|
+ })
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
}
|
|
|
// 开始搜索蓝牙设备
|
|
|
- startScan(success, fail) {
|
|
|
+ async startScan(success, fail) {
|
|
|
+
|
|
|
+ let open = await this.getSetting()
|
|
|
+ if (!open) {
|
|
|
+ if (fail) {
|
|
|
+ fail("需要先开启定位");
|
|
|
+ }
|
|
|
+ console.log('需要先开启定位');
|
|
|
+ }
|
|
|
+ if (!this.isAvailable && !this.hasPermission) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
wx.startBluetoothDevicesDiscovery({
|
|
|
- services: ["ffc0", "ab00", "ffe5"],
|
|
|
+ // services: ["ffc0", "ab00", "ffe5"],
|
|
|
success: (res) => {
|
|
|
// this.onBluetoothDeviceFound();
|
|
|
console.log('蓝牙设备搜索已启动:', res);
|
|
@@ -199,6 +269,13 @@ class bleManager {
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
if (fail) {
|
|
|
+ if (err.errno == 1509008) {
|
|
|
+ wx.showToast({
|
|
|
+ title: '搜索蓝牙需要先开启定位权限',
|
|
|
+ icon: 'none',
|
|
|
+ duration: 2000
|
|
|
+ })
|
|
|
+ }
|
|
|
fail(err);
|
|
|
}
|
|
|
console.log('启动蓝牙设备搜索失败', err ?? "err is null");
|
|
@@ -206,49 +283,85 @@ class bleManager {
|
|
|
// reject(new Error('启动蓝牙设备搜索失败', err ?? "err is null"));
|
|
|
}
|
|
|
});
|
|
|
- // return new Promise((resolve, reject) => {
|
|
|
- // wx.startBluetoothDevicesDiscovery({
|
|
|
- // services: ["ffc0", "ab00", "ffe5"],
|
|
|
- // success: (res) => {
|
|
|
- // // this.onBluetoothDeviceFound();
|
|
|
- // console.log('蓝牙设备搜索已启动:', res);
|
|
|
- // resolve(res);
|
|
|
- // },
|
|
|
- // fail: (err) => {
|
|
|
- // reject(new Error('启动蓝牙设备搜索失败', err ?? "err is null"));
|
|
|
- // }
|
|
|
- // });
|
|
|
- // });
|
|
|
}
|
|
|
|
|
|
// 监听发现新设备的事件
|
|
|
onBluetoothDeviceFound(callback) {
|
|
|
wx.onBluetoothDeviceFound((res) => {
|
|
|
- const devices = res.devices.map(device => ({
|
|
|
- deviceId: device.deviceId,
|
|
|
- name: device.name || device.localName
|
|
|
- }));
|
|
|
+
|
|
|
+ let newDevices = this.fiterDevice(res)
|
|
|
// this.devices.push(...devices);
|
|
|
- console.log('发现设备:', this.devices);
|
|
|
+ if (newDevices.length > 0) {
|
|
|
+ // console.log('发现设备:', newDevices[0].deviceId, newDevices[0].uuid);
|
|
|
+ }
|
|
|
if (callback) {
|
|
|
- callback(devices);
|
|
|
+ callback(newDevices);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
+ ab2hex(buffer) {
|
|
|
+ var hexArr = Array.prototype.map.call(
|
|
|
+ new Uint8Array(buffer),
|
|
|
+ function (bit) {
|
|
|
+ return ('00' + bit.toString(16)).slice(-2)
|
|
|
+ }
|
|
|
+ )
|
|
|
+ return hexArr.join('');
|
|
|
+ }
|
|
|
+ fiterDevice(res) {
|
|
|
+ var devices = res.devices.filter(device => {
|
|
|
+ const name = device.name || '';
|
|
|
+ const localName = device.localName || '';
|
|
|
+ let isNot = this.isNotEmpty(name) || this.isNotEmpty(localName);
|
|
|
+ if (isNot) {
|
|
|
+ let mac = this.ab2hex(device.advertisData)
|
|
|
+ // console.log(mac)
|
|
|
+ device.mac = mac
|
|
|
+ }
|
|
|
+ return isNot
|
|
|
+ });
|
|
|
|
|
|
+ let newDevices = devices.map((device) => {
|
|
|
+ let uuid = device.advertisServiceUUIDs[0] ?? ""
|
|
|
+ return {
|
|
|
+ deviceId: device.deviceId,
|
|
|
+ name: device.name,
|
|
|
+ localName: device.localName,
|
|
|
+ uuid: uuid,
|
|
|
+ mac: device.mac
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return newDevices
|
|
|
+ }
|
|
|
+ isNotEmpty(name) {
|
|
|
+ let isNot = (name !== ''
|
|
|
+ && (name.includes("猫王") ||
|
|
|
+ name.includes("MW_") ||
|
|
|
+ name.includes("妙播") ||
|
|
|
+ name.includes("AirSmart") ||
|
|
|
+ name === "le")
|
|
|
+ )
|
|
|
+ // if (!isNot && name !== '') {
|
|
|
+ // console.log('不是猫王设备名称:', name)
|
|
|
+ // }
|
|
|
+ return isNot;
|
|
|
+ }
|
|
|
// 连接到指定设备
|
|
|
- connectToDevice(deviceId) {
|
|
|
+ connectToDevice(device) {
|
|
|
+ this.device = device
|
|
|
+
|
|
|
return new Promise((resolve, reject) => {
|
|
|
+ console.log("开始连接蓝牙:", device.deviceId)
|
|
|
wx.createBLEConnection({
|
|
|
- deviceId: deviceId,
|
|
|
+ deviceId: device.deviceId,
|
|
|
success: (res) => {
|
|
|
- this.connectedDeviceId = deviceId;
|
|
|
console.log('连接成功:', res);
|
|
|
resolve(res);
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
+ this.device = null
|
|
|
console.error('连接失败:', err);
|
|
|
- reject(new Error('连接失败'));
|
|
|
+ reject(false);
|
|
|
}
|
|
|
});
|
|
|
});
|
|
@@ -256,7 +369,9 @@ class bleManager {
|
|
|
|
|
|
// 停止搜索
|
|
|
stopScan() {
|
|
|
+
|
|
|
return new Promise((resolve, reject) => {
|
|
|
+
|
|
|
wx.stopBluetoothDevicesDiscovery({
|
|
|
success: (res) => {
|
|
|
console.log('停止搜索成功:', res);
|
|
@@ -267,20 +382,42 @@ class bleManager {
|
|
|
reject(new Error('停止搜索失败'));
|
|
|
}
|
|
|
});
|
|
|
+
|
|
|
});
|
|
|
}
|
|
|
+ closeBle() {
|
|
|
+ wx.closeBluetoothAdapter({
|
|
|
+ success(res) {
|
|
|
+ console.log(res)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
|
|
|
// 发现服务
|
|
|
discoverServices(deviceId) {
|
|
|
+ console.log('发现服务:', deviceId);
|
|
|
+
|
|
|
return new Promise((resolve, reject) => {
|
|
|
wx.getBLEDeviceServices({
|
|
|
deviceId: deviceId,
|
|
|
success: (res) => {
|
|
|
- this.services = res.services;
|
|
|
- console.log('发现服务:', this.services);
|
|
|
- resolve(res.services);
|
|
|
+ this.device.services = res.services;
|
|
|
+ console.log('发现服务:', res.services);
|
|
|
+ let service_id = "";
|
|
|
+ for (let i = 0; i < res.services.length; i++) {
|
|
|
+ if (services[i].uuid.toUpperCase().indexOf("AB00") != -1
|
|
|
+ || services[i].uuid.toUpperCase().indexOf("FFC0") != -1
|
|
|
+ ) {
|
|
|
+ service_id = services[i].uuid;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.device.serviceId = service_id;
|
|
|
+ resolve(service_id);
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
+ this.device.serviceId = null;
|
|
|
+
|
|
|
console.error('发现服务失败:', err);
|
|
|
reject(new Error('发现服务失败'));
|
|
|
}
|
|
@@ -288,21 +425,29 @@ class bleManager {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- // 发现特征值
|
|
|
+ // 发现特征值 read / write
|
|
|
discoverCharacteristics(deviceId, serviceId) {
|
|
|
+ console.log('发现特征值:', deviceId, serviceId);
|
|
|
+
|
|
|
+ if (deviceId !== this.device.deviceId) {
|
|
|
+ console.log('设备id不匹配')
|
|
|
+ return false
|
|
|
+ }
|
|
|
return new Promise((resolve, reject) => {
|
|
|
wx.getBLEDeviceCharacteristics({
|
|
|
deviceId: deviceId,
|
|
|
serviceId: serviceId,
|
|
|
success: (res) => {
|
|
|
// this.characteristics[serviceId] = res.characteristics;
|
|
|
- this.characteristicId = res.characteristics;
|
|
|
- console.log('发现特征值:', this.characteristicId);
|
|
|
+ console.log('发现特征值:', res.characteristics);
|
|
|
+ this.device.characteristics = res.characteristics;
|
|
|
+
|
|
|
resolve(res.characteristics);
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
+ this.device.characteristics = null;
|
|
|
console.error('发现特征值失败:', err);
|
|
|
- reject(new Error('发现特征值失败'));
|
|
|
+ reject("");
|
|
|
}
|
|
|
});
|
|
|
});
|
|
@@ -310,6 +455,11 @@ class bleManager {
|
|
|
|
|
|
// 读取特征值
|
|
|
readCharacteristicValue(deviceId, serviceId, characteristicId) {
|
|
|
+ if (deviceId !== this.device.deviceId) {
|
|
|
+ console.log('设备id不匹配2')
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ console.log('开始读取特征值', deviceId, serviceId, characteristicId)
|
|
|
return new Promise((resolve, reject) => {
|
|
|
wx.readBLECharacteristicValue({
|
|
|
deviceId: deviceId,
|
|
@@ -321,44 +471,44 @@ class bleManager {
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
console.error('读取特征值失败:', err);
|
|
|
- reject(new Error('读取特征值失败'));
|
|
|
+ reject("");
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 监听特征值变化
|
|
|
- notifyCharacteristicValueChange(deviceId, serviceId, characteristicId, state, callback) {
|
|
|
- // return new Promise((resolve, reject) => {
|
|
|
+ notifyCharacteristicValueChange(deviceId, serviceId, characteristicId, callback) {
|
|
|
wx.notifyBLECharacteristicValueChange({
|
|
|
- deviceId: deviceId,
|
|
|
- serviceId: serviceId,
|
|
|
- characteristicId: characteristicId,
|
|
|
- state: state, // true 表示开启通知,false 表示关闭通知
|
|
|
- success: (res) => {
|
|
|
- console.log('通知特征值变化成功:', res);
|
|
|
- // resolve(res);
|
|
|
- if (callback) {
|
|
|
- callback(res)
|
|
|
- }
|
|
|
- },
|
|
|
- fail: (err) => {
|
|
|
- console.error('通知特征值变化失败:', err);
|
|
|
- // reject(new Error('通知特征值变化失败'));
|
|
|
- }
|
|
|
- });
|
|
|
- // });
|
|
|
- }
|
|
|
+ deviceId: deviceId, //设备mac IOS和安卓系统不一样
|
|
|
+ serviceId: serviceId, //服务通道,这里主要是notify
|
|
|
+ characteristicId: characteristicId, //notify uuid
|
|
|
+ state: true,
|
|
|
+ success: function (res) {
|
|
|
+ console.log("开启notify 成功")
|
|
|
+ //TODO onBLECharacteristicValueChange 监听特征值 设备的数据在这里获取到
|
|
|
+ wx.onBLECharacteristicValueChange(function (characteristic) {
|
|
|
+ console.log('characteristic value comed:')
|
|
|
+ let buffer = characteristic.value
|
|
|
+ let dataView = new DataView(buffer)
|
|
|
+ let dataResult = []
|
|
|
+ console.log("dataView.byteLength", dataView.byteLength)
|
|
|
+ for (let i = 0; i < dataView.byteLength; i++) {
|
|
|
+ console.log("0x" + dataView.getUint8(i).toString(16))
|
|
|
+ dataResult.push(dataView.getUint8(i).toString(16))
|
|
|
+ }
|
|
|
+ const result = dataResult
|
|
|
+ console.log("拿到的数据:", result)
|
|
|
|
|
|
- // 搜索蓝牙服务
|
|
|
- searchServices(deviceId) {
|
|
|
- return this.discoverServices(deviceId);
|
|
|
+ if (callback) {
|
|
|
+ callback(result)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ fail: function (res) { }
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
- // 搜索蓝牙特征值
|
|
|
- searchCharacteristics(deviceId, serviceId) {
|
|
|
- return this.discoverCharacteristics(deviceId, serviceId);
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
const ble = new bleManager();
|