import base64ToArrayBuffer from 'base64-arraybuffer'; import { hexToBase64, decimalArrayAsBigEndianNumber } from '../../parsing/binary'; import { sendCommand } from '../sendCommands'; import { BluetoothProbeEmitter } from '../emitter/BluetoothProbeEmitter'; import { DummyProbeEmitter } from '../emitter/DummyProbeEmitter'; const isCommandCorrect = responseArray => responseArray[0] === 0x7e && responseArray[1] === 0x08; export const parseBatteryPercentage = aBase64String => { const arrayBuffer = new Uint8Array(base64ToArrayBuffer.decode(aBase64String)); if (arrayBuffer.length < 4 || !isCommandCorrect(arrayBuffer)) { return null; } const voltage = Number(decimalArrayAsBigEndianNumber(arrayBuffer.slice(2, 4))) / 1000; return Math.max(Math.min(Math.round((voltage - 3.0) / 0.009), 100), 0); }; export const BATTERY_PROBE_COMMAND = hexToBase64('7E 08'); export const getProbeBatteryStatus = ({ bluetoothContext }) => { const probeEmitter = bluetoothContext.mockProbe ? new DummyProbeEmitter(true) : new BluetoothProbeEmitter(bluetoothContext.connectedDevice, bluetoothContext.manager); const receiver = ({ timeoutId }) => ({ appendString: commandResult => { clearTimeout(timeoutId); probeEmitter.cancel().finally(() => bluetoothContext.mutex.release()); const batteryPercentage = parseBatteryPercentage(commandResult); bluetoothContext.setBatteryPercentage(batteryPercentage); }, reject: _anErrorObject => { clearTimeout(timeoutId); probeEmitter.cancel().finally(() => bluetoothContext.mutex.release()); }, }); const task = () => { sendCommand({ bluetoothContext, probeEmitter, receiver, probeCommand: BATTERY_PROBE_COMMAND, timeOutInMs: bluetoothContext.timeOuts.probeBatteryTimeOutInMs, }); }; return task; };