UNPKG

react-native-bluetooth-obd-manager

Version:

A React Native hook library to manage Bluetooth Low Energy connections and communication with ELM327 OBD-II adapters.

248 lines 8.11 kB
import type { Dispatch } from 'react'; import type { Peripheral as BlePeripheral } from 'react-native-ble-manager'; export interface Peripheral extends BlePeripheral { id: string; name?: string; rssi?: number; advertising?: { isConnectable?: boolean; serviceUUIDs?: string[]; manufacturerData?: Buffer; serviceData?: Record<string, Buffer>; txPowerLevel?: number; }; } export type BleManagerState = 'on' | 'off' | 'turning_on' | 'turning_off' | 'unknown' | 'resetting' | 'unsupported' | 'unauthorized'; export interface BleManagerDidUpdateValueForCharacteristicEvent { peripheral: string; characteristic: string; service: string; value: number[]; } export interface BleError { errorCode: string; message: string; attErrorCode?: number; } /** * Configuration details for the active BLE connection to an ELM327 device. * Stored once a compatible service/characteristic set is found. */ export interface ActiveDeviceConfig { /** The UUID of the primary service used for communication */ serviceUUID: string; /** The UUID of the characteristic used for writing commands */ writeCharacteristicUUID: string; /** The UUID of the characteristic used for receiving notifications */ notifyCharacteristicUUID: string; /** Whether the write characteristic supports Write (with response) or WriteWithoutResponse */ writeType: 'Write' | 'WriteWithoutResponse'; } /** * Extends the base Peripheral type to include prediction flags for OBD compatibility. */ export interface PeripheralWithPrediction extends Peripheral { /** Indicates if this device is likely an OBD-II adapter based on name heuristics */ isLikelyOBD?: boolean; /** Additional information about prediction reasoning (for debugging) */ prediction?: string; } export interface DeferredPromise<T> { promise: Promise<T>; resolve: (value: T | PromiseLike<T>) => void; reject: (reason: Error) => void; } export interface BleDisconnectPeripheralEvent { peripheral: string; reason?: string; } /** * Interface representing chunked Bluetooth response data. * Each element in the array represents a distinct data packet received. */ export interface ChunkedResponse { /** The complete flattened byte array (excluding the prompt byte) */ data: Uint8Array; /** The original response chunks as received from the device */ chunks: Uint8Array[]; } export interface CommandExecutionState { promise: DeferredPromise<string | Uint8Array | ChunkedResponse>; timeoutId: NodeJS.Timeout | null; responseBuffer: number[]; responseChunks: number[][]; expectedReturnType: 'string' | 'bytes' | 'chunked'; } export interface CurrentCommand { timeoutId?: NodeJS.Timeout; responseBuffer: number[]; expectedReturnType: 'string' | 'bytes'; } /** * Represents the state managed by the Bluetooth context and reducer. */ export interface BluetoothState { /** Whether the Bluetooth adapter is on */ isBluetoothOn: boolean; /** Whether required permissions are granted */ hasPermissions: boolean; /** Whether the BluetoothProvider is still initializing */ isInitializing: boolean; /** The most recent error that occurred, if any */ error: BleError | Error | null; isScanning: boolean; discoveredDevices: PeripheralWithPrediction[]; isConnecting: boolean; isDisconnecting: boolean; connectedDevice: Peripheral | null; activeDeviceConfig: ActiveDeviceConfig | null; isAwaitingResponse: boolean; isStreaming: boolean; lastSuccessfulCommandTimestamp: number | null; } /** * Actions that can be dispatched to the Bluetooth reducer. * Uses a discriminated union based on the 'type' property. */ export type BluetoothAction = { type: 'SET_INITIALIZING'; payload: boolean; } | { type: 'SET_BLUETOOTH_STATE'; payload: boolean; } | { type: 'SET_PERMISSIONS_STATUS'; payload: boolean; } | { type: 'SET_ERROR'; payload: BleError | Error | null; } | { type: 'RESET_STATE'; } | { type: 'SCAN_START'; } | { type: 'SCAN_STOP'; } | { type: 'DEVICE_FOUND'; payload: PeripheralWithPrediction; } | { type: 'CLEAR_DISCOVERED_DEVICES'; } | { type: 'CONNECT_START'; } | { type: 'CONNECT_SUCCESS'; payload: { device: Peripheral; config: ActiveDeviceConfig; }; } | { type: 'CONNECT_FAILURE'; payload: BleError | Error; } | { type: 'DEVICE_DISCONNECTED'; } | { type: 'DISCONNECT_START'; } | { type: 'DISCONNECT_SUCCESS'; } | { type: 'DISCONNECT_FAILURE'; payload: BleError | Error; } | { type: 'SEND_COMMAND_START'; } | { type: 'COMMAND_SUCCESS'; payload?: string | Uint8Array; } | { type: 'COMMAND_FAILURE'; payload: BleError | Error; } | { type: 'COMMAND_TIMEOUT'; } | { type: 'DATA_RECEIVED'; payload: number[]; } | { type: 'SET_STREAMING_STATUS'; payload: boolean; } | { type: 'UPDATE_LAST_SUCCESS_TIMESTAMP'; } | { type: 'STREAMING_INACTIVITY_TIMEOUT'; }; /** * Type for the dispatch function provided by the Bluetooth context. */ export type BluetoothDispatch = Dispatch<BluetoothAction>; /** * Structure of the state context provided to consumers. */ export type BluetoothContextState = BluetoothState; /** * Structure of the object returned by the `useBluetooth` hook. */ export interface UseBluetoothResult extends BluetoothContextState { /** * Checks if required Bluetooth permissions are granted. * @returns Promise resolving to true if permissions are granted, false otherwise */ checkPermissions: () => Promise<boolean>; /** * Requests Bluetooth permissions from the user. * @returns Promise resolving to true if permissions are granted, false otherwise */ requestBluetoothPermissions: () => Promise<boolean>; /** * Prompts the user to enable Bluetooth if it's not already on. * On iOS, this is a no-op as there's no API to open Bluetooth settings. */ promptEnableBluetooth: () => Promise<void>; /** * Scans for nearby Bluetooth devices. * @param scanDuration Duration to scan in milliseconds (default: 5000) */ scanDevices: (scanDuration?: number) => Promise<void>; /** * Connects to a Bluetooth device. * @param deviceId ID of the device to connect to * @returns Promise resolving to the connected peripheral */ connectToDevice: (deviceId: string) => Promise<Peripheral>; /** * Disconnects from the currently connected device. */ disconnect: () => Promise<void>; /** * Sends a command to the connected ELM327 device and returns the response as a string. * @param command The command to send (e.g., "AT Z", "01 0C") * @param options Options for command execution * @returns Promise resolving to the string response */ sendCommand: (command: string, options?: { timeout?: number; }) => Promise<string>; /** * Sends a command to the connected ELM327 device and returns the raw response bytes. * @param command The command to send * @param options Options for command execution * @returns Promise resolving to the raw byte response */ sendCommandRaw: (command: string, options?: { timeout?: number; }) => Promise<Uint8Array>; /** * Sends a command to the connected ELM327 device and returns the response as * an array of chunks, preserving the original data packet boundaries. * @param command The command to send * @param options Options for command execution * @returns Promise resolving to the chunked response */ sendCommandRawChunked: (command: string, options?: { timeout?: number; }) => Promise<ChunkedResponse>; /** * Sets the streaming state. * When true, enables automatic inactivity monitoring. * @param shouldStream Whether streaming should be active */ setStreaming: (shouldStream: boolean) => void; } //# sourceMappingURL=index.d.ts.map