Types & Interfaces
Comprehensive TypeScript type definitions for the BT Management module, providing type safety and clear API contracts for medical device integration.
Overview
The BT Management module uses a robust type system to ensure type safety across device communication, data parsing, and event handling. This document covers all TypeScript interfaces, enums, and type definitions used throughout the system.
Core Interfaces
IBaseDevice
Base interface that all medical devices must implement.
export interface IBaseDevice {
readonly deviceData: DeviceData;
readonly deviceModel: IMedicalDevice;
readonly deviceId: string;
readonly deviceName: IntegratedDevices;
// Connection method — connect() auto-subscribes to all characteristics
// internally via the private bt-connection-handler.subscribeToAllCharacteristics.
// Do NOT add a separate subscribe call to your public interface; the SDK
// handles it.
connect: () => Promise<void>;
}
Usage:
// All device implementations must extend IBaseDevice
class DeviceF4 extends BaseDevice implements IBaseDevice {
// Implementation
}
DeviceData
Complete device information structure containing all device metadata.
export type DeviceData = {
model: IMedicalDevice;
name: IntegratedDevices;
localName: string;
manufacturerData: string;
sn: string;
id: string;
supportedMeasurementTypeKeys: MeasurementTypeKey[];
};
Example:
const deviceData: DeviceData = {
model: {
deviceName: IntegratedDevices.F4,
mainService: {
/* service config */
},
},
name: IntegratedDevices.F4,
localName: "F4",
manufacturerData: "0x1234",
sn: "F4-123456",
id: "ble-device-id-123",
supportedMeasurementTypeKeys: [MeasurementTypeKey.bodyWeight],
};
IMedicalDevice
Device configuration interface defining BLE services and parsing models.
export interface IMedicalDevice {
deviceName: IntegratedDevices;
mainService: IService | IService[];
}
Single Service Example:
const glucoseMeter: IMedicalDevice = {
deviceName: IntegratedDevices.TAIDOC_GLUCOSE,
mainService: {
uuid: "00001523-1212-efde-1523-785feabcd123",
monitorUuids: [
/* monitoring characteristics */
],
writeUuid: {
uuid: "00001524-1212-efde-1523-785feabcd123",
mainCommandUuid: "512600000000A31A",
},
},
};
Multi-Service Example:
const multiSensorDevice: IMedicalDevice = {
deviceName: IntegratedDevices.COSINUSS,
mainService: [
{
uuid: "0000180d-0000-1000-8000-00805f9b34fb", // Heart Rate
monitorUuids: [
/* HR characteristics */
],
},
{
uuid: "00001822-0000-1000-8000-00805f9b34fb", // Pulse Oximeter
monitorUuids: [
/* SpO2 characteristics */
],
},
{
uuid: "00001809-0000-1000-8000-00805f9b34fb", // Temperature
monitorUuids: [
/* Temperature characteristics */
],
},
],
};
Service & Characteristic Types
IService
BLE service definition with monitoring and write characteristics.
export interface IService {
uuid: string;
monitorUuids: IMonitorCharacteristic[];
writeUuid?: IWriteCharacteristic;
}
IMonitorCharacteristic
Characteristic configuration for data monitoring and parsing.
export interface IMonitorCharacteristic {
uuid: string;
parsingModel: ParsingModel;
}
IWriteCharacteristic
Characteristic configuration for sending commands to devices.
export interface IWriteCharacteristic {
uuid: string;
mainCommandUuid: string;
}
Example:
const writeCharacteristic: IWriteCharacteristic = {
uuid: "8b00ace7-eb0b-49b0-bbe9-9aee0a26e1a3",
mainCommandUuid: "a508f700000000ee", // Command to start measurement
};
Data Parsing Types
ParsingModel
Model for parsing BLE characteristic data into measurements.
export interface ParsingModel {
caseValuePosition?: number[];
cases: ParsingCase[];
messageCountParsingDefinition?: (msg: string[]) => number;
}
Example:
const bloodPressureParsingModel: ParsingModel = {
caseValuePosition: [0, 1, 7], // Bytes that determine message type
messageCountParsingDefinition: (msg: string[]): number =>
parseInt((msg?.[6] ?? "0") + (msg?.[5] ?? "0"), 16) + 8,
cases: [
{
returnType: MeasurementTypeKey.bloodPressure,
caseType: CaseType.RESULT,
caseValue: "a50805",
parseDefinitions: [
/* parsing rules */
],
},
],
};
ParsingCase
Individual case definition for different message types.
export interface ParsingCase {
returnType?: MeasurementTypeKey;
caseType: CaseType;
parseDefinitions: ParserDefinition[];
caseValue: string;
description?: string;
}
Types of Cases:
// Result case - final measurement
const resultCase: ParsingCase = {
returnType: MeasurementTypeKey.bloodPressure,
caseType: CaseType.RESULT,
caseValue: "a50805",
parseDefinitions: [
{
name: "systolic",
parseType: "number",
byteIndexes: [21, 20],
parseReference: 16,
},
],
};
// Stream case - real-time data
const streamCase: ParsingCase = {
returnType: MeasurementTypeKey.bloodPressure,
caseType: CaseType.STREAM,
caseValue: "a50804",
parseDefinitions: [],
};
// Other case - status/control
const otherCase: ParsingCase = {
caseType: CaseType.OTHER,
caseValue: "a50803",
parseDefinitions: [],
description: "User on home screen",
};
ParserDefinition
Definition for extracting and converting individual data fields.
export interface ParserDefinition {
name: string;
parseType: string;
byteIndexes: number[];
parseReference?: number;
bitParseDefinition?: ParserDefinition[];
customParserDefinition?: (data: any) => any;
}
Parse Types:
// Number parsing
const numberField: ParserDefinition = {
name: "systolic",
parseType: "number",
byteIndexes: [21, 20],
parseReference: 16, // Hexadecimal
};
// String parsing
const stringField: ParserDefinition = {
name: "deviceId",
parseType: "string",
byteIndexes: [5, 6, 7],
parseReference: 16,
};
// Boolean parsing
const booleanField: ParserDefinition = {
name: "isConnected",
parseType: "boolean",
byteIndexes: [8],
parseReference: 16,
};
// Custom parsing
const customField: ParserDefinition = {
name: "bodyWeight",
parseType: "custom",
byteIndexes: [5, 6, 7, 8],
customParserDefinition: (a: string): number => parseInt(a, 16) / 100,
};
// Date parsing
const dateField: ParserDefinition = {
name: "timestamp",
parseType: "date",
byteIndexes: [10, 11],
parseReference: 16,
};
Enums
IntegratedDevices
Enumeration of all supported medical device types.
export enum IntegratedDevices {
// Scales
F4 = "F4",
FORA_SCALE = "FORA W550",
RPM_SCALE = "GBS-2012-B",
S5 = "Le S5",
// Blood Pressure Monitors
BP2 = "BP2",
// Pulse Oximeters
SPO2 = "Oxyfit",
PC60WF = "OxySmart",
COSINUSS = "two",
CMED = "cmed",
// Thermometers
AOJ20A = "AOJ-20A",
ANDESFITTEMP = "TEMP",
FORATEMP = "FORA IR20",
CLEVERTEMP = "TAIDOC TD1107",
// Glucose Meters
TAIDOC_GLUCOSE = "TAIDOC TD4216",
GLUCOCHECK = "GlucoCheck",
BGM = "BGM",
// Urinalysis
BC01 = "BC01",
// Spirometers
SP80B = "PULMO80B",
// Other
ALIVE_COR = "alivecor",
}
DeviceStatus
Device connection and operation status enumeration.
Note: The
DeviceStatusenum has exactly 4 values:Connected,Disconnected,Measuring, andLowBattery. No other status values exist in the SDK.
export enum DeviceStatus {
CONNECTED = "Connected",
DISCONNECTED = "Disconnected",
MEASURING = "Measuring",
LOW_BATTERY = "LowBattery",
}
Usage in Event Handling:
const handleDeviceStatus = (status: DeviceStatus, device: DeviceData) => {
switch (status) {
case DeviceStatus.CONNECTED:
console.log(`${device.name} is ready for measurements`);
break;
case DeviceStatus.MEASURING:
console.log(`${device.name} is taking a measurement`);
break;
case DeviceStatus.DISCONNECTED:
console.log(`${device.name} has disconnected`);
break;
case DeviceStatus.LOW_BATTERY:
console.log(`${device.name} battery is low`);
break;
}
};
CaseType
Message type classification for data parsing.
export enum CaseType {
RESULT = "result", // Final measurement data
STREAM = "stream", // Real-time data stream
OTHER = "other", // Status/control messages
SN = "sn", // Serial number data
ERROR = "error", // Error conditions
}
BleCustomEvents
Event types for device communication.
export enum BleCustomEvents {
ON_DEVICE_STATUS = "onDeviceStatus",
ON_MEASUREMENT = "onMeasurement",
ON_START_SCAN = "onStartScan",
ON_DEVICE_ERROR = "onDeviceError",
ON_COSINUSS_DEVICE_PARAMS = "onCosinussDevice",
}
Event & Communication Types
BTProviderProps
Props interface for the BTProvider component. The provider exposes exactly five user-facing callbacks plus permissionFallback, and is generic over the tuple of accepted devices.
export interface BTProviderChildWrapperProps<T extends readonly IntegratedDevices[]> {
bleManager: BleManager;
acceptedDevices: T;
onDeviceFound?: (
device: BTManagedDevice<T[number]>,
manager: BTManager<T>,
) => Promise<void>;
onError?: (data: ErrorCallback) => void;
onDeviceStatusChanged?: (data: DeviceStatusChangeCallback) => void;
onResult?: (data: ResultCallback<T[number]>) => void;
}
export interface BTProviderProps<T> extends BTProviderChildWrapperProps<T> {
onAccessPermissionChanged?: (accessPermission: boolean) => void;
permissionFallback?: () => React.ReactNode;
}
Callback contract:
onDeviceFound(device, manager)— invoked when a matching device is discovered. Callawait device.connect()to establish the connection;connect()auto-subscribes to all relevant characteristics internally. Do not calldevice.subscribeToAllCharacteristics()directly — it is a private method on the connection handler.onError({ error, deviceData? })— invoked on scan or device errors, with the underlying error and optional device context.onResult({ deviceData, data })— invoked when a final measurement is produced.onDeviceStatusChanged({ deviceData, status, measurementTypeKey? })— invoked when a connected device transitions to one of the fourDeviceStatusstates.onAccessPermissionChanged(granted)— invoked when Bluetooth / location permission state changes.
DeviceStatusInfo
Event data structure for device status changes.
export interface DeviceStatusInfo {
status: DeviceStatus;
device: DeviceData;
measurementTypeKey?: MeasurementTypeKey;
}
MeasurementInfo
Event data structure for measurement updates.
export interface MeasurementInfo {
measurement: Measurement;
device: DeviceData;
}
Queue Management Types
IDeviceQueueManager
Interface for managing device connection queues.
export interface IDeviceQueueManager {
subscribeToTimer: (
onTimerWorks: (device: IBaseDevice) => Promise<void>,
) => EmitterSubscription;
addTimerForDevice: (device: IBaseDevice) => void;
removeAllTimersForDevice: (deviceName: IntegratedDevices) => void;
}
ScanEvents
Scanning event enumeration for internal event handling.
export enum ScanEvents {
ON_START_SCAN = "ON_START_SCAN",
ON_DEVICE_FOUND_INTERNAL = "ON_DEVICE_FOUND_INTERNAL",
ON_ERROR_INTERNAL = "ON_ERROR_INTERNAL",
ON_DEVICE_FOUND_EXTERNAL = "ON_DEVICE_FOUND_EXTERNAL",
ON_ERROR_EXTERNAL = "ON_ERROR_EXTERNAL",
}
ScanDeviceQueueEvents
Queue management event enumeration.
export enum ScanDeviceQueueEvents {
ON_DEVICE_TIMEOUT = "ON_DEVICE_TIMEOUT",
}
Diagnostic & Error Types
BloodPressureStates
Blood pressure measurement status enumeration.
export enum BloodPressureStates {
REGULAR = "Regular",
LOOSE_SLEEVE = "The sleeve is loose. Unable to analyze.",
DISTURB_DETECTED = "Disturb Detected.",
WEAK_SIGNAL = "Weak Signal.",
DEVICE_ERROR = "Unknown device error.",
}
DiagnosticKeyEnum
Urinalysis parameter enumeration.
export enum DiagnosticKeyEnum {
URO = "URO", // Urobilinogen
BLD_PRO_LEU_VC = "BLD_PRO_LEU_VC", // Blood/Protein/Leukocytes/Vitamin C
BIL_KET = "BIL_KET", // Bilirubin/Ketones
GLU = "GLU", // Glucose
NIT = "NIT", // Nitrites
PH = "PH", // pH
SG = "SG", // Specific Gravity
}
DiagnosticKeys
Type alias for diagnostic result keys.
export type DiagnosticKeys = keyof typeof diagnosticResults;
// Usage with diagnostic results
const diagnosticResults = {
URO: ["Norm", "1+", "2+", "3+"],
BLD_PRO_LEU_VC: ["-", "+-", "1+", "2+", "3+"],
BIL_KET: ["-", "1+", "2+", "3+"],
GLU: ["-", "+-", "1+", "2+", "3+", "4+"],
NIT: ["-", "+"],
PH: ["5", "6", "7", "8", "9"],
SG: ["1.005", "1.010", "1.015", "1.020", "1.025", "1.030"],
};
Type Guards & Utilities
Type Guards
Type guard functions for runtime type checking.
// Device type guard
export function isValidDevice(device: any): device is IBaseDevice {
return (
device &&
typeof device.deviceId === "string" &&
typeof device.deviceName === "string" &&
typeof device.connect === "function"
);
}
// Measurement type guard
export function isBloodPressureMeasurement(
measurement: Measurement,
): measurement is BloodPressureMeasurement {
return measurement.measurementTypeKey === MeasurementTypeKey.bloodPressure;
}
// Device data validation
export function isValidDeviceData(data: any): data is DeviceData {
return (
data &&
typeof data.id === "string" &&
typeof data.name === "string" &&
Array.isArray(data.supportedMeasurementTypeKeys)
);
}
Utility Types
Helpful utility types for working with the BT Management system.
// Extract device names from IntegratedDevices enum
export type DeviceName = keyof typeof IntegratedDevices;
// Create a union type of all measurement types
export type AnyMeasurement =
| BloodPressureMeasurement
| BodyWeightMeasurement
| BodyTemperatureMeasurement
| BloodGlucoseMeasurement
| PulseOximeterMeasurement
| EcgMeasurement
| SpirometryMeasurement
| UrineAnalyzeMeasurement;
// Device configuration partial type for testing
export type PartialDeviceConfig = Partial<IMedicalDevice> & {
deviceName: IntegratedDevices;
};
// Event callback types
export type DeviceFoundCallback = (
device: IBaseDevice,
scanInstance: ScanManagerImplementation,
) => void;
export type MeasurementCallback = (
measurement: Measurement,
device: DeviceData,
) => void;
export type DeviceStatusCallback = (
status: DeviceStatus,
device: DeviceData,
measurementType?: MeasurementTypeKey,
) => void;
export type DeviceErrorCallback = (error: string, device: DeviceData) => void;
Generic Types
Generic Device Interface
Generic interface for type-safe device implementations.
export interface ITypedDevice<TMeasurement extends Measurement>
extends IBaseDevice {
readonly supportedMeasurementType: MeasurementTypeKey;
// Type-safe measurement processing
processMeasurement(data: TMeasurement): void;
validateMeasurement(data: TMeasurement): string | undefined;
}
// Usage example
export class TypedDeviceF4 implements ITypedDevice<BodyWeightMeasurement> {
readonly supportedMeasurementType = MeasurementTypeKey.bodyWeight;
processMeasurement(data: BodyWeightMeasurement): void {
// Type-safe access to bodyWeight property
console.log(`Weight: ${data.bodyWeight} kg`);
}
validateMeasurement(data: BodyWeightMeasurement): string | undefined {
if (data.bodyWeight <= 0) {
return "Invalid weight measurement";
}
return undefined;
}
}
Generic Parser Type
Generic type for custom parser functions.
export type CustomParser<TInput, TOutput> = (input: TInput) => TOutput;
// Specific parser implementations
export type HexToNumberParser = CustomParser<string, number>;
export type HexToStringParser = CustomParser<string, string>;
export type HexToBooleanParser = CustomParser<string, boolean>;
// Parser definition with generic typing
export interface TypedParserDefinition<TOutput> {
name: string;
parseType: "custom";
byteIndexes: number[];
customParserDefinition: CustomParser<string, TOutput>;
}
// Usage
const weightParser: TypedParserDefinition<number> = {
name: "bodyWeight",
parseType: "custom",
byteIndexes: [5, 6, 7, 8],
customParserDefinition: (hex: string): number => parseInt(hex, 16) / 100,
};
Type Examples
Complete Device Implementation Type
// Full type definition for a device implementation
interface CompleteDeviceImplementation {
// Device identification
deviceInfo: DeviceData;
deviceConfig: IMedicalDevice;
// Connection management
connectionState: DeviceStatus;
connectionPromise: Promise<void> | null;
// Data processing
messageCollector: MessageCollector;
parsingModel: ParsingModel;
lastMeasurement: Measurement | null;
// Event handling
statusCallbacks: DeviceStatusCallback[];
measurementCallbacks: MeasurementCallback[];
errorCallbacks: DeviceErrorCallback[];
// Lifecycle methods
initialize(): Promise<void>;
connect(): Promise<void>;
disconnect(): Promise<void>;
cleanup(): void;
// Data methods
processIncomingData(data: string[]): void;
validateMeasurement(measurement: Measurement): boolean;
handleError(error: string): void;
}
Event System Types
// Event emitter types for type-safe event handling
interface TypedEventEmitter {
on<T extends keyof BleEventMap>(event: T, listener: BleEventMap[T]): void;
emit<T extends keyof BleEventMap>(
event: T,
...args: Parameters<BleEventMap[T]>
): void;
removeListener<T extends keyof BleEventMap>(
event: T,
listener: BleEventMap[T],
): void;
}
// Event map for type safety
interface BleEventMap {
[BleCustomEvents.ON_DEVICE_STATUS]: (info: DeviceStatusInfo) => void;
[BleCustomEvents.ON_MEASUREMENT]: (info: MeasurementInfo) => void;
[BleCustomEvents.ON_DEVICE_ERROR]: (
error: string,
device: DeviceData,
) => void;
}
Testing Types
Mock Types
Types for testing and mocking.
// Mock device for testing
export interface MockDevice extends IBaseDevice {
simulateConnection(): Promise<void>;
simulateDisconnection(): void;
simulateMeasurement(measurement: Measurement): void;
simulateError(error: string): void;
getConnectionHistory(): string[];
}
// Test fixture types
export interface DeviceTestFixture {
device: MockDevice;
expectedMeasurements: Measurement[];
simulatedMessages: string[][];
expectedErrors: string[];
}
// Test configuration
export interface TestConfiguration {
deviceType: IntegratedDevices;
testData: DeviceTestFixture;
timeout: number;
retryCount: number;
}
Type Safety Best Practices
Strict Typing
// Always use strict typing for device operations
interface StrictDeviceOperations {
// Use specific enums instead of strings
status: DeviceStatus; // Good
// status: string; // Avoid
// Use specific measurement types
measurement: BloodPressureMeasurement; // Good
// measurement: any; // Avoid
// Use type guards for runtime checks
validateDevice(device: unknown): device is IBaseDevice;
// Use generics for reusable code
processTypedMeasurement<T extends Measurement>(measurement: T): T;
}
Error Handling Types
// Structured error types
export interface BleError {
code: number;
message: string;
deviceId?: string;
context?: Record<string, any>;
}
export interface DeviceError extends BleError {
deviceName: IntegratedDevices;
measurementContext?: MeasurementTypeKey;
}
// Result types for operations that can fail
export type DeviceOperationResult<T> =
| { success: true; data: T }
| { success: false; error: DeviceError };
// Usage
async function connectDevice(
device: IBaseDevice,
): Promise<DeviceOperationResult<DeviceData>> {
try {
await device.connect();
return { success: true, data: device.deviceData };
} catch (error) {
return {
success: false,
error: {
code: 1001,
message: "Connection failed",
deviceName: device.deviceName,
deviceId: device.deviceId,
},
};
}
}
Dependencies
The types depend on these external libraries:
// External dependencies
import {
Measurement,
MeasurementTypeKey,
BloodPressureMeasurement,
} from "@ovok/core";
import { BleManager, Device, BleError } from "react-native-ble-plx";
import { EmitterSubscription } from "react-native";
import { EffectCallback } from "react";
Related Documentation
Device Types: Medical device configurationsBTProvider: React provider componentDevice Services: Core service implementations@ovok/core: Core measurement types