import type { ReadStrategy } from '../parsing/ReadStrategy'; import { createErrorFromCode, SFPToolboxErrorCode } from '../error/error'; import { ReadingClerk } from '../parsing/ReadingClerk'; import type { BluetoothContextType } from './context'; import { BluetoothProbeEmitter } from './emitter/BluetoothProbeEmitter'; import { DummyProbeEmitter } from './emitter/DummyProbeEmitter'; import LocalLogger from './LocalLogger'; export type MockCode = string; interface Params { bluetoothContext: BluetoothContextType | null; mockCode?: MockCode; onSuccess?: any; onError?: any; onBeginReading: any; readStrategy: ReadStrategy; interval?: number; recoverMeterNumber?: Function | undefined; onPress?: Function | undefined; meterTypeCode?: string | undefined; chunkDelay?: number; } export const readMeter = ({ mockCode, onBeginReading, bluetoothContext, onSuccess, onError, readStrategy, interval, recoverMeterNumber, onPress, meterTypeCode, chunkDelay, }: Params) => { const probeEmitter = mockCode ? new DummyProbeEmitter(true, interval, chunkDelay) : new BluetoothProbeEmitter(bluetoothContext?.connectedDevice, bluetoothContext?.manager); const obj: { unsubscribe: Function; run: Function; promise: null | Promise; probeEmitter: DummyProbeEmitter | BluetoothProbeEmitter; } = { probeEmitter, unsubscribe: function () { this.probeEmitter.error({ code: SFPToolboxErrorCode.OperationCancelled, message: 'Operation was cancelled', }); }, run: async function () { await bluetoothContext?.mutex.acquire(); return new Promise((resolve, reject) => { try { const clerk = new ReadingClerk(resolve, reject, onBeginReading, readStrategy, recoverMeterNumber); LocalLogger.log( '\nMeter reading information:', `\nmeterTypeCode: ${meterTypeCode}\ninterpretationCode: ${readStrategy?.interpretationCode}\nmeterFamily: ${readStrategy?.meterFamily?.code}`, ); this.probeEmitter.subscribe(clerk); this.probeEmitter.start( readStrategy.meterFamily.probeCommand(readStrategy.meterPassword), mockCode, ); } catch (error: any) { reject(createErrorFromCode(SFPToolboxErrorCode.Unknown)); } }); }, promise: null, }; obj.promise = obj .run() .then(result => { bluetoothContext?.mutex.release(); if (recoverMeterNumber) { onPress?.(); } onSuccess(result); }) .catch(error => { bluetoothContext?.mutex.release(); onError(error); }); return obj; };