84 lines
2.1 KiB
TypeScript
84 lines
2.1 KiB
TypeScript
import type { DeviceAdapter, NormalizedReading } from '../types';
|
||
|
||
/**
|
||
* 小米手环 BLE 适配器
|
||
*
|
||
* 支持 Mi Band 7/8 等型号,使用标准 Heart Rate Service 读取心率数据。
|
||
* 未来可扩展步数(0xFEE1)、睡眠等 Mi Band 专有 Service。
|
||
*/
|
||
|
||
// 标准 BLE Heart Rate Service
|
||
const HRS_SERVICE = '0000180D-0000-1000-8000-00805F9B34FB';
|
||
const HRM_CHARACTERISTIC = '00002A37-0000-1000-8000-00805F9B34FB';
|
||
|
||
// 小米 Mi Band 专有 Service(步数/活动量)
|
||
// const MI_BAND_SERVICE = '0000FEE1-0000-1000-8000-8000-00805F9B34FB';
|
||
|
||
/** 解析心率测量值(Heart Rate Measurement 格式) */
|
||
function parseHeartRate(data: ArrayBuffer): number | null {
|
||
const view = new DataView(data);
|
||
if (view.byteLength < 2) return null;
|
||
|
||
const flags = view.getUint8(0);
|
||
// Bit 0: Heart Rate Format — 0 = UINT8, 1 = UINT16
|
||
const isUINT16 = (flags & 0x01) !== 0;
|
||
|
||
if (isUINT16) {
|
||
if (view.byteLength < 3) return null;
|
||
return view.getUint16(1, true); // little-endian
|
||
}
|
||
return view.getUint8(1);
|
||
}
|
||
|
||
export const XiaomiBandAdapter: DeviceAdapter = {
|
||
name: 'Xiaomi Band',
|
||
|
||
supportedModels: [
|
||
'Mi Band',
|
||
'Mi Smart Band',
|
||
'Xiaomi Band',
|
||
'Xiaomi Smart Band',
|
||
'MI BAND',
|
||
'MiBand',
|
||
],
|
||
|
||
serviceUUIDs: [HRS_SERVICE],
|
||
|
||
notifyCharacteristics: [
|
||
{ service: HRS_SERVICE, characteristic: HRM_CHARACTERISTIC },
|
||
],
|
||
|
||
readCharacteristics: [
|
||
{ service: HRS_SERVICE, characteristic: HRM_CHARACTERISTIC },
|
||
],
|
||
|
||
parseNotification(
|
||
_serviceUUID: string,
|
||
charUUID: string,
|
||
data: ArrayBuffer,
|
||
): NormalizedReading[] {
|
||
if (charUUID.toUpperCase().includes('2A37')) {
|
||
const hr = parseHeartRate(data);
|
||
if (hr !== null && hr > 0 && hr < 300) {
|
||
return [{
|
||
device_type: 'heart_rate',
|
||
values: { heart_rate: hr },
|
||
measured_at: new Date().toISOString(),
|
||
}];
|
||
}
|
||
}
|
||
return [];
|
||
},
|
||
|
||
parseReadResponse(
|
||
_serviceUUID: string,
|
||
_charUUID: string,
|
||
_data: ArrayBuffer,
|
||
): NormalizedReading[] {
|
||
// 读取模式暂不支持,使用通知模式获取数据
|
||
return [];
|
||
},
|
||
};
|
||
|
||
export default XiaomiBandAdapter;
|