ReedawFoodApp/toolJs/Bluetooth.js

489 lines
13 KiB
JavaScript
Raw Normal View History

2025-05-30 11:14:38 +08:00
import $store from '@/store'
2026-03-23 09:50:49 +08:00
import useBluetooth from '@/toolJs/Bluetooth.js'
2025-05-30 11:14:38 +08:00
import $tools from '@/toolJs/tools.js'
2026-03-23 09:50:49 +08:00
import $data from '@/content.json'
// // 蓝牙连接
let unitList = []
2025-05-30 11:14:38 +08:00
let devicesList = []
2026-03-23 09:50:49 +08:00
let searchTimer = null
let UNIT_MAP = $data.units
2025-05-30 11:14:38 +08:00
export default {
openBluetoothAdapter,
startBluetoothDeviceDiscovery,
onBluetoothDeviceFound,
2026-03-23 09:50:49 +08:00
Bluetoothfilter,
createBLEConnection,
getBLEDeviceServices,
getBLEDeviceCharacteristics,
2025-05-30 11:14:38 +08:00
closeBluetoothAdapter,
2026-03-23 09:50:49 +08:00
closeBLEConnection,
getBLECharacteristicValueChange,
onBLEConnectionStateChange,
2025-05-30 11:14:38 +08:00
stopBluetoothDevicesDiscovery
}
2026-03-23 09:50:49 +08:00
// // 初始化蓝牙
2025-05-30 11:14:38 +08:00
function openBluetoothAdapter() {
2026-03-23 09:50:49 +08:00
devicesList = []
unitList = []
clearTimeout(searchTimer);
2025-05-30 11:14:38 +08:00
uni.openBluetoothAdapter({
success: e => {
2026-03-23 09:50:49 +08:00
$store.commit("changeBluetoothValue", {
bleTipsText: "蓝牙搜索中",
isConnectStatus: 0,
unitList: $data.unitMinus,
})
startBluetoothDeviceDiscovery()
2025-05-30 11:14:38 +08:00
},
2026-03-23 09:50:49 +08:00
fail: err => {
$store.commit("changeBluetoothValue", {
bleTipsText: "连接超时,点击重新连接",
isConnectStatus: 1,
unitList: $data.unitMinus,
})
2025-05-30 11:14:38 +08:00
}
});
}
// 开始搜寻附近的蓝牙外围设备
function startBluetoothDeviceDiscovery() {
uni.startBluetoothDevicesDiscovery({
allowDuplicatesKey: true,
interval: 200, //上报设备的间隔
success: res => {
2026-03-23 09:50:49 +08:00
onBluetoothDeviceFound();
searchTimer = setTimeout(() => {
uni.stopBluetoothDevicesDiscovery()
if (!devicesList.length) {
clearTimeout(searchTimer);
$store.commit("changeBluetoothValue", {
bleTipsText: "连接超时,点击重新连接",
isConnectStatus: 1
});
}
}, 30000); // 30秒超时
2025-05-30 11:14:38 +08:00
},
fail: res => {
2026-03-23 09:50:49 +08:00
$store.commit("changeBluetoothValue", {
bleTipsText: "连接超时,点击重新连接",
isConnectStatus: 1
})
2025-05-30 11:14:38 +08:00
}
});
}
/**
* 发现外围设备
*/
2026-03-23 09:50:49 +08:00
2025-05-30 11:14:38 +08:00
function onBluetoothDeviceFound() {
uni.onBluetoothDeviceFound(res => {
res.devices.forEach(device => {
if (!device.name && !device.localName) {
2026-03-23 09:50:49 +08:00
device.advertisData = device.advertisData ? device.advertisData : ''
let value = $tools.ab2hex(device.advertisData, "")
let type = value.substring(0, 2)
let id = value.substring(12, 16)
if (type.toLowerCase() == 'c0') {
clearTimeout(searchTimer);
device.deviceName = "c00002"
Bluetoothfilter(device)
}
return
}
if (device.name.toLowerCase().indexOf('pc-c06pro') != -1 ||
device.name.toLowerCase().indexOf('pc-c02pro') != -1 ||
device.name.toLowerCase().indexOf('pc-c09pro') != -1 ||
(device.localName && device.localName.toLowerCase().indexOf('pc-c06pro') != -1) ||
(device.localName && device.localName.toLowerCase().indexOf('pc-c02pro') != -1) ||
(device.localName && device.localName.toLowerCase().indexOf('pc-c09pro') != -1)) {
clearTimeout(searchTimer);
const bytes = new Uint8Array(device.advertisData);
const macBytes = bytes.slice(6, 12);
device.macAddr = $tools.ab2hex(macBytes, ':').toUpperCase()
stopBluetoothDevicesDiscovery()
Bluetoothfilter(device)
2025-05-30 11:14:38 +08:00
return
}
2026-03-23 09:50:49 +08:00
if (device.name.toLowerCase().indexOf("g02") != -1 ||
device.name.toLowerCase().indexOf('ypc') != -1 ||
device.name.toLowerCase().indexOf('pc-x01') != -1 ||
device.name.toLowerCase().indexOf('da') != -1 ||
device.name.toLowerCase().indexOf('pcl') != -1 ||
device.name.toLowerCase().indexOf('pcf01') != -1 ||
device.name.toLowerCase().indexOf('Yihejia_Lung') != -1) {
clearTimeout(searchTimer);
const bytes = new Uint8Array(device.advertisData);
const macBytes = bytes.slice(6, 12);
device.macAddr = $tools.ab2hex(macBytes, ':').toUpperCase()
stopBluetoothDevicesDiscovery()
Bluetoothfilter(device)
2025-05-30 11:14:38 +08:00
return
}
})
});
}
// 蓝牙过滤
2026-03-23 09:50:49 +08:00
function Bluetoothfilter(device) {
2025-05-30 11:14:38 +08:00
const foundDevices = devicesList
const idx = $tools.inArray(foundDevices, "deviceId", device.deviceId)
if (idx === -1) {
devicesList.push(device);
2026-03-23 09:50:49 +08:00
// 体脂秤
if (device.name.toLowerCase().indexOf("pcl") != -1) {
uni.navigateTo({
url: "/pageTwo/devices/PCL?deviceId=" + device.deviceId
})
return
}
// 思迈德协议,假阻抗,体脂秤
if (device.name.toLowerCase() == "c00002") {
uni.navigateTo({
url: "/pageTwo/devices/PCL22?deviceId=" + device.deviceId
})
return
}
// 思迈德协议,假阻抗,体脂秤
if (device.name.toLowerCase() == "da") {
uni.navigateTo({
url: "/pageTwo/devices/PCL22S?deviceId=" + device.deviceId
})
return
}
// 身高仪
if (device.name.indexOf("G02") != -1) {
uni.navigateTo({
url: "/pageTwo/devices/G02?deviceId=" + device.deviceId
})
return
}
// 跳绳
if (device.name.indexOf("YPC") != -1) {
uni.navigateTo({
url: "/pages/skiping/skip?deviceId=" + device.deviceId
})
return
}
// 婴儿秤
if (device.name.indexOf("Chipsea_BLE") != -1) {
uni.navigateTo({
url: "/pageTwo/devices/B20?deviceId=" + device.deviceId
})
return
}
// 心率秤
if (device.name.toLowerCase().indexOf('pc-x01') != -1) {
uni.navigateTo({
url: "/pageTwo/devices/PCX01?deviceId=" + device.deviceId
})
return
}
//厨房秤
if (device.name.toLowerCase().indexOf('pc-c06pro') != -1 ||
device.name.toLowerCase().indexOf('pc-c02pro') != -1 ||
device.name.toLowerCase().indexOf('pc-c09pro') != -1) {
handleDevType(device)
return
}
2025-05-30 11:14:38 +08:00
}
}
2026-03-23 09:50:49 +08:00
// 排查设备
function handleDevType(device) {
$model.getCheckDevice({
mac: device.macAddr,
}).then(res => {
console.log("排查设备:", device, res)
if (res.code == 0) {
createBLEConnection(device.deviceId)
} else {
devicesList = []
$tools.msg('设备未登记,请联系出售方进行系统认证')
$store.commit("changeBluetoothValue", {
type: 1,
isConnectStatus: 1,
bleTipsText: "连接超时,点击重新连接",
})
}
})
}
//连接设备
function createBLEConnection(device_id) {
uni.createBLEConnection({
deviceId: device_id,
success: res => {
setTimeout(function() {
getBLEDeviceServices(device_id)
}, 200)
},
fail: res => {
$store.commit("changeBluetoothValue", {
type: 1,
isConnectStatus: 1,
bleTipsText: "连接超时,点击重新连接",
})
}
});
}
2025-05-30 11:14:38 +08:00
/**
2026-03-23 09:50:49 +08:00
* 获取设备的UUID
2025-05-30 11:14:38 +08:00
*/
2026-03-23 09:50:49 +08:00
function getBLEDeviceServices(device_id) {
let serviceList = [];
uni.getBLEDeviceServices({
deviceId: device_id,
success: res => {
console.log("获取设备的UUID成功", res)
stopBluetoothDevicesDiscovery();
serviceList = res.services;
for (let i = 0; i < serviceList.length; i++) {
let service = serviceList[i];
if (service.uuid.indexOf("FFF0") != -1) {
getBLEDeviceCharacteristics(device_id, service.uuid);
break;
}
}
2025-05-30 11:14:38 +08:00
},
2026-03-23 09:50:49 +08:00
fail: res => {
$store.commit("changeBluetoothValue", {
type: 1,
isConnectStatus: 1,
bleTipsText: "连接超时,点击重新连接",
})
console.log('获取设备的UUID失败:', res)
}
2025-05-30 11:14:38 +08:00
});
}
2026-03-23 09:50:49 +08:00
/**
* 获取指定服务的特征值
*/
function getBLEDeviceCharacteristics(deviceId, serviceId) {
let characteristicsList = [];
uni.getBLEDeviceCharacteristics({
deviceId: deviceId,
serviceId: serviceId,
success: res => {
let write, notify
for (let i = 0; i < res.characteristics.length; i++) {
let item = res.characteristics[i];
if (item.uuid.indexOf('0000FFF2') != -1) {
write = item.uuid
} else if (item.uuid.indexOf('0000FFF1') != -1) {
notify = item.uuid
}
}
getBLECharacteristicValueChange(deviceId, serviceId, notify, write)
},
fail: res => {
$store.commit("changeBluetoothValue", {
type: 1,
isConnectStatus: 1,
bleTipsText: "连接超时,点击重新连接",
})
console.log('获取特征值失败:', JSON.stringify(res))
2025-05-30 11:14:38 +08:00
}
})
}
2026-03-23 09:50:49 +08:00
function getBLECharacteristicValueChange(deviceId, serviceId, notify, write) {
let that = this
uni.notifyBLECharacteristicValueChange({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: notify,
state: true,
success: () => {
$store.commit('changeBluetoothValue', {
deviceId: deviceId,
serviceId: serviceId,
notify: notify,
write: write,
unit: "g",
type: 1,
countWeight: "",
bleTipsText: "测量中,请将食物放到秤上",
isConnectStatus: 2
})
uni.onBLECharacteristicValueChange(function(res) {
const value = res.value
const dataView = new DataView(value)
const header = dataView.getUint8(0)
// MCU主动上报数据
if (header === 0xC7) {
const cmd = dataView.getUint8(2)
switch (cmd) {
case 0x02:
const statusByte = dataView.getUint8(4)
const isNegative = !!(statusByte & 0x80) // 最高位表示正负
const statusType = statusByte & 0x0F // 状态类型
// 组合24位重量值 (大端序)
const weightValue =
(dataView.getUint8(5) << 16) |
(dataView.getUint8(6) << 8) |
dataView.getUint8(7)
// 精度和单位
const unitByte = dataView.getUint8(8)
const precision = (unitByte & 0xF0) >> 4 // 高4位精度
const unitIndex = unitByte & 0x0F // 低4位单位
// 计算实际重量
let finalWeight = weightValue / Math.pow(10, precision)
console.log("类型:", cmd, "重量",
finalWeight, "小数点", precision, "单位", UNIT_MAP[unitIndex])
if (isNegative) finalWeight = -finalWeight
$store.commit("changeBluetoothValue", {
countWeight: finalWeight,
unit: UNIT_MAP[unitIndex],
type: statusType
})
break
case 0x03:
break
case 0x08:
const start0 = []
const value2 = $tools.ab2hex(res.value, "");
const start = parseUnitMask(value2.substring(8, 10), UNIT_MAP.slice(0,
7))
const start1 = parseUnitMask(value2.substring(10, 12), UNIT_MAP.slice(8,
10))
start.push.apply(start, start1)
if (start.length) {
$data.unitMinus.forEach(item => {
start.forEach(item2 => {
if (item.unit == item2) {
start0.push(item)
}
})
})
}
$store.commit("changeBluetoothValue", {
unitList: start0.length ? start0 : $data.unitMinus
})
console.log("2222222", start, start0)
break
}
}
})
},
fail: res => {
console.log('获取特征值失败:', JSON.stringify(res))
}
})
}
// 获取服务
// function getBLEDeviceServices(uuid) {
// let serviceList = [];
// let serviceId = ""
// uni.getBLEDeviceServices({
// deviceId: deviceId,
// success: res => {
// console.log("获取设备的UUID成功", res)
// serviceList = res.services;
// for (let i = 0; i < serviceList.length; i++) {
// let service = serviceList[i];
// if (service.uuid.indexOf(uuid) != -1) {
// serviceId = service.uuid
// break;
// }
// }
// $store.commit("getIsUseBluetooth", {
// serviceId: serviceId
// });
// },
// fail: res => {
// console.log('获取设备的UUID失败:', res)
// }
// });
// }
2025-05-30 11:14:38 +08:00
/**
* 断开蓝牙模块
*/
function closeBluetoothAdapter() {
uni.closeBluetoothAdapter({
success: res => {
2026-03-23 09:50:49 +08:00
clearTimeout(searchTimer);
$store.commit("changeBluetoothValue", {
deviceId: "",
serviceId: "",
notify: "",
write: "",
unit: "g",
countWeight: '',
type: 1,
unitList: $data.unitMinus,
isConnectStatus: 1,
bleTipsText: "连接超时,点击重新连接",
})
2025-05-30 11:14:38 +08:00
console.log('蓝牙模块关闭成功');
}
})
}
/**
* 断开蓝牙连接
*/
function closeBLEConnection(deviceId) {
uni.closeBLEConnection({
deviceId: deviceId,
success: res => {
console.log('断开蓝牙连接成功');
}
});
}
2026-03-23 09:50:49 +08:00
// 监听蓝牙连接状态
function onBLEConnectionStateChange() {
uni.onBLEConnectionStateChange(function(res) {
console.log("监听蓝牙连接状态", res.connected)
if (!res.connected) {
$store.commit("changeBluetoothValue", {
bleTipsText: "连接超时,点击重新连接",
unitList: $data.unitMinus,
isConnectStatus: 1,
type: 1,
})
closeBLEConnection()
closeBluetoothAdapter()
}
$store.commit("changeBluetooth", res.connected);
})
2025-05-30 11:14:38 +08:00
}
2026-03-23 09:50:49 +08:00
/**
* 停止搜索蓝牙设备
*/
function stopBluetoothDevicesDiscovery() {
uni.stopBluetoothDevicesDiscovery({
2025-05-30 11:14:38 +08:00
success: e => {
2026-03-23 09:50:49 +08:00
console.log("停止搜索蓝牙设备", e)
2025-05-30 11:14:38 +08:00
},
});
}
2026-03-23 09:50:49 +08:00
function parseUnitMask(hexValue, UNIT_MAP) {
// 转换为数字
const mask = typeof hexValue === 'string' ? parseInt(hexValue, 16) : hexValue;
// 验证输入
if (isNaN(mask) || mask < 0 || mask > 0xFF) {
console.error('无效的位掩码值');
return [];
2025-05-30 11:14:38 +08:00
}
2026-03-23 09:50:49 +08:00
// 存储结果
const usedUnits = [];
// 遍历每一位
for (let i = 0; i < 8; i++) {
// 使用位运算检查第 i 位是否为 1
if (mask & (1 << i)) {
usedUnits.push(UNIT_MAP[i]);
}
}
return usedUnits;
2025-05-30 11:14:38 +08:00
}