wx-starlock/stores/bluetooth.js

404 lines
13 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @description 蓝牙数据持久化
*/
import { defineStore } from 'pinia'
// 定时器
let timer
export const useBluetoothStore = defineStore('ble', {
state() {
return {
/*
* 蓝牙状态
* -1 未知(初始状态)
* 0 正常
* 1 系统蓝牙未打开
* 2 小程序蓝牙功能被禁用
* 3 系统蓝牙未打开且小程序蓝牙功能被禁用
*/
bluetoothStatus: -1,
// 设备列表
deviceList: [],
// 当前锁信息
currentLockInfo: {}
}
},
actions: {
// 初始化蓝牙模块并监听蓝牙状态变化
initBluetooth() {
const that = this
// 初始化蓝牙模块
return new Promise(resolve => {
uni.openBluetoothAdapter({
success() {
that.bluetoothStatus = 0
console.log('蓝牙初始化成功')
resolve()
},
fail(err) {
console.log('蓝牙初始化失败', err)
// 系统蓝牙未打开
if(err.errCode === 10001) {
if(that.bluetoothStatus === 2) {
that.bluetoothStatus = 3
} else {
that.bluetoothStatus = 1
}
}
// 小程序蓝牙功能被禁用
if(err.errno === 103) {
if(that.bluetoothStatus === 1) {
that.bluetoothStatus = 3
} else {
that.bluetoothStatus = 2
}
}
resolve()
}
})
})
},
// 监听蓝牙状态变化
onBluetoothState() {
const that = this
uni.onBluetoothAdapterStateChange((res) => {
console.log('蓝牙状态改变', res)
if(that.bluetoothStatus === 3 && res.available) {
that.bluetoothStatus = 2
} else if (that.bluetoothStatus === 2 && !res.available) {
that.bluetoothStatus = 3
} else if (that.bluetoothStatus === 1 && res.available) {
that.bluetoothStatus = 0
} else if (that.bluetoothStatus === 0 && !res.available){
that.bluetoothStatus = 1
} else if (that.bluetoothStatus === -1) {
if(res.available) {
that.bluetoothStatus = 0
} else {
that.bluetoothStatus = 1
}
}
})
},
// 监听蓝牙设备连接状态
onBluetoothConnectStatus() {
const that = this
uni.onBLEConnectionStateChange(function (res) {
if(res.deviceId === that.currentLockInfo.deviceId) {
console.log('设备连接状态改变', res)
that.updateCurrentLockInfo({
...that.currentLockInfo,
connected: res.connected
})
}
})
},
// 监听蓝牙设备特征值改变
onBluetoothCharacteristicValueChange() {
const that = this
uni.onBLECharacteristicValueChange(function (res) {
// 待完善
console.log('特征值改变', res)
})
},
// 开始搜索蓝牙设备
getBluetoothDevices() {
const that = this
if(this.bluetoothStatus !== 0) {
console.log('搜索未执行', this.bluetoothStatus)
this.getBluetoothStatus()
return
}
uni.startBluetoothDevicesDiscovery({
success: function (res) {
setTimeout(() => {
that.searchBluetoothDevices()
}, 300)
},
fail: async function (res) {
console.log('开始搜索失败', res)
if(res.errCode === 10000) {
// 重新初始化蓝牙适配器
await that.initBluetooth()
that.getBluetoothDevices()
}
}
})
},
// 定时查询蓝牙设备
searchBluetoothDevices() {
const that = this
if(this.bluetoothStatus !== 0) {
console.log('搜索未执行', this.bluetoothStatus)
this.getBluetoothStatus()
return
}
timer = setInterval(() => {
uni.getBluetoothDevices({
success(res) {
const deviceList = res.devices
that.deviceList = []
for(let i = 0; i < deviceList.length; i++) {
if(deviceList[i]?.advertisServiceUUIDs) {
const uuid = deviceList[i]?.advertisServiceUUIDs[0]
if(uuid && uuid.slice(2,8)==='758824' && uuid.slice(30,32)==='00') {
that.deviceList.push(deviceList[i])
}
}
}
console.log('设备列表', that.deviceList)
},
fail: async function (err) {
console.log('获取设备列表失败', err)
if(res.errCode === 10000) {
// 重新初始化蓝牙适配器
await that.initBluetooth()
}
}
})
}, 1000)
},
// 停止搜索蓝牙设备
stopGetBluetoothDevices() {
clearInterval(timer)
uni.stopBluetoothDevicesDiscovery()
},
// 蓝牙状态提示
getBluetoothStatus() {
if(this.bluetoothStatus === 1) {
uni.showModal({
title: '提示',
content: '蓝牙尚未打开,请先打开蓝牙',
showCancel: false,
confirmText: '确定',
})
} else if(this.bluetoothStatus === 2 || this.bluetoothStatus === 3) {
uni.showModal({
title: '提示',
content: '小程序蓝牙功能被禁用,请打开小程序蓝牙权限',
showCancel: false,
confirmText: '去设置',
success(res) {
if(res.confirm) {
uni.openSetting()
}
}
})
}
},
// 检查小程序设置
checkSetting() {
const that = this
uni.getSetting({
async success(res) {
const bluetooth = res.authSetting['scope.bluetooth']
if(that.bluetoothStatus === -1) {
if(bluetooth) {
that.bluetoothStatus = 0
} else {
that.bluetoothStatus = 2
}
} else if(that.bluetoothStatus === 0 && !bluetooth) {
that.bluetoothStatus = 2
} else if(that.bluetoothStatus === 1 && !bluetooth) {
that.bluetoothStatus = 3
} else if(that.bluetoothStatus === 2 && bluetooth) {
that.bluetoothStatus = 0
await that.initBluetooth()
} else if(that.bluetoothStatus === 3 && bluetooth) {
that.bluetoothStatus = 1
await that.initBluetooth()
that.onBluetoothState()
}
console.log('蓝牙权限', bluetooth, that.bluetoothStatus)
}
})
},
// 连接蓝牙设备+获取设备服务+获取设备特征值
connectBluetoothDevice() {
const that = this
return new Promise((resolve) => {
if(that.bluetoothStatus !== 0) {
console.log('连接未执行', that.bluetoothStatus)
that.getBluetoothStatus()
resolve(false)
return
}
uni.createBLEConnection({
deviceId: that.currentLockInfo.deviceId,
success(res) {
console.log('连接成功', res)
// 获取设备服务
uni.getBLEDeviceServices({
deviceId: that.currentLockInfo.deviceId,
success (res) {
let serviceId
for(let i = 0; i < res.services.length; i++) {
if(res.services[i].isPrimary) {
serviceId = res.services[i].uuid
}
}
// 获取设备对应服务的特征值
uni.getBLEDeviceCharacteristics({
deviceId: that.currentLockInfo.deviceId,
serviceId: serviceId,
success (res) {
let notifyCharacteristicId
let writeCharacteristicId
for(let i = 0; i < res.characteristics.length; i++) {
const characteristic = res.characteristics[i]
if(characteristic.properties.notify) {
notifyCharacteristicId = characteristic.uuid
}
if(characteristic.properties.write) {
writeCharacteristicId = characteristic.uuid
}
}
that.updateCurrentLockInfo({
...that.currentLockInfo,
serviceId,
notifyCharacteristicId,
writeCharacteristicId
})
that.notifyBluetoothCharacteristicValueChange()
resolve(true)
},
fail(res) {
if(res.errCode === 10006) {
uni.showToast({
title: '连接失败,请靠近设备并保持设备处于唤醒状态',
icon: 'none'
})
}
console.log('获取设备特征值失败', res)
resolve(false)
}
})
},
fail(res) {
if(res.errCode === 10006) {
uni.showToast({
title: '连接失败,请靠近设备并保持设备处于唤醒状态',
icon: 'none'
})
}
console.log('获取设备服务失败', res)
resolve(false)
}
})
},
fail(res) {
uni.showToast({
title: '连接失败,请靠近设备并保持设备处于唤醒状态',
icon: 'none'
})
console.log('连接失败', res)
resolve(false)
}
})
})
},
// 更新当前锁信息
updateCurrentLockInfo(lockInfo) {
console.log('更新当前锁信息', lockInfo)
this.currentLockInfo = lockInfo
},
// 订阅设备特征值改变
notifyBluetoothCharacteristicValueChange() {
const that = this
uni.notifyBLECharacteristicValueChange({
state: true,
deviceId: that.currentLockInfo.deviceId,
serviceId: that.currentLockInfo.serviceId,
characteristicId: that.currentLockInfo.notifyCharacteristicId,
success() {
console.log('订阅成功', res)
},
fail(res) {
console.log('订阅失败', res)
}
})
},
// 重新连接设备
reconnectDevice() {
const that = this
return new Promise(async resolve => {
uni.createBLEConnection({
deviceId: that.currentLockInfo.deviceId,
success (res) {
console.log('重连成功', res)
that.notifyBluetoothCharacteristicValueChange()
resolve(true)
},
fail(res) {
console.log('重连失败', res)
uni.showModal({
title: '提示',
content: '设备连接已断开,请靠近设备并保持设备处于唤醒状态',
showCancel: false,
confirmText: '确定'
})
resolve(false)
}
})
})
},
// 断开蓝牙连接
closeBluetoothConnection() {
const that = this
uni.closeBLEConnection({
deviceId: that.currentLockInfo.deviceId,
success(res) {
console.log('断开连接成功', res)
},
fail(res) {
console.log('断开连接失败', res)
}
})
},
// 写入特征值
async writeBLECharacteristicValue(binaryData) {
const that = this
// 确认蓝牙状态正常
if(this.bluetoothStatus !== 0) {
console.log('写入未执行', this.bluetoothStatus)
this.getBluetoothStatus()
return
}
// 确认设备连接正常
if(!that.currentLockInfo.connected) {
const result = await that.reconnectDevice()
if(!result) return
}
console.log('设备ID', that.currentLockInfo.deviceId)
console.log('设备名称:', that.currentLockInfo.name)
console.log('设备主服务:', that.currentLockInfo.serviceId)
console.log('设备写入特征值:', that.currentLockInfo.writeCharacteristicId)
console.log('设备写入数据:', Array.from(binaryData))
// 次数
const count = Math.ceil(binaryData.length / 20)
for(let i = 0; i < count; i++) {
const writeData = binaryData.slice(i * 20, i === (count - 1) ? binaryData.length - 1 : (i + 1) * 20)
uni.writeBLECharacteristicValue({
deviceId: that.currentLockInfo.deviceId,
serviceId: that.currentLockInfo.serviceId,
characteristicId: that.currentLockInfo.writeCharacteristicId,
value: writeData,
success() {
console.log('数据写入成功')
},
fail(res) {
console.log('写入失败', res)
}
})
}
}
}
})