expo-duooomi-app/ble/services/DeviceInfoService.ts

144 lines
4.6 KiB
TypeScript

import { Buffer } from 'buffer'
import { COMMAND_TYPES, EVENT_TYPES } from '../protocol/Constants'
import {
type BindingResponse,
type DeleteFileResponse,
type DeviceInfo,
type PrepareTransferResponse,
type UnBindResponse,
type VersionInfo,
} from '../protocol/types'
import { BleProtocolService } from './BleProtocolService'
export class DeviceInfoService {
private protocol = BleProtocolService.getInstance()
private static instance: DeviceInfoService
private listeners: Map<string, Set<Function>> = new Map()
private constructor() {
this.protocol.addListener(EVENT_TYPES.DEVICE_INFO.code, this.onDeviceInfo)
this.protocol.addListener(EVENT_TYPES.VERSION_INFO.code, this.onVersionInfo)
this.protocol.addListener(EVENT_TYPES.BIND_DEVICE.code, this.onBindDevice)
this.protocol.addListener(EVENT_TYPES.UNBIND_DEVICE.code, this.onUnBindDevice)
this.protocol.addListener(EVENT_TYPES.DELETE_FILE.code, this.onDeleteFile)
this.protocol.addListener(EVENT_TYPES.PREPARE_TRANSFER.code, this.onPrepareTransfer)
}
private onDeviceInfo = (data: ArrayBuffer, deviceId: string) => {
try {
const json = this.prase<DeviceInfo>(data)
this.emit(EVENT_TYPES.DEVICE_INFO.name, json)
} catch (e) {
console.error('Failed to parse device info', e)
}
}
private onVersionInfo = (data: ArrayBuffer, deviceId: string) => {
try {
const json = this.prase<VersionInfo>(data)
this.emit(EVENT_TYPES.VERSION_INFO.name, json)
} catch (e) {
console.error('Failed to parse activation status', e)
}
}
private onBindDevice = (data: ArrayBuffer, deviceId: string) => {
try {
const json = this.prase<BindingResponse>(data)
this.emit(EVENT_TYPES.BIND_DEVICE.name, json)
} catch (e) {
console.error('Failed to parse activation status', e)
}
}
private onUnBindDevice = (data: ArrayBuffer, deviceId: string) => {
try {
const json = this.prase<UnBindResponse>(data)
this.emit(EVENT_TYPES.UNBIND_DEVICE.name, json)
} catch (e) {
console.error('Failed to parse activation status', e)
}
}
private onDeleteFile = (data: ArrayBuffer, deviceId: string) => {
try {
const json = this.prase<DeleteFileResponse>(data)
this.emit(EVENT_TYPES.DELETE_FILE.name, json)
} catch (e) {
console.error('Failed to parse delete file response', e)
}
}
private onPrepareTransfer = (data: ArrayBuffer, deviceId: string) => {
try {
const json = this.prase<PrepareTransferResponse>(data)
this.emit(EVENT_TYPES.PREPARE_TRANSFER.name, json)
} catch (e) {
console.error('Failed to parse prepare transfer response', e)
}
}
public static getInstance(): DeviceInfoService {
if (!DeviceInfoService.instance) {
DeviceInfoService.instance = new DeviceInfoService()
}
return DeviceInfoService.instance
}
private prase<T>(data: ArrayBuffer): T {
const str = Buffer.from(data).toString('utf-8')
const cleanStr = str.replace(/\0/g, '')
return JSON.parse(cleanStr) as T
}
public addListener(event: string, cb: Function) {
if (!this.listeners.has(event)) this.listeners.set(event, new Set())
this.listeners.get(event)!.add(cb)
}
public removeListener(event: string, cb: Function) {
if (this.listeners.has(event)) {
this.listeners.get(event)!.delete(cb)
}
}
private emit(event: string, data: any) {
this.listeners.get(event)?.forEach((cb) => cb(data))
}
public async getDeviceInfo(deviceId: string) {
await this.protocol.send(deviceId, COMMAND_TYPES.GET_DEVICE_INFO, { type: COMMAND_TYPES.GET_DEVICE_INFO })
}
public async getDeviceVersion(deviceId: string) {
await this.protocol.send(deviceId, COMMAND_TYPES.GET_DEVICE_VERSION, { type: COMMAND_TYPES.GET_DEVICE_VERSION })
}
public async bindDevice(deviceId: string, userId: string) {
await this.protocol.send(deviceId, COMMAND_TYPES.BIND_DEVICE, { type: COMMAND_TYPES.BIND_DEVICE, userId: userId })
}
public async unbindDevice(deviceId: string, userId: string) {
await this.protocol.send(deviceId, COMMAND_TYPES.UNBIND_DEVICE, {
type: COMMAND_TYPES.UNBIND_DEVICE,
userId: userId,
})
}
public async deleteFile(deviceId: string, key: string) {
await this.protocol.send(deviceId, COMMAND_TYPES.DELETE_FILE, {
type: COMMAND_TYPES.DELETE_FILE,
key: key,
})
}
public async prepareTransfer(deviceId: string, key: string, size: number) {
await this.protocol.send(deviceId, COMMAND_TYPES.PREPARE_TRANSFER, {
type: COMMAND_TYPES.PREPARE_TRANSFER,
key: key,
size: size,
})
}
}