feat(lefu): 迁移乐福体脂秤 SDK,接入设备扫描连接与 WiFi 配网
- 新增 lefu 服务层(扫描/连接/断开/保活重连/测量回调/WiFi 配网),事件回调支持多监听 - connectedDevice 接入真实蓝牙扫描连接,修复断线重连 UI 未同步、蓝牙/定位开关误判 - connectedWifi 接入真实 WiFi 配网,补连接状态校验与退出配网模式 - 新增 5 张设备图标并调整应用入口 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
feb494080c
commit
f53f11e6e9
@@ -0,0 +1,11 @@
|
||||
import type { LeFuConfig } from './types'
|
||||
|
||||
/** 乐福 SDK 配置 */
|
||||
export const LEFU_CONFIG: LeFuConfig = {
|
||||
key: 'lefudc91611833e18d94',
|
||||
secret: 'eQ50JYimMp0X7uhNLj6D3lTEk4TUUvEG7dvaqKM9t1U=',
|
||||
// domain1: 'http://10.10.10.10:8889',
|
||||
// domain2: 'http://10.10.10.10:8889/weight',
|
||||
domain1: 'http://device.shuziweidao.com:80/gateway',
|
||||
domain2: 'http://device.shuziweidao.com:80/weight',
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import type { DeviceSetting } from './types'
|
||||
|
||||
/** 支持的设备型号配置列表(5款) */
|
||||
export const DEVICE_SETTINGS: DeviceSetting[] = [
|
||||
{
|
||||
advLength: 999, calorieStatus: 0, createBy: null,
|
||||
deviceAccuracyType: 2, deviceCalcuteType: 3, deviceConnectType: 2,
|
||||
deviceFuncType: 223, deviceName: 'CF568_G', devicePowerType: 3,
|
||||
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,11',
|
||||
id: 65, imgUrl: null, macAddressStart: 6, remark: null,
|
||||
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
||||
},
|
||||
{
|
||||
advLength: 999, calorieStatus: 0, createBy: null,
|
||||
deviceAccuracyType: 2, deviceCalcuteType: 3, deviceConnectType: 2,
|
||||
deviceFuncType: 223, deviceName: 'YX-B4-568-BW', devicePowerType: 3,
|
||||
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,11',
|
||||
id: 65, imgUrl: null, macAddressStart: 6, remark: null,
|
||||
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
||||
},
|
||||
{
|
||||
advLength: 999, calorieStatus: 0, createBy: null,
|
||||
deviceAccuracyType: 2, deviceCalcuteType: 4, deviceConnectType: 2,
|
||||
deviceFuncType: 65759, deviceName: 'CF636_G', devicePowerType: 3,
|
||||
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,2',
|
||||
id: 216, imgUrl: null, macAddressStart: 6, remark: null,
|
||||
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
||||
},
|
||||
{
|
||||
advLength: 999, calorieStatus: 0, createBy: null,
|
||||
deviceAccuracyType: 2, deviceCalcuteType: 4, deviceConnectType: 2,
|
||||
deviceFuncType: 65759, deviceName: 'YX-B8-636-BW', devicePowerType: 3,
|
||||
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,2',
|
||||
id: 216, imgUrl: null, macAddressStart: 6, remark: null,
|
||||
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
||||
},
|
||||
{
|
||||
advLength: 999, calorieStatus: 0, createBy: null,
|
||||
deviceAccuracyType: 2, deviceCalcuteType: 4, deviceConnectType: 2,
|
||||
deviceFuncType: 223, deviceName: 'CF577', devicePowerType: 3,
|
||||
deviceProtocolType: 3, deviceType: 1, deviceUnitType: '0,1,11',
|
||||
id: 51, imgUrl: null, macAddressStart: 6, remark: null,
|
||||
sign: 'FF', status: 0, uhStatus: 1, updateBy: null,
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,10 @@
|
||||
export { leFuService } from './service'
|
||||
export type {
|
||||
ScannedDevice,
|
||||
LeFuWifiItem,
|
||||
ProgressData,
|
||||
LockData,
|
||||
LeFuConfig,
|
||||
DeviceSetting,
|
||||
DeviceInfo,
|
||||
} from './types'
|
||||
@@ -0,0 +1,410 @@
|
||||
import { LEFU_CONFIG } from './config'
|
||||
import { DEVICE_SETTINGS } from './deviceSettings'
|
||||
import type {
|
||||
RawDevice,
|
||||
LeFuPlugin,
|
||||
ScannedDevice,
|
||||
LeFuWifiItem,
|
||||
ProgressData,
|
||||
LockData,
|
||||
LeFuConfig,
|
||||
DeviceInfo,
|
||||
} from './types'
|
||||
|
||||
/** 顶层加载插件(对齐 demo,requirePlugin 必须在文件顶层调用) */
|
||||
const plugin = requirePlugin('ppScale-plugin') as LeFuPlugin
|
||||
|
||||
/** 统一日志前缀,便于定位问题 */
|
||||
const TAG = '[LeFuService]'
|
||||
|
||||
/**
|
||||
* 乐福体脂秤服务(单例)
|
||||
* 只保留 SDK 底层必需能力:蓝牙扫描、连接、断开、测量回调、保活与重连。
|
||||
* 业务层能力(WiFi 配网、用户同步、清空成员等)不在此维护。
|
||||
*/
|
||||
class LeFuService {
|
||||
// ─── 内部状态 ───────────────────────────────
|
||||
/** 当前激活的协议实例,非空表示已连接 */
|
||||
private _activeProtocol: any = null
|
||||
/** 当前蓝牙连接状态(取值来自 plugin.BLUE_STATE) */
|
||||
private _connectState = ''
|
||||
/** 设备固件信息 */
|
||||
private _deviceInfo: DeviceInfo | null = null
|
||||
/** 总线是否已订阅(避免重复 subscribe) */
|
||||
private _busSubscribed = false
|
||||
/** 是否为用户主动发起的连接/断开(用于区分是否自动重连) */
|
||||
private _intentionalConnect = false
|
||||
|
||||
/** 已重连次数 */
|
||||
private _reconnectCount = 0
|
||||
/** 最大自动重连次数 */
|
||||
private readonly _maxReconnect = 3
|
||||
/** 重连定时器 */
|
||||
private _reconnectTimer: number | null = null
|
||||
/** 保活心跳定时器 */
|
||||
private _keepAliveTimer: number | null = null
|
||||
/** 最近一次连接/扫描到的原始设备(用于断线重连) */
|
||||
private _lastRawDevice: RawDevice | null = null
|
||||
|
||||
// ─── 事件回调(每个事件支持多个监听者,用 Set 存储) ───
|
||||
private _onDevicesListCbs: Set<(devices: ScannedDevice[]) => void> = new Set()
|
||||
private _onConnectStateCbs: Set<(state: string) => void> = new Set()
|
||||
private _onDeviceConnectCbs: Set<() => void> = new Set()
|
||||
private _onProgressCbs: Set<(data: ProgressData) => void> = new Set()
|
||||
private _onLockedCbs: Set<(data: LockData) => void> = new Set()
|
||||
private _onDisconnectedCbs: Set<() => void> = new Set()
|
||||
private _onDeviceInfoCbs: Set<(info: DeviceInfo) => void> = new Set()
|
||||
|
||||
// ─── 只读状态访问器 ─────────────────────────
|
||||
/** SDK 配置(key/secret 等) */
|
||||
get config(): LeFuConfig { return LEFU_CONFIG }
|
||||
/** 是否已连接(存在激活协议实例) */
|
||||
get isConnected(): boolean { return !!this._activeProtocol }
|
||||
/** 当前连接状态字符串 */
|
||||
get connectState(): string { return this._connectState }
|
||||
/** 蓝牙状态枚举(由插件提供,兜底为空对象) */
|
||||
get BLUE_STATE(): Record<string, string> { return plugin.BLUE_STATE ?? {} }
|
||||
/** 设备固件信息 */
|
||||
get deviceInfo(): DeviceInfo | null { return this._deviceInfo }
|
||||
|
||||
// ─── 事件回调注册(均返回反注册函数) ───────
|
||||
/** 订阅「扫描结果列表」事件 */
|
||||
onDevicesList(cb: (devices: ScannedDevice[]) => void): () => void { this._onDevicesListCbs.add(cb); return () => { this._onDevicesListCbs.delete(cb) } }
|
||||
/** 订阅「连接状态变化」事件 */
|
||||
onConnectState(cb: (state: string) => void): () => void { this._onConnectStateCbs.add(cb); return () => { this._onConnectStateCbs.delete(cb) } }
|
||||
/** 订阅「设备已连接」事件 */
|
||||
onDeviceConnect(cb: () => void): () => void { this._onDeviceConnectCbs.add(cb); return () => { this._onDeviceConnectCbs.delete(cb) } }
|
||||
/** 订阅「测量进度」事件 */
|
||||
onMeasuring(cb: (data: ProgressData) => void): () => void { this._onProgressCbs.add(cb); return () => { this._onProgressCbs.delete(cb) } }
|
||||
/** 订阅「测量锁定结果」事件 */
|
||||
onLocked(cb: (data: LockData) => void): () => void { this._onLockedCbs.add(cb); return () => { this._onLockedCbs.delete(cb) } }
|
||||
/** 订阅「断开连接」事件 */
|
||||
onDisconnected(cb: () => void): () => void { this._onDisconnectedCbs.add(cb); return () => { this._onDisconnectedCbs.delete(cb) } }
|
||||
/** 订阅「设备固件信息」事件 */
|
||||
onDeviceInfo(cb: (info: DeviceInfo) => void): () => void { this._onDeviceInfoCbs.add(cb); return () => { this._onDeviceInfoCbs.delete(cb) } }
|
||||
|
||||
// ─── 扫描与连接 ─────────────────────────────
|
||||
/**
|
||||
* 开始扫描设备
|
||||
* 初始化插件设备配置、订阅总线事件,然后启动蓝牙扫描。
|
||||
*/
|
||||
startScan(): void {
|
||||
console.log(TAG, 'startScan()')
|
||||
plugin.Blue.setDeviceSetting(DEVICE_SETTINGS)
|
||||
this._subscribeBus()
|
||||
plugin.Blue.start(DEVICE_SETTINGS.map(s => s.deviceName), false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅插件总线事件(幂等,只订阅一次)
|
||||
* 将底层 SDK 事件桥接为服务层的回调。
|
||||
*/
|
||||
private _subscribeBus(): void {
|
||||
if (this._busSubscribed) {
|
||||
console.log(TAG, 'bus 已订阅,跳过')
|
||||
return
|
||||
}
|
||||
this._busSubscribed = true
|
||||
|
||||
// 扫描结果列表:转换为展示层结构后回调
|
||||
plugin.bus.subscribe('devicesList', (devList: RawDevice[]) => {
|
||||
console.log(TAG, 'bus[devicesList],设备数:', devList?.length, devList)
|
||||
if (!devList?.length) {
|
||||
this._onDevicesListCbs.forEach(cb => cb([]))
|
||||
return
|
||||
}
|
||||
const devices: ScannedDevice[] = devList.map((item: RawDevice) => ({
|
||||
name: item.name || item.deviceName || '未知设备',
|
||||
raw: item,
|
||||
model: {},
|
||||
}))
|
||||
this._onDevicesListCbs.forEach(cb => cb(devices))
|
||||
})
|
||||
|
||||
// 设备模型:仅打印日志,暂未对外暴露
|
||||
plugin.bus.subscribe('devicesModel', (res: any) => {
|
||||
console.log(TAG, 'bus[devicesModel] 完整数据:', JSON.stringify(res))
|
||||
})
|
||||
|
||||
// 设备固件信息:缓存并回调
|
||||
plugin.bus.subscribe('deviceInfo', (res: DeviceInfo) => {
|
||||
console.log(TAG, 'bus[deviceInfo]:', res)
|
||||
this._deviceInfo = res
|
||||
this._onDeviceInfoCbs.forEach(cb => cb(res))
|
||||
})
|
||||
|
||||
// 设备连接成功:重置重连计数,初始化协议实例并同步时间/MTU
|
||||
plugin.bus.subscribe('deviceConnect', () => {
|
||||
console.log(TAG, 'bus[deviceConnect]')
|
||||
this._intentionalConnect = false
|
||||
this._reconnectCount = 0
|
||||
plugin.ScaleAction.startDataProgress(true)
|
||||
this._activeProtocol = plugin.ScaleAction.getActiveProtocol()
|
||||
if (!this._activeProtocol) {
|
||||
console.error(TAG, 'getActiveProtocol() 返回空,无法完成连接初始化')
|
||||
return
|
||||
}
|
||||
// 更新 MTU 后同步时间,全部完成再通知业务层「已连接」
|
||||
this._activeProtocol.codeUpdateMTU((mtuRes: any) => {
|
||||
console.log(TAG, 'codeUpdateMTU:', mtuRes)
|
||||
this._activeProtocol.codeSyncTime((syncRes: any) => {
|
||||
console.log(TAG, 'codeSyncTime:', syncRes)
|
||||
this._onDeviceConnectCbs.forEach(cb => cb())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// 连接状态变化:驱动保活、重连与清理
|
||||
plugin.bus.subscribe('connectState', (res: string) => {
|
||||
console.log(TAG, 'bus[connectState]:', res)
|
||||
this._connectState = res
|
||||
this._onConnectStateCbs.forEach(cb => cb(res))
|
||||
// 连接成功:启动保活心跳
|
||||
if (res === plugin.BLUE_STATE.CONNECTSUCCESS) {
|
||||
this._startKeepAlive()
|
||||
return
|
||||
}
|
||||
// 连接失败:停止保活,尝试重连
|
||||
if (res === plugin.BLUE_STATE.CONNECTFAILED) {
|
||||
this._stopKeepAlive()
|
||||
this._intentionalConnect = false
|
||||
this._doReconnect()
|
||||
return
|
||||
}
|
||||
// 蓝牙不可用:做完整清理
|
||||
if (res === plugin.BLUE_STATE.UNAVAILABLE) {
|
||||
this._stopKeepAlive()
|
||||
this._stopReconnectTimer()
|
||||
if (this._activeProtocol) {
|
||||
this._activeProtocol = null
|
||||
this._onDisconnectedCbs.forEach(cb => cb())
|
||||
}
|
||||
return
|
||||
}
|
||||
// 蓝牙就绪:如有缓存设备且非主动断开,尝试重连
|
||||
if (res === plugin.BLUE_STATE.READY) {
|
||||
if (this._intentionalConnect) {
|
||||
this._intentionalConnect = false
|
||||
} else if (this._lastRawDevice && !this._activeProtocol) {
|
||||
this._stopReconnectTimer()
|
||||
wx.openBluetoothAdapter({
|
||||
success: () => this.connect(this._lastRawDevice!),
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 测量进度:透传给业务层
|
||||
plugin.bus.subscribe('progressData', (res: ProgressData) => {
|
||||
this._onProgressCbs.forEach(cb => cb(res))
|
||||
})
|
||||
|
||||
// 测量锁定结果:透传给业务层
|
||||
plugin.bus.subscribe('lockData', (res: LockData) => {
|
||||
this._onLockedCbs.forEach(cb => cb(res))
|
||||
})
|
||||
|
||||
// 即将断开:清理协议实例,若非主动断开则触发重连
|
||||
plugin.bus.subscribe('deviceWillDisconnect', () => {
|
||||
console.warn(TAG, 'bus[deviceWillDisconnect],intentionalConnect:', this._intentionalConnect)
|
||||
this._stopKeepAlive()
|
||||
this._activeProtocol = null
|
||||
this._onDisconnectedCbs.forEach(cb => cb())
|
||||
if (!this._intentionalConnect) {
|
||||
this._doReconnect()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接指定设备
|
||||
* 记录缓存设备、标记主动连接,清理旧状态后创建新的 BLE 连接。
|
||||
*/
|
||||
connect(rawDevice: RawDevice): void {
|
||||
console.log(TAG, 'connect():', rawDevice.name)
|
||||
this._lastRawDevice = rawDevice
|
||||
this._intentionalConnect = true
|
||||
this._stopKeepAlive()
|
||||
this._stopReconnectTimer()
|
||||
// 先断开旧连接(此时状态仍在),再清空内部状态
|
||||
if (this.isConnected) {
|
||||
plugin.Blue.disconnect()
|
||||
}
|
||||
this._activeProtocol = null
|
||||
this._connectState = ''
|
||||
this._deviceInfo = null
|
||||
// 直连缓存设备时不走 startScan,需手动初始化插件设备配置和总线订阅
|
||||
plugin.Blue.setDeviceSetting(DEVICE_SETTINGS)
|
||||
this._subscribeBus()
|
||||
plugin.Blue.stopBluetoothDevicesDiscovery()
|
||||
plugin.Blue.clearProtocol()
|
||||
plugin.Blue.createBLEConnection(rawDevice)
|
||||
}
|
||||
|
||||
/**
|
||||
* 主动断开连接
|
||||
* 标记主动断开以阻止自动重连,并停止保活。
|
||||
*/
|
||||
disconnect(): void {
|
||||
console.log(TAG, 'disconnect()')
|
||||
this._intentionalConnect = true
|
||||
this._stopKeepAlive()
|
||||
plugin.Blue.disconnect()
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止扫描
|
||||
* 停止蓝牙设备发现、清除重连定时器与扫描回调。
|
||||
*/
|
||||
stopScan(): void {
|
||||
console.log(TAG, 'stopScan()')
|
||||
this._stopReconnectTimer()
|
||||
wx.stopBluetoothDevicesDiscovery()
|
||||
this._onDevicesListCbs.clear()
|
||||
}
|
||||
|
||||
// ─── WiFi 配网 ─────────────────────────────
|
||||
/**
|
||||
* 获取周围 WiFi 列表
|
||||
* 依赖已连接的设备协议实例,下发查询指令后返回附近热点。
|
||||
*/
|
||||
getWifiList(): Promise<LeFuWifiItem[]> {
|
||||
console.log(TAG, 'getWifiList()')
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this._activeProtocol) {
|
||||
reject(new Error('设备未连接,无法获取 WiFi 列表'))
|
||||
return
|
||||
}
|
||||
let timer: number | null = null
|
||||
let delayTimer: number | null = null
|
||||
// 15s 整体超时
|
||||
timer = setTimeout(() => {
|
||||
if (delayTimer !== null) { clearTimeout(delayTimer); delayTimer = null }
|
||||
reject(new Error('获取 WiFi 列表超时'))
|
||||
}, 15000)
|
||||
// 延时 2s 后下发查询指令(等待设备进入配网模式)
|
||||
delayTimer = setTimeout(() => {
|
||||
this._activeProtocol.dataFindSurroundDevice((res: any[]) => {
|
||||
if (timer !== null) { clearTimeout(timer); timer = null }
|
||||
if (delayTimer !== null) { clearTimeout(delayTimer); delayTimer = null }
|
||||
console.log(TAG, 'getWifiList 结果:', res)
|
||||
if (!res?.length) {
|
||||
this._activeProtocol.dataExitWifiConfig(() => { })
|
||||
resolve([])
|
||||
return
|
||||
}
|
||||
resolve(res.map((item: any) => ({ ssid: item.ssid || item.name || '', signal: item.signal })))
|
||||
})
|
||||
}, 2000)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置设备连接指定 WiFi
|
||||
* 型号含 5 段走新协议 domain2,否则走老协议 domain1;成功返回码为 23。
|
||||
*/
|
||||
configWifi(ssid: string, password: string): Promise<void> {
|
||||
const version = (this._deviceInfo?.modelNumber ?? '').split('-').length === 5 ? 'domain2' : 'domain1'
|
||||
console.log(TAG, 'configWifi():', ssid, version, 'activeProtocol=', !!this._activeProtocol)
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this._activeProtocol) {
|
||||
reject(new Error('设备未连接,无法配网'))
|
||||
return
|
||||
}
|
||||
let settled = false
|
||||
const timer = setTimeout(() => {
|
||||
if (settled) return
|
||||
settled = true
|
||||
reject(new Error('配网超时,请重试'))
|
||||
}, 20000)
|
||||
const callback = (res: number) => {
|
||||
if (settled) return
|
||||
settled = true
|
||||
clearTimeout(timer)
|
||||
res === 23 ? resolve() : reject(new Error(`配网失败,错误码:${res}`))
|
||||
}
|
||||
if (version === 'domain1') {
|
||||
this._activeProtocol.dataConfigNetWork({ domain: LEFU_CONFIG.domain1, ssid, password }, callback)
|
||||
} else {
|
||||
this._activeProtocol.dataConfigUserNetWork(
|
||||
{ domain: LEFU_CONFIG.domain2, ssid, password, userName: 'apiUser', userPassword: '3acebb95eb49577e9c2a2082589b9bd6' },
|
||||
callback,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询设备是否已配置 WiFi
|
||||
* 返回码 0x01 表示已配网。
|
||||
*/
|
||||
checkWifiConfig(): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this._activeProtocol) { reject(new Error('设备未连接')); return }
|
||||
this._activeProtocol.codeFetchWifiConfig((res: number | undefined | null) => {
|
||||
resolve(res === 0x01)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出配网模式
|
||||
* 配网流程结束(含页面退出)时调用,让设备退出 WiFi 配置状态。
|
||||
*/
|
||||
exitWifiConfig(): void {
|
||||
if (!this._activeProtocol) return
|
||||
this._activeProtocol.dataExitWifiConfig(() => {
|
||||
console.log(TAG, '退出配网模式完成')
|
||||
})
|
||||
}
|
||||
|
||||
// ─── 私有:保活与重连 ───────────────────────
|
||||
/** 启动保活心跳:文档建议每 10s 发送一次 keepAlive,防止设备主动断开 */
|
||||
private _startKeepAlive(): void {
|
||||
this._stopKeepAlive()
|
||||
this._keepAliveTimer = setInterval(() => { this._activeProtocol?.sendKeepAliveCode?.() }, 10000)
|
||||
}
|
||||
|
||||
/** 停止保活心跳定时器 */
|
||||
private _stopKeepAlive(): void {
|
||||
if (this._keepAliveTimer !== null) {
|
||||
clearInterval(this._keepAliveTimer)
|
||||
this._keepAliveTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
/** 停止重连定时器并重置重连计数 */
|
||||
private _stopReconnectTimer(): void {
|
||||
if (this._reconnectTimer !== null) {
|
||||
clearTimeout(this._reconnectTimer)
|
||||
this._reconnectTimer = null
|
||||
}
|
||||
this._reconnectCount = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行自动重连
|
||||
* 超过最大次数则放弃;否则延时 2s 后重建连接。
|
||||
*/
|
||||
private _doReconnect(): void {
|
||||
if (this._reconnectCount >= this._maxReconnect) {
|
||||
console.warn(TAG, '重连次数已达上限')
|
||||
this._onDisconnectedCbs.forEach(cb => cb())
|
||||
return
|
||||
}
|
||||
if (!this._lastRawDevice) {
|
||||
console.warn(TAG, '无缓存设备,放弃重连')
|
||||
return
|
||||
}
|
||||
this._reconnectCount++
|
||||
console.log(TAG, `_doReconnect 第 ${this._reconnectCount} 次`)
|
||||
this._stopReconnectTimer()
|
||||
this._reconnectTimer = setTimeout(() => {
|
||||
plugin.Blue.clearProtocol()
|
||||
plugin.Blue.createBLEConnection(this._lastRawDevice!)
|
||||
}, 2000)
|
||||
}
|
||||
}
|
||||
|
||||
/** 导出单例实例 */
|
||||
export const leFuService = new LeFuService()
|
||||
@@ -0,0 +1,90 @@
|
||||
/** ppScale-plugin 原始设备对象 */
|
||||
export type RawDevice = Record<string, any>
|
||||
|
||||
/** 乐福 SDK 插件对象(运行时由 requirePlugin 注入) */
|
||||
export type LeFuPlugin = Record<string, any>
|
||||
|
||||
|
||||
/** 设备配置(来自 master device.setting 列表) */
|
||||
export interface DeviceSetting {
|
||||
advLength: number
|
||||
calorieStatus: number
|
||||
deviceAccuracyType: number
|
||||
deviceCalcuteType: number
|
||||
deviceConnectType: number
|
||||
deviceFuncType: number
|
||||
deviceName: string
|
||||
devicePowerType: number
|
||||
deviceProtocolType: number
|
||||
deviceType: number
|
||||
deviceUnitType: string
|
||||
id: number
|
||||
macAddressStart: number
|
||||
sign: string
|
||||
status: number
|
||||
uhStatus: number
|
||||
createBy: null
|
||||
imgUrl: null
|
||||
remark: null
|
||||
updateBy: null
|
||||
}
|
||||
|
||||
/** 扫描到的设备(展示层使用) */
|
||||
export interface ScannedDevice {
|
||||
/** 设备名称 */
|
||||
name: string
|
||||
/** plugin 返回的原始设备对象,连接时传回给 SDK */
|
||||
raw: RawDevice
|
||||
/** 设备模型(含 deviceConnectType 等信息) */
|
||||
model: Record<string, any>
|
||||
}
|
||||
|
||||
/** WiFi 项 */
|
||||
export interface LeFuWifiItem {
|
||||
/** WiFi SSID */
|
||||
ssid: string
|
||||
/** 信号强度(部分设备上报) */
|
||||
signal?: number
|
||||
}
|
||||
|
||||
/** 测量进度数据(progressData 事件,测量过程中多次回调) */
|
||||
export interface ProgressData {
|
||||
/** 体重,单位:克 */
|
||||
weight: number
|
||||
/** 单位枚举值 */
|
||||
unit: number
|
||||
/** 是否正在心率测量 */
|
||||
isHeartRating: boolean
|
||||
}
|
||||
|
||||
/** 测量锁定数据(lockData 事件,测量完成时回调一次) */
|
||||
export interface LockData {
|
||||
/** 体重,单位:克 */
|
||||
weight: number
|
||||
/** 阻抗值(用于体成分分析) */
|
||||
resistance: number
|
||||
/** 心率(部分设备上报) */
|
||||
heartRate?: number
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
/** 乐福服务配置 */
|
||||
export interface LeFuConfig {
|
||||
key: string
|
||||
secret: string
|
||||
/** 老协议域名(无鉴权) */
|
||||
domain1: string
|
||||
/** 新协议域名(有鉴权) */
|
||||
domain2: string
|
||||
}
|
||||
|
||||
/** 设备固件信息(deviceInfo 事件返回) */
|
||||
export interface DeviceInfo {
|
||||
/** 固件版本号,格式:mcu.ble.wifi.res,如 "006.005.004.305" */
|
||||
firmwareRevision: string
|
||||
/** 设备型号,用于请求服务端版本接口 */
|
||||
modelNumber: string
|
||||
/** 设备序列号 */
|
||||
serialNumber: string
|
||||
[key: string]: any
|
||||
}
|
||||
Reference in New Issue
Block a user