91 lines
4.6 KiB
Plaintext
91 lines
4.6 KiB
Plaintext
// H5平台 Web Bluetooth 设备扫描实现
|
||
import { DeviceManager } from './device-manager.uts';
|
||
import { ServiceManager } from './service-manager.uts';
|
||
import { BleDataProcessor } from '../data-processor.uts';
|
||
import * as BleUtils from '../ble-utils.uts';
|
||
import type { BleDevice, BleOptions, BleConnectOptionsExt, BleDataReceivedCallback, BleConnectionStateChangeCallback } from '../interface.uts'
|
||
|
||
export const BLE_SERVICE_PREFIXES = ['bae']; // 这里写你的实际前缀
|
||
|
||
// 实例化各个管理器
|
||
const deviceManager = new DeviceManager();
|
||
const serviceManager = new ServiceManager();
|
||
const dataProcessor = BleDataProcessor.getInstance();
|
||
|
||
// 导出简化接口
|
||
export const scanDevices = async (options?: { optionalServices?: string[] }) => deviceManager.startScan(options);
|
||
export const connectDevice = async (deviceId: string, options?: BleConnectOptionsExt) => deviceManager.connectDevice(deviceId, options);
|
||
export const disconnectDevice = async (deviceId: string) => deviceManager.disconnectDevice(deviceId);
|
||
export const getConnectedDevices = () => deviceManager.getConnectedDevices();
|
||
export const discoverServices = async (deviceId: string) => {
|
||
// 获取 server 实例
|
||
const server = deviceManager.servers[deviceId];
|
||
if (!server) throw new Error('设备未连接');
|
||
return serviceManager.discoverServices(deviceId, server);
|
||
};
|
||
export const getCharacteristics = async (deviceId: string, serviceId: string) => serviceManager.getCharacteristics(deviceId, serviceId);
|
||
export const writeCharacteristic = async (deviceId: string, serviceId: string, characteristicId: string, data: string | ArrayBuffer) => serviceManager.writeCharacteristic(deviceId, serviceId, characteristicId, data);
|
||
export const subscribeCharacteristic = async (deviceId: string, serviceId: string, characteristicId: string, callback) => serviceManager.subscribeCharacteristic(deviceId, serviceId, characteristicId, callback);
|
||
export const readCharacteristic = async (deviceId: string, serviceId: string, characteristicId: string) => serviceManager.readCharacteristic(deviceId, serviceId, characteristicId);
|
||
export const sendCommand = async (deviceId: string, serviceId: string, writeCharId: string, notifyCharId: string, command: string, params: any = null, timeout: number = 5000) => dataProcessor.sendAndReceive(deviceId, serviceId, writeCharId, notifyCharId, command, params, timeout);
|
||
// Event adapter helpers: translate DeviceManager callbacks into payload objects
|
||
export const onDeviceFound = (listener) => deviceManager.onDeviceFound((device) => {
|
||
try { listener({ device }); } catch (e) { /* ignore listener errors */ }
|
||
});
|
||
|
||
export const onScanFinished = (listener) => deviceManager.onScanFinished(() => {
|
||
try { listener({}); } catch (e) {}
|
||
});
|
||
|
||
export const onConnectionStateChange = (listener) => deviceManager.onConnectionStateChange((deviceId, state) => {
|
||
try { listener({ device: { deviceId }, state }); } catch (e) {}
|
||
});
|
||
|
||
/**
|
||
* 自动连接并初始化蓝牙设备,获取可用serviceId、writeCharId、notifyCharId
|
||
* @param deviceId 设备ID
|
||
* @returns {Promise<{serviceId: string, writeCharId: string, notifyCharId: string}>}
|
||
*/
|
||
export const autoConnect = async (deviceId: string): Promise<{serviceId: string, writeCharId: string, notifyCharId: string}> => {
|
||
// 1. 连接设备
|
||
await connectDevice(deviceId);
|
||
|
||
// 2. 服务发现
|
||
const services = await discoverServices(deviceId);
|
||
if (!services || services.length === 0) throw new Error('未发现服务');
|
||
|
||
// 3. 获取私有serviceId(优先bae前缀或通过dataProcessor模板)
|
||
let serviceId = '';
|
||
for (const s of services) {
|
||
if (s.uuid && BLE_SERVICE_PREFIXES.some(prefix => s.uuid.startsWith(prefix))) {
|
||
serviceId = s.uuid;
|
||
break;
|
||
}
|
||
}
|
||
if (!serviceId) {
|
||
// 可扩展:通过dataProcessor获取模板serviceId
|
||
serviceId = services[0].uuid;
|
||
}
|
||
|
||
// 4. 获取特征值
|
||
const characteristics = await getCharacteristics(deviceId, serviceId);
|
||
if (!characteristics || characteristics.length === 0) throw new Error('未发现特征值');
|
||
|
||
// 5. 找到write和notify特征
|
||
let writeCharId = '';
|
||
let notifyCharId = '';
|
||
for (const c of characteristics) {
|
||
if (!writeCharId && (c.properties.write || c.properties.writeWithoutResponse)) writeCharId = c.uuid;
|
||
if (!notifyCharId && (c.properties.notify || c.properties.indicate)) notifyCharId = c.uuid;
|
||
}
|
||
if (!writeCharId || !notifyCharId) throw new Error('未找到可用的写/通知特征');
|
||
|
||
// 6. 注册notification
|
||
await subscribeCharacteristic(deviceId, serviceId, notifyCharId, (data) => {
|
||
// 可在此处分发/处理notification
|
||
// console.log('Notification:', data);
|
||
});
|
||
|
||
// 7. 返回结果
|
||
return { serviceId, writeCharId, notifyCharId };
|
||
}; |