RingBluetoothSDK v1.0.0
微信小程序 BLE 戒指通信 SDK 公开接口文档
前提:所有蓝牙操作前必须先调用 authenticate() 完成认证,否则会抛出 未认证 错误。
Quick Start
const bleSDK = require('../../utils/ble-sdk')
// 1. 认证(必须先调用)
const { success, error } = await bleSDK.authenticate('userId', 'userKey')
// 2. 初始化蓝牙适配器
await bleSDK.initBluetoothAdapter()
// 3. 扫描并连接
const devices = await bleSDK.scanDevices('Hi Ring')
await bleSDK.connect(deviceId)
// 4. 同步时间
await bleSDK.synchronizeTime_ring()
// 5. 监听数据
bleSDK.on('onDataReceived', (data) => {
console.log(data.type, data.parsed)
})
认证 Authentication
所有蓝牙交互前必须先完成认证,认证基于 HTTP 请求到服务端验证。
| 方法 | 参数 | 返回值 | 说明 |
authenticate(userId, userKey) async |
userId: string 必填
userKey: string 必填 |
Promise<{ success: boolean, error: string }> |
HTTP 认证,成功后可执行蓝牙操作 |
isAuthenticated() |
— |
boolean |
是否已认证 |
getUserId() |
— |
string |
获取当前用户ID |
getUserKey() |
— |
string |
获取当前用户密钥 |
setUserId(userId) |
userId: string |
void |
设置用户ID(持久化到本地存储) |
setUserKey(userKey) |
userKey: string |
void |
设置用户密钥(持久化到本地存储) |
const { success, error } = await bleSDK.authenticate('user123', 'key456')
if (success) {
console.log('认证成功')
} else {
console.error('认证失败:', error)
}
蓝牙初始化 Init
| 方法 | 返回值 | 说明 |
initBluetoothAdapter() async |
Promise<void> |
初始化微信蓝牙适配器并注册监听器,失败时抛出异常 |
checkBluetoothAvailability() async |
Promise<boolean> |
检查系统蓝牙是否可用 |
isBluetoothEnabled() |
boolean |
蓝牙适配器是否已就绪 |
hasLocationPermission() async |
Promise<boolean> |
是否有位置权限 |
hasBluetoothPermission() async |
Promise<boolean> |
是否有蓝牙权限 |
注意:initBluetoothAdapter() 抛出异常时的常见错误:
• 手机蓝牙未开启 — 用户未开启系统蓝牙
• 蓝牙权限被拒绝 — 小程序未获得蓝牙权限
设备扫描 Scan
| 方法 | 参数 | 返回值 | 说明 |
scanDevices(nameFilter) async |
nameFilter?: string 可选 默认读取配置中的设备名过滤器 |
Promise<res> |
开始扫描,按名称前缀过滤设备 |
stopScan() async |
— |
Promise<void> |
停止扫描 |
getDiscoveredDevices() |
— |
Array<device> |
获取已发现的设备列表 |
await bleSDK.scanDevices('Hi Ring')
bleSDK.on('onDeviceFound', (device) => {
console.log('发现设备:', device.name, device.deviceId)
})
设备连接 Connection
| 方法 | 参数 | 返回值 | 说明 |
connect(deviceId, options) async |
deviceId: string 必填
options?: { timeout } |
Promise<res> |
按设备ID连接 |
connectByName(deviceName) async |
deviceName: string 必填 |
Promise<res> |
按设备名称扫描并连接(内部先扫描再连接) |
disconnect() async |
— |
Promise<void> |
断开连接 |
disconnectWithCallback() async |
— |
Promise<{ onDisconnected: true }> |
断开连接并返回确认对象 |
disconnectAll() |
— |
void |
断开所有连接(异步触发,无返回值) |
isConnected() |
— |
boolean |
是否已连接 |
getConnectedDeviceId() |
— |
string | null |
获取已连接设备ID |
getConnectionState() |
— |
'disconnected' | 'connecting' | 'connected' | 'disconnecting' |
获取当前连接状态 |
// 方式1:按 ID 连接
await bleSDK.connect('xx:xx:xx:xx:xx:xx')
// 方式2:按名称扫描并连接
await bleSDK.connectByName('Hi Ring')
// 监听连接状态
bleSDK.on('onConnected', ({ deviceId }) => console.log('已连接', deviceId))
bleSDK.on('onDisconnected', () => console.log('已断开'))
bleSDK.on('onConnectFailed', (err) => console.error('连接失败:', err))
数据传输 Data Transfer
| 方法 | 参数 | 返回值 | 说明 |
writeData(data, serviceId, characteristicId) async |
data: ArrayBuffer 必填
serviceId?: string
characteristicId?: string |
Promise<res> |
向设备写入数据(通过写入队列,保证串行) |
readData(serviceId, characteristicId) async |
serviceId?: string
characteristicId?: string |
Promise<res> |
读取设备数据 |
sendData(data) async |
data: string | ArrayBuffer | number[] |
Promise<res> |
发送数据(支持多种格式,内部转换为 ArrayBuffer) |
sendCommand(command, payload) async |
command: number | number[]
payload?: string | ArrayBuffer | number[] |
Promise<res> |
发送带命令字节的指令 |
sendHeartbeat() async |
— |
Promise<res> |
发送心跳包 |
戒指指令 Ring Commands
以下指令触发后,实际数据通过 onDataReceived 事件回调返回。
| 方法 | 返回值 | 回调 data.type | 说明 |
shutdown_ring() async |
Promise<void> |
— |
关机指令 |
reset_ring() async |
Promise<void> |
— |
重启指令 |
fetchTime_ring() async |
Promise<{ ok: true }> |
timeData |
获取设备时间 |
synchronizeTime_ring() async |
Promise<{ timestamp }> |
— |
同步手机时间到设备 |
fetchRingversion_ring() async |
Promise<{ ok: true }> |
ringversionData |
获取固件版本 |
fetchBatteryLevel_ring() async |
Promise<{ ok: true }> |
batteryLevelData |
获取电池电量 |
fetchBatteryChargingStatus_ring() async |
Promise<{ ok: true }> |
chargingStatusData |
获取充电状态 |
fetchLastStep_ring() async |
Promise<{ ok: true }> |
lastStepData |
获取最新步数 |
fetchLastOtherValue_ring() async |
Promise<{ ok: true }> |
lastOtherValueData |
获取综合摘要数据 |
fetchTouchthreshold_ring() async |
Promise<{ touchthreshold: number }> |
touchthresholdData |
获取触摸灵敏度阈值(5秒超时) |
fetchGoodOrBad_ring() async |
Promise<{ chipStatus: 0 | 1 }> |
goodOrBadData |
芯片检测(5秒超时,返回 1=正常 0=异常) |
fetchiOSRealMac_ring() async |
Promise<{ ok: true }> |
iOSRealMacData |
获取 iOS 真实 MAC 地址 |
异步数据回调示例
bleSDK.on('onDataReceived', (data) => {
switch (data.type) {
case 'timeData':
console.log('设备时间:', data.parsed.timestamp)
break
case 'ringversionData':
console.log('固件版本:', data.parsed.Ringversion)
break
case 'batteryLevelData':
console.log('电量:', data.parsed.BatteryLevel)
break
case 'chargingStatusData':
console.log('充电中:', data.parsed.isBatteryCharging)
break
case 'lastStepData':
console.log('步数:', data.parsed.totalSteps)
break
case 'lastOtherValueData':
console.log('摘要:', data.parsed)
break
case 'iOSRealMacData':
console.log('MAC:', data.parsed.mac)
break
case 'touchthresholdData':
console.log('灵敏度:', data.parsed.touchthreshold)
break
case 'goodOrBadData':
console.log('芯片状态:', data.parsed.chipStatus === 1 ? '正常' : '异常')
break
}
})
戒指设置 Ring Settings
| 方法 | 参数 | 返回值 | 说明 |
heartSetting_ring(setValue) async |
setValue: number 必填 心率监测间隔(分钟) |
Promise<{ setValue, result: 'success' }> |
设置心率监测间隔时间 |
bloodSetting_ring(setValue) async |
setValue: number 必填 血氧监测间隔(分钟) |
Promise<{ setValue, result: 'success' }> |
设置血氧监测间隔时间 |
pressSetting_ring(setValue) async |
setValue: number 必填 压力监测间隔(分钟) |
Promise<{ setValue, result: 'success' }> |
设置压力监测间隔时间 |
手动测试 Manual Testing
触发测试
| 方法 | 返回值 | 说明 |
heartRate_test() async |
Promise<{ ok: true, message: string }> |
触发心率测试,结果通过 onDataReceived 回调返回 |
bloodOxygen_test() async |
Promise<{ ok: true, message: string }> |
触发血氧测试 |
hrv_test() async |
Promise<{ ok: true, message: string }> |
触发 HRV 测试 |
stopManualTesting(stop) |
{ ok: true, message: string } |
停止测试,stop 传 true |
读取测试数据
| 方法 | 返回值 | 说明 |
fetchHeartData() async |
Promise<{ ok: true }> |
触发心率数据读取(结果通过回调返回) |
fetchOxygenbloodData() async |
Promise<{ ok: true }> |
触发血氧数据读取 |
fetchHRVData() async |
Promise<{ ok: true }> |
触发 HRV 数据读取 |
测试完整流程
// 1. 触发测试
await bleSDK.heartRate_test()
// 2. 监听结果
bleSDK.on('onDataReceived', (data) => {
if (data.type === 'heartTestResult') {
console.log('心率结果:', data.parsed)
// data.parsed = { timestamp, value, dataType: 'heartRate' }
}
if (data.type === 'bloodTestResult') {
console.log('血氧结果:', data.parsed)
// data.parsed = { timestamp, value, spo2: {...}, heartRate: {...}, dataType: 'bloodOxygen' }
}
if (data.type === 'hrvTestResult') {
console.log('HRV 结果:', data.parsed)
// data.parsed = { timestamp, intervals, value, status, dataType: 'HRV' }
}
})
// 3. 停止测试
bleSDK.stopManualTesting(true)
批量数据同步 Batch Sync
| 方法 | 参数 | 返回值 | 说明 |
fetchLatestDataByType(dataType, timestamp, maxRetries) async |
dataType: number 必填
timestamp: number 必填
maxRetries?: number |
Promise<Array> |
同步指定类型的批量数据,返回解析后的记录数组 |
fetchBatchDataFromBluetooth(timestampMap, callback) |
timestampMap: { [dataType]: timestamp }
callback?: { onRespond } |
void |
按类型逐个批量同步(串行执行,完成后回调通知) |
支持的数据类型
| 常量 | 值 | 说明 |
STEP | 1 | 步数 |
HEART | 2 | 心率 |
RRI | 3 | RR间期 |
STRESS | 4 | 压力 |
BLOOD | 5 | 血氧 |
TEMPERATURE | 6 | 温度 |
SLEEP | 7 | 睡眠 |
CALORIE_DISTANCE | 8 | 卡路里/距离 |
SYSTEM_LOG | 9 | 系统日志 |
同步示例
// 方式1:单个类型同步
const steps = await bleSDK.fetchLatestDataByType(1, timestamp)
// steps = [{ timestamp, steps }]
const heart = await bleSDK.fetchLatestDataByType(2, timestamp)
// heart = [{ timestamp, heartRate }]
// 方式2:批量同步(回调方式)
bleSDK.fetchBatchDataFromBluetooth({
1: timestamp, // 步数
2: timestamp, // 心率
4: timestamp, // 压力
5: timestamp, // 血氧
6: timestamp, // 温度
7: timestamp // 睡眠
}, {
onRespond: (result, error) => {
if (result) {
result.results.forEach(item => {
console.log(`类型${item.dataType}:`, item.records)
})
}
}
})
自动回连 Auto Reconnect
| 方法 | 返回值 | 说明 |
autoLinkSetting_ring() |
{ autoLinkEnabled: true, result: 'success' } |
开启自动回连 |
unAutoLinkSetting_ring() |
{ autoLinkEnabled: false, result: 'success' } |
关闭自动回连 |
isAutoLinkEnabled() |
boolean |
是否已开启自动回连 |
心跳 Heartbeat
| 方法 | 参数 | 返回值 | 说明 |
startAutoHeartbeat(interval) |
interval?: number(毫秒,默认 30000) |
void |
启动自动心跳定时器 |
stopAutoHeartbeat() |
— |
void |
停止自动心跳 |
销毁 Destroy
| 方法 | 说明 |
destroy() |
销毁 SDK 实例:断开连接、停止扫描、关闭蓝牙适配器、清空心跳定时器 |
事件注册 Events
| 方法 | 参数 | 说明 |
on(callbackName, callback) |
callbackName: string
callback: Function |
注册事件回调 |
off(callbackName) |
callbackName: string |
移除事件回调 |
可用事件列表
| 事件名 | 回调参数 | 说明 |
onDeviceFound | device: { name, deviceId, ... } | 发现设备 |
onConnectionStateChange | state: string | 连接状态变化 |
onDataReceived | data: { type, parsed, ... } | 数据接收(见下方 type 列表) |
onError | error: string | 错误发生 |
onScanStarted | — | 扫描开始 |
onScanFinished | — | 扫描结束 |
onScanFailed | error: string | 扫描失败 |
onConnecting | — | 正在连接 |
onConnected | { deviceId } | 已连接 |
onDisconnected | — | 已断开 |
onServicesDiscovered | — | 服务发现完成 |
onConnectFailed | error: string | 连接失败 |
onWriteSuccess | — | 写入成功 |
onWriteFailed | error: string | 写入失败 |
onReadFailed | error: string | 读取失败 |
onLog | message: string | SDK 内部日志 |
onDataReceived 回调 data.type 列表
| data.type | data.parsed 说明 | 触发方式 |
timeData | { timestamp: number } | fetchTime_ring() |
ringversionData | { Ringversion: string } | fetchRingversion_ring() |
batteryLevelData | { BatteryLevel: number } | fetchBatteryLevel_ring() |
chargingStatusData | { isBatteryCharging: boolean } | fetchBatteryChargingStatus_ring() |
lastStepData | StepModel { timestamp, totalSteps, totalCalories, totalDistance } | fetchLastStep_ring() |
lastOtherValueData | SummaryModel { heartModel, bloodModel, temperatureModel, sleepModel, stressModel } | fetchLastOtherValue_ring() |
iOSRealMacData | { mac: string, hex: string } | fetchiOSRealMac_ring() |
touchthresholdData | { touchthreshold: number } | fetchTouchthreshold_ring() |
goodOrBadData | { chipStatus: 0 | 1 } | fetchGoodOrBad_ring() |
heartTestResult | { timestamp, value, dataType: 'heartRate' } | heartRate_test() |
bloodTestResult | { timestamp, value, spo2: {...}, heartRate: {...}, dataType: 'bloodOxygen' } | bloodOxygen_test() |
hrvTestResult | { timestamp, intervals, value, status, dataType: 'HRV' } | hrv_test() |
batchData | 批量同步数据块 | fetchLatestDataByType() |
sensorData | 其他传感器数据 | DATA_SERVICE 被动上报 |
数据模型 Models
StepModel
{
timestamp: number, // Unix 时间戳
totalSteps: number, // 总步数
totalCalories: number, // 总卡路里
totalDistance: number // 总距离
}
HeartModel
{
timestamp: number,
heartValue: number // 心率值
}
BloodModel
{
timestamp: number,
spo2: number, // 血氧值 (%)
heartRate: number // 心率值 (BPM)
}
StressModel
{
timestamp: number,
stressLevel: number, // 压力等级
heartRate: number, // 心率
confidence: number, // 置信度
abnormalFlag: number // 异常标志 (0=正常, 1=异常)
}
TemperatureModel
{
timestamp: number,
temperatureValue: number // 温度值 (°C)
}
SleepModel
{
sleepTimestamp: number, // 入睡时间戳
wakeTimestamp: number // 醒来时间戳
}
RSIIntervalModel
{
timestamp: number,
intervals: number[] // RR 间期数组 (ms)
}
SummaryModel
{
heartModel: { timestamp, heartValue },
bloodModel: { timestamp, spo2, heartRate },
temperatureModel: { timestamp, temperatureValue },
sleepModel: { sleepTimestamp, wakeTimestamp },
stressModel: { timestamp, stressLevel, heartRate, confidence, abnormalFlag }
}
配置 Config
| 方法 | 参数 | 返回值 | 说明 |
getConfig() |
— |
SDKConfig |
获取配置实例 |
setDeviceNameFilter(filter) |
filter: string |
void |
设置设备名称过滤器(扫描时使用) |
getDeviceNameFilter() |
— |
string |
获取设备名称过滤器 |
SDKConfig 可配置项
| 方法 | 默认值 | 说明 |
setConnectTimeout(ms) | 10000 | 连接超时时间 (ms) |
setWriteTimeout(ms) | 5000 | 写入超时时间 (ms) |
setReadTimeout(ms) | 5000 | 读取超时时间 (ms) |
setScanTimeout(ms) | 10000 | 扫描超时时间 (ms) |
setRetryCount(count) | 3 | 重试次数 |
setRetryInterval(ms) | 1000 | 重试间隔 (ms) |
setHeartbeatInterval(ms) | 30000 | 心跳间隔 (ms) |
错误码 Error Codes
| 常量 | 值 | 说明 |
BLE_ERROR.NONE | 0 | 无错误 |
BLE_ERROR.BLUETOOTH_NOT_AVAILABLE | 1001 | 蓝牙不可用 |
BLE_ERROR.BLUETOOTH_DISABLED | 1002 | 蓝牙已关闭 |
BLE_ERROR.LOCATION_PERMISSION_DENIED | 1003 | 位置权限被拒绝 |
BLE_ERROR.BLUETOOTH_PERMISSION_DENIED | 1004 | 蓝牙权限被拒绝 |
BLE_ERROR.DEVICE_NOT_FOUND | 2001 | 设备未找到 |
BLE_ERROR.CONNECTION_FAILED | 2002 | 连接失败 |
BLE_ERROR.CONNECTION_TIMEOUT | 2003 | 连接超时 |
BLE_ERROR.DISCONNECTED | 2004 | 已断开 |
BLE_ERROR.SERVICE_NOT_FOUND | 2005 | 服务未找到 |
BLE_ERROR.CHARACTERISTIC_NOT_FOUND | 2006 | 特征值未找到 |
BLE_ERROR.WRITE_FAILED | 3001 | 写入失败 |
BLE_ERROR.WRITE_TIMEOUT | 3002 | 写入超时 |
BLE_ERROR.READ_FAILED | 3003 | 读取失败 |
BLE_ERROR.READ_TIMEOUT | 3004 | 读取超时 |
BLE_ERROR.NOTIFY_FAILED | 3005 | 通知设置失败 |
BLE_ERROR.NOTIFY_TIMEOUT | 3006 | 通知超时 |
BLE_ERROR.RETRY_EXHAUSTED | 5001 | 重试耗尽 |
BLE_ERROR.SEND_FAILED | 5002 | 发送失败 |
BLE_ERROR.ILLEGAL_STATE | 6001 | 非法状态 |
BLE_ERROR.UNKNOWN | 9999 | 未知错误 |