# @ovok/native/next/bluetooth

Canonical page: https://docs.ovok.com/native-sdk/reference/next-bluetooth

Bluetooth for `@ovok/native/next`, in layers: the framework-free `BluetoothRuntime` and its ports, device drivers,
the `react-native-ble-plx` and React Native adapters, React hooks over the runtime, and optional UI built only from
those hooks.

Import from `@ovok/native/next/bluetooth`.

## Components [#components]

### BluetoothDevicePicker() [#bluetoothdevicepicker]

```ts
function BluetoothDevicePicker(__namedParameters): Element;
```

A bottom sheet listing the found devices; picking one connects to it. Built only from public hooks.

#### Parameters [#parameters]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | [`BluetoothDevicePickerProps`](#bluetoothdevicepickerprops) |

#### Returns [#returns]

`Element`

***

### BluetoothProvider() [#bluetoothprovider]

```ts
function BluetoothProvider(__namedParameters): Element;
```

Gives the Bluetooth hooks below it a runtime.

#### Parameters [#parameters-1]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | [`BluetoothProviderProps`](#bluetoothproviderprops) |

#### Returns [#returns-1]

`Element`

## Hooks [#hooks]

### useBluetooth() [#usebluetooth]

```ts
function useBluetooth(): BluetoothRuntime;
```

The runtime of the enclosing `BluetoothProvider`: every Bluetooth action is a call on it.

#### Returns [#returns-2]

[`BluetoothRuntime`](#bluetoothruntime)

#### Throws [#throws]

When rendered outside `BluetoothProvider`.

***

### useBluetoothPermission() [#usebluetoothpermission]

```ts
function useBluetoothPermission(): "unknown" | BluetoothPermission;
```

The Bluetooth permission, re-checked whenever the app returns to the foreground; `unknown` until first checked.

#### Returns [#returns-3]

`"unknown"` \| [`BluetoothPermission`](#bluetoothpermission)

***

### useBluetoothState() [#usebluetoothstate]

```ts
function useBluetoothState(): AdapterState;
```

The Bluetooth adapter state.

#### Returns [#returns-4]

[`AdapterState`](#adapterstate)

***

### useMeasurements() [#usemeasurements]

```ts
function useMeasurements(): readonly DeviceReading[];
```

The recent readings, oldest first, each with its save state.

#### Returns [#returns-5]

readonly [`DeviceReading`](#devicereading)[]

***

### useNearbyDevice() [#usenearbydevice]

```ts
function useNearbyDevice(deviceId): NearbyDevice | null;
```

One found device, or `null` until the scan finds it.

#### Parameters [#parameters-2]

| Parameter | Type |
| ------ | ------ |
| `deviceId` | `string` |

#### Returns [#returns-6]

[`NearbyDevice`](#nearbydevice) \| `null`

***

### useNearbyDevices() [#usenearbydevices]

```ts
function useNearbyDevices(): readonly NearbyDevice[];
```

The supported devices the scan found, each with its connection state.

#### Returns [#returns-7]

readonly [`NearbyDevice`](#nearbydevice)[]

***

### usePairedDevices() [#usepaireddevices]

```ts
function usePairedDevices(): readonly string[];
```

IDs of the paired devices.

#### Returns [#returns-8]

readonly `string`[]

***

### useScanning() [#usescanning]

```ts
function useScanning(): boolean;
```

Whether a scan is requested.

#### Returns [#returns-9]

`boolean`

## Classes [#classes]

### BluetoothError [#bluetootherror]

Every failure the Bluetooth runtime reports; `cause` holds the underlying error, when any.

#### Extends [#extends]

- `Error`

#### Constructors [#constructors]

##### Constructor [#constructor]

```ts
new BluetoothError(
   code,
   message,
   cause?
): BluetoothError;
```

###### Parameters [#parameters-3]

| Parameter | Type | Description |
| ------ | ------ | ------ |
| `code` | [`BluetoothErrorCode`](#bluetootherrorcode) | Why it failed. |
| `message` | `string` | - |
| `cause?` | `unknown` | - |

###### Returns [#returns-10]

[`BluetoothError`](#bluetootherror)

###### Overrides [#overrides]

`Error.constructor`

#### Properties [#properties]

| Property | Modifier | Type | Default value | Description | Overrides |
| ------ | ------ | ------ | ------ | ------ | ------ |
| <a id="property-code"></a> `code` | `public readonly` | [`BluetoothErrorCode`](#bluetootherrorcode) | `undefined` | Why it failed. | - |
| <a id="property-name"></a> `name` | `public readonly` | `"BluetoothError"` | `"BluetoothError"` | Always `"BluetoothError"`. | `Error.name` |

***

### BluetoothRuntime [#bluetoothruntime]

Scans for supported devices, connects to them, collects their readings and saves each one. Framework-free: React
hooks and components sit on top of it. Every failure is a `BluetoothError`. Call `dispose()` when done.

#### Constructors [#constructors-1]

##### Constructor [#constructor-1]

```ts
new BluetoothRuntime(options): BluetoothRuntime;
```

###### Parameters [#parameters-4]

| Parameter | Type |
| ------ | ------ |
| `options` | [`BluetoothRuntimeOptions`](#bluetoothruntimeoptions) |

###### Returns [#returns-11]

[`BluetoothRuntime`](#bluetoothruntime)

#### Methods [#methods]

##### checkPermission() [#checkpermission]

```ts
checkPermission(): Promise<BluetoothPermission>;
```

Reads the permission without prompting.

###### Returns [#returns-12]

`Promise`\<[`BluetoothPermission`](#bluetoothpermission)\>

##### connect() [#connect]

```ts
connect(deviceId): Promise<void>;
```

Connects to a found device for this session; resolves once connected.

###### Parameters [#parameters-5]

| Parameter | Type |
| ------ | ------ |
| `deviceId` | `string` |

###### Returns [#returns-13]

`Promise`\<`void`\>

###### Throws [#throws-1]

BluetoothError `device-not-found`, `connection-failed` or the driver's failure.

##### disconnect() [#disconnect]

```ts
disconnect(deviceId): Promise<void>;
```

Disconnects a device; a paired one stays disconnected until `connect` or `pair` is called again.

###### Parameters [#parameters-6]

| Parameter | Type |
| ------ | ------ |
| `deviceId` | `string` |

###### Returns [#returns-14]

`Promise`\<`void`\>

##### dispose() [#dispose]

```ts
dispose(): Promise<void>;
```

Stops scanning and disconnects every device; resolves once they have disconnected, after which nothing changes.

###### Returns [#returns-15]

`Promise`\<`void`\>

##### forget() [#forget]

```ts
forget(deviceId): Promise<void>;
```

Forgets a paired device and disconnects it.

###### Parameters [#parameters-7]

| Parameter | Type |
| ------ | ------ |
| `deviceId` | `string` |

###### Returns [#returns-16]

`Promise`\<`void`\>

##### getSnapshot() [#getsnapshot]

```ts
getSnapshot(): BluetoothSnapshot;
```

The current state.

###### Returns [#returns-17]

[`BluetoothSnapshot`](#bluetoothsnapshot)

##### openPermissionSettings() [#openpermissionsettings]

```ts
openPermissionSettings(): Promise<void>;
```

Opens the app's system settings, where a blocked permission can be granted.

###### Returns [#returns-18]

`Promise`\<`void`\>

##### pair() [#pair]

```ts
pair(deviceId): Promise<void>;
```

Remembers a device, so it connects whenever the scan finds it, and connects to it now.

###### Parameters [#parameters-8]

| Parameter | Type |
| ------ | ------ |
| `deviceId` | `string` |

###### Returns [#returns-19]

`Promise`\<`void`\>

##### requestPermission() [#requestpermission]

```ts
requestPermission(): Promise<BluetoothPermission>;
```

Prompts for the permission when the OS still can.

###### Returns [#returns-20]

`Promise`\<[`BluetoothPermission`](#bluetoothpermission)\>

##### retrySaves() [#retrysaves]

```ts
retrySaves(): Promise<void>;
```

Saves the readings whose save failed again, and the readings the sink queued offline.

###### Returns [#returns-21]

`Promise`\<`void`\>

##### startScan() [#startscan]

```ts
startScan(): Promise<void>;
```

Asks for permission when needed, then scans whenever the adapter is on, until `stopScan`.

###### Returns [#returns-22]

`Promise`\<`void`\>

###### Throws [#throws-2]

BluetoothError `permission-denied` when permission is not granted; `runtime-disposed` after `dispose`.

##### stopRecording() [#stoprecording]

```ts
stopRecording(deviceId): Promise<void>;
```

Stops the recording a connected recorder holds open, for instance once the user confirms it while
its `recording.leadOffSince` is set. The stored recording then arrives as a reading.

###### Parameters [#parameters-9]

| Parameter | Type |
| ------ | ------ |
| `deviceId` | `string` |

###### Returns [#returns-23]

`Promise`\<`void`\>

###### Throws [#throws-3]

BluetoothError `no-open-recording` when the device holds none; `runtime-disposed` after `dispose`.

##### stopScan() [#stopscan]

```ts
stopScan(): void;
```

Stops scanning; connected devices stay connected.

###### Returns [#returns-24]

`void`

##### subscribe() [#subscribe]

```ts
subscribe(listener): () => void;
```

Calls `listener` after every state change; returns the unsubscribe.

###### Parameters [#parameters-10]

| Parameter | Type |
| ------ | ------ |
| `listener` | () => `void` |

###### Returns [#returns-25]

() => `void`

##### subscribeWaveform() [#subscribewaveform]

```ts
subscribeWaveform(listener): () => void;
```

Calls `listener` with the live ECG samples of recording devices, for display; returns the unsubscribe.

###### Parameters [#parameters-11]

| Parameter | Type |
| ------ | ------ |
| `listener` | (`waveform`) => `void` |

###### Returns [#returns-26]

() => `void`

##### syncHistory() [#synchistory]

```ts
syncHistory(deviceId): Promise<void>;
```

Reads the records a device stored, connecting it first when it is not connected. One that
`readsHistoryOnRequest` reads them over its connection, even while it measures; any other is
reconnected, since it reads them each time it connects.

###### Parameters [#parameters-12]

| Parameter | Type |
| ------ | ------ |
| `deviceId` | `string` |

###### Returns [#returns-27]

`Promise`\<`void`\>

###### Throws [#throws-4]

BluetoothError as `connect` does; `runtime-disposed` after `dispose`.

## Functions [#functions]

### acceptedMemorySlots() [#acceptedmemoryslots]

```ts
function acceptedMemorySlots(slots): ResultPolicy;
```

Keeps the readings of the device users in `slots` (a multi-user device reports its user as `memorySlot`, starting at
1), and drops the others. A reading that names no device user is kept.

#### Parameters [#parameters-13]

| Parameter | Type |
| ------ | ------ |
| `slots` | readonly `number`[] |

#### Returns [#returns-28]

[`ResultPolicy`](#resultpolicy-2)

***

### bleManagerScanner() [#blemanagerscanner]

```ts
function bleManagerScanner(bleManager): BluetoothScanner;
```

A scanner over a `react-native-ble-plx` `BleManager`.

#### Parameters [#parameters-14]

| Parameter | Type |
| ------ | ------ |
| `bleManager` | `BleManager` |

#### Returns [#returns-29]

[`BluetoothScanner`](#bluetoothscanner)

***

### builtInDevices() [#builtindevices]

```ts
function builtInDevices(accepted, __namedParameters?): DeviceSupport;
```

Support for the SDK's integrated devices and `defineCustomDevice` declarations, over `react-native-ble-plx`.

#### Parameters [#parameters-15]

| Parameter | Type |
| ------ | ------ |
| `accepted` | readonly [`AcceptedDevice`](/native-sdk/reference/bt-management#accepteddevice)[] |
| `__namedParameters?` | [`BuiltInDevicesOptions`](#builtindevicesoptions) |

#### Returns [#returns-30]

[`DeviceSupport`](#devicesupport)

***

### createBluetoothRuntime() [#createbluetoothruntime]

```ts
function createBluetoothRuntime(__namedParameters): BluetoothRuntime;
```

A `BluetoothRuntime` wired for React Native: BLE through `bleManager`, OS permissions, saving through `client`.

#### Parameters [#parameters-16]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | [`CreateBluetoothRuntimeOptions`](#createbluetoothruntimeoptions) |

#### Returns [#returns-31]

[`BluetoothRuntime`](#bluetoothruntime)

***

### defineDevice() [#definedevice]

```ts
function defineDevice(__namedParameters): DeviceSupport;
```

Support for one device a third party defines with its own protocol.

#### Parameters [#parameters-17]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | [`DeviceDefinition`](#devicedefinition) |

#### Returns [#returns-32]

[`DeviceSupport`](#devicesupport)

***

### keepReadings() [#keepreadings]

```ts
function keepReadings(events, policy): AsyncIterable<DeviceEvent>;
```

A driver's events minus the readings `policy` drops.

#### Parameters [#parameters-18]

| Parameter | Type |
| ------ | ------ |
| `events` | `AsyncIterable`\<[`DeviceEvent`](#deviceevent)\> |
| `policy` | [`ResultPolicy`](#resultpolicy-2) |

#### Returns [#returns-33]

`AsyncIterable`\<[`DeviceEvent`](#deviceevent)\>

***

### osBluetoothPermissions() [#osbluetoothpermissions]

```ts
function osBluetoothPermissions(): BluetoothPermissions;
```

The platform's Bluetooth permissions through `react-native-permissions`.

#### Returns [#returns-34]

[`BluetoothPermissions`](#bluetoothpermissions)

***

### ovokReadingSink() [#ovokreadingsink]

```ts
function ovokReadingSink(client): ReadingSink;
```

Saves readings for the signed-in account through the `Ovok` measurements API.

#### Parameters [#parameters-19]

| Parameter | Type |
| ------ | ------ |
| `client` | `Pick`\<`Ovok`, `"measurements"`\> |

#### Returns [#returns-35]

[`ReadingSink`](#readingsink)

***

### policyByKind() [#policybykind]

```ts
function policyByKind(policies, fallback?): ResultPolicy;
```

Applies a policy per measurement type, and `fallback` to the other types.

#### Parameters [#parameters-20]

| Parameter | Type | Default value |
| ------ | ------ | ------ |
| `policies` | `Partial`\<`Record`\<`MeasurementTypeKey`, [`ResultPolicy`](#resultpolicy-2)\>\> | `undefined` |
| `fallback?` | [`ResultPolicy`](#resultpolicy-2) | `everyReading` |

#### Returns [#returns-36]

[`ResultPolicy`](#resultpolicy-2)

## Interfaces [#interfaces]

### BluetoothDevicePickerProps [#bluetoothdevicepickerprops]

Props of [BluetoothDevicePicker](#bluetoothdevicepicker).

#### Extends [#extends-1]

- [`OvokUiProps`](/native-sdk/reference/ui#ovokuiprops)

#### Properties [#properties-1]

| Property | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ |
| <a id="property-dismisslabel"></a> `dismissLabel?` | `string` | Dismiss button label; defaults to "Not now". | - |
| <a id="property-getdeviceimage"></a> `getDeviceImage?` | (`device`) => `string` \| `undefined` | Returns an image URI for a device, shown in its default row. | - |
| <a id="property-labelfordevice"></a> `labelForDevice?` | (`device`) => `string` | Returns the display name of a device; defaults to its advertised name. | - |
| <a id="property-ondismiss"></a> `onDismiss?` | () => `void` | Called when the user dismisses the picker; the dismiss button only renders when provided. | - |
| <a id="property-onselect"></a> `onSelect?` | (`device`) => `void` | Called with the picked device once the connection starts; its outcome shows on `device.connection`. | - |
| <a id="property-renderrow"></a> `renderRow?` | (`device`, `actions`) => `ReactNode` | Renders a custom row; return `undefined` to fall back to the default row. | - |
| <a id="property-slots"></a> `slots?` | `Partial`\<[`OvokUiSlots`](/native-sdk/reference/ui#ovokuislots)\> | Replace individual primitives without forking an SDK component. | [`OvokUiProps`](/native-sdk/reference/ui#ovokuiprops).[`slots`](/native-sdk/reference/ui#property-slots-9) |
| <a id="property-testid"></a> `testID?` | `string` | Test identifier of the modal; the backdrop gets the `-backdrop` suffix. | - |
| <a id="property-theme"></a> `theme?` | [`OvokThemeOverride`](/native-sdk/reference/ui#ovokthemeoverride) | A partial theme is merged with the active react-native-paper theme. | [`OvokUiProps`](/native-sdk/reference/ui#ovokuiprops).[`theme`](/native-sdk/reference/ui#property-theme-9) |
| <a id="property-title"></a> `title?` | `string` | Heading text; defaults to "Choose a device". | - |
| <a id="property-visible"></a> `visible` | `boolean` | Whether the picker is shown. | - |

***

### BluetoothPermissions [#bluetoothpermissions]

The OS permission prompts Bluetooth needs.

#### Methods [#methods-1]

##### check() [#check]

```ts
check(): Promise<BluetoothPermission>;
```

The current permission, without prompting.

###### Returns [#returns-37]

`Promise`\<[`BluetoothPermission`](#bluetoothpermission)\>

##### openSettings() [#opensettings]

```ts
openSettings(): Promise<void>;
```

Opens the app's system settings, where a blocked permission can be granted.

###### Returns [#returns-38]

`Promise`\<`void`\>

##### request() [#request]

```ts
request(): Promise<BluetoothPermission>;
```

Prompts for the permission when the OS still can, and resolves to the outcome.

###### Returns [#returns-39]

`Promise`\<[`BluetoothPermission`](#bluetoothpermission)\>

***

### BluetoothScanner [#bluetoothscanner]

The BLE adapter as the runtime uses it: its state and scanning.

#### Extended by [#extended-by]

- [`WebBluetoothScanner`](/native-sdk/reference/next-bluetooth-web#webbluetoothscanner)

#### Methods [#methods-2]

##### scan() [#scan]

```ts
scan(onFound, onError): () => void;
```

Reports peripherals until the returned stop is called; `onError` may be called before `scan` returns.

###### Parameters [#parameters-21]

| Parameter | Type |
| ------ | ------ |
| `onFound` | (`peripheral`) => `void` |
| `onError` | (`error`) => `void` |

###### Returns [#returns-40]

() => `void`

##### watchState() [#watchstate]

```ts
watchState(listener): () => void;
```

Reports the adapter state now and on every change; returns the unsubscribe.

###### Parameters [#parameters-22]

| Parameter | Type |
| ------ | ------ |
| `listener` | (`state`) => `void` |

###### Returns [#returns-41]

() => `void`

***

### DeviceSupport [#devicesupport]

Recognises peripherals by their advertisement.

#### Methods [#methods-3]

##### match() [#match]

```ts
match(advertisement): DeviceMatch | undefined;
```

The match for a peripheral this support handles, or `undefined`.

###### Parameters [#parameters-23]

| Parameter | Type |
| ------ | ------ |
| `advertisement` | [`Advertisement`](#advertisement) |

###### Returns [#returns-42]

[`DeviceMatch`](#devicematch) \| `undefined`

***

### ReadingSink [#readingsink]

Where readings are saved.

#### Methods [#methods-4]

##### flushQueued() [#flushqueued]

```ts
flushQueued(): Promise<readonly string[]>;
```

Retries the queued readings; resolves to the queue IDs now saved.

###### Returns [#returns-43]

`Promise`\<readonly `string`[]\>

##### save() [#save]

```ts
save(reading): Promise<SaveResult>;
```

Saves one reading, or queues it offline; the same reading may be saved again after a failure.

###### Parameters [#parameters-24]

| Parameter | Type |
| ------ | ------ |
| `reading` | [`DeviceReading`](#devicereading) |

###### Returns [#returns-44]

`Promise`\<[`SaveResult`](#saveresult)\>

## Type Aliases [#type-aliases]

### AdapterState [#adapterstate]

```ts
type AdapterState = "unknown" | "on" | "off" | "unauthorized" | "unsupported";
```

Bluetooth adapter state; `unknown` until the platform reports it.

***

### Advertisement [#advertisement]

```ts
type Advertisement = object;
```

What a scanned peripheral advertises.

#### Properties [#properties-2]

##### manufacturerData [#manufacturerdata]

```ts
manufacturerData: string | null;
```

Advertised manufacturer data, base64 encoded, or `null`.

##### name [#name]

```ts
name: string;
```

Advertised name, or the iOS local name when the name is not known yet; empty when neither is.

##### serviceUUIDs [#serviceuuids]

```ts
serviceUUIDs: readonly string[];
```

Advertised service UUIDs.

***

### BluetoothErrorCode [#bluetootherrorcode]

```ts
type BluetoothErrorCode =
  | "permission-denied"
  | "powered-off"
  | "unsupported"
  | "scan-failed"
  | "connection-failed"
  | "pairing-required"
  | "discovery-failed"
  | "device-error"
  | "frame-invalid"
  | "measurement-failed"
  | "device-not-found"
  | "no-open-recording"
  | "runtime-disposed"
  | "save-failed"
  | "unknown";
```

Why a Bluetooth operation failed.

***

### BluetoothPermission [#bluetoothpermission]

```ts
type BluetoothPermission = "granted" | "denied" | "blocked";
```

Whether the app may use Bluetooth; `blocked` means only the system settings can grant it.

***

### BluetoothProviderProps [#bluetoothproviderprops]

```ts
type BluetoothProviderProps = React.PropsWithChildren<{
  androidForegroundService?: AndroidBluetoothForegroundServiceOptions;
  onForegroundServiceError?: (error) => void;
  runtime: BluetoothRuntime;
}>;
```

Props of [BluetoothProvider](#bluetoothprovider).

***

### BluetoothRuntimeOptions [#bluetoothruntimeoptions]

```ts
type BluetoothRuntimeOptions = object;
```

What a `BluetoothRuntime` is built from.

#### Properties [#properties-3]

##### devices [#devices]

```ts
devices: readonly DeviceSupport[];
```

The devices to look for; the first support that matches a peripheral handles it.

##### pairedStorage? [#pairedstorage]

```ts
pairedStorage?: OvokStorage;
```

Where the paired device IDs persist; without it pairing lasts until the runtime is disposed.

##### permissions [#permissions]

```ts
permissions: BluetoothPermissions;
```

The OS permission prompts.

##### resultPolicy? [#resultpolicy]

```ts
resultPolicy?: ResultPolicy;
```

Which readings of a connection to keep; defaults to every reading.

##### scanner [#scanner]

```ts
scanner: BluetoothScanner;
```

The BLE adapter.

##### sink [#sink]

```ts
sink: ReadingSink;
```

Where readings are saved.

***

### BluetoothSnapshot [#bluetoothsnapshot]

```ts
type BluetoothSnapshot = object;
```

Everything the runtime knows, replaced (never mutated) on each change.

#### Properties [#properties-4]

##### adapter [#adapter]

```ts
adapter: AdapterState;
```

Bluetooth adapter state.

##### devices [#devices-1]

```ts
devices: readonly NearbyDevice[];
```

Supported peripherals found, in discovery order.

##### paired [#paired]

```ts
paired: readonly string[];
```

IDs of the paired devices, which connect whenever the scan finds them.

##### permission [#permission]

```ts
permission: BluetoothPermission | "unknown";
```

Bluetooth permission; `unknown` until first checked.

##### readings [#readings]

```ts
readings: readonly DeviceReading[];
```

Recent readings, oldest first.

##### scanError [#scanerror]

```ts
scanError: BluetoothError | null;
```

The last scan error, or `null`; cleared when a scan starts.

##### scanning [#scanning]

```ts
scanning: boolean;
```

Whether a scan is requested; it runs whenever the adapter is on.

***

### BuiltInDevicesOptions [#builtindevicesoptions]

```ts
type BuiltInDevicesOptions = object;
```

Options for `builtInDevices`.

#### Properties [#properties-5]

##### recordCursorStorage? [#recordcursorstorage]

```ts
recordCursorStorage?: OvokStorage;
```

Where a device that hands over its stored records remembers which it already handed over, so the next connection
reads only the others, such as the stored files of a Viatom ER1 or BP2 whose readings were saved or queued.
Without it every connection reads them all.

***

### ConnectionState [#connectionstate]

```ts
type ConnectionState =
  | "idle"
  | "connecting"
  | "connected"
  | "measuring"
  | "disconnected"
  | "failed";
```

Where a device's connection stands.

***

### CreateBluetoothRuntimeOptions [#createbluetoothruntimeoptions]

```ts
type CreateBluetoothRuntimeOptions = object;
```

What `createBluetoothRuntime` needs.

#### Properties [#properties-6]

##### bleManager [#blemanager]

```ts
bleManager: BleManager;
```

The app's `react-native-ble-plx` manager.

##### client [#client]

```ts
client: Ovok;
```

Saves the readings and keeps the paired devices in its secure storage.

##### devices [#devices-2]

```ts
devices: readonly DeviceSupport[];
```

The devices to look for.

##### resultPolicy? [#resultpolicy-1]

```ts
resultPolicy?: ResultPolicy;
```

Which readings of a connection to keep; defaults to every reading.

***

### DeviceDefinition [#devicedefinition]

```ts
type DeviceDefinition = object;
```

A device a third party adds: how to recognise it and the protocol that reads it.

#### Properties [#properties-7]

##### key [#key]

```ts
key: string;
```

Device key reported on its readings; unique among the devices a runtime supports.

##### matches [#matches]

```ts
matches: (advertisement) => boolean;
```

Whether an advertisement is this device.

###### Parameters [#parameters-25]

| Parameter | Type |
| ------ | ------ |
| `advertisement` | [`Advertisement`](#advertisement) |

###### Returns [#returns-45]

`boolean`

##### protocol [#protocol]

```ts
protocol: DeviceProtocol;
```

The conversation that turns the device's bytes into readings; give each stored reading its `recordedAt`.

***

### DeviceEvent [#deviceevent]

```ts
type DeviceEvent =
  | {
  kind: "status";
  status: "connected" | "measuring" | "disconnected";
}
  | {
  information: DeviceInformation;
  kind: "information";
}
  | {
  delivered?: () => void;
  id: string | null;
  kind: "reading";
  reading: Measurement;
}
  | {
  kind: "recording";
  recording: DeviceRecording | null;
  stop: () => Promise<void>;
}
  | {
  kind: "history";
  sync: () => Promise<void>;
}
  | {
  kind: "waveform";
  waveform: Omit<DeviceWaveform, "deviceId">;
}
  | {
  error: BluetoothError;
  kind: "error";
};
```

What a driver reports while it runs.

#### Union Members [#union-members]

##### Type Literal [#type-literal]

```ts
{
  kind: "status";
  status: "connected" | "measuring" | "disconnected";
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `kind` | `"status"` | The connection moved on. |
| `status` | `"connected"` \| `"measuring"` \| `"disconnected"` | Where it stands now. |

***

##### Type Literal [#type-literal-1]

```ts
{
  information: DeviceInformation;
  kind: "information";
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `information` | [`DeviceInformation`](#deviceinformation) | What it reported. |
| `kind` | `"information"` | The device reported who made it, which model it is and its serial number. |

***

##### Type Literal [#type-literal-2]

```ts
{
  delivered?: () => void;
  id: string | null;
  kind: "reading";
  reading: Measurement;
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `delivered()?` | () => `void` | Called once the reading is saved or queued, so a device can skip the stored record it came from. |
| `id` | `string` \| `null` | Names the reading so a resend is recognised; `null` when it has none, and then it is never deduplicated. |
| `kind` | `"reading"` | The device sent a reading. |
| `reading` | `Measurement` | The decoded reading. |

***

##### Type Literal [#type-literal-3]

```ts
{
  kind: "recording";
  recording: DeviceRecording | null;
  stop: () => Promise<void>;
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `kind` | `"recording"` | The recording the device holds open changed. |
| `recording` | [`DeviceRecording`](#devicerecording) \| `null` | The open recording, or `null` once it has closed. |
| `stop()` | () => `Promise`\<`void`\> | Stops the open recording. |

***

##### Type Literal [#type-literal-4]

```ts
{
  kind: "history";
  sync: () => Promise<void>;
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `kind` | `"history"` | The device keeps the records it stored until asked for them, so connecting does not read them. |
| `sync()` | () => `Promise`\<`void`\> | Reads the records the device stored. |

***

##### Type Literal [#type-literal-5]

```ts
{
  kind: "waveform";
  waveform: Omit<DeviceWaveform, "deviceId">;
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `kind` | `"waveform"` | The device sent live ECG samples while recording; for display only. |
| `waveform` | `Omit`\<[`DeviceWaveform`](#devicewaveform), `"deviceId"`\> | The samples, without the device, which the runtime adds. |

***

##### Type Literal [#type-literal-6]

```ts
{
  error: BluetoothError;
  kind: "error";
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `error` | [`BluetoothError`](#bluetootherror) | The error. |
| `kind` | `"error"` | The device or its protocol reported an error; the connection may continue. |

***

### DeviceInformation [#deviceinformation]

```ts
type DeviceInformation = object;
```

What a device's Device Information service reports about it; a field is absent when the device leaves it out.

#### Properties [#properties-8]

##### manufacturerName? [#manufacturername]

```ts
manufacturerName?: string;
```

Manufacturer Name String.

##### model? [#model]

```ts
model?: string;
```

Model Number String.

##### serialNumber? [#serialnumber]

```ts
serialNumber?: string;
```

Serial Number String.

***

### DeviceMatch [#devicematch]

```ts
type DeviceMatch = object;
```

A peripheral a support recognised: the device key its readings carry and the driver that runs it.

#### Properties [#properties-9]

##### driver [#driver]

```ts
driver: Driver;
```

The driver that talks to it.

##### key [#key-1]

```ts
key: string;
```

Device key reported on its readings.

***

### DeviceProtocol [#deviceprotocol]

```ts
type DeviceProtocol = (link) => AsyncIterable<Measurement>;
```

One device's conversation over a link, as the readings it produces.

#### Parameters [#parameters-26]

| Parameter | Type |
| ------ | ------ |
| `link` | [`Link`](#link) |

#### Returns [#returns-46]

`AsyncIterable`\<`Measurement`\>

***

### DeviceReading [#devicereading]

```ts
type DeviceReading = object;
```

A reading a device sent, and whether it has been saved.

#### Properties [#properties-10]

##### device [#device]

```ts
device: Pick<NearbyDevice, "id" | "key" | "name" | "information">;
```

The device that sent it.

##### id [#id]

```ts
id: string;
```

Unique; the same for every resend of a stored reading that carries its time.

##### measurement [#measurement]

```ts
measurement: Measurement;
```

The decoded measurement.

##### receivedAt [#receivedat]

```ts
receivedAt: Date;
```

When the app received it.

##### save [#save-1]

```ts
save: SaveState;
```

Where saving it stands.

***

### DeviceRecording [#devicerecording]

```ts
type DeviceRecording = object;
```

A recording a recorder holds open, as its last realtime answer reported it.

#### Properties [#properties-11]

##### leadOffSince? [#leadoffsince]

```ts
leadOffSince?: Date;
```

When the electrodes lost contact, while they have none; the recording stays open until it is
stopped. An app can offer `stopRecording` once this is old enough, as the vendor app does.

##### seconds [#seconds]

```ts
seconds: number;
```

Seconds recorded so far, as of the last change.

##### storesOnStop [#storesonstop]

```ts
storesOnStop: boolean;
```

Stopping now stores the recording; a shorter one is discarded by the device.

***

### DeviceWaveform [#devicewaveform]

```ts
type DeviceWaveform = object;
```

The ECG samples a recording device sent in one realtime answer, for drawing a live trace; never saved.

#### Properties [#properties-12]

##### at [#at]

```ts
at: Date;
```

When the answer carrying them arrived.

##### deviceId [#deviceid]

```ts
deviceId: string;
```

Platform identifier of the device.

##### millivoltsPerCount [#millivoltspercount]

```ts
millivoltsPerCount: number;
```

Millivolts per sample count.

##### sampleRateHz [#sampleratehz]

```ts
sampleRateHz: number;
```

Samples per second.

##### samples [#samples]

```ts
samples: readonly number[];
```

Raw sample counts, oldest first.

***

### Driver [#driver-1]

```ts
type Driver = (peripheral, signal) => AsyncIterable<DeviceEvent>;
```

Connects to a peripheral and reports what happens until it disconnects or `signal` aborts.

#### Parameters [#parameters-27]

| Parameter | Type |
| ------ | ------ |
| `peripheral` | [`Peripheral`](#peripheral) |
| `signal` | `AbortSignal` |

#### Returns [#returns-47]

`AsyncIterable`\<[`DeviceEvent`](#deviceevent)\>

***

### Link [#link]

```ts
type Link = object;
```

An open GATT connection: bytes in, bytes out, no knowledge of any device.

#### Methods [#methods-5]

##### close() [#close]

```ts
close(): Promise<void>;
```

Ends every subscription and disconnects.

###### Returns [#returns-48]

`Promise`\<`void`\>

##### subscribe() [#subscribe-1]

```ts
subscribe(service, characteristic): AsyncIterable<Uint8Array<ArrayBufferLike>>;
```

Notified or indicated values until the connection drops.

###### Parameters [#parameters-28]

| Parameter | Type |
| ------ | ------ |
| `service` | `string` |
| `characteristic` | `string` |

###### Returns [#returns-49]

`AsyncIterable`\<`Uint8Array`\<`ArrayBufferLike`\>\>

##### write() [#write]

```ts
write(
   service,
   characteristic,
   bytes
): Promise<void>;
```

Writes bytes to a characteristic, with response.

###### Parameters [#parameters-29]

| Parameter | Type |
| ------ | ------ |
| `service` | `string` |
| `characteristic` | `string` |
| `bytes` | `Uint8Array` |

###### Returns [#returns-50]

`Promise`\<`void`\>

#### Properties [#properties-13]

##### deviceInformation? [#deviceinformation-1]

```ts
readonly deviceInformation?: DeviceInformation;
```

What the device reported about itself when the link opened; absent when the link did not read it.

***

### NearbyDevice [#nearbydevice]

```ts
type NearbyDevice = object;
```

A supported peripheral the scan found.

#### Properties [#properties-14]

##### connection [#connection]

```ts
connection: ConnectionState;
```

Its connection state.

##### error [#error]

```ts
error: BluetoothError | null;
```

The last error its connection reported, or `null`.

##### id [#id-1]

```ts
id: string;
```

Platform identifier of the peripheral.

##### information? [#information]

```ts
information?: DeviceInformation;
```

What the device reported about itself on its last connection; absent until it has connected.

##### key [#key-2]

```ts
key: string;
```

Device key its support identified it as.

##### name [#name-1]

```ts
name: string;
```

Name it advertised.

##### readsHistoryOnRequest? [#readshistoryonrequest]

```ts
readsHistoryOnRequest?: boolean;
```

True once connected for a device that reads the records it stored only on `syncHistory`, which
it may do while it measures; any other reads them each time it connects.

##### recording? [#recording]

```ts
recording?: DeviceRecording;
```

The recording the device holds open, for recorders that report one; absent when none is open.

***

### Peripheral [#peripheral]

```ts
type Peripheral = object;
```

A peripheral a scan found, and the way to open a connection to it.

#### Methods [#methods-6]

##### openLink() [#openlink]

```ts
openLink(signal): Promise<Link>;
```

Connects and discovers its services; aborting `signal` closes the link.

###### Parameters [#parameters-30]

| Parameter | Type |
| ------ | ------ |
| `signal` | `AbortSignal` |

###### Returns [#returns-51]

`Promise`\<[`Link`](#link)\>

#### Properties [#properties-15]

##### advertisement [#advertisement-1]

```ts
advertisement: Advertisement;
```

What it advertised.

##### id [#id-2]

```ts
id: string;
```

Platform identifier of the peripheral.

***

### ResultPolicy [#resultpolicy-2]

```ts
type ResultPolicy = () => (reading) => boolean;
```

Makes, for each connection, the test of which readings to keep.

#### Returns [#returns-52]

(`reading`) => `boolean`

***

### SaveResult [#saveresult]

```ts
type SaveResult =
  | {
  status: "saved";
}
  | {
  queueId: string;
  status: "queued";
};
```

How a sink took a reading.

#### Union Members [#union-members-1]

##### Type Literal [#type-literal-7]

```ts
{
  status: "saved";
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `status` | `"saved"` | Saved. |

***

##### Type Literal [#type-literal-8]

```ts
{
  queueId: string;
  status: "queued";
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `queueId` | `string` | Names the reading in the queue. |
| `status` | `"queued"` | Kept offline until `flushQueued` saves it. |

***

### SaveState [#savestate]

```ts
type SaveState =
  | {
  status: "saving";
}
  | {
  status: "saved";
}
  | {
  queueId: string;
  status: "queued";
}
  | {
  error: BluetoothError;
  status: "failed";
};
```

Where saving a reading stands.

#### Union Members [#union-members-2]

##### Type Literal [#type-literal-9]

```ts
{
  status: "saving";
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `status` | `"saving"` | The sink has not answered yet. |

***

##### Type Literal [#type-literal-10]

```ts
{
  status: "saved";
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `status` | `"saved"` | Saved. |

***

##### Type Literal [#type-literal-11]

```ts
{
  queueId: string;
  status: "queued";
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `queueId` | `string` | Names the queued reading in the sink's queue. |
| `status` | `"queued"` | Kept offline by the sink until a flush saves it. |

***

##### Type Literal [#type-literal-12]

```ts
{
  error: BluetoothError;
  status: "failed";
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `error` | [`BluetoothError`](#bluetootherror) | Why, with code `save-failed`. |
| `status` | `"failed"` | The sink could not save or queue it; `retrySaves` tries again. |

## Variables [#variables]

### dailyTotalsOnly [#dailytotalsonly]

```ts
const dailyTotalsOnly: ResultPolicy;
```

Activity totals count only once their day has closed, and each day only once.

***

### everyReading [#everyreading]

```ts
const everyReading: ResultPolicy;
```

Keeps every reading.

***

### firstReadingPerKind [#firstreadingperkind]

```ts
const firstReadingPerKind: ResultPolicy;
```

Keeps the first reading of each measurement type per connection.

***

### SIG\_PROTOCOLS [#sig_protocols]

```ts
const SIG_PROTOCOLS: ReadonlyMap<string, DeviceProtocol>;
```

By the ids the SDK catalog gives the Bluetooth SIG profiles.

## References [#references]

### AcceptedDevice [#accepteddevice]

Re-exports [AcceptedDevice](/native-sdk/reference/bt-management#accepteddevice)

***

### IntegratedDevices [#integrateddevices]

Re-exports [IntegratedDevices](/native-sdk/reference/bt-management#integrateddevices)
