/
dr.af2015
/
PulseMonitor
Обзор
Документация
Войти
/
dr.af2015
/
PulseMonitor
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
client/src/lib/bluetooth.ts
127 строк
4 KB
draf2025
Add initial project structure and basic UI components for heart rate monitoring application.
11 мар 2025, 18:21
11 мар 2025, 18:21
4578eb7
Код
Авторство
О чём код?
import { Device } from "@shared/schema"; declare global { interface Navigator { bluetooth: { requestDevice(options: { filters: Array<{ services?: string[]; address?: string }>; optionalServices?: string[]; }): Promise<BluetoothDevice>; }; } interface BluetoothDevice { gatt?: { connect(): Promise<BluetoothRemoteGATTServer>; }; id: string; name?: string; } interface BluetoothRemoteGATTServer { getPrimaryService(service: string): Promise<BluetoothRemoteGATTService>; } interface BluetoothRemoteGATTService { getCharacteristic(characteristic: string): Promise<BluetoothRemoteGATTCharacteristic>; } interface BluetoothRemoteGATTCharacteristic { startNotifications(): Promise<BluetoothRemoteGATTCharacteristic>; addEventListener( type: string, listener: (event: { target: BluetoothRemoteGATTCharacteristic }) => void ): void; value?: DataView; } } const MI_BAND_SERVICE = "0000fee0-0000-1000-8000-00805f9b34fb"; const HEART_RATE_SERVICE = "0000180d-0000-1000-8000-00805f9b34fb"; const HEART_RATE_MEASUREMENT = "00002a37-0000-1000-8000-00805f9b34fb"; export class BluetoothManager { private devices: Map<string, BluetoothDevice> = new Map(); private socket: WebSocket; constructor() { const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"; const wsUrl = `${protocol}//${window.location.host}/ws`; this.socket = new WebSocket(wsUrl); this.socket.addEventListener("open", () => { console.log("WebSocket connection established"); }); this.socket.addEventListener("error", (error) => { console.error("WebSocket error:", error); }); } async scanForDevices(): Promise<BluetoothDevice[]> { try { if (!navigator.bluetooth) { throw new Error("Bluetooth not supported"); } const device = await navigator.bluetooth.requestDevice({ filters: [{ services: [MI_BAND_SERVICE] }], optionalServices: [HEART_RATE_SERVICE], }); return [device]; } catch (error) { console.error("Bluetooth scan error:", error); throw new Error("Failed to scan for devices"); } } async connectToDevice(device: Device): Promise<void> { try { if (!navigator.bluetooth) { throw new Error("Bluetooth not supported"); } const bluetoothDevice = await navigator.bluetooth.requestDevice({ filters: [{ address: device.address }], optionalServices: [HEART_RATE_SERVICE], }); const server = await bluetoothDevice.gatt?.connect(); if (!server) throw new Error("Failed to connect to device"); const service = await server.getPrimaryService(HEART_RATE_SERVICE); const characteristic = await service.getCharacteristic(HEART_RATE_MEASUREMENT); await characteristic.startNotifications(); characteristic.addEventListener("characteristicvaluechanged", (event) => { const value = (event.target as BluetoothRemoteGATTCharacteristic).value; if (!value) return; const heartRate = value.getUint8(1); if (this.socket.readyState === WebSocket.OPEN) { this.socket.send(JSON.stringify({ type: "heartrate_update", deviceId: device.id, heartRate, })); } }); this.devices.set(device.address, bluetoothDevice); } catch (error) { console.error("Connection error:", error); throw new Error("Failed to connect to device"); } } async disconnectDevice(address: string): Promise<void> { const device = this.devices.get(address); if (device?.gatt?.connected) { device.gatt.disconnect(); } this.devices.delete(address); } } export const bluetoothManager = new BluetoothManager();