# @ovok/native/bt-management

Canonical page: https://docs.ovok.com/native-sdk/reference/bt-management

Bluetooth Low Energy device management: scanning, pairing, connecting, reading measurements and syncing them.

Import from `@ovok/native/bt-management`.

## Components [#components]

### BluetoothDevicePicker() [#bluetoothdevicepicker]

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

A theme-aware picker for BTManager's multi-device auto-connect callback.

#### Parameters [#parameters]

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

#### Returns [#returns]

`Element`

***

### BluetoothRuntimeProvider() [#bluetoothruntimeprovider]

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

Provides a `BluetoothRuntime` to the Bluetooth hooks below it.

#### Parameters [#parameters-1]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `PropsWithChildren`\<\{ `runtime`: [`BluetoothRuntime`](#bluetoothruntime); \}\> |

#### Returns [#returns-1]

`Element`

***

### BTProvider() [#btprovider]

```ts
function BTProvider<T>(__namedParameters):
  | string
  | number
  | bigint
  | boolean
  | Iterable<ReactNode, any, any>
  | Promise<AwaitedReactNode>
  | Element
  | null
  | undefined;
```

Provides Bluetooth management to its children, optionally requesting permission on mount and
gating the children behind it.

#### Type Parameters [#type-parameters]

| Type Parameter |
| ------ |
| <a id="type-parameter-t-11"></a> `T` *extends* readonly [`AcceptedDevice`](#accepteddevice)[] |

#### Parameters [#parameters-2]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `PropsWithChildren`\<[`BTProviderProps`](#btproviderprops)\<`T`\>\> |

#### Returns [#returns-2]

  \| `string`
  \| `number`
  \| `bigint`
  \| `boolean`
  \| `Iterable`\<`ReactNode`, `any`, `any`\>
  \| `Promise`\<`AwaitedReactNode`\>
  \| `Element`
  \| `null`
  \| `undefined`

***

### DefaultPermissionFallback() [#defaultpermissionfallback]

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

Default screen shown when Bluetooth permission is denied or blocked, with a button to request
access or open settings.

#### Parameters [#parameters-3]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | [`BTProviderPermissionFallbackProps`](#btproviderpermissionfallbackprops) |

#### Returns [#returns-3]

`Element`

## Hooks [#hooks]

### useBackgroundSync() [#usebackgroundsync]

```ts
function useBackgroundSync(__namedParameters?): object;
```

Turns background Bluetooth sync on or off and reports its status.

#### Parameters [#parameters-4]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters?` | [`UseBackgroundSyncOptions`](#usebackgroundsyncoptions) |

#### Returns [#returns-4]

| Name | Type | Description |
| ------ | ------ | ------ |
| `enabled` | `boolean` | Whether background sync is on. |
| `error?` | `Error` | Error from the last attempt to change the state. |
| `flush()` | () => `Promise`\<`void`\> | Delivers queued background results now. |
| `reason?` | `string` | Why sync is restricted, when it is. |
| `setEnabled()` | (`enabled`) => `Promise`\<`void`\> | Turns background sync on or off. |
| `status` | [`BackgroundSyncStatus`](#backgroundsyncstatus) | Current sync status. |

***

### useBluetoothPermission() [#usebluetoothpermission]

```ts
function useBluetoothPermission(__namedParameters?): object;
```

Tracks Bluetooth permission and requests it, again when the app resumes from settings.

#### Parameters [#parameters-5]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters?` | [`UseBluetoothPermissionOptions`](#usebluetoothpermissionoptions) |

#### Returns [#returns-5]

| Name | Type | Default value | Description |
| ------ | ------ | ------ | ------ |
| `accessPermission` | `boolean` \| `undefined` | - | Whether permission is granted; `undefined` until known. |
| `openSettings()` | () => `void` | - | Opens the system settings for the app. |
| `request()` | () => `Promise`\<`boolean`\> | - | Asks the user for Bluetooth permission. |
| `requestPermission()` | () => `Promise`\<`boolean`\> | `request` | Alias of `request`. |
| `status` | [`BluetoothPermissionStatus`](#bluetoothpermissionstatus) | - | Current permission status. |

***

### useBluetoothRuntime() [#usebluetoothruntime]

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

Returns the runtime of the enclosing `BTProvider`.

#### Returns [#returns-6]

[`BluetoothRuntime`](#bluetoothruntime)

#### Throws [#throws]

If rendered outside `BTProvider`.

***

### useBluetoothSelector() [#usebluetoothselector]

```ts
function useBluetoothSelector<Selection>(selector, isEqual?): Selection;
```

Subscribes to a slice of the runtime state, re-rendering only when it changes by `isEqual`.

#### Type Parameters [#type-parameters-1]

| Type Parameter |
| ------ |
| <a id="type-parameter-selection"></a> `Selection` |

#### Parameters [#parameters-6]

| Parameter | Type | Default value |
| ------ | ------ | ------ |
| `selector` | (`snapshot`) => `Selection` | `undefined` |
| `isEqual?` | (`previous`, `next`) => `boolean` | `Object.is` |

#### Returns [#returns-7]

`Selection`

***

### useBluetoothState() [#usebluetoothstate]

```ts
function useBluetoothState(__namedParameters?): object;
```

Reports whether Bluetooth is usable, folding permission status into the adapter state.

#### Parameters [#parameters-7]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters?` | [`UseBluetoothStateOptions`](#usebluetoothstateoptions) |

#### Returns [#returns-8]

| Name | Type | Description |
| ------ | ------ | ------ |
| `openSettings()` | () => `void` | Opens the system settings for the app. |
| `permissionStatus` | [`BluetoothPermissionStatus`](#bluetoothpermissionstatus) | Current permission status. |
| `requestPermission()` | () => `Promise`\<`boolean`\> | Asks the user for Bluetooth permission. |
| `state` | [`BluetoothState`](#bluetoothstate) | Adapter state; `unauthorized` when permission is denied or blocked. |

***

### useBTDevice() [#usebtdevice]

```ts
function useBTDevice<Filter>(filter, __namedParameters?): object;
```

Follows and controls one device matched by a model key or filter.

#### Type Parameters [#type-parameters-2]

| Type Parameter |
| ------ |
| <a id="type-parameter-filter"></a> `Filter` *extends* [`BTDeviceFilter`](#btdevicefilter) |

#### Parameters [#parameters-8]

| Parameter | Type |
| ------ | ------ |
| `filter` | `Filter` |
| `__namedParameters?` | [`UseBTDeviceOptions`](#usebtdeviceoptions) |

#### Returns [#returns-9]

| Name | Type | Default value | Description |
| ------ | ------ | ------ | ------ |
| `connect()` | () => `Promise`\<`void`\> | - | Connects to the selected device. |
| `device` | [`RuntimeDevice`](#runtimedevice) \| `undefined` | `selected` | The selected device, if any. |
| `devices` | readonly [`RuntimeDevice`](#runtimedevice)[] | `matches` | Every device matching the filter. |
| `disconnect()` | () => `Promise`\<`void`\> | - | Disconnects from the selected device. |
| `events` | readonly [`DeviceConnectionEvent`](#deviceconnectionevent)[] | - | Recent connection events of the selected device. |
| `latestResult` | [`RuntimeResult`](#runtimeresult) \| `undefined` | `selected.latestResult` | Most recent result of the selected device. |
| `model` | `Filter` *extends* [`DeviceKey`](#devicekey) ? `Filter` : `undefined` | - | Model key asked for; `undefined` for a filter. |
| `raw` | [`RawBluetoothAccess`](#rawbluetoothaccess) \| `undefined` | - | Raw GATT access, when `allowRawAccess` is set. |
| `requiresSelection` | `boolean` | - | True when several devices match and none is selected. |
| `results` | readonly [`RuntimeResult`](#runtimeresult)[] | - | Recent results of the selected device. |
| `select()` | (`deviceId`) => `boolean` | - | Selects a device by ID. |
| `status` | [`DeviceStatus`](#devicestatus) \| `undefined` | `selected.status` | Status of the selected device. |

***

### useBTDevices() [#usebtdevices]

```ts
function useBTDevices(filter): readonly RuntimeDevice[];
```

Every connected or nearby device `filter` asks for, in the order Bluetooth found them.

#### Parameters [#parameters-9]

| Parameter | Type |
| ------ | ------ |
| `filter` | [`BTDeviceFilter`](#btdevicefilter) |

#### Returns [#returns-10]

readonly [`RuntimeDevice`](#runtimedevice)[]

***

### useDeviceConnection() [#usedeviceconnection]

```ts
function useDeviceConnection(id?): object;
```

Follows the status and connection events of one device.

#### Parameters [#parameters-10]

| Parameter | Type |
| ------ | ------ |
| `id?` | `string` |

#### Returns [#returns-11]

| Name | Type | Description |
| ------ | ------ | ------ |
| `events` | readonly [`DeviceConnectionEvent`](#deviceconnectionevent)[] | Recent connection events, oldest first. |
| `status?` | [`DeviceStatus`](#devicestatus) | Latest status of the device. |

***

### useHealthImport() [#usehealthimport]

```ts
function useHealthImport<TType>(__namedParameters): object;
```

Manages the health data import switch and the access status of the given types.

#### Type Parameters [#type-parameters-3]

| Type Parameter |
| ------ |
| <a id="type-parameter-ttype-1"></a> `TType` *extends* `string` |

#### Parameters [#parameters-11]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | \{ `adapter`: [`HealthImportAdapter`](#healthimportadapter)\<`TType`\>; `background?`: `boolean`; `types`: readonly `TType`[]; \} |
| `__namedParameters.adapter` | [`HealthImportAdapter`](#healthimportadapter)\<`TType`\> |
| `__namedParameters.background?` | `boolean` |
| `__namedParameters.types` | readonly `TType`[] |

#### Returns [#returns-12]

| Name | Type | Description |
| ------ | ------ | ------ |
| `enabled` | `boolean` | Whether import is switched on. |
| `error?` | `Error` | Error of the last status check or request. |
| `notShared` | readonly `TType`[] | Types the user has not shared. |
| `setEnabled()` | (`enabled`) => `Promise`\<`void`\> | Switches import on, requesting access first, or off. |
| `statusByType` | `Partial`\<`Record`\<`TType`, `Awaited`\<`ReturnType`\<[`HealthImportAdapter`](#healthimportadapter)\<`TType`\>\[`"getStatus"`\]\>\>\>\> | Access status per type. |

***

### useMeasurements() [#usemeasurements]

```ts
function useMeasurements(onResult?, __namedParameters?): object;
```

Collects results from every device, filtered by a result policy.

#### Parameters [#parameters-12]

| Parameter | Type |
| ------ | ------ |
| `onResult?` | (`result`) => `void` |
| `__namedParameters?` | [`UseMeasurementsOptions`](#usemeasurementsoptions) |

#### Returns [#returns-13]

| Name | Type | Description |
| ------ | ------ | ------ |
| `clear()` | () => `void` | Clears the collected results. |
| `measurements` | readonly [`RuntimeResult`](#runtimeresult)[] | Kept results, oldest first. |

***

### useNearbyDeviceOffer() [#usenearbydeviceoffer]

```ts
function useNearbyDeviceOffer(__namedParameters): object;
```

Offers a newly found, not yet paired nearby device to the user to accept, decline or postpone.

#### Parameters [#parameters-13]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | [`UseNearbyDeviceOfferOptions`](#usenearbydeviceofferoptions) |

#### Returns [#returns-14]

| Name | Type | Description |
| ------ | ------ | ------ |
| `accept()` | () => `Promise`\<`void`\> | Pairs the offered device and remembers it. |
| `decline()` | (`deviceId?`) => `Promise`\<`void`\> | Remembers a device as declined so it is not offered again. |
| `device?` | [`RuntimeDevice`](#runtimedevice) | Device currently offered. |
| `error?` | [`BluetoothError`](#bluetootherror) | Error from the last pairing attempt. |
| `later()` | () => `void` | Hides the current offer until the app restarts. |
| `status` | [`NearbyDeviceOfferStatus`](#nearbydeviceofferstatus) | Offer status. |
| `undecline()` | (`deviceId`) => `Promise`\<`void`\> | Forgets a declined device so it can be offered again. |

***

### useNearbyDevices() [#usenearbydevices]

```ts
function useNearbyDevices(): object;
```

Lists devices found by scanning and connects to one on request.

#### Returns [#returns-15]

| Name | Type | Description |
| ------ | ------ | ------ |
| `devices` | readonly [`RuntimeDevice`](#runtimedevice)[] | Devices currently found. |
| `pair()` | (`id`) => `Promise`\<[`RuntimeDevice`](#runtimedevice) \| `undefined`\> | Connects to the device with the given ID; resolves to it, or `undefined` if unknown. |

***

### useOpenSeries() [#useopenseries]

```ts
function useOpenSeries(manager): readonly OpenSeries[];
```

The series a `BTManager` is recording, updated as each value arrives: the live values to show while a device
streams (`latest`), before the series is stored.

#### Parameters [#parameters-14]

| Parameter | Type |
| ------ | ------ |
| `manager` | `SeriesSource` \| `undefined` |

#### Returns [#returns-16]

readonly [`OpenSeries`](#openseries)[]

***

### usePairedDevices() [#usepaireddevices]

```ts
function usePairedDevices(__namedParameters): object;
```

Keeps a persisted list of paired device IDs, optionally connecting to them automatically.

#### Parameters [#parameters-15]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | [`UsePairedDevicesOptions`](#usepaireddevicesoptions) |

#### Returns [#returns-17]

| Name | Type | Description |
| ------ | ------ | ------ |
| `forget()` | (`id`) => `Promise`\<`void`\> | Disconnects a device and removes it from the paired list. |
| `pair()` | (`device`) => `Promise`\<`void`\> | Adds a device to the paired list. |
| `paired` | readonly `string`[] | IDs of the paired devices. |

***

### useQueuedResults() [#usequeuedresults]

```ts
function useQueuedResults<T>(coordinator): readonly BackgroundSyncResult<T>[];
```

The results a `BackgroundSyncCoordinator` still holds for the current account: readings not saved yet.

#### Type Parameters [#type-parameters-4]

| Type Parameter |
| ------ |
| <a id="type-parameter-t-14"></a> `T` *extends* [`DeviceKey`](#devicekey) |

#### Parameters [#parameters-16]

| Parameter | Type |
| ------ | ------ |
| `coordinator` | `QueueSource`\<`T`\> \| `undefined` |

#### Returns [#returns-18]

readonly [`BackgroundSyncResult`](#backgroundsyncresult)\<`T`\>[]

***

### useRequestPermissions() [#userequestpermissions]

```ts
function useRequestPermissions(__namedParameters): object;
```

Requests Bluetooth permission for `BTProvider`, optionally on mount.

#### Parameters [#parameters-17]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | `Pick`\<[`BTProviderProps`](#btproviderprops)\<[`IntegratedDevices`](#integrateddevices)[]\>, `"onAccessPermissionChanged"` \| `"requestPermissionOnMount"`\> |

#### Returns [#returns-19]

| Name | Type | Default value | Description |
| ------ | ------ | ------ | ------ |
| `accessPermission` | `boolean` \| `undefined` | - | Whether permission is granted; `undefined` until known. |
| `openBleSetting()` | () => `void` | `openSettings` | Opens the system settings for the app. |
| `requestPermission()` | () => `Promise`\<`boolean`\> | - | Asks the user for Bluetooth permission. |
| `status` | [`BluetoothPermissionStatus`](#bluetoothpermissionstatus) | - | Current permission status. |

***

### useRuntimeEvent() [#useruntimeevent]

```ts
function useRuntimeEvent<K>(event, callback): void;
```

Listens for a runtime event for as long as the component is mounted.

#### Type Parameters [#type-parameters-5]

| Type Parameter |
| ------ |
| <a id="type-parameter-k-1"></a> `K` *extends* keyof [`RuntimeEventMap`](#runtimeeventmap) |

#### Parameters [#parameters-18]

| Parameter | Type |
| ------ | ------ |
| `event` | `K` |
| `callback` | (`value`) => `void` |

#### Returns [#returns-20]

`void`

***

### useScanControl() [#usescancontrol]

```ts
function useScanControl(): object;
```

Exposes scan pause/resume to apps using BTProvider.

#### Returns [#returns-21]

| Name | Type | Description |
| ------ | ------ | ------ |
| `canControl` | `boolean` | Whether a manager is available to control scanning. |
| `pauseScan()` | () => `void` | Pauses scanning. |
| `resumeScan()` | () => `void` | Resumes scanning. |

## Classes [#classes]

### A606CommandSequencer [#a606commandsequencer]

Decides what to send a device, and when.

These protocols are self-clocking: the device answers a request, and the answer is what
says which request comes next. A file read walks its offsets that way, and an identity
check gates everything after it on the reply to the first command. Neither can be
expressed by re-sending one fixed frame, which is all the SDK could do before.

At most one command is outstanding at a time. The transport serialises writes, so an
implementation may assume the frame it is answering is the reply to the command it last
returned.

#### Implements [#implements]

- [`CommandSequencer`](#commandsequencer)

#### Constructors [#constructors]

##### Constructor [#constructor]

```ts
new A606CommandSequencer(clockSync?): A606CommandSequencer;
```

###### Parameters [#parameters-19]

| Parameter | Type |
| ------ | ------ |
| `clockSync?` | [`ClockSyncOptions`](#clocksyncoptions) |

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

[`A606CommandSequencer`](#a606commandsequencer)

#### Methods [#methods]

##### initialCommands() [#initialcommands]

```ts
initialCommands(): readonly DeviceCommand[];
```

Sent once every characteristic is subscribed. Empty starts a device that only listens.

May resolve later, for a first command that depends on state read from storage.

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

readonly [`DeviceCommand`](#devicecommand)[]

###### Implementation of [#implementation-of]

[`CommandSequencer`](#commandsequencer).[`initialCommands`](#initialcommands-8)

##### isHistoryTransfer() [#ishistorytransfer]

```ts
isHistoryTransfer(): boolean;
```

True when accepted results are records downloaded from device history.

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

`boolean`

###### Implementation of [#implementation-of-1]

[`CommandSequencer`](#commandsequencer).[`isHistoryTransfer`](#ishistorytransfer-5)

##### nextCommand() [#nextcommand]

```ts
nextCommand(frame): readonly DeviceCommand[] | undefined;
```

Answers one complete frame, with the characteristic it arrived on.

Returning `undefined` sends nothing, which is how a sequencer waits: an unidentified
device is left alone rather than addressed with an opcode that may mean something else
on the hardware actually present.

###### Parameters [#parameters-20]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

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

readonly [`DeviceCommand`](#devicecommand)[] \| `undefined`

###### Implementation of [#implementation-of-2]

[`CommandSequencer`](#commandsequencer).[`nextCommand`](#nextcommand-8)

***

### A606Device [#a606device]

Viatom/Lepu ZH-SG-A606 meter, which uploads stored records after connection.

#### Extends [#extends]

- [`BTManagedDevice`](#abstract-btmanageddevice)\<[`ZH_SG_A606`](#enumeration-member-zh_sg_a606)\>

#### Accessors [#accessors]

##### readsHistoryOnRequest [#readshistoryonrequest]

###### Get Signature [#get-signature]

```ts
get readsHistoryOnRequest(): boolean;
```

Whether the records the device stored are read only on `syncHistory`. Such a device goes live
as soon as it connects; any other reads its stored records each time it connects.

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

`boolean`

###### Inherited from [#inherited-from]

[`BTManagedDevice`](#abstract-btmanageddevice).[`readsHistoryOnRequest`](#readshistoryonrequest-3)

#### Constructors [#constructors-1]

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

```ts
new A606Device(device, params): A606Device;
```

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

| Parameter | Type |
| ------ | ------ |
| `device` | `Device` |
| `params` | `CreateDeviceParams`\<[`ZH_SG_A606`](#enumeration-member-zh_sg_a606)\> |

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

[`A606Device`](#a606device)

###### Overrides [#overrides]

[`BTManagedDevice`](#abstract-btmanageddevice).[`constructor`](#constructor-9)

#### Methods [#methods-1]

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

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

Connects to the device and starts reading.

Resolves immediately if already connected and shares the pending promise while connecting.

###### Returns [#returns-28]

`Promise`\<`void`\>

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

If the device has been destroyed.

###### Inherited from [#inherited-from-1]

[`BTManagedDevice`](#abstract-btmanageddevice).[`connect`](#connect-3)

##### destroy() [#destroy]

```ts
destroy(): void;
```

Stops the connection and data processing and clears the callbacks.

###### Returns [#returns-29]

`void`

###### Inherited from [#inherited-from-2]

[`BTManagedDevice`](#abstract-btmanageddevice).[`destroy`](#destroy-3)

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

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

Stops this device's subscriptions and closes its BLE connection.

###### Returns [#returns-30]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-3]

[`BTManagedDevice`](#abstract-btmanageddevice).[`disconnect`](#disconnect-3)

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

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

Stops a recording the device holds open; only recorders that report one support it.

###### Returns [#returns-31]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-4]

[`BTManagedDevice`](#abstract-btmanageddevice).[`stopRecording`](#stoprecording-3)

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

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

Reads the records the device stored: over the open connection, or once it next connects.

###### Returns [#returns-32]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-5]

[`BTManagedDevice`](#abstract-btmanageddevice).[`syncHistory`](#synchistory-3)

#### Properties [#properties]

| Property | Modifier | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ | ------ |
| <a id="property-device"></a> `device` | `public readonly` | `Device` | The underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`device`](#property-device-3) |
| <a id="property-devicedata"></a> `deviceData` | `public` | [`DeviceData`](#devicedata) | Identity and capabilities of this device, updated as device information is read. | [`BTManagedDevice`](#abstract-btmanageddevice).[`deviceData`](#property-devicedata-3) |
| <a id="property-id"></a> `id` | `public` | `string` | Platform identifier of the underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`id`](#property-id-3) |
| <a id="property-onconnectionevent"></a> `onConnectionEvent?` | `public` | (`data`) => `void` | Called for connection lifecycle events such as connected, bonded or history download. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onConnectionEvent`](#property-onconnectionevent-3) |
| <a id="property-ondevicedisconnected"></a> `onDeviceDisconnected?` | `public` | () => `void` | Called when the device disconnects. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceDisconnected`](#property-ondevicedisconnected-3) |
| <a id="property-ondevicestatuschanged"></a> `onDeviceStatusChanged?` | `public` | (`status`, `measurementTypeKey?`) => `void` | Called when the connection status changes. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceStatusChanged`](#property-ondevicestatuschanged-3) |
| <a id="property-onerror"></a> `onError?` | `public` | (`error`) => `void` | Called with a normalised error; cleared by `destroy`. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onError`](#property-onerror-3) |
| <a id="property-onresult"></a> `onResult?` | `public` | (`data`, `delivered?`) => `void` | Called with each measurement that passes the result policy; cleared by `destroy`. `delivered` is called once the app took it: the promise its result callback returned resolved. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onResult`](#property-onresult-3) |
| <a id="property-onwaveform"></a> `onWaveform?` | `public` | (`waveform`) => `void` | Called with the ECG samples of each realtime answer while a recorder records; for display only. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onWaveform`](#property-onwaveform-3) |

***

### A606FrameReader [#a606framereader]

Reads the `& C/D ... checksum` frames used by Viatom's ZH-SG glucose protocol.

#### Implements [#implements-1]

- `FrameReader`

#### Constructors [#constructors-2]

##### Constructor [#constructor-2]

```ts
new A606FrameReader(): A606FrameReader;
```

###### Returns [#returns-33]

[`A606FrameReader`](#a606framereader)

#### Methods [#methods-2]

##### readFrame() [#readframe]

```ts
readFrame(buffer): FrameReadResult;
```

Extracts the next complete frame from the notification buffer.

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

| Parameter | Type |
| ------ | ------ |
| `buffer` | readonly `string`[] |

###### Returns [#returns-34]

`FrameReadResult`

###### Implementation of [#implementation-of-3]

`FrameReader.readFrame`

***

### Aoj20aDevice [#aoj20adevice]

AOJ-20A driver with clock sync, offline history and named device errors.

#### Extends [#extends-1]

- [`BTManagedDevice`](#abstract-btmanageddevice)\<[`AOJ20A`](#enumeration-member-aoj20a)\>

#### Accessors [#accessors-1]

##### readsHistoryOnRequest [#readshistoryonrequest-1]

###### Get Signature [#get-signature-1]

```ts
get readsHistoryOnRequest(): boolean;
```

Whether the records the device stored are read only on `syncHistory`. Such a device goes live
as soon as it connects; any other reads its stored records each time it connects.

###### Returns [#returns-35]

`boolean`

###### Inherited from [#inherited-from-6]

[`BTManagedDevice`](#abstract-btmanageddevice).[`readsHistoryOnRequest`](#readshistoryonrequest-3)

#### Constructors [#constructors-3]

##### Constructor [#constructor-3]

```ts
new Aoj20aDevice(device, params): Aoj20aDevice;
```

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

| Parameter | Type |
| ------ | ------ |
| `device` | `Device` |
| `params` | `CreateDeviceParams`\<[`AOJ20A`](#enumeration-member-aoj20a)\> |

###### Returns [#returns-36]

[`Aoj20aDevice`](#aoj20adevice)

###### Overrides [#overrides-1]

[`BTManagedDevice`](#abstract-btmanageddevice).[`constructor`](#constructor-9)

#### Methods [#methods-3]

##### connect() [#connect-1]

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

Connects to the device and starts reading.

Resolves immediately if already connected and shares the pending promise while connecting.

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

`Promise`\<`void`\>

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

If the device has been destroyed.

###### Inherited from [#inherited-from-7]

[`BTManagedDevice`](#abstract-btmanageddevice).[`connect`](#connect-3)

##### destroy() [#destroy-1]

```ts
destroy(): void;
```

Stops the connection and data processing and clears the callbacks.

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

`void`

###### Inherited from [#inherited-from-8]

[`BTManagedDevice`](#abstract-btmanageddevice).[`destroy`](#destroy-3)

##### disconnect() [#disconnect-1]

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

Stops this device's subscriptions and closes its BLE connection.

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

`Promise`\<`void`\>

###### Inherited from [#inherited-from-9]

[`BTManagedDevice`](#abstract-btmanageddevice).[`disconnect`](#disconnect-3)

##### stopRecording() [#stoprecording-1]

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

Stops a recording the device holds open; only recorders that report one support it.

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

`Promise`\<`void`\>

###### Inherited from [#inherited-from-10]

[`BTManagedDevice`](#abstract-btmanageddevice).[`stopRecording`](#stoprecording-3)

##### syncHistory() [#synchistory-1]

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

Reads the records the device stored: over the open connection, or once it next connects.

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

`Promise`\<`void`\>

###### Inherited from [#inherited-from-11]

[`BTManagedDevice`](#abstract-btmanageddevice).[`syncHistory`](#synchistory-3)

#### Properties [#properties-1]

| Property | Modifier | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ | ------ |
| <a id="property-device-1"></a> `device` | `public readonly` | `Device` | The underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`device`](#property-device-3) |
| <a id="property-devicedata-1"></a> `deviceData` | `public` | [`DeviceData`](#devicedata) | Identity and capabilities of this device, updated as device information is read. | [`BTManagedDevice`](#abstract-btmanageddevice).[`deviceData`](#property-devicedata-3) |
| <a id="property-id-1"></a> `id` | `public` | `string` | Platform identifier of the underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`id`](#property-id-3) |
| <a id="property-onconnectionevent-1"></a> `onConnectionEvent?` | `public` | (`data`) => `void` | Called for connection lifecycle events such as connected, bonded or history download. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onConnectionEvent`](#property-onconnectionevent-3) |
| <a id="property-ondevicedisconnected-1"></a> `onDeviceDisconnected?` | `public` | () => `void` | Called when the device disconnects. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceDisconnected`](#property-ondevicedisconnected-3) |
| <a id="property-ondevicestatuschanged-1"></a> `onDeviceStatusChanged?` | `public` | (`status`, `measurementTypeKey?`) => `void` | Called when the connection status changes. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceStatusChanged`](#property-ondevicestatuschanged-3) |
| <a id="property-onerror-1"></a> `onError?` | `public` | (`error`) => `void` | Called with a normalised error; cleared by `destroy`. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onError`](#property-onerror-3) |
| <a id="property-onresult-1"></a> `onResult?` | `public` | (`data`, `delivered?`) => `void` | Called with each measurement that passes the result policy; cleared by `destroy`. `delivered` is called once the app took it: the promise its result callback returned resolved. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onResult`](#property-onresult-3) |
| <a id="property-onwaveform-1"></a> `onWaveform?` | `public` | (`waveform`) => `void` | Called with the ECG samples of each realtime answer while a recorder records; for display only. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onWaveform`](#property-onwaveform-3) |

***

### AojCommandSequencer [#aojcommandsequencer]

Walks AOJ's clock, metadata, history and optional clear exchange.

#### Implements [#implements-2]

- [`CommandSequencer`](#commandsequencer)

#### Constructors [#constructors-4]

##### Constructor [#constructor-4]

```ts
new AojCommandSequencer(params): AojCommandSequencer;
```

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

| Parameter | Type |
| ------ | ------ |
| `params` | `AojCommandSequencerParams` |

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

[`AojCommandSequencer`](#aojcommandsequencer)

#### Methods [#methods-4]

##### commandProgress() [#commandprogress]

```ts
commandProgress(frame): "ignored" | "partial" | "complete";
```

Describes whether a frame is ignored, partial, or completes the outstanding command.

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

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

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

`"ignored"` \| `"partial"` \| `"complete"`

###### Implementation of [#implementation-of-4]

[`CommandSequencer`](#commandsequencer).[`commandProgress`](#commandprogress-2)

##### initialCommands() [#initialcommands-1]

```ts
initialCommands(): readonly DeviceCommand[];
```

Sent once every characteristic is subscribed. Empty starts a device that only listens.

May resolve later, for a first command that depends on state read from storage.

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

readonly [`DeviceCommand`](#devicecommand)[]

###### Implementation of [#implementation-of-5]

[`CommandSequencer`](#commandsequencer).[`initialCommands`](#initialcommands-8)

##### isHistoryTransfer() [#ishistorytransfer-1]

```ts
isHistoryTransfer(): boolean;
```

True when accepted results are records downloaded from device history.

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

`boolean`

###### Implementation of [#implementation-of-6]

[`CommandSequencer`](#commandsequencer).[`isHistoryTransfer`](#ishistorytransfer-5)

##### nextCommand() [#nextcommand-1]

```ts
nextCommand(frame): readonly DeviceCommand[] | undefined;
```

Answers one complete frame, with the characteristic it arrived on.

Returning `undefined` sends nothing, which is how a sequencer waits: an unidentified
device is left alone rather than addressed with an opcode that may mean something else
on the hardware actually present.

###### Parameters [#parameters-26]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

###### Returns [#returns-46]

readonly [`DeviceCommand`](#devicecommand)[] \| `undefined`

###### Implementation of [#implementation-of-7]

[`CommandSequencer`](#commandsequencer).[`nextCommand`](#nextcommand-8)

***

### AojFrameReader [#aojframereader]

Reads AOJ's `aa 01 command length payload xor` notifications.

#### Implements [#implements-3]

- `FrameReader`

#### Constructors [#constructors-5]

##### Constructor [#constructor-5]

```ts
new AojFrameReader(): AojFrameReader;
```

###### Returns [#returns-47]

[`AojFrameReader`](#aojframereader)

#### Methods [#methods-5]

##### readFrame() [#readframe-1]

```ts
readFrame(buffer): FrameReadResult;
```

Extracts the next complete frame from the notification buffer.

###### Parameters [#parameters-27]

| Parameter | Type |
| ------ | ------ |
| `buffer` | readonly `string`[] |

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

`FrameReadResult`

###### Implementation of [#implementation-of-8]

`FrameReader.readFrame`

***

### BackgroundSyncCoordinator [#backgroundsynccoordinator]

Queues results for the signed-in account and delivers them, retrying failed deliveries.

#### Type Parameters [#type-parameters-6]

| Type Parameter |
| ------ |
| <a id="type-parameter-t"></a> `T` *extends* [`DeviceKey`](#devicekey) |

#### Constructors [#constructors-6]

##### Constructor [#constructor-6]

```ts
new BackgroundSyncCoordinator<T>(options): BackgroundSyncCoordinator<T>;
```

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

| Parameter | Type |
| ------ | ------ |
| `options` | `CoordinatorOptions`\<`T`\> |

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

[`BackgroundSyncCoordinator`](#backgroundsynccoordinator)\<`T`\>

#### Methods [#methods-6]

##### enqueue() [#enqueue]

```ts
enqueue(result): Promise<void>;
```

Queues a result for the current account and tries to deliver the queue.

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

| Parameter | Type |
| ------ | ------ |
| `result` | [`ResultCallback`](#resultcallback)\<`T`\> |

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

`Promise`\<`void`\>

##### flush() [#flush]

```ts
flush(options?): Promise<void>;
```

Tries to deliver the queued results; resolves once the attempt is done.

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

| Parameter | Type |
| ------ | ------ |
| `options?` | [`BackgroundSyncFlushOptions`](#backgroundsyncflushoptions) |

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

`Promise`\<`void`\>

##### getQueued() [#getqueued]

```ts
getQueued(): readonly BackgroundSyncResult<T>[];
```

The current account's results still waiting to be accepted, oldest first: readings to show as not saved yet.
Kept up to date by every enqueue and flush; `subscribe` reads the stored queue in first.

###### Returns [#returns-52]

readonly [`BackgroundSyncResult`](#backgroundsyncresult)\<`T`\>[]

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

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

Calls `listener` whenever the waiting results change; the first subscriber reads the stored queue in.

###### Parameters [#parameters-31]

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

###### Returns [#returns-53]

() => `void`

##### updateOptions() [#updateoptions]

```ts
updateOptions(options): void;
```

Replaces the coordinator options.

###### Parameters [#parameters-32]

| Parameter | Type |
| ------ | ------ |
| `options` | `CoordinatorOptions`\<`T`\> |

###### Returns [#returns-54]

`void`

***

### BloodGlucoseDevice [#bloodglucosedevice]

Decodes the legacy TaiDoc, GlucoCheck Gold and TeleBGM glucose protocols.

#### Extends [#extends-2]

- [`BTManagedDevice`](#abstract-btmanageddevice)\<`GlucoseDevice`\>

#### Accessors [#accessors-2]

##### readsHistoryOnRequest [#readshistoryonrequest-2]

###### Get Signature [#get-signature-2]

```ts
get readsHistoryOnRequest(): boolean;
```

Whether the records the device stored are read only on `syncHistory`. Such a device goes live
as soon as it connects; any other reads its stored records each time it connects.

###### Returns [#returns-55]

`boolean`

###### Inherited from [#inherited-from-12]

[`BTManagedDevice`](#abstract-btmanageddevice).[`readsHistoryOnRequest`](#readshistoryonrequest-3)

#### Constructors [#constructors-7]

##### Constructor [#constructor-7]

```ts
new BloodGlucoseDevice(device, params): BloodGlucoseDevice;
```

###### Parameters [#parameters-33]

| Parameter | Type |
| ------ | ------ |
| `device` | `Device` |
| `params` | `CreateDeviceParams`\<`GlucoseDevice`\> |

###### Returns [#returns-56]

[`BloodGlucoseDevice`](#bloodglucosedevice)

###### Overrides [#overrides-2]

[`BTManagedDevice`](#abstract-btmanageddevice).[`constructor`](#constructor-9)

#### Methods [#methods-7]

##### connect() [#connect-2]

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

Connects to the device and starts reading.

Resolves immediately if already connected and shares the pending promise while connecting.

###### Returns [#returns-57]

`Promise`\<`void`\>

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

If the device has been destroyed.

###### Inherited from [#inherited-from-13]

[`BTManagedDevice`](#abstract-btmanageddevice).[`connect`](#connect-3)

##### destroy() [#destroy-2]

```ts
destroy(): void;
```

Stops the connection and data processing and clears the callbacks.

###### Returns [#returns-58]

`void`

###### Inherited from [#inherited-from-14]

[`BTManagedDevice`](#abstract-btmanageddevice).[`destroy`](#destroy-3)

##### disconnect() [#disconnect-2]

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

Stops this device's subscriptions and closes its BLE connection.

###### Returns [#returns-59]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-15]

[`BTManagedDevice`](#abstract-btmanageddevice).[`disconnect`](#disconnect-3)

##### stopRecording() [#stoprecording-2]

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

Stops a recording the device holds open; only recorders that report one support it.

###### Returns [#returns-60]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-16]

[`BTManagedDevice`](#abstract-btmanageddevice).[`stopRecording`](#stoprecording-3)

##### syncHistory() [#synchistory-2]

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

Reads the records the device stored: over the open connection, or once it next connects.

###### Returns [#returns-61]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-17]

[`BTManagedDevice`](#abstract-btmanageddevice).[`syncHistory`](#synchistory-3)

#### Properties [#properties-2]

| Property | Modifier | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ | ------ |
| <a id="property-device-2"></a> `device` | `public readonly` | `Device` | The underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`device`](#property-device-3) |
| <a id="property-devicedata-2"></a> `deviceData` | `public` | [`DeviceData`](#devicedata) | Identity and capabilities of this device, updated as device information is read. | [`BTManagedDevice`](#abstract-btmanageddevice).[`deviceData`](#property-devicedata-3) |
| <a id="property-id-2"></a> `id` | `public` | `string` | Platform identifier of the underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`id`](#property-id-3) |
| <a id="property-onconnectionevent-2"></a> `onConnectionEvent?` | `public` | (`data`) => `void` | Called for connection lifecycle events such as connected, bonded or history download. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onConnectionEvent`](#property-onconnectionevent-3) |
| <a id="property-ondevicedisconnected-2"></a> `onDeviceDisconnected?` | `public` | () => `void` | Called when the device disconnects. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceDisconnected`](#property-ondevicedisconnected-3) |
| <a id="property-ondevicestatuschanged-2"></a> `onDeviceStatusChanged?` | `public` | (`status`, `measurementTypeKey?`) => `void` | Called when the connection status changes. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceStatusChanged`](#property-ondevicestatuschanged-3) |
| <a id="property-onerror-2"></a> `onError?` | `public` | (`error`) => `void` | Called with a normalised error; cleared by `destroy`. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onError`](#property-onerror-3) |
| <a id="property-onresult-2"></a> `onResult?` | `public` | (`data`, `delivered?`) => `void` | Called with each measurement that passes the result policy; cleared by `destroy`. `delivered` is called once the app took it: the promise its result callback returned resolved. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onResult`](#property-onresult-3) |
| <a id="property-onwaveform-2"></a> `onWaveform?` | `public` | (`waveform`) => `void` | Called with the ECG samples of each realtime answer while a recorder records; for display only. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onWaveform`](#property-onwaveform-3) |

***

### BluetoothError [#bluetootherror]

Error carrying a stable code and an optional translation key.

#### Extends [#extends-3]

- `Error`

#### Constructors [#constructors-8]

##### Constructor [#constructor-8]

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

###### Parameters [#parameters-34]

| Parameter | Type | Description |
| ------ | ------ | ------ |
| `code` | [`BluetoothErrorCode`](#bluetootherrorcode) | Stable machine-readable failure code. |
| `message` | `string` | - |
| `translationKey?` | `string` | Translation key, when the message is one. |
| `originalError?` | `unknown` | Underlying error this one was created from. |

###### Returns [#returns-62]

[`BluetoothError`](#bluetootherror)

###### Overrides [#overrides-3]

`Error.constructor`

#### Properties [#properties-3]

| Property | Modifier | Type | Default value | Description | Overrides |
| ------ | ------ | ------ | ------ | ------ | ------ |
| <a id="property-code"></a> `code` | `public readonly` | [`BluetoothErrorCode`](#bluetootherrorcode) | `undefined` | Stable machine-readable failure code. | - |
| <a id="property-name"></a> `name` | `public readonly` | `"BluetoothError"` | `"BluetoothError"` | Always `"BluetoothError"`. | `Error.name` |
| <a id="property-originalerror"></a> `originalError?` | `public readonly` | `unknown` | `undefined` | Underlying error this one was created from. | - |
| <a id="property-translationkey"></a> `translationKey?` | `public readonly` | `string` | `undefined` | Translation key, when the message is one. | - |

***

### `abstract` BTManagedDevice [#abstract-btmanageddevice]

Base class for a Bluetooth device managed by the SDK: connects, subscribes, parses frames and
reports results, status changes and connection events through its callbacks.

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

- [`BloodGlucoseDevice`](#bloodglucosedevice)
- [`CustomDevice`](#customdevice)
- [`VerovalEcgDevice`](#verovalecgdevice)
- [`VerovalActivityDevice`](#verovalactivitydevice)
- [`TrasenseS9Device`](#trasenses9device)
- [`CheckmePodDevice`](#checkmepoddevice)
- [`Aoj20aDevice`](#aoj20adevice)
- [`GenialT31Device`](#genialt31device)
- [`A606Device`](#a606device)
- [`CheckmeProDevice`](#checkmeprodevice)

#### Type Parameters [#type-parameters-7]

| Type Parameter | Default type |
| ------ | ------ |
| <a id="type-parameter-t-1"></a> `T` *extends* [`DeviceKey`](#devicekey) | [`BP2`](#enumeration-member-bp2) |

#### Implements [#implements-4]

- [`IBTManagedDevice`](#ibtmanageddevice)

#### Accessors [#accessors-3]

##### readsHistoryOnRequest [#readshistoryonrequest-3]

###### Get Signature [#get-signature-3]

```ts
get readsHistoryOnRequest(): boolean;
```

Whether the records the device stored are read only on `syncHistory`. Such a device goes live
as soon as it connects; any other reads its stored records each time it connects.

###### Returns [#returns-63]

`boolean`

#### Constructors [#constructors-9]

##### Constructor [#constructor-9]

```ts
new BTManagedDevice<T>(device, __namedParameters): BTManagedDevice<T>;
```

###### Parameters [#parameters-35]

| Parameter | Type | Description |
| ------ | ------ | ------ |
| `device` | `Device` | The underlying BLE device. |
| `__namedParameters` | `CreateDeviceParams`\<`T`\> | - |

###### Returns [#returns-64]

[`BTManagedDevice`](#abstract-btmanageddevice)\<`T`\>

#### Methods [#methods-8]

##### connect() [#connect-3]

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

Connects to the device and starts reading.

Resolves immediately if already connected and shares the pending promise while connecting.

###### Returns [#returns-65]

`Promise`\<`void`\>

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

If the device has been destroyed.

###### Implementation of [#implementation-of-9]

[`IBTManagedDevice`](#ibtmanageddevice).[`connect`](#property-connect)

##### destroy() [#destroy-3]

```ts
destroy(): void;
```

Stops the connection and data processing and clears the callbacks.

###### Returns [#returns-66]

`void`

##### disconnect() [#disconnect-3]

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

Stops this device's subscriptions and closes its BLE connection.

###### Returns [#returns-67]

`Promise`\<`void`\>

###### Implementation of [#implementation-of-10]

[`IBTManagedDevice`](#ibtmanageddevice).[`disconnect`](#property-disconnect-1)

##### stopRecording() [#stoprecording-3]

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

Stops a recording the device holds open; only recorders that report one support it.

###### Returns [#returns-68]

`Promise`\<`void`\>

##### syncHistory() [#synchistory-3]

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

Reads the records the device stored: over the open connection, or once it next connects.

###### Returns [#returns-69]

`Promise`\<`void`\>

#### Properties [#properties-4]

| Property | Modifier | Type | Description |
| ------ | ------ | ------ | ------ |
| <a id="property-device-3"></a> `device` | `public readonly` | `Device` | The underlying BLE device. |
| <a id="property-devicedata-3"></a> `deviceData` | `public` | [`DeviceData`](#devicedata) | Identity and capabilities of this device, updated as device information is read. |
| <a id="property-id-3"></a> `id` | `public` | `string` | Platform identifier of the underlying BLE device. |
| <a id="property-onconnectionevent-3"></a> `onConnectionEvent?` | `public` | (`data`) => `void` | Called for connection lifecycle events such as connected, bonded or history download. |
| <a id="property-ondevicedisconnected-3"></a> `onDeviceDisconnected?` | `public` | () => `void` | Called when the device disconnects. |
| <a id="property-ondevicestatuschanged-3"></a> `onDeviceStatusChanged?` | `public` | (`status`, `measurementTypeKey?`) => `void` | Called when the connection status changes. |
| <a id="property-onerror-3"></a> `onError?` | `public` | (`error`) => `void` | Called with a normalised error; cleared by `destroy`. |
| <a id="property-onresult-3"></a> `onResult?` | `public` | (`data`, `delivered?`) => `void` | Called with each measurement that passes the result policy; cleared by `destroy`. `delivered` is called once the app took it: the promise its result callback returned resolved. |
| <a id="property-onwaveform-3"></a> `onWaveform?` | `public` | (`waveform`) => `void` | Called with the ECG samples of each realtime answer while a recorder records; for display only. |

***

### BTManager [#btmanager]

Scans for, connects to and reports readings from the accepted Bluetooth devices.

#### Type Parameters [#type-parameters-8]

| Type Parameter |
| ------ |
| <a id="type-parameter-t-2"></a> `T` *extends* readonly [`AcceptedDevice`](#accepteddevice)[] |

#### Constructors [#constructors-10]

##### Constructor [#constructor-10]

```ts
new BTManager<T>(
   bleManager,
   acceptedDevices,
   options?
): BTManager<T>;
```

###### Parameters [#parameters-36]

| Parameter | Type |
| ------ | ------ |
| `bleManager` | `BleManager` |
| `acceptedDevices` | `T` |
| `options?` | [`BTManagerOptions`](#btmanageroptions) |

###### Returns [#returns-70]

[`BTManager`](#btmanager)\<`T`\>

#### Methods [#methods-9]

##### destroy() [#destroy-4]

```ts
destroy(): void;
```

Stops scanning, disconnects devices and releases the manager.

###### Returns [#returns-71]

`void`

##### disconnectDevice() [#disconnectdevice]

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

Disconnects one device so it can be rediscovered by a later advertisement.

###### Parameters [#parameters-37]

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

###### Returns [#returns-72]

`Promise`\<`void`\>

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

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

Disconnects one device and ignores later advertisements for this manager's lifetime.

###### Parameters [#parameters-38]

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

###### Returns [#returns-73]

`Promise`\<`void`\>

##### getOpenSeries() [#getopenseries]

```ts
getOpenSeries(): readonly OpenSeries[];
```

The series being recorded, each with its latest values: what to show while a device streams.

###### Returns [#returns-74]

readonly [`OpenSeries`](#openseries)[]

##### keepConnecting() [#keepconnecting]

```ts
keepConnecting(deviceIds): void;
```

On iOS, keeps a connection request pending for each device, so the system reconnects it when it advertises and
the app can read it in the background without the advertisement carrying a service UUID. Use it for the devices
the user has paired. Does nothing on other platforms.

A device that connects is handled like one the scan found, and its request is made again if it drops the link.
Explicitly disconnecting, forgetting or stopping the scan ends the request.

###### Parameters [#parameters-39]

| Parameter | Type |
| ------ | ------ |
| `deviceIds` | readonly `string`[] |

###### Returns [#returns-75]

`void`

##### onConnectionEvent() [#onconnectionevent]

```ts
onConnectionEvent(callback?): void;
```

Sets the callback called for device connection events.

###### Parameters [#parameters-40]

| Parameter | Type |
| ------ | ------ |
| `callback?` | (`data`) => `void` |

###### Returns [#returns-76]

`void`

##### onDeviceFound() [#ondevicefound]

```ts
onDeviceFound(callback?): void;
```

Sets the callback called with each newly discovered device.

###### Parameters [#parameters-41]

| Parameter | Type |
| ------ | ------ |
| `callback?` | (`device`, `manager`) => `Promise`\<`void`\> |

###### Returns [#returns-77]

`void`

##### onDeviceStatusChanged() [#ondevicestatuschanged]

```ts
onDeviceStatusChanged(callback?): void;
```

Sets the callback called when a device's connection status changes.

###### Parameters [#parameters-42]

| Parameter | Type |
| ------ | ------ |
| `callback?` | (`data`) => `void` |

###### Returns [#returns-78]

`void`

##### onError() [#onerror]

```ts
onError(callback?): void;
```

Sets the callback called with Bluetooth errors.

###### Parameters [#parameters-43]

| Parameter | Type |
| ------ | ------ |
| `callback?` | (`data`) => `void` |

###### Returns [#returns-79]

`void`

##### onResult() [#onresult]

```ts
onResult(callback?): void;
```

Sets the callback called with each result; series that closed while nobody listened are delivered first. It may
return a promise that resolves once the result is queued or saved: with `recordCursorStorage` set, the stored file
the result came from (a Viatom ER1's or BP2's) is then not read again. A file whose promise rejects, or whose
callback returns nothing, is read again on the next history sync.

###### Parameters [#parameters-44]

| Parameter | Type |
| ------ | ------ |
| `callback?` | (`data`) => `void` \| `Promise`\<`unknown`\> |

###### Returns [#returns-80]

`void`

##### onWaveform() [#onwaveform]

```ts
onWaveform(callback?): void;
```

Sets the callback called with the live ECG samples of recording devices; for display, never saved.

###### Parameters [#parameters-45]

| Parameter | Type |
| ------ | ------ |
| `callback?` | (`waveform`) => `void` |

###### Returns [#returns-81]

`void`

##### pauseScan() [#pausescan]

```ts
pauseScan(): void;
```

Pauses discovery without tearing down devices or their callbacks.

Use this when an app temporarily stops scanning, for example while it is in the
background but an already-connected device may still deliver a measurement.

###### Returns [#returns-82]

`void`

##### restoreDevices() [#restoredevices]

```ts
restoreDevices(devices): void;
```

Treats already-known BLE devices as freshly discovered and clears their forgotten state.

###### Parameters [#parameters-46]

| Parameter | Type |
| ------ | ------ |
| `devices` | readonly `Device`[] |

###### Returns [#returns-83]

`void`

##### resumeScan() [#resumescan]

```ts
resumeScan(): void;
```

Resumes discovery without clearing devices or callbacks.

Restarting unconditionally also recovers when an app stopped the underlying BLE scan
directly while BTManager still believed it was active.

###### Returns [#returns-84]

`void`

##### setAutoConnect() [#setautoconnect]

```ts
setAutoConnect(
   enabledOrOptions,
   delayMs?,
   onDeviceSelectionRequired?
): void;
```

Enables or disables automatic connection, either with positional arguments or an options object.

###### Parameters [#parameters-47]

| Parameter | Type |
| ------ | ------ |
| `enabledOrOptions` | \| `boolean` \| \{ `delayMs?`: `number`; `enabled`: `boolean`; `onDeviceSelectionRequired?`: (`selection`) => `void`; \} |
| `delayMs?` | `number` |
| `onDeviceSelectionRequired?` | (`selection`) => `void` |

###### Returns [#returns-85]

`void`

##### setBackgroundScanEnabled() [#setbackgroundscanenabled]

```ts
setBackgroundScanEnabled(enabled): void;
```

Switches only the scan policy; the app can keep a foreground scan broad.

###### Parameters [#parameters-48]

| Parameter | Type |
| ------ | ------ |
| `enabled` | `boolean` |

###### Returns [#returns-86]

`void`

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

```ts
startScan(): void;
```

Starts scanning once the Bluetooth adapter is powered on; does nothing while a scan is running.

###### Returns [#returns-87]

`void`

##### stopRecording() [#stoprecording-4]

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

Stops the recording a connected recorder holds open, for instance once the user confirms it
after a `recording` event with `leadOff`. Rejects when the device is not connected or holds
no recording.

###### Parameters [#parameters-49]

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

###### Returns [#returns-88]

`Promise`\<`void`\>

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

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

Stops scanning, disconnects the devices and clears the callbacks.

###### Returns [#returns-89]

`void`

##### subscribeOpenSeries() [#subscribeopenseries]

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

Calls `listener` whenever a series gets a value or closes; returns the unsubscribe.

###### Parameters [#parameters-50]

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

###### Returns [#returns-90]

() => `void`

***

### CheckmeFrameReader [#checkmeframereader]

Handles split notifications, concatenated notifications, and both vendor envelopes.

#### Implements [#implements-5]

- `FrameReader`

#### Constructors [#constructors-11]

##### Constructor [#constructor-11]

```ts
new CheckmeFrameReader(): CheckmeFrameReader;
```

###### Returns [#returns-91]

[`CheckmeFrameReader`](#checkmeframereader)

#### Methods [#methods-10]

##### readFrame() [#readframe-2]

```ts
readFrame(buffer): FrameReadResult;
```

Extracts the next complete frame from the notification buffer.

###### Parameters [#parameters-51]

| Parameter | Type |
| ------ | ------ |
| `buffer` | readonly `string`[] |

###### Returns [#returns-92]

`FrameReadResult`

###### Implementation of [#implementation-of-11]

`FrameReader.readFrame`

***

### CheckmePodDevice [#checkmepoddevice]

Checkme Pod and Checkme Pod-WPS's realtime protocol from ViHealth.

#### Extends [#extends-4]

- [`BTManagedDevice`](#abstract-btmanageddevice)\<[`CHECKME_POD`](#enumeration-member-checkme_pod)\>

#### Accessors [#accessors-4]

##### readsHistoryOnRequest [#readshistoryonrequest-4]

###### Get Signature [#get-signature-4]

```ts
get readsHistoryOnRequest(): boolean;
```

Whether the records the device stored are read only on `syncHistory`. Such a device goes live
as soon as it connects; any other reads its stored records each time it connects.

###### Returns [#returns-93]

`boolean`

###### Inherited from [#inherited-from-18]

[`BTManagedDevice`](#abstract-btmanageddevice).[`readsHistoryOnRequest`](#readshistoryonrequest-3)

#### Constructors [#constructors-12]

##### Constructor [#constructor-12]

```ts
new CheckmePodDevice(device, params): CheckmePodDevice;
```

###### Parameters [#parameters-52]

| Parameter | Type |
| ------ | ------ |
| `device` | `Device` |
| `params` | `CreateDeviceParams`\<[`CHECKME_POD`](#enumeration-member-checkme_pod)\> |

###### Returns [#returns-94]

[`CheckmePodDevice`](#checkmepoddevice)

###### Overrides [#overrides-4]

[`BTManagedDevice`](#abstract-btmanageddevice).[`constructor`](#constructor-9)

#### Methods [#methods-11]

##### connect() [#connect-4]

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

Connects to the device and starts reading.

Resolves immediately if already connected and shares the pending promise while connecting.

###### Returns [#returns-95]

`Promise`\<`void`\>

###### Throws [#throws-5]

If the device has been destroyed.

###### Inherited from [#inherited-from-19]

[`BTManagedDevice`](#abstract-btmanageddevice).[`connect`](#connect-3)

##### destroy() [#destroy-5]

```ts
destroy(): void;
```

Stops the connection and data processing and clears the callbacks.

###### Returns [#returns-96]

`void`

###### Inherited from [#inherited-from-20]

[`BTManagedDevice`](#abstract-btmanageddevice).[`destroy`](#destroy-3)

##### disconnect() [#disconnect-4]

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

Stops this device's subscriptions and closes its BLE connection.

###### Returns [#returns-97]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-21]

[`BTManagedDevice`](#abstract-btmanageddevice).[`disconnect`](#disconnect-3)

##### stopRecording() [#stoprecording-5]

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

Stops a recording the device holds open; only recorders that report one support it.

###### Returns [#returns-98]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-22]

[`BTManagedDevice`](#abstract-btmanageddevice).[`stopRecording`](#stoprecording-3)

##### syncHistory() [#synchistory-4]

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

Reads the records the device stored: over the open connection, or once it next connects.

###### Returns [#returns-99]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-23]

[`BTManagedDevice`](#abstract-btmanageddevice).[`syncHistory`](#synchistory-3)

#### Properties [#properties-5]

| Property | Modifier | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ | ------ |
| <a id="property-device-4"></a> `device` | `public readonly` | `Device` | The underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`device`](#property-device-3) |
| <a id="property-devicedata-4"></a> `deviceData` | `public` | [`DeviceData`](#devicedata) | Identity and capabilities of this device, updated as device information is read. | [`BTManagedDevice`](#abstract-btmanageddevice).[`deviceData`](#property-devicedata-3) |
| <a id="property-id-4"></a> `id` | `public` | `string` | Platform identifier of the underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`id`](#property-id-3) |
| <a id="property-onconnectionevent-4"></a> `onConnectionEvent?` | `public` | (`data`) => `void` | Called for connection lifecycle events such as connected, bonded or history download. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onConnectionEvent`](#property-onconnectionevent-3) |
| <a id="property-ondevicedisconnected-4"></a> `onDeviceDisconnected?` | `public` | () => `void` | Called when the device disconnects. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceDisconnected`](#property-ondevicedisconnected-3) |
| <a id="property-ondevicestatuschanged-4"></a> `onDeviceStatusChanged?` | `public` | (`status`, `measurementTypeKey?`) => `void` | Called when the connection status changes. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceStatusChanged`](#property-ondevicestatuschanged-3) |
| <a id="property-onerror-4"></a> `onError?` | `public` | (`error`) => `void` | Called with a normalised error; cleared by `destroy`. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onError`](#property-onerror-3) |
| <a id="property-onresult-4"></a> `onResult?` | `public` | (`data`, `delivered?`) => `void` | Called with each measurement that passes the result policy; cleared by `destroy`. `delivered` is called once the app took it: the promise its result callback returned resolved. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onResult`](#property-onresult-3) |
| <a id="property-onwaveform-4"></a> `onWaveform?` | `public` | (`waveform`) => `void` | Called with the ECG samples of each realtime answer while a recorder records; for display only. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onWaveform`](#property-onwaveform-3) |

***

### CheckmePodFrameReader [#checkmepodframereader]

Reads split and concatenated Checkme Pod notifications with CRC validation.

#### Implements [#implements-6]

- `FrameReader`

#### Constructors [#constructors-13]

##### Constructor [#constructor-13]

```ts
new CheckmePodFrameReader(): CheckmePodFrameReader;
```

###### Returns [#returns-100]

[`CheckmePodFrameReader`](#checkmepodframereader)

#### Methods [#methods-12]

##### readFrame() [#readframe-3]

```ts
readFrame(buffer): FrameReadResult;
```

Extracts the next CRC-valid frame from the notification buffer.

###### Parameters [#parameters-53]

| Parameter | Type |
| ------ | ------ |
| `buffer` | readonly `string`[] |

###### Returns [#returns-101]

`FrameReadResult`

###### Implementation of [#implementation-of-12]

`FrameReader.readFrame`

***

### CheckmePodSequencer [#checkmepodsequencer]

Drives the info -\> clock sync -\> realtime exchange used by Checkme Pod.

#### Implements [#implements-7]

- [`CommandSequencer`](#commandsequencer)

#### Constructors [#constructors-14]

##### Constructor [#constructor-14]

```ts
new CheckmePodSequencer(params): CheckmePodSequencer;
```

###### Parameters [#parameters-54]

| Parameter | Type |
| ------ | ------ |
| `params` | [`CheckmePodSequencerParams`](#checkmepodsequencerparams) |

###### Returns [#returns-102]

[`CheckmePodSequencer`](#checkmepodsequencer)

#### Methods [#methods-13]

##### initialCommands() [#initialcommands-2]

```ts
initialCommands(): readonly DeviceCommand[];
```

Sent once every characteristic is subscribed. Empty starts a device that only listens.

May resolve later, for a first command that depends on state read from storage.

###### Returns [#returns-103]

readonly [`DeviceCommand`](#devicecommand)[]

###### Implementation of [#implementation-of-13]

[`CommandSequencer`](#commandsequencer).[`initialCommands`](#initialcommands-8)

##### nextCommand() [#nextcommand-2]

```ts
nextCommand(frame): readonly DeviceCommand[] | undefined;
```

Answers one complete frame, with the characteristic it arrived on.

Returning `undefined` sends nothing, which is how a sequencer waits: an unidentified
device is left alone rather than addressed with an opcode that may mean something else
on the hardware actually present.

###### Parameters [#parameters-55]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

###### Returns [#returns-104]

readonly [`DeviceCommand`](#devicecommand)[] \| `undefined`

###### Implementation of [#implementation-of-14]

[`CommandSequencer`](#commandsequencer).[`nextCommand`](#nextcommand-8)

***

### CheckmeProDevice [#checkmeprodevice]

Viatom Checkme Pro history transfer, matching the CheckmeBleInterface in ViHealth.

#### Extends [#extends-5]

- [`BTManagedDevice`](#abstract-btmanageddevice)\<[`CHECKME`](#enumeration-member-checkme)\>

#### Accessors [#accessors-5]

##### readsHistoryOnRequest [#readshistoryonrequest-5]

###### Get Signature [#get-signature-5]

```ts
get readsHistoryOnRequest(): boolean;
```

Whether the records the device stored are read only on `syncHistory`. Such a device goes live
as soon as it connects; any other reads its stored records each time it connects.

###### Returns [#returns-105]

`boolean`

###### Inherited from [#inherited-from-24]

[`BTManagedDevice`](#abstract-btmanageddevice).[`readsHistoryOnRequest`](#readshistoryonrequest-3)

#### Constructors [#constructors-15]

##### Constructor [#constructor-15]

```ts
new CheckmeProDevice(device, params): CheckmeProDevice;
```

###### Parameters [#parameters-56]

| Parameter | Type |
| ------ | ------ |
| `device` | `Device` |
| `params` | `CreateDeviceParams`\<[`CHECKME`](#enumeration-member-checkme)\> |

###### Returns [#returns-106]

[`CheckmeProDevice`](#checkmeprodevice)

###### Overrides [#overrides-5]

[`BTManagedDevice`](#abstract-btmanageddevice).[`constructor`](#constructor-9)

#### Methods [#methods-14]

##### connect() [#connect-5]

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

Connects to the device and starts reading.

Resolves immediately if already connected and shares the pending promise while connecting.

###### Returns [#returns-107]

`Promise`\<`void`\>

###### Throws [#throws-6]

If the device has been destroyed.

###### Inherited from [#inherited-from-25]

[`BTManagedDevice`](#abstract-btmanageddevice).[`connect`](#connect-3)

##### destroy() [#destroy-6]

```ts
destroy(): void;
```

Stops the connection and data processing and clears the callbacks.

###### Returns [#returns-108]

`void`

###### Inherited from [#inherited-from-26]

[`BTManagedDevice`](#abstract-btmanageddevice).[`destroy`](#destroy-3)

##### disconnect() [#disconnect-5]

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

Stops this device's subscriptions and closes its BLE connection.

###### Returns [#returns-109]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-27]

[`BTManagedDevice`](#abstract-btmanageddevice).[`disconnect`](#disconnect-3)

##### stopRecording() [#stoprecording-6]

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

Stops a recording the device holds open; only recorders that report one support it.

###### Returns [#returns-110]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-28]

[`BTManagedDevice`](#abstract-btmanageddevice).[`stopRecording`](#stoprecording-3)

##### syncHistory() [#synchistory-5]

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

Reads the records the device stored: over the open connection, or once it next connects.

###### Returns [#returns-111]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-29]

[`BTManagedDevice`](#abstract-btmanageddevice).[`syncHistory`](#synchistory-3)

#### Properties [#properties-6]

| Property | Modifier | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ | ------ |
| <a id="property-device-5"></a> `device` | `public readonly` | `Device` | The underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`device`](#property-device-3) |
| <a id="property-devicedata-5"></a> `deviceData` | `public` | [`DeviceData`](#devicedata) | Identity and capabilities of this device, updated as device information is read. | [`BTManagedDevice`](#abstract-btmanageddevice).[`deviceData`](#property-devicedata-3) |
| <a id="property-id-5"></a> `id` | `public` | `string` | Platform identifier of the underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`id`](#property-id-3) |
| <a id="property-onconnectionevent-5"></a> `onConnectionEvent?` | `public` | (`data`) => `void` | Called for connection lifecycle events such as connected, bonded or history download. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onConnectionEvent`](#property-onconnectionevent-3) |
| <a id="property-ondevicedisconnected-5"></a> `onDeviceDisconnected?` | `public` | () => `void` | Called when the device disconnects. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceDisconnected`](#property-ondevicedisconnected-3) |
| <a id="property-ondevicestatuschanged-5"></a> `onDeviceStatusChanged?` | `public` | (`status`, `measurementTypeKey?`) => `void` | Called when the connection status changes. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceStatusChanged`](#property-ondevicestatuschanged-3) |
| <a id="property-onerror-5"></a> `onError?` | `public` | (`error`) => `void` | Called with a normalised error; cleared by `destroy`. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onError`](#property-onerror-3) |
| <a id="property-onresult-5"></a> `onResult?` | `public` | (`data`, `delivered?`) => `void` | Called with each measurement that passes the result policy; cleared by `destroy`. `delivered` is called once the app took it: the promise its result callback returned resolved. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onResult`](#property-onresult-3) |
| <a id="property-onwaveform-5"></a> `onWaveform?` | `public` | (`waveform`) => `void` | Called with the ECG samples of each realtime answer while a recorder records; for display only. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onWaveform`](#property-onwaveform-3) |

***

### CheckmeProSequencer [#checkmeprosequencer]

Downloads Checkme Pro history using the command exchange in ViHealth's CheckmeBleInterface.
The device returns list records first; the daily list and ECG list then point to waveform
files, which are read with the same offset-based transfer.

#### Implements [#implements-8]

- [`CommandSequencer`](#commandsequencer)

#### Constructors [#constructors-16]

##### Constructor [#constructor-16]

```ts
new CheckmeProSequencer(params): CheckmeProSequencer;
```

###### Parameters [#parameters-57]

| Parameter | Type |
| ------ | ------ |
| `params` | [`CheckmeTransferParams`](#checkmetransferparams) |

###### Returns [#returns-112]

[`CheckmeProSequencer`](#checkmeprosequencer)

#### Methods [#methods-15]

##### commandTimeoutMs() [#commandtimeoutms]

```ts
commandTimeoutMs(): number | undefined;
```

The response timeout for the currently outstanding command, when a protocol needs one.

###### Returns [#returns-113]

`number` \| `undefined`

###### Implementation of [#implementation-of-15]

[`CommandSequencer`](#commandsequencer).[`commandTimeoutMs`](#commandtimeoutms-2)

##### initialCommands() [#initialcommands-3]

```ts
initialCommands(): readonly DeviceCommand[];
```

Sent once every characteristic is subscribed. Empty starts a device that only listens.

May resolve later, for a first command that depends on state read from storage.

###### Returns [#returns-114]

readonly [`DeviceCommand`](#devicecommand)[]

###### Implementation of [#implementation-of-16]

[`CommandSequencer`](#commandsequencer).[`initialCommands`](#initialcommands-8)

##### isHistoryTransfer() [#ishistorytransfer-2]

```ts
isHistoryTransfer(): boolean;
```

True when accepted results are records downloaded from device history.

###### Returns [#returns-115]

`boolean`

###### Implementation of [#implementation-of-17]

[`CommandSequencer`](#commandsequencer).[`isHistoryTransfer`](#ishistorytransfer-5)

##### isNormalDisconnect() [#isnormaldisconnect]

```ts
isNormalDisconnect(): boolean;
```

True when a timeout-style disconnect is the device's normal completion signal.

###### Returns [#returns-116]

`boolean`

###### Implementation of [#implementation-of-18]

[`CommandSequencer`](#commandsequencer).[`isNormalDisconnect`](#isnormaldisconnect-1)

##### nextCommand() [#nextcommand-3]

```ts
nextCommand(frame): readonly DeviceCommand[] | undefined;
```

Answers one complete frame, with the characteristic it arrived on.

Returning `undefined` sends nothing, which is how a sequencer waits: an unidentified
device is left alone rather than addressed with an opcode that may mean something else
on the hardware actually present.

###### Parameters [#parameters-58]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

###### Returns [#returns-117]

readonly [`DeviceCommand`](#devicecommand)[] \| `undefined`

###### Implementation of [#implementation-of-19]

[`CommandSequencer`](#commandsequencer).[`nextCommand`](#nextcommand-8)

##### onCommandTimeout() [#oncommandtimeout]

```ts
onCommandTimeout(): CommandTimeoutResult;
```

Re-sends the current command or ends the exchange after a response timeout.

###### Returns [#returns-118]

[`CommandTimeoutResult`](#commandtimeoutresult)

###### Implementation of [#implementation-of-20]

[`CommandSequencer`](#commandsequencer).[`onCommandTimeout`](#oncommandtimeout-2)

***

### CustomDevice [#customdevice]

Runs a device registered with defineCustomDevice.

Everything specific to the device is data: the services and characteristics it exposes,
how a complete frame is recognised, which frame carries which reading, and how each byte
range becomes a number. What is left here is the safety net - a reading is reported only
when every property the declaration named decoded to a finite number inside the range the
catalog accepts. Anything else is reported through onError and no measurement is emitted.

#### Extends [#extends-6]

- [`BTManagedDevice`](#abstract-btmanageddevice)\<[`CustomDeviceId`](#customdeviceid)\>

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

- [`VerovalDuoControlDevice`](#verovalduocontroldevice)

#### Accessors [#accessors-6]

##### readsHistoryOnRequest [#readshistoryonrequest-6]

###### Get Signature [#get-signature-6]

```ts
get readsHistoryOnRequest(): boolean;
```

A Lepu device that polls live keeps its stored files until asked; without polling it reads them on connect.

###### Returns [#returns-119]

`boolean`

###### Overrides [#overrides-6]

[`BTManagedDevice`](#abstract-btmanageddevice).[`readsHistoryOnRequest`](#readshistoryonrequest-3)

#### Constructors [#constructors-17]

##### Constructor [#constructor-17]

```ts
new CustomDevice(
   device,
   params,
   definition
): CustomDevice;
```

###### Parameters [#parameters-59]

| Parameter | Type |
| ------ | ------ |
| `device` | `Device` |
| `params` | `CreateDeviceParams`\<[`CustomDeviceId`](#customdeviceid)\> |
| `definition` | [`CustomDeviceDefinition`](#customdevicedefinition) |

###### Returns [#returns-120]

[`CustomDevice`](#customdevice)

###### Overrides [#overrides-7]

[`BTManagedDevice`](#abstract-btmanageddevice).[`constructor`](#constructor-9)

#### Methods [#methods-16]

##### connect() [#connect-6]

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

Connects to the device and starts reading.

Resolves immediately if already connected and shares the pending promise while connecting.

###### Returns [#returns-121]

`Promise`\<`void`\>

###### Throws [#throws-7]

If the device has been destroyed.

###### Inherited from [#inherited-from-30]

[`BTManagedDevice`](#abstract-btmanageddevice).[`connect`](#connect-3)

##### destroy() [#destroy-7]

```ts
destroy(): void;
```

Stops the connection and data processing and clears the callbacks.

###### Returns [#returns-122]

`void`

###### Inherited from [#inherited-from-31]

[`BTManagedDevice`](#abstract-btmanageddevice).[`destroy`](#destroy-3)

##### disconnect() [#disconnect-6]

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

Stops this device's subscriptions and closes its BLE connection.

###### Returns [#returns-123]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-32]

[`BTManagedDevice`](#abstract-btmanageddevice).[`disconnect`](#disconnect-3)

##### stopRecording() [#stoprecording-7]

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

Stops the open recording; the device stores it when it is long enough, and the files are then read.

###### Returns [#returns-124]

`Promise`\<`void`\>

###### Overrides [#overrides-8]

[`BTManagedDevice`](#abstract-btmanageddevice).[`stopRecording`](#stoprecording-3)

##### syncHistory() [#synchistory-6]

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

Reads the records the device stored: over the open connection, or once it next connects.

###### Returns [#returns-125]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-33]

[`BTManagedDevice`](#abstract-btmanageddevice).[`syncHistory`](#synchistory-3)

#### Properties [#properties-7]

| Property | Modifier | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ | ------ |
| <a id="property-device-6"></a> `device` | `public readonly` | `Device` | The underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`device`](#property-device-3) |
| <a id="property-devicedata-6"></a> `deviceData` | `public` | [`DeviceData`](#devicedata) | Identity and capabilities of this device, updated as device information is read. | [`BTManagedDevice`](#abstract-btmanageddevice).[`deviceData`](#property-devicedata-3) |
| <a id="property-id-6"></a> `id` | `public` | `string` | Platform identifier of the underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`id`](#property-id-3) |
| <a id="property-onconnectionevent-6"></a> `onConnectionEvent?` | `public` | (`data`) => `void` | Called for connection lifecycle events such as connected, bonded or history download. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onConnectionEvent`](#property-onconnectionevent-3) |
| <a id="property-ondevicedisconnected-6"></a> `onDeviceDisconnected?` | `public` | () => `void` | Called when the device disconnects. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceDisconnected`](#property-ondevicedisconnected-3) |
| <a id="property-ondevicestatuschanged-6"></a> `onDeviceStatusChanged?` | `public` | (`status`, `measurementTypeKey?`) => `void` | Called when the connection status changes. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceStatusChanged`](#property-ondevicestatuschanged-3) |
| <a id="property-onerror-6"></a> `onError?` | `public` | (`error`) => `void` | Called with a normalised error; cleared by `destroy`. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onError`](#property-onerror-3) |
| <a id="property-onresult-6"></a> `onResult?` | `public` | (`data`, `delivered?`) => `void` | Called with each measurement that passes the result policy; cleared by `destroy`. `delivered` is called once the app took it: the promise its result callback returned resolved. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onResult`](#property-onresult-3) |
| <a id="property-onwaveform-6"></a> `onWaveform?` | `public` | (`waveform`) => `void` | Called with the ECG samples of each realtime answer while a recorder records; for display only. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onWaveform`](#property-onwaveform-3) |

***

### DeviceSelectionRequiredError [#deviceselectionrequirederror]

Thrown when several devices match and none was selected.

#### Extends [#extends-7]

- `Error`

#### Constructors [#constructors-18]

##### Constructor [#constructor-18]

```ts
new DeviceSelectionRequiredError(model, ids): DeviceSelectionRequiredError;
```

###### Parameters [#parameters-60]

| Parameter | Type |
| ------ | ------ |
| `model` | `string` |
| `ids` | readonly `string`[] |

###### Returns [#returns-126]

[`DeviceSelectionRequiredError`](#deviceselectionrequirederror)

###### Overrides [#overrides-9]

`Error.constructor`

***

### GenialT31CommandSequencer [#genialt31commandsequencer]

Answers Genial's handshake, clock request, temperature and error frames.

#### Implements [#implements-9]

- [`CommandSequencer`](#commandsequencer)

#### Constructors [#constructors-19]

##### Constructor [#constructor-19]

```ts
new GenialT31CommandSequencer(now?): GenialT31CommandSequencer;
```

###### Parameters [#parameters-61]

| Parameter | Type |
| ------ | ------ |
| `now?` | () => `Date` |

###### Returns [#returns-127]

[`GenialT31CommandSequencer`](#genialt31commandsequencer)

#### Methods [#methods-17]

##### initialCommands() [#initialcommands-4]

```ts
initialCommands(): readonly DeviceCommand[];
```

Sent once every characteristic is subscribed. Empty starts a device that only listens.

May resolve later, for a first command that depends on state read from storage.

###### Returns [#returns-128]

readonly [`DeviceCommand`](#devicecommand)[]

###### Implementation of [#implementation-of-21]

[`CommandSequencer`](#commandsequencer).[`initialCommands`](#initialcommands-8)

##### nextCommand() [#nextcommand-4]

```ts
nextCommand(frame): readonly DeviceCommand[] | undefined;
```

Answers one complete frame, with the characteristic it arrived on.

Returning `undefined` sends nothing, which is how a sequencer waits: an unidentified
device is left alone rather than addressed with an opcode that may mean something else
on the hardware actually present.

###### Parameters [#parameters-62]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

###### Returns [#returns-129]

readonly [`DeviceCommand`](#devicecommand)[] \| `undefined`

###### Implementation of [#implementation-of-22]

[`CommandSequencer`](#commandsequencer).[`nextCommand`](#nextcommand-8)

***

### GenialT31Device [#genialt31device]

Genial T31 Bluetooth thermometer, as used by the ViHealth app.

#### Extends [#extends-8]

- [`BTManagedDevice`](#abstract-btmanageddevice)\<[`GENIAL_T31`](#enumeration-member-genial_t31)\>

#### Accessors [#accessors-7]

##### readsHistoryOnRequest [#readshistoryonrequest-7]

###### Get Signature [#get-signature-7]

```ts
get readsHistoryOnRequest(): boolean;
```

Whether the records the device stored are read only on `syncHistory`. Such a device goes live
as soon as it connects; any other reads its stored records each time it connects.

###### Returns [#returns-130]

`boolean`

###### Inherited from [#inherited-from-34]

[`BTManagedDevice`](#abstract-btmanageddevice).[`readsHistoryOnRequest`](#readshistoryonrequest-3)

#### Constructors [#constructors-20]

##### Constructor [#constructor-20]

```ts
new GenialT31Device(device, params): GenialT31Device;
```

###### Parameters [#parameters-63]

| Parameter | Type |
| ------ | ------ |
| `device` | `Device` |
| `params` | `CreateDeviceParams`\<[`GENIAL_T31`](#enumeration-member-genial_t31)\> |

###### Returns [#returns-131]

[`GenialT31Device`](#genialt31device)

###### Overrides [#overrides-10]

[`BTManagedDevice`](#abstract-btmanageddevice).[`constructor`](#constructor-9)

#### Methods [#methods-18]

##### connect() [#connect-7]

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

Connects to the device and starts reading.

Resolves immediately if already connected and shares the pending promise while connecting.

###### Returns [#returns-132]

`Promise`\<`void`\>

###### Throws [#throws-8]

If the device has been destroyed.

###### Inherited from [#inherited-from-35]

[`BTManagedDevice`](#abstract-btmanageddevice).[`connect`](#connect-3)

##### destroy() [#destroy-8]

```ts
destroy(): void;
```

Stops the connection and data processing and clears the callbacks.

###### Returns [#returns-133]

`void`

###### Inherited from [#inherited-from-36]

[`BTManagedDevice`](#abstract-btmanageddevice).[`destroy`](#destroy-3)

##### disconnect() [#disconnect-7]

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

Stops this device's subscriptions and closes its BLE connection.

###### Returns [#returns-134]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-37]

[`BTManagedDevice`](#abstract-btmanageddevice).[`disconnect`](#disconnect-3)

##### stopRecording() [#stoprecording-8]

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

Stops a recording the device holds open; only recorders that report one support it.

###### Returns [#returns-135]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-38]

[`BTManagedDevice`](#abstract-btmanageddevice).[`stopRecording`](#stoprecording-3)

##### syncHistory() [#synchistory-7]

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

Reads the records the device stored: over the open connection, or once it next connects.

###### Returns [#returns-136]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-39]

[`BTManagedDevice`](#abstract-btmanageddevice).[`syncHistory`](#synchistory-3)

#### Properties [#properties-8]

| Property | Modifier | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ | ------ |
| <a id="property-device-7"></a> `device` | `public readonly` | `Device` | The underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`device`](#property-device-3) |
| <a id="property-devicedata-7"></a> `deviceData` | `public` | [`DeviceData`](#devicedata) | Identity and capabilities of this device, updated as device information is read. | [`BTManagedDevice`](#abstract-btmanageddevice).[`deviceData`](#property-devicedata-3) |
| <a id="property-id-7"></a> `id` | `public` | `string` | Platform identifier of the underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`id`](#property-id-3) |
| <a id="property-onconnectionevent-7"></a> `onConnectionEvent?` | `public` | (`data`) => `void` | Called for connection lifecycle events such as connected, bonded or history download. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onConnectionEvent`](#property-onconnectionevent-3) |
| <a id="property-ondevicedisconnected-7"></a> `onDeviceDisconnected?` | `public` | () => `void` | Called when the device disconnects. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceDisconnected`](#property-ondevicedisconnected-3) |
| <a id="property-ondevicestatuschanged-7"></a> `onDeviceStatusChanged?` | `public` | (`status`, `measurementTypeKey?`) => `void` | Called when the connection status changes. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceStatusChanged`](#property-ondevicestatuschanged-3) |
| <a id="property-onerror-7"></a> `onError?` | `public` | (`error`) => `void` | Called with a normalised error; cleared by `destroy`. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onError`](#property-onerror-3) |
| <a id="property-onresult-7"></a> `onResult?` | `public` | (`data`, `delivered?`) => `void` | Called with each measurement that passes the result policy; cleared by `destroy`. `delivered` is called once the app took it: the promise its result callback returned resolved. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onResult`](#property-onresult-3) |
| <a id="property-onwaveform-7"></a> `onWaveform?` | `public` | (`waveform`) => `void` | Called with the ECG samples of each realtime answer while a recorder records; for display only. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onWaveform`](#property-onwaveform-3) |

***

### GenialT31FrameReader [#genialt31framereader]

Reads the A6 ... checksum 6A frames used by Genial T31 thermometers.

#### Implements [#implements-10]

- `FrameReader`

#### Constructors [#constructors-21]

##### Constructor [#constructor-21]

```ts
new GenialT31FrameReader(): GenialT31FrameReader;
```

###### Returns [#returns-137]

[`GenialT31FrameReader`](#genialt31framereader)

#### Methods [#methods-19]

##### readFrame() [#readframe-4]

```ts
readFrame(buffer): FrameReadResult;
```

Extracts the next complete frame from the notification buffer.

###### Parameters [#parameters-64]

| Parameter | Type |
| ------ | ------ |
| `buffer` | readonly `string`[] |

###### Returns [#returns-138]

`FrameReadResult`

###### Implementation of [#implementation-of-23]

`FrameReader.readFrame`

***

### LepuFileTransfer [#lepufiletransfer]

Downloads the records a Lepu device has stored.

Every opcode this uses is generic and inert - list, open, read, close - so unlike a
realtime poll it is safe on hardware whose model is not known. That is what makes it the
one thing the whole family can be asked for without identifying it first.

The exchange is self-clocking and has no windowing: each reply decides the next request,
and the device chooses how much to send, so the offset advances by what actually arrived
rather than by an assumed chunk size. There is no retry in the protocol either - a single
dropped reply stalls the transfer with nothing to resume it - which is what the data
processor's stuck-data timeout is the watchdog for.

A short read is an error, not a truncated success: the device is asked to close the file
and the reading is discarded, because half an ECG that looks like a whole one is worse
than none.

#### Implements [#implements-11]

- [`CommandSequencer`](#commandsequencer)

#### Constructors [#constructors-22]

##### Constructor [#constructor-22]

```ts
new LepuFileTransfer(params): LepuFileTransfer;
```

###### Parameters [#parameters-65]

| Parameter | Type |
| ------ | ------ |
| `params` | [`LepuFileTransferParams`](#lepufiletransferparams) |

###### Returns [#returns-139]

[`LepuFileTransfer`](#lepufiletransfer)

#### Methods [#methods-20]

##### initialCommands() [#initialcommands-5]

```ts
initialCommands(delayBeforeWriteMs?): readonly DeviceCommand[];
```

Sent once every characteristic is subscribed. Empty starts a device that only listens.

May resolve later, for a first command that depends on state read from storage.

###### Parameters [#parameters-66]

| Parameter | Type |
| ------ | ------ |
| `delayBeforeWriteMs?` | `number` |

###### Returns [#returns-140]

readonly [`DeviceCommand`](#devicecommand)[]

###### Implementation of [#implementation-of-24]

[`CommandSequencer`](#commandsequencer).[`initialCommands`](#initialcommands-8)

##### isHistoryTransfer() [#ishistorytransfer-3]

```ts
isHistoryTransfer(): boolean;
```

True when accepted results are records downloaded from device history.

###### Returns [#returns-141]

`boolean`

###### Implementation of [#implementation-of-25]

[`CommandSequencer`](#commandsequencer).[`isHistoryTransfer`](#ishistorytransfer-5)

##### nextCommand() [#nextcommand-5]

```ts
nextCommand(frame): readonly DeviceCommand[] | undefined;
```

Answers one complete frame, with the characteristic it arrived on.

Returning `undefined` sends nothing, which is how a sequencer waits: an unidentified
device is left alone rather than addressed with an opcode that may mean something else
on the hardware actually present.

###### Parameters [#parameters-67]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

###### Returns [#returns-142]

readonly [`DeviceCommand`](#devicecommand)[] \| `undefined`

###### Implementation of [#implementation-of-26]

[`CommandSequencer`](#commandsequencer).[`nextCommand`](#nextcommand-8)

***

### S9CommandSequencer [#s9commandsequencer]

Runs only the SH09 commands verified on firmware image 1.

#### Implements [#implements-12]

- [`CommandSequencer`](#commandsequencer)

#### Constructors [#constructors-23]

##### Constructor [#constructor-23]

```ts
new S9CommandSequencer(params): S9CommandSequencer;
```

###### Parameters [#parameters-68]

| Parameter | Type |
| ------ | ------ |
| `params` | `S9CommandSequencerParams` |

###### Returns [#returns-143]

[`S9CommandSequencer`](#s9commandsequencer)

#### Methods [#methods-21]

##### commandProgress() [#commandprogress-1]

```ts
commandProgress(frame): "ignored" | "partial" | "complete";
```

Describes whether a frame is ignored, partial, or completes the outstanding command.

###### Parameters [#parameters-69]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

###### Returns [#returns-144]

`"ignored"` \| `"partial"` \| `"complete"`

###### Implementation of [#implementation-of-27]

[`CommandSequencer`](#commandsequencer).[`commandProgress`](#commandprogress-2)

##### commandTimeoutMs() [#commandtimeoutms-1]

```ts
commandTimeoutMs(): number;
```

The response timeout for the currently outstanding command, when a protocol needs one.

###### Returns [#returns-145]

`number`

###### Implementation of [#implementation-of-28]

[`CommandSequencer`](#commandsequencer).[`commandTimeoutMs`](#commandtimeoutms-2)

##### initialCommands() [#initialcommands-6]

```ts
initialCommands(): readonly DeviceCommand[];
```

Sent once every characteristic is subscribed. Empty starts a device that only listens.

May resolve later, for a first command that depends on state read from storage.

###### Returns [#returns-146]

readonly [`DeviceCommand`](#devicecommand)[]

###### Implementation of [#implementation-of-29]

[`CommandSequencer`](#commandsequencer).[`initialCommands`](#initialcommands-8)

##### isHistoryTransfer() [#ishistorytransfer-4]

```ts
isHistoryTransfer(): boolean;
```

True when accepted results are records downloaded from device history.

###### Returns [#returns-147]

`boolean`

###### Implementation of [#implementation-of-30]

[`CommandSequencer`](#commandsequencer).[`isHistoryTransfer`](#ishistorytransfer-5)

##### nextCommand() [#nextcommand-6]

```ts
nextCommand(frame): readonly DeviceCommand[] | undefined;
```

Answers one complete frame, with the characteristic it arrived on.

Returning `undefined` sends nothing, which is how a sequencer waits: an unidentified
device is left alone rather than addressed with an opcode that may mean something else
on the hardware actually present.

###### Parameters [#parameters-70]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

###### Returns [#returns-148]

readonly [`DeviceCommand`](#devicecommand)[] \| `undefined`

###### Implementation of [#implementation-of-31]

[`CommandSequencer`](#commandsequencer).[`nextCommand`](#nextcommand-8)

##### onCommandTimeout() [#oncommandtimeout-1]

```ts
onCommandTimeout(): CommandTimeoutResult;
```

Re-sends the current command or ends the exchange after a response timeout.

###### Returns [#returns-149]

[`CommandTimeoutResult`](#commandtimeoutresult)

###### Implementation of [#implementation-of-32]

[`CommandSequencer`](#commandsequencer).[`onCommandTimeout`](#oncommandtimeout-2)

***

### S9FrameReader [#s9framereader]

SH09 notifications are fixed-width, zero-padded 20-byte replies.

#### Implements [#implements-13]

- `FrameReader`

#### Constructors [#constructors-24]

##### Constructor [#constructor-24]

```ts
new S9FrameReader(): S9FrameReader;
```

###### Returns [#returns-150]

[`S9FrameReader`](#s9framereader)

#### Methods [#methods-22]

##### readFrame() [#readframe-5]

```ts
readFrame(buffer): FrameReadResult;
```

Returns the next fixed-width frame in the buffer.

###### Parameters [#parameters-71]

| Parameter | Type |
| ------ | ------ |
| `buffer` | readonly `string`[] |

###### Returns [#returns-151]

`FrameReadResult`

###### Implementation of [#implementation-of-33]

`FrameReader.readFrame`

***

### TrasenseS9Device [#trasenses9device]

Trasense SH09. Its address and advertisement data are sensitive and never logged.

#### Extends [#extends-9]

- [`BTManagedDevice`](#abstract-btmanageddevice)\<[`TRASENSE_S9`](#enumeration-member-trasense_s9)\>

#### Accessors [#accessors-8]

##### readsHistoryOnRequest [#readshistoryonrequest-8]

###### Get Signature [#get-signature-8]

```ts
get readsHistoryOnRequest(): boolean;
```

Whether the records the device stored are read only on `syncHistory`. Such a device goes live
as soon as it connects; any other reads its stored records each time it connects.

###### Returns [#returns-152]

`boolean`

###### Inherited from [#inherited-from-40]

[`BTManagedDevice`](#abstract-btmanageddevice).[`readsHistoryOnRequest`](#readshistoryonrequest-3)

#### Constructors [#constructors-25]

##### Constructor [#constructor-25]

```ts
new TrasenseS9Device(device, params): TrasenseS9Device;
```

###### Parameters [#parameters-72]

| Parameter | Type |
| ------ | ------ |
| `device` | `Device` |
| `params` | `CreateDeviceParams`\<[`TRASENSE_S9`](#enumeration-member-trasense_s9)\> |

###### Returns [#returns-153]

[`TrasenseS9Device`](#trasenses9device)

###### Overrides [#overrides-11]

[`BTManagedDevice`](#abstract-btmanageddevice).[`constructor`](#constructor-9)

#### Methods [#methods-23]

##### connect() [#connect-8]

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

Connects to the device and starts reading.

Resolves immediately if already connected and shares the pending promise while connecting.

###### Returns [#returns-154]

`Promise`\<`void`\>

###### Throws [#throws-9]

If the device has been destroyed.

###### Inherited from [#inherited-from-41]

[`BTManagedDevice`](#abstract-btmanageddevice).[`connect`](#connect-3)

##### destroy() [#destroy-9]

```ts
destroy(): void;
```

Stops the connection and data processing and clears the callbacks.

###### Returns [#returns-155]

`void`

###### Inherited from [#inherited-from-42]

[`BTManagedDevice`](#abstract-btmanageddevice).[`destroy`](#destroy-3)

##### disconnect() [#disconnect-8]

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

Stops this device's subscriptions and closes its BLE connection.

###### Returns [#returns-156]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-43]

[`BTManagedDevice`](#abstract-btmanageddevice).[`disconnect`](#disconnect-3)

##### stopRecording() [#stoprecording-9]

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

Stops a recording the device holds open; only recorders that report one support it.

###### Returns [#returns-157]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-44]

[`BTManagedDevice`](#abstract-btmanageddevice).[`stopRecording`](#stoprecording-3)

##### syncHistory() [#synchistory-8]

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

Reads the records the device stored: over the open connection, or once it next connects.

###### Returns [#returns-158]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-45]

[`BTManagedDevice`](#abstract-btmanageddevice).[`syncHistory`](#synchistory-3)

#### Properties [#properties-9]

| Property | Modifier | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ | ------ |
| <a id="property-device-8"></a> `device` | `public readonly` | `Device` | The underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`device`](#property-device-3) |
| <a id="property-devicedata-8"></a> `deviceData` | `public` | [`DeviceData`](#devicedata) | Identity and capabilities of this device, updated as device information is read. | [`BTManagedDevice`](#abstract-btmanageddevice).[`deviceData`](#property-devicedata-3) |
| <a id="property-id-8"></a> `id` | `public` | `string` | Platform identifier of the underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`id`](#property-id-3) |
| <a id="property-onconnectionevent-8"></a> `onConnectionEvent?` | `public` | (`data`) => `void` | Called for connection lifecycle events such as connected, bonded or history download. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onConnectionEvent`](#property-onconnectionevent-3) |
| <a id="property-ondevicedisconnected-8"></a> `onDeviceDisconnected?` | `public` | () => `void` | Called when the device disconnects. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceDisconnected`](#property-ondevicedisconnected-3) |
| <a id="property-ondevicestatuschanged-8"></a> `onDeviceStatusChanged?` | `public` | (`status`, `measurementTypeKey?`) => `void` | Called when the connection status changes. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceStatusChanged`](#property-ondevicestatuschanged-3) |
| <a id="property-onerror-8"></a> `onError?` | `public` | (`error`) => `void` | Called with a normalised error; cleared by `destroy`. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onError`](#property-onerror-3) |
| <a id="property-onresult-8"></a> `onResult?` | `public` | (`data`, `delivered?`) => `void` | Called with each measurement that passes the result policy; cleared by `destroy`. `delivered` is called once the app took it: the promise its result callback returned resolved. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onResult`](#property-onresult-3) |
| <a id="property-onwaveform-8"></a> `onWaveform?` | `public` | (`waveform`) => `void` | Called with the ECG samples of each realtime answer while a recorder records; for display only. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onWaveform`](#property-onwaveform-3) |

***

### VerovalActivityDevice [#verovalactivitydevice]

HARTMANN's Veroval Activity wristband, including stored step and heart-rate history.

#### Extends [#extends-10]

- [`BTManagedDevice`](#abstract-btmanageddevice)\<[`VEROVAL_ACTIVITY`](#enumeration-member-veroval_activity)\>

#### Accessors [#accessors-9]

##### readsHistoryOnRequest [#readshistoryonrequest-9]

###### Get Signature [#get-signature-9]

```ts
get readsHistoryOnRequest(): boolean;
```

Whether the records the device stored are read only on `syncHistory`. Such a device goes live
as soon as it connects; any other reads its stored records each time it connects.

###### Returns [#returns-159]

`boolean`

###### Inherited from [#inherited-from-46]

[`BTManagedDevice`](#abstract-btmanageddevice).[`readsHistoryOnRequest`](#readshistoryonrequest-3)

#### Constructors [#constructors-26]

##### Constructor [#constructor-26]

```ts
new VerovalActivityDevice(device, params): VerovalActivityDevice;
```

###### Parameters [#parameters-73]

| Parameter | Type |
| ------ | ------ |
| `device` | `Device` |
| `params` | `CreateDeviceParams`\<[`VEROVAL_ACTIVITY`](#enumeration-member-veroval_activity)\> |

###### Returns [#returns-160]

[`VerovalActivityDevice`](#verovalactivitydevice)

###### Overrides [#overrides-12]

[`BTManagedDevice`](#abstract-btmanageddevice).[`constructor`](#constructor-9)

#### Methods [#methods-24]

##### connect() [#connect-9]

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

Connects to the device and starts reading.

Resolves immediately if already connected and shares the pending promise while connecting.

###### Returns [#returns-161]

`Promise`\<`void`\>

###### Throws [#throws-10]

If the device has been destroyed.

###### Inherited from [#inherited-from-47]

[`BTManagedDevice`](#abstract-btmanageddevice).[`connect`](#connect-3)

##### destroy() [#destroy-10]

```ts
destroy(): void;
```

Stops the connection and data processing and clears the callbacks.

###### Returns [#returns-162]

`void`

###### Inherited from [#inherited-from-48]

[`BTManagedDevice`](#abstract-btmanageddevice).[`destroy`](#destroy-3)

##### disconnect() [#disconnect-9]

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

Stops this device's subscriptions and closes its BLE connection.

###### Returns [#returns-163]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-49]

[`BTManagedDevice`](#abstract-btmanageddevice).[`disconnect`](#disconnect-3)

##### stopRecording() [#stoprecording-10]

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

Stops a recording the device holds open; only recorders that report one support it.

###### Returns [#returns-164]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-50]

[`BTManagedDevice`](#abstract-btmanageddevice).[`stopRecording`](#stoprecording-3)

##### syncHistory() [#synchistory-9]

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

Reads the records the device stored: over the open connection, or once it next connects.

###### Returns [#returns-165]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-51]

[`BTManagedDevice`](#abstract-btmanageddevice).[`syncHistory`](#synchistory-3)

#### Properties [#properties-10]

| Property | Modifier | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ | ------ |
| <a id="property-device-9"></a> `device` | `public readonly` | `Device` | The underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`device`](#property-device-3) |
| <a id="property-devicedata-9"></a> `deviceData` | `public` | [`DeviceData`](#devicedata) | Identity and capabilities of this device, updated as device information is read. | [`BTManagedDevice`](#abstract-btmanageddevice).[`deviceData`](#property-devicedata-3) |
| <a id="property-id-9"></a> `id` | `public` | `string` | Platform identifier of the underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`id`](#property-id-3) |
| <a id="property-onconnectionevent-9"></a> `onConnectionEvent?` | `public` | (`data`) => `void` | Called for connection lifecycle events such as connected, bonded or history download. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onConnectionEvent`](#property-onconnectionevent-3) |
| <a id="property-ondevicedisconnected-9"></a> `onDeviceDisconnected?` | `public` | () => `void` | Called when the device disconnects. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceDisconnected`](#property-ondevicedisconnected-3) |
| <a id="property-ondevicestatuschanged-9"></a> `onDeviceStatusChanged?` | `public` | (`status`, `measurementTypeKey?`) => `void` | Called when the connection status changes. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceStatusChanged`](#property-ondevicestatuschanged-3) |
| <a id="property-onerror-9"></a> `onError?` | `public` | (`error`) => `void` | Called with a normalised error; cleared by `destroy`. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onError`](#property-onerror-3) |
| <a id="property-onresult-9"></a> `onResult?` | `public` | (`data`, `delivered?`) => `void` | Called with each measurement that passes the result policy; cleared by `destroy`. `delivered` is called once the app took it: the promise its result callback returned resolved. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onResult`](#property-onresult-3) |
| <a id="property-onwaveform-9"></a> `onWaveform?` | `public` | (`waveform`) => `void` | Called with the ECG samples of each realtime answer while a recorder records; for display only. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onWaveform`](#property-onwaveform-3) |

***

### VerovalActivitySequencer [#verovalactivitysequencer]

Drives the private history protocol used by the Veroval Activity wristband.

#### Implements [#implements-14]

- [`CommandSequencer`](#commandsequencer)

#### Constructors [#constructors-27]

##### Constructor [#constructor-27]

```ts
new VerovalActivitySequencer(params): VerovalActivitySequencer;
```

###### Parameters [#parameters-74]

| Parameter | Type |
| ------ | ------ |
| `params` | `VerovalActivitySequencerParams` |

###### Returns [#returns-166]

[`VerovalActivitySequencer`](#verovalactivitysequencer)

#### Methods [#methods-25]

##### initialCommands() [#initialcommands-7]

```ts
initialCommands(): readonly DeviceCommand[];
```

Sent once every characteristic is subscribed. Empty starts a device that only listens.

May resolve later, for a first command that depends on state read from storage.

###### Returns [#returns-167]

readonly [`DeviceCommand`](#devicecommand)[]

###### Implementation of [#implementation-of-34]

[`CommandSequencer`](#commandsequencer).[`initialCommands`](#initialcommands-8)

##### nextCommand() [#nextcommand-7]

```ts
nextCommand(frame): readonly DeviceCommand[] | undefined;
```

Answers one complete frame, with the characteristic it arrived on.

Returning `undefined` sends nothing, which is how a sequencer waits: an unidentified
device is left alone rather than addressed with an opcode that may mean something else
on the hardware actually present.

###### Parameters [#parameters-75]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

###### Returns [#returns-168]

readonly [`DeviceCommand`](#devicecommand)[] \| `undefined`

###### Implementation of [#implementation-of-35]

[`CommandSequencer`](#commandsequencer).[`nextCommand`](#nextcommand-8)

***

### VerovalDuoControlDevice [#verovalduocontroldevice]

The Veroval duo control.

A device class rather than a declaration, because reading it is a conversation: the two
user memories are asked in turn, and the device answers with bare control bytes as often
as with payload. The decoding is still declared - the class supplies the framing and the
walk, and nothing else.

Readings are stored measurements, not live ones. The device hands over its history when
asked, so what arrives was taken before the connection and may be days old.

#### Extends [#extends-11]

- [`CustomDevice`](#customdevice)

#### Accessors [#accessors-10]

##### readsHistoryOnRequest [#readshistoryonrequest-10]

###### Get Signature [#get-signature-10]

```ts
get readsHistoryOnRequest(): boolean;
```

A Lepu device that polls live keeps its stored files until asked; without polling it reads them on connect.

###### Returns [#returns-169]

`boolean`

###### Inherited from [#inherited-from-52]

[`CustomDevice`](#customdevice).[`readsHistoryOnRequest`](#readshistoryonrequest-6)

#### Constructors [#constructors-28]

##### Constructor [#constructor-28]

```ts
new VerovalDuoControlDevice(device, params): VerovalDuoControlDevice;
```

###### Parameters [#parameters-76]

| Parameter | Type |
| ------ | ------ |
| `device` | `Device` |
| `params` | `CreateDeviceParams`\<[`CustomDeviceId`](#customdeviceid)\> |

###### Returns [#returns-170]

[`VerovalDuoControlDevice`](#verovalduocontroldevice)

###### Overrides [#overrides-13]

[`CustomDevice`](#customdevice).[`constructor`](#constructor-17)

#### Methods [#methods-26]

##### connect() [#connect-10]

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

Connects to the device and starts reading.

Resolves immediately if already connected and shares the pending promise while connecting.

###### Returns [#returns-171]

`Promise`\<`void`\>

###### Throws [#throws-11]

If the device has been destroyed.

###### Inherited from [#inherited-from-53]

[`CustomDevice`](#customdevice).[`connect`](#connect-6)

##### destroy() [#destroy-11]

```ts
destroy(): void;
```

Stops the connection and data processing and clears the callbacks.

###### Returns [#returns-172]

`void`

###### Inherited from [#inherited-from-54]

[`CustomDevice`](#customdevice).[`destroy`](#destroy-7)

##### disconnect() [#disconnect-10]

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

Stops this device's subscriptions and closes its BLE connection.

###### Returns [#returns-173]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-55]

[`CustomDevice`](#customdevice).[`disconnect`](#disconnect-6)

##### stopRecording() [#stoprecording-11]

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

Stops the open recording; the device stores it when it is long enough, and the files are then read.

###### Returns [#returns-174]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-56]

[`CustomDevice`](#customdevice).[`stopRecording`](#stoprecording-7)

##### syncHistory() [#synchistory-10]

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

Reads the records the device stored: over the open connection, or once it next connects.

###### Returns [#returns-175]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-57]

[`CustomDevice`](#customdevice).[`syncHistory`](#synchistory-6)

#### Properties [#properties-11]

| Property | Modifier | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ | ------ |
| <a id="property-device-10"></a> `device` | `public readonly` | `Device` | The underlying BLE device. | [`CustomDevice`](#customdevice).[`device`](#property-device-6) |
| <a id="property-devicedata-10"></a> `deviceData` | `public` | [`DeviceData`](#devicedata) | Identity and capabilities of this device, updated as device information is read. | [`CustomDevice`](#customdevice).[`deviceData`](#property-devicedata-6) |
| <a id="property-id-10"></a> `id` | `public` | `string` | Platform identifier of the underlying BLE device. | [`CustomDevice`](#customdevice).[`id`](#property-id-6) |
| <a id="property-onconnectionevent-10"></a> `onConnectionEvent?` | `public` | (`data`) => `void` | Called for connection lifecycle events such as connected, bonded or history download. | [`CustomDevice`](#customdevice).[`onConnectionEvent`](#property-onconnectionevent-6) |
| <a id="property-ondevicedisconnected-10"></a> `onDeviceDisconnected?` | `public` | () => `void` | Called when the device disconnects. | [`CustomDevice`](#customdevice).[`onDeviceDisconnected`](#property-ondevicedisconnected-6) |
| <a id="property-ondevicestatuschanged-10"></a> `onDeviceStatusChanged?` | `public` | (`status`, `measurementTypeKey?`) => `void` | Called when the connection status changes. | [`CustomDevice`](#customdevice).[`onDeviceStatusChanged`](#property-ondevicestatuschanged-6) |
| <a id="property-onerror-10"></a> `onError?` | `public` | (`error`) => `void` | Called with a normalised error; cleared by `destroy`. | [`CustomDevice`](#customdevice).[`onError`](#property-onerror-6) |
| <a id="property-onresult-10"></a> `onResult?` | `public` | (`data`, `delivered?`) => `void` | Called with each measurement that passes the result policy; cleared by `destroy`. `delivered` is called once the app took it: the promise its result callback returned resolved. | [`CustomDevice`](#customdevice).[`onResult`](#property-onresult-6) |
| <a id="property-onwaveform-10"></a> `onWaveform?` | `public` | (`waveform`) => `void` | Called with the ECG samples of each realtime answer while a recorder records; for display only. | [`CustomDevice`](#customdevice).[`onWaveform`](#property-onwaveform-6) |

***

### VerovalEcgDevice [#verovalecgdevice]

The Veroval ECG.

Reading it is a download rather than a decode, so the whole recording is assembled before
anything is reported: thirty-four seconds of samples at 128 Hz, two bytes each, converted
to millivolts with the device's own calibration.

The vendor's app plots a thirty-second window of this with a baseline-wander filter
applied. That is a display transform, not calibration, so it is deliberately not
reproduced here - what is reported is what the device recorded.

#### Extends [#extends-12]

- [`BTManagedDevice`](#abstract-btmanageddevice)\<[`VEROVAL_ECG`](#enumeration-member-veroval_ecg)\>

#### Accessors [#accessors-11]

##### readsHistoryOnRequest [#readshistoryonrequest-11]

###### Get Signature [#get-signature-11]

```ts
get readsHistoryOnRequest(): boolean;
```

Whether the records the device stored are read only on `syncHistory`. Such a device goes live
as soon as it connects; any other reads its stored records each time it connects.

###### Returns [#returns-176]

`boolean`

###### Inherited from [#inherited-from-58]

[`BTManagedDevice`](#abstract-btmanageddevice).[`readsHistoryOnRequest`](#readshistoryonrequest-3)

#### Constructors [#constructors-29]

##### Constructor [#constructor-29]

```ts
new VerovalEcgDevice(device, params): VerovalEcgDevice;
```

###### Parameters [#parameters-77]

| Parameter | Type |
| ------ | ------ |
| `device` | `Device` |
| `params` | `CreateDeviceParams`\<[`VEROVAL_ECG`](#enumeration-member-veroval_ecg)\> |

###### Returns [#returns-177]

[`VerovalEcgDevice`](#verovalecgdevice)

###### Overrides [#overrides-14]

[`BTManagedDevice`](#abstract-btmanageddevice).[`constructor`](#constructor-9)

#### Methods [#methods-27]

##### connect() [#connect-11]

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

Connects to the device and starts reading.

Resolves immediately if already connected and shares the pending promise while connecting.

###### Returns [#returns-178]

`Promise`\<`void`\>

###### Throws [#throws-12]

If the device has been destroyed.

###### Inherited from [#inherited-from-59]

[`BTManagedDevice`](#abstract-btmanageddevice).[`connect`](#connect-3)

##### destroy() [#destroy-12]

```ts
destroy(): void;
```

Stops the connection and data processing and clears the callbacks.

###### Returns [#returns-179]

`void`

###### Inherited from [#inherited-from-60]

[`BTManagedDevice`](#abstract-btmanageddevice).[`destroy`](#destroy-3)

##### disconnect() [#disconnect-11]

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

Stops this device's subscriptions and closes its BLE connection.

###### Returns [#returns-180]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-61]

[`BTManagedDevice`](#abstract-btmanageddevice).[`disconnect`](#disconnect-3)

##### stopRecording() [#stoprecording-12]

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

Stops a recording the device holds open; only recorders that report one support it.

###### Returns [#returns-181]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-62]

[`BTManagedDevice`](#abstract-btmanageddevice).[`stopRecording`](#stoprecording-3)

##### syncHistory() [#synchistory-11]

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

Reads the records the device stored: over the open connection, or once it next connects.

###### Returns [#returns-182]

`Promise`\<`void`\>

###### Inherited from [#inherited-from-63]

[`BTManagedDevice`](#abstract-btmanageddevice).[`syncHistory`](#synchistory-3)

#### Properties [#properties-12]

| Property | Modifier | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ | ------ |
| <a id="property-device-11"></a> `device` | `public readonly` | `Device` | The underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`device`](#property-device-3) |
| <a id="property-devicedata-11"></a> `deviceData` | `public` | [`DeviceData`](#devicedata) | Identity and capabilities of this device, updated as device information is read. | [`BTManagedDevice`](#abstract-btmanageddevice).[`deviceData`](#property-devicedata-3) |
| <a id="property-id-11"></a> `id` | `public` | `string` | Platform identifier of the underlying BLE device. | [`BTManagedDevice`](#abstract-btmanageddevice).[`id`](#property-id-3) |
| <a id="property-onconnectionevent-11"></a> `onConnectionEvent?` | `public` | (`data`) => `void` | Called for connection lifecycle events such as connected, bonded or history download. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onConnectionEvent`](#property-onconnectionevent-3) |
| <a id="property-ondevicedisconnected-11"></a> `onDeviceDisconnected?` | `public` | () => `void` | Called when the device disconnects. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceDisconnected`](#property-ondevicedisconnected-3) |
| <a id="property-ondevicestatuschanged-11"></a> `onDeviceStatusChanged?` | `public` | (`status`, `measurementTypeKey?`) => `void` | Called when the connection status changes. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onDeviceStatusChanged`](#property-ondevicestatuschanged-3) |
| <a id="property-onerror-11"></a> `onError?` | `public` | (`error`) => `void` | Called with a normalised error; cleared by `destroy`. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onError`](#property-onerror-3) |
| <a id="property-onresult-11"></a> `onResult?` | `public` | (`data`, `delivered?`) => `void` | Called with each measurement that passes the result policy; cleared by `destroy`. `delivered` is called once the app took it: the promise its result callback returned resolved. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onResult`](#property-onresult-3) |
| <a id="property-onwaveform-11"></a> `onWaveform?` | `public` | (`waveform`) => `void` | Called with the ECG samples of each realtime answer while a recorder records; for display only. | [`BTManagedDevice`](#abstract-btmanageddevice).[`onWaveform`](#property-onwaveform-3) |

## Functions [#functions]

### aoj20aThermometer() [#aoj20athermometer]

```ts
function aoj20aThermometer(params): CustomDeviceDefinition;
```

The AOJ-20A infrared thermometer.

Declared without a write characteristic, because the device sends its reading rather than
waiting to be asked: the vendor app has a request for it, calls it from nowhere, and still
displays temperatures - so the reply arrives when someone takes a measurement. Not writing
also means not polling, which for a spot-check device would otherwise re-report the same
reading for as long as the link stayed up.

Only the realtime reply is declared. The stored-history reply shares the header and would
need its own case; nothing reads history yet, and a case that decoded it into the same
measurement would post old readings as though they had just been taken.

#### Parameters [#parameters-78]

| Parameter | Type |
| ------ | ------ |
| `params` | `AojDeviceParams` |

#### Returns [#returns-183]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### aojCommandByte() [#aojcommandbyte]

```ts
function aojCommandByte(frame): number;
```

Reads the command byte of a frame.

#### Parameters [#parameters-79]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

#### Returns [#returns-184]

`number`

***

### bluetoothErrorCodeFor() [#bluetootherrorcodefor]

```ts
function bluetoothErrorCodeFor(error): BluetoothErrorCode;
```

Classifies any thrown value into a `BluetoothErrorCode`.

#### Parameters [#parameters-80]

| Parameter | Type |
| ------ | ------ |
| `error` | `unknown` |

#### Returns [#returns-185]

[`BluetoothErrorCode`](#bluetootherrorcode)

***

### bosoMedicusMonitor() [#bosomedicusmonitor]

```ts
function bosoMedicusMonitor(params): CustomDeviceDefinition;
```

Declares a boso medicus system monitor.

The monitor stores readings and sends them through the standard 0x1810/0x2A35 profile after
pairing. The shared profile declaration handles mmHg, optional timestamps, pulse rate and
the profile's user/status bytes without inventing a boso-specific wire format.

#### Parameters [#parameters-81]

| Parameter | Type |
| ------ | ------ |
| `params` | [`BosoMedicusParams`](#bosomedicusparams) |

#### Returns [#returns-186]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### bp2aMonitor() [#bp2amonitor]

```ts
function bp2aMonitor(params): CustomDeviceDefinition;
```

BP2A, the arm-cuff monitor of the series.

#### Parameters [#parameters-82]

| Parameter | Type |
| ------ | ------ |
| `params` | `ViatomBpParams` |

#### Returns [#returns-187]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### bp2tMonitor() [#bp2tmonitor]

```ts
function bp2tMonitor(params): CustomDeviceDefinition;
```

BP2T, documented by the vendor alongside BP2 and BP2A as the same protocol.

#### Parameters [#parameters-83]

| Parameter | Type |
| ------ | ------ |
| `params` | `ViatomBpParams` |

#### Returns [#returns-188]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### bp2vMonitor() [#bp2vmonitor]

```ts
function bp2vMonitor(params): CustomDeviceDefinition;
```

BP2V, the WiFi variant that uses the BP2 realtime layout without ECG frames.

#### Parameters [#parameters-84]

| Parameter | Type |
| ------ | ------ |
| `params` | `ViatomBpParams` |

#### Returns [#returns-189]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### bp2wMonitor() [#bp2wmonitor]

```ts
function bp2wMonitor(params): CustomDeviceDefinition;
```

BP2W. Documented in its own section, but decoding the same realtime struct.

#### Parameters [#parameters-85]

| Parameter | Type |
| ------ | ------ |
| `params` | `ViatomBpParams` |

#### Returns [#returns-190]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### bpu26Monitor() [#bpu26monitor]

```ts
function bpu26Monitor(params): CustomDeviceDefinition;
```

BPU 26, the Veroval compact+ upper-arm monitor.

#### Parameters [#parameters-86]

| Parameter | Type |
| ------ | ------ |
| `params` | `VerovalBpParams` |

#### Returns [#returns-191]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### bpw26Monitor() [#bpw26monitor]

```ts
function bpw26Monitor(params): CustomDeviceDefinition;
```

BPW 26, the Veroval compact+ wrist monitor.

#### Parameters [#parameters-87]

| Parameter | Type |
| ------ | ------ |
| `params` | `VerovalBpParams` |

#### Returns [#returns-192]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### btDeviceMatches() [#btdevicematches]

```ts
function btDeviceMatches(device, filter): boolean;
```

Whether a runtime device is one `filter` asks for.

#### Parameters [#parameters-88]

| Parameter | Type |
| ------ | ------ |
| `device` | [`RuntimeDevice`](#runtimedevice) |
| `filter` | [`BTDeviceFilter`](#btdevicefilter) |

#### Returns [#returns-193]

`boolean`

***

### buildA606ConnectedCommand() [#builda606connectedcommand]

```ts
function buildA606ConnectedCommand(): string[];
```

The vendor's post-connect command for the ZH-SG family.

#### Returns [#returns-194]

`string`[]

***

### buildA606TimeCommand() [#builda606timecommand]

```ts
function buildA606TimeCommand(now): string[];
```

Writes the local clock in the six-byte YY MM DD hh mm ss payload.

#### Parameters [#parameters-89]

| Parameter | Type |
| ------ | ------ |
| `now` | `Date` |

#### Returns [#returns-195]

`string`[]

***

### buildA606UploadCommand() [#builda606uploadcommand]

```ts
function buildA606UploadCommand(ack?): string[];
```

Requests the next stored record after the current one was accepted.

#### Parameters [#parameters-90]

| Parameter | Type | Default value |
| ------ | ------ | ------ |
| `ack?` | `boolean` | `false` |

#### Returns [#returns-196]

`string`[]

***

### buildAojFrame() [#buildaojframe]

```ts
function buildAojFrame(command, payload?): string[];
```

Builds an AOJ frame for a command and payload, with its XOR checksum.

#### Parameters [#parameters-91]

| Parameter | Type | Default value |
| ------ | ------ | ------ |
| `command` | `number` | `undefined` |
| `payload?` | readonly `number`[] | `[]` |

#### Returns [#returns-197]

`string`[]

***

### buildGenialT31TimeCommand() [#buildgenialt31timecommand]

```ts
function buildGenialT31TimeCommand(now?): string[];
```

Builds the vendor's A6 05 37 weekday hour minute second checksum 6A clock frame.

#### Parameters [#parameters-92]

| Parameter | Type |
| ------ | ------ |
| `now?` | `Date` |

#### Returns [#returns-198]

`string`[]

***

### checkmeCommand() [#checkmecommand]

```ts
function checkmeCommand(command, payload?): string[];
```

Builds the frame for a command with an optional hex payload.

#### Parameters [#parameters-93]

| Parameter | Type | Default value |
| ------ | ------ | ------ |
| `command` | `number` | `undefined` |
| `payload?` | readonly `string`[] | `[]` |

#### Returns [#returns-199]

`string`[]

***

### checkmePodCommand() [#checkmepodcommand]

```ts
function checkmePodCommand(
   command,
   payload?,
   sequence?
): string[];
```

Builds the AA command envelope used by Checkme Pod and Checkme Pod-WPS.

#### Parameters [#parameters-94]

| Parameter | Type | Default value |
| ------ | ------ | ------ |
| `command` | `number` | `undefined` |
| `payload?` | readonly `string`[] | `[]` |
| `sequence?` | `number` | `0` |

#### Returns [#returns-200]

`string`[]

***

### checkmePodSyncTime() [#checkmepodsynctime]

```ts
function checkmePodSyncTime(now?): string[];
```

Builds the frame that sets the device clock to the given time.

#### Parameters [#parameters-95]

| Parameter | Type |
| ------ | ------ |
| `now?` | `Date` |

#### Returns [#returns-201]

`string`[]

***

### checkmeReadContent() [#checkmereadcontent]

```ts
function checkmeReadContent(sequence): string[];
```

Builds the frame that requests the chunk with the given sequence number.

#### Parameters [#parameters-96]

| Parameter | Type |
| ------ | ------ |
| `sequence` | `number` |

#### Returns [#returns-202]

`string`[]

***

### checkmeReadEnd() [#checkmereadend]

```ts
function checkmeReadEnd(): string[];
```

Builds the frame that closes the open file.

#### Returns [#returns-203]

`string`[]

***

### checkmeReadFileStart() [#checkmereadfilestart]

```ts
function checkmeReadFileStart(name): string[];
```

Builds the frame that opens the named file for reading.

#### Parameters [#parameters-97]

| Parameter | Type |
| ------ | ------ |
| `name` | `string` |

#### Returns [#returns-204]

`string`[]

***

### clockSyncCapabilityForDevice() [#clocksynccapabilityfordevice]

```ts
function clockSyncCapabilityForDevice(deviceName): ClockSyncCapability;
```

Built-in capability declarations; custom declarations provide their own value.

#### Parameters [#parameters-98]

| Parameter | Type |
| ------ | ------ |
| `deviceName` | `string` |

#### Returns [#returns-205]

[`ClockSyncCapability`](#clocksynccapability)

***

### createBackgroundBleManager() [#createbackgroundblemanager]

```ts
function createBackgroundBleManager(__namedParameters?): BleManager;
```

Creates a BLE manager configured for iOS CoreBluetooth state restoration. The returned
manager must be created once at module scope, not inside a React render.

#### Parameters [#parameters-99]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters?` | [`BackgroundBleManagerOptions`](#backgroundblemanageroptions) |

#### Returns [#returns-206]

`BleManager`

***

### createBluetoothRuntime() [#createbluetoothruntime]

```ts
function createBluetoothRuntime(bleManager?, initialBackgroundScanEnabled?): BluetoothRuntime;
```

Creates the store that backs the Bluetooth hooks.

#### Parameters [#parameters-100]

| Parameter | Type |
| ------ | ------ |
| `bleManager?` | `BleManager` |
| `initialBackgroundScanEnabled?` | `boolean` |

#### Returns [#returns-207]

[`BluetoothRuntime`](#bluetoothruntime)

***

### createFakeBleDevice() [#createfakebledevice]

```ts
function createFakeBleDevice(__namedParameters): FakeBleDevice;
```

Creates a GATT-capable fake device for connection and notification tests.

#### Parameters [#parameters-101]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters` | [`FakeBleDeviceOptions`](#fakebledeviceoptions) |

#### Returns [#returns-208]

[`FakeBleDevice`](#fakebledevice)

***

### createFakeBleManager() [#createfakeblemanager]

```ts
function createFakeBleManager(__namedParameters?): FakeBleManager;
```

Creates a fake BLE manager with a controllable adapter state and scan results.

#### Parameters [#parameters-102]

| Parameter | Type |
| ------ | ------ |
| `__namedParameters?` | [`FakeBleManagerOptions`](#fakeblemanageroptions) |

#### Returns [#returns-209]

[`FakeBleManager`](#fakeblemanager)

***

### createFileQueueStorage() [#createfilequeuestorage]

```ts
function createFileQueueStorage(prefix?): BackgroundSyncStorage;
```

Stores each queue key in its own document file, so ECGs are not limited by KV entry sizes.

#### Parameters [#parameters-103]

| Parameter | Type | Default value |
| ------ | ------ | ------ |
| `prefix?` | `string` | `"ovok-native-background-sync"` |

#### Returns [#returns-210]

[`BackgroundSyncStorage`](#backgroundsyncstorage)

***

### createLegacyResultId() [#createlegacyresultid]

```ts
function createLegacyResultId(deviceData, data): string;
```

The id SDKs before 1.16.1 gave the same reading, to find what they saved.

#### Parameters [#parameters-104]

| Parameter | Type |
| ------ | ------ |
| `deviceData` | [`DeviceData`](#devicedata) |
| `data` | `Measurement` |

#### Returns [#returns-211]

`string`

***

### createStableResultId() [#createstableresultid]

```ts
function createStableResultId(
   deviceData,
   data,
   receivedAt?
): string;
```

Creates an identity that is stable when a device sends its stored history again, in any time zone. A reading
without a time of its own is a new measurement each time, so it is told apart by when it arrived.

#### Parameters [#parameters-105]

| Parameter | Type |
| ------ | ------ |
| `deviceData` | [`DeviceData`](#devicedata) |
| `data` | `Measurement` |
| `receivedAt?` | `Date` |

#### Returns [#returns-212]

`string`

***

### decodeAojError() [#decodeaojerror]

```ts
function decodeAojError(code): string | undefined;
```

Describes a temperature error code in words, or `undefined` for an unknown code.

#### Parameters [#parameters-106]

| Parameter | Type |
| ------ | ------ |
| `code` | `number` |

#### Returns [#returns-213]

`string` \| `undefined`

***

### decodeCheckmeEcgFile() [#decodecheckmeecgfile]

```ts
function decodeCheckmeEcgFile(bytes): CheckmeEcgFile | undefined;
```

Decodes Checkme's 21-byte ECG header and little-endian signed waveform.

#### Parameters [#parameters-107]

| Parameter | Type |
| ------ | ------ |
| `bytes` | readonly `string`[] |

#### Returns [#returns-214]

[`CheckmeEcgFile`](#checkmeecgfile) \| `undefined`

***

### decodeCheckmePodResponse() [#decodecheckmepodresponse]

```ts
function decodeCheckmePodResponse(frame): CheckmePodResponse | undefined;
```

Decodes a complete response frame, or returns `undefined` if its header or length is invalid.

#### Parameters [#parameters-108]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

#### Returns [#returns-215]

[`CheckmePodResponse`](#checkmepodresponse) \| `undefined`

***

### decodeCheckmeResponse() [#decodecheckmeresponse]

```ts
function decodeCheckmeResponse(bytes): CheckmeResponse | undefined;
```

Decodes the two response envelopes used by Checkme Pro's vendor library.

#### Parameters [#parameters-109]

| Parameter | Type |
| ------ | ------ |
| `bytes` | readonly `string`[] |

#### Returns [#returns-216]

[`CheckmeResponse`](#checkmeresponse) \| `undefined`

***

### decodePulsebitEcgFile() [#decodepulsebitecgfile]

```ts
function decodePulsebitEcgFile(bytes): CheckmeEcgFile | undefined;
```

Decodes the 44-byte Pulsebit ECG header and its signed waveform.

#### Parameters [#parameters-110]

| Parameter | Type |
| ------ | ------ |
| `bytes` | readonly `string`[] |

#### Returns [#returns-217]

[`CheckmeEcgFile`](#checkmeecgfile) \| `undefined`

***

### decodeVerovalEcgSamples() [#decodeverovalecgsamples]

```ts
function decodeVerovalEcgSamples(bytes, calibration?): number[];
```

Turns the bytes of a recording into millivolts.

A trailing odd byte is ignored: half a sample is not a sample. The conversion is the
device's own, applied as it states it rather than reduced to a single factor, so a header
that reports a different range still decodes correctly.

#### Parameters [#parameters-111]

| Parameter | Type | Default value |
| ------ | ------ | ------ |
| `bytes` | readonly `string`[] | `undefined` |
| `calibration?` | [`EcgCalibration`](#ecgcalibration) | `DEFAULT_CALIBRATION` |

#### Returns [#returns-218]

`number`[]

***

### decodeViatomEcgRecording() [#decodeviatomecgrecording]

```ts
function decodeViatomEcgRecording(bytes): ViatomEcgRecording;
```

Decodes an ER1/ER2 recording. A file whose waveform does not last as long as its tail
records is returned empty, because that file is in a format this decoder does not read.

#### Parameters [#parameters-112]

| Parameter | Type |
| ------ | ------ |
| `bytes` | `Uint8Array` |

#### Returns [#returns-219]

[`ViatomEcgRecording`](#viatomecgrecording)

***

### defineCustomDevice() [#definecustomdevice]

```ts
function defineCustomDevice(spec, options?): CustomDeviceDefinition;
```

Validates a declaration and compiles it into a runnable device.

Every rule the declarative decoder relies on is checked here, at registration, because the
alternative is a plausible wrong number at read time. Registration fails loudly - it
throws, naming the exact position in the declaration - and a device that fails to compile
is never scanned for.

#### Parameters [#parameters-113]

| Parameter | Type |
| ------ | ------ |
| `spec` | [`CustomDeviceSpec`](#customdevicespec) |
| `options?` | \{ `createCommandSequencer?`: [`CustomSequencerFactory`](#customsequencerfactory); `createFrameHandler?`: [`CustomFrameHandlerFactory`](#customframehandlerfactory); `decorateReading?`: [`CustomReadingDecorator`](#customreadingdecorator); `frameReader?`: `FrameReader`; \} |
| `options.createCommandSequencer?` | [`CustomSequencerFactory`](#customsequencerfactory) |
| `options.createFrameHandler?` | [`CustomFrameHandlerFactory`](#customframehandlerfactory) |
| `options.decorateReading?` | [`CustomReadingDecorator`](#customreadingdecorator) |
| `options.frameReader?` | `FrameReader` |

#### Returns [#returns-220]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### defineRecordedDeviceFrames() [#definerecordeddeviceframes]

```ts
function defineRecordedDeviceFrames<T>(fixtures): Readonly<Record<T, readonly RecordedBleFrame[]>>;
```

A registry helper lets an app keep fixtures for every device it supports.

#### Type Parameters [#type-parameters-9]

| Type Parameter |
| ------ |
| <a id="type-parameter-t-12"></a> `T` *extends* `string` |

#### Parameters [#parameters-114]

| Parameter | Type |
| ------ | ------ |
| `fixtures` | `Record`\<`T`, readonly [`RecordedBleFrame`](#recordedbleframe)[]\> |

#### Returns [#returns-221]

`Readonly`\<`Record`\<`T`, readonly [`RecordedBleFrame`](#recordedbleframe)[]\>\>

***

### describeLepuResponseType() [#describelepuresponsetype]

```ts
function describeLepuResponseType(frame): string;
```

Why a device refused, in words, for an error a person will read.

#### Parameters [#parameters-115]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

#### Returns [#returns-222]

`string`

***

### deviceTitle() [#devicetitle]

```ts
function deviceTitle(deviceData): string;
```

Returns the most useful human-readable name for a connected device.
A product sharing a parser with other brands is named by its variant. Known
integrated and catalog devices keep their product name even when the
peripheral reports a radio-module manufacturer and model. Unknown devices
fall back to their reported identity and then their advertised name.

#### Parameters [#parameters-116]

| Parameter | Type |
| ------ | ------ |
| `deviceData` | [`DeviceData`](#devicedata) |

#### Returns [#returns-223]

`string`

***

### er1Recorder() [#er1recorder]

```ts
function er1Recorder(advertisedName, params): CustomDeviceDefinition;
```

The ER1, and the handheld recorders sold under other names on the same protocol.

#### Parameters [#parameters-117]

| Parameter | Type |
| ------ | ------ |
| `advertisedName` | `string` |
| `params` | `ViatomEcgParams` |

#### Returns [#returns-224]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### er2Recorder() [#er2recorder]

```ts
function er2Recorder(advertisedName, params): CustomDeviceDefinition;
```

The ER2, which reads the same block but over a link that grants nothing beyond the
minimum. Asking it for the MTU the rest of the family grants is what the vendor's own SDK
declines to do, and a command longer than the link carries is truncated rather than
refused.

#### Parameters [#parameters-118]

| Parameter | Type |
| ------ | ------ |
| `advertisedName` | `string` |
| `params` | `ViatomEcgParams` |

#### Returns [#returns-225]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### er3Recorder() [#er3recorder]

```ts
function er3Recorder(advertisedName, params): CustomDeviceDefinition;
```

The ER3, which reads the same parameter block from a different opcode.

#### Parameters [#parameters-119]

| Parameter | Type |
| ------ | ------ |
| `advertisedName` | `string` |
| `params` | `ViatomEcgParams` |

#### Returns [#returns-226]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### findDeviceVariant() [#finddevicevariant]

```ts
function findDeviceVariant(device, advertisedName): DeviceVariant | undefined;
```

The brand and model behind an advertised name, for a parser listed in `DEVICE_VARIANTS`.

#### Parameters [#parameters-120]

| Parameter | Type |
| ------ | ------ |
| `device` | `string` |
| `advertisedName` | `string` |

#### Returns [#returns-227]

[`DeviceVariant`](#devicevariant) \| `undefined`

***

### getBackgroundServiceUUIDs() [#getbackgroundserviceuuids]

```ts
function getBackgroundServiceUUIDs(acceptedDevices, additionalServiceUUIDs?): string[];
```

The services a background scan asks for: those of every accepted device whose services are known, and
`additionalServiceUUIDs`. In the background iOS (and Android with the screen off) reports only devices advertising a
listed service, so an accepted device whose services aren't known is found by a foreground scan only. One such
device must not empty the list: iOS can't scan in the background without one.

#### Parameters [#parameters-121]

| Parameter | Type | Default value |
| ------ | ------ | ------ |
| `acceptedDevices` | readonly [`AcceptedDevice`](#accepteddevice)[] | `undefined` |
| `additionalServiceUUIDs?` | readonly `string`[] | `[]` |

#### Returns [#returns-228]

`string`[]

***

### getClockParts() [#getclockparts]

```ts
function getClockParts(date, timezone?): object;
```

Splits a date into calendar and clock parts in the given timezone.

#### Parameters [#parameters-122]

| Parameter | Type | Default value |
| ------ | ------ | ------ |
| `date` | `Date` | `undefined` |
| `timezone?` | [`ClockSyncTimezone`](#clocksynctimezone) | `"local"` |

#### Returns [#returns-229]

| Name | Type | Description |
| ------ | ------ | ------ |
| `day` | `number` | Day of the month. |
| `hours` | `number` | Hours, 0-23. |
| `milliseconds` | `number` | Milliseconds, 0-999. |
| `minutes` | `number` | Minutes, 0-59. |
| `month` | `number` | Month, 1-12. |
| `seconds` | `number` | Seconds, 0-59. |
| `year` | `number` | Full year. |

***

### getRestoredBleState() [#getrestoredblestate]

```ts
function getRestoredBleState(restoreStateIdentifier?): BleRestoredState | null | undefined;
```

Returns the state restored for an identifier, or `undefined` if restoration has not run yet.

#### Parameters [#parameters-123]

| Parameter | Type | Default value |
| ------ | ------ | ------ |
| `restoreStateIdentifier?` | `string` | `DEFAULT_RESTORE_STATE_IDENTIFIER` |

#### Returns [#returns-230]

`BleRestoredState` \| `null` \| `undefined`

***

### isClockSyncEnabled() [#isclocksyncenabled]

```ts
function isClockSyncEnabled(options?): boolean;
```

True unless clock synchronisation is explicitly disabled.

#### Parameters [#parameters-124]

| Parameter | Type |
| ------ | ------ |
| `options?` | [`ClockSyncOptions`](#clocksyncoptions) |

#### Returns [#returns-231]

`boolean`

***

### isLepuSuccess() [#islepusuccess]

```ts
function isLepuSuccess(frame): boolean;
```

Whether the frame reports success.

#### Parameters [#parameters-125]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

#### Returns [#returns-232]

`boolean`

***

### isTrasenseS9Advertisement() [#istrasenses9advertisement]

```ts
function isTrasenseS9Advertisement(advertisedName, manufacturerData?): boolean;
```

The SH09 reuses company ID 0x0A0A and advertises only as "S9". Require both
fields and the exact manufacturer payload length; the name alone is ambiguous.
react-native-ble-plx exposes the manufacturer-specific bytes as base64, including
the two company-ID bytes at the start of the AD structure.

#### Parameters [#parameters-126]

| Parameter | Type |
| ------ | ------ |
| `advertisedName` | `string` |
| `manufacturerData?` | `string` |

#### Returns [#returns-233]

`boolean`

***

### lepodMonitor() [#lepodmonitor]

```ts
function lepodMonitor(advertisedName, params): CustomDeviceDefinition;
```

Declares a Lepod, reporting every reading its realtime frame carries.

An instrument that is not attached reports a value outside the physiological range for
what it measures, so that reading is discarded and reported while the others in the same
frame are still delivered. The device also marks those conditions in bits of a lead-off
byte, which a declaration cannot select on - reading them quietly needs a device class.

#### Parameters [#parameters-127]

| Parameter | Type |
| ------ | ------ |
| `advertisedName` | `string` |
| `params` | `LepodParams` |

#### Returns [#returns-234]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### lepuDevice() [#lepudevice]

```ts
function lepuDevice(params): CustomDeviceDefinition;
```

Builds a custom device definition for a Lepu/Viatom family product from its params.

#### Parameters [#parameters-128]

| Parameter | Type |
| ------ | ------ |
| `params` | [`LepuDeviceParams`](#lepudeviceparams) |

#### Returns [#returns-235]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### lepuNameMatch() [#lepunamematch]

```ts
function lepuNameMatch(name, vocabulary?): RegExp;
```

Builds a matcher for one advertised name that cannot also match a longer one.

The vendor tests these names with a substring check in a hand-ordered cascade, so `BP2`
only fails to match a BP2W because `BP2W` happens to be checked first. Order is a fragile
place to keep a safety property: it lives in whoever wrote the list, is invisible at the
point of use, and an insertion in the wrong place silently binds the wrong driver.

Here the exclusions are derived instead. Every name in the vocabulary that extends this
one becomes a negative lookahead, so the matcher is correct wherever it is used and in
whatever order it is tried.

The match is deliberately open at the end, because these devices advertise a serial after
the model - `BP2 1234` - and the serial's shape varies across the family.

#### Parameters [#parameters-129]

| Parameter | Type | Default value |
| ------ | ------ | ------ |
| `name` | `string` | `undefined` |
| `vocabulary?` | readonly `string`[] | `LEPU_DEVICE_NAMES` |

#### Returns [#returns-236]

`RegExp`

***

### lepuResponseType() [#lepuresponsetype]

```ts
function lepuResponseType(frame): number;
```

Reads the response type byte of a frame.

#### Parameters [#parameters-130]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

#### Returns [#returns-237]

`number`

***

### lpBp2wMonitor() [#lpbp2wmonitor]

```ts
function lpBp2wMonitor(params): CustomDeviceDefinition;
```

LP-BP2W, the Lepu-branded WiFi variant of the BP2 family.

#### Parameters [#parameters-131]

| Parameter | Type |
| ------ | ------ |
| `params` | `ViatomBpParams` |

#### Returns [#returns-238]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### parseA606Record() [#parsea606record]

```ts
function parseA606Record(frame): A606Record | undefined;
```

Decodes the 12-byte glucose payload inside a verified 16-byte ZH-SG record.

#### Parameters [#parameters-132]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

#### Returns [#returns-239]

[`A606Record`](#a606record) \| `undefined`

***

### parseCheckmeBloodPressureRecords() [#parsecheckmebloodpressurerecords]

```ts
function parseCheckmeBloodPressureRecords(bytes): CheckmeBloodPressureRecord[];
```

Parses a blood pressure list file into records, skipping entries with an invalid date.

#### Parameters [#parameters-133]

| Parameter | Type |
| ------ | ------ |
| `bytes` | readonly `string`[] |

#### Returns [#returns-240]

[`CheckmeBloodPressureRecord`](#checkmebloodpressurerecord)[]

***

### parseCheckmeDailyRecords() [#parsecheckmedailyrecords]

```ts
function parseCheckmeDailyRecords(bytes): CheckmeDailyRecord[];
```

Parses a daily list file into records, skipping entries with an invalid date.

#### Parameters [#parameters-134]

| Parameter | Type |
| ------ | ------ |
| `bytes` | readonly `string`[] |

#### Returns [#returns-241]

[`CheckmeDailyRecord`](#checkmedailyrecord)[]

***

### parseCheckmeEcgRecords() [#parsecheckmeecgrecords]

```ts
function parseCheckmeEcgRecords(bytes): CheckmeEcgRecord[];
```

Parses an ECG list file into records, skipping entries with an invalid date.

#### Parameters [#parameters-135]

| Parameter | Type |
| ------ | ------ |
| `bytes` | readonly `string`[] |

#### Returns [#returns-242]

[`CheckmeEcgRecord`](#checkmeecgrecord)[]

***

### parseCheckmeOxygenRecords() [#parsecheckmeoxygenrecords]

```ts
function parseCheckmeOxygenRecords(bytes): CheckmeOxygenRecord[];
```

Parses an oxygen list file into records, skipping entries with an invalid date.

#### Parameters [#parameters-136]

| Parameter | Type |
| ------ | ------ |
| `bytes` | readonly `string`[] |

#### Returns [#returns-243]

[`CheckmeOxygenRecord`](#checkmeoxygenrecord)[]

***

### parseCheckmePodRealtimeReading() [#parsecheckmepodrealtimereading]

```ts
function parseCheckmePodRealtimeReading(content): CheckmePodRealtimeReading | undefined;
```

Decodes the 20-byte RtParam prefix used by the vendor's realtime response.

#### Parameters [#parameters-137]

| Parameter | Type |
| ------ | ------ |
| `content` | readonly `string`[] |

#### Returns [#returns-244]

[`CheckmePodRealtimeReading`](#checkmepodrealtimereading) \| `undefined`

***

### parseCheckmeTemperatureRecords() [#parsecheckmetemperaturerecords]

```ts
function parseCheckmeTemperatureRecords(bytes): CheckmeTemperatureRecord[];
```

Parses a temperature list file into records, skipping entries with an invalid date.

#### Parameters [#parameters-138]

| Parameter | Type |
| ------ | ------ |
| `bytes` | readonly `string`[] |

#### Returns [#returns-245]

[`CheckmeTemperatureRecord`](#checkmetemperaturerecord)[]

***

### parseLepuDeviceInfo() [#parselepudeviceinfo]

```ts
function parseLepuDeviceInfo(frame): LepuDeviceInfo | undefined;
```

Reads the reply to `GET_INFO`, or nothing if the frame is not one.

The command byte is checked rather than assumed, because this is the answer a driver
decides its identity on: parsing some other frame as device info would produce a model
number out of whatever bytes happened to sit at offset 20, and the gate would then pass
on a coincidence.

A frame too short to hold the layout is refused for the same reason, as is one whose
response type is anything but success: an error reply carries a reason where the device
information would be, and reading it as a model number would identify the hardware from
an error code. The vendor's own struct is at least 56 bytes; anything shorter than the
serial length field cannot be read without inventing the parts that are missing.

#### Parameters [#parameters-139]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

#### Returns [#returns-246]

[`LepuDeviceInfo`](#lepudeviceinfo) \| `undefined`

***

### parsePulsebitEcgRecords() [#parsepulsebitecgrecords]

```ts
function parsePulsebitEcgRecords(bytes): PulsebitEcgRecord[];
```

Decodes the 17-byte ECG index used by Pulsebit and Checkme EX.

#### Parameters [#parameters-140]

| Parameter | Type |
| ------ | ------ |
| `bytes` | readonly `string`[] |

#### Returns [#returns-247]

[`PulsebitEcgRecord`](#pulsebitecgrecord)[]

***

### parseRecordedAt() [#parserecordedat]

```ts
function parseRecordedAt(frame): Date | undefined;
```

Reads the recording time from a history frame, or `undefined` if it is not a valid date.

#### Parameters [#parameters-141]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

#### Returns [#returns-248]

`Date` \| `undefined`

***

### parseVerovalDuoControlRecordMetadata() [#parseverovalduocontrolrecordmetadata]

```ts
function parseVerovalDuoControlRecordMetadata(frame, recordOffset):
  | Pick<VerovalDuoControlMeasurement, "recordedAt" | "irregularHeartbeat">
  | undefined;
```

Reads the timestamp and irregular heartbeat flag of a stored record, or `undefined` if invalid.

#### Parameters [#parameters-142]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |
| `recordOffset` | `number` |

#### Returns [#returns-249]

  \| `Pick`\<[`VerovalDuoControlMeasurement`](#verovalduocontrolmeasurement), `"recordedAt"` \| `"irregularHeartbeat"`\>
  \| `undefined`

***

### recordedAtFromT31Frame() [#recordedatfromt31frame]

```ts
function recordedAtFromT31Frame(frame, now): Date | undefined;
```

Reconstructs when a reading was taken from the weekday and time in a frame, or `undefined` if invalid.

#### Parameters [#parameters-143]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |
| `now` | `Date` |

#### Returns [#returns-250]

`Date` \| `undefined`

***

### recordedAtFromViatomFileName() [#recordedatfromviatomfilename]

```ts
function recordedAtFromViatomFileName(name): Date | undefined;
```

Reads the recording time encoded in the ER file name, when present.

#### Parameters [#parameters-144]

| Parameter | Type |
| ------ | ------ |
| `name` | `string` |

#### Returns [#returns-251]

`Date` \| `undefined`

***

### replayRecordedFrames() [#replayrecordedframes]

```ts
function replayRecordedFrames(frames, sink): Promise<void>;
```

Replays captured characteristic frames through an app-provided test sink.

#### Parameters [#parameters-145]

| Parameter | Type |
| ------ | ------ |
| `frames` | readonly [`RecordedBleFrame`](#recordedbleframe)[] |
| `sink` | [`RecordedFrameSink`](#recordedframesink) |

#### Returns [#returns-252]

`Promise`\<`void`\>

***

### requestBluetoothPermission() [#requestbluetoothpermission]

```ts
function requestBluetoothPermission(): Promise<boolean>;
```

Asks the OS for the Bluetooth permissions the platform needs; resolves to whether all were granted.

#### Returns [#returns-253]

`Promise`\<`boolean`\>

***

### reviveResultDates() [#reviveresultdates]

```ts
function reviveResultDates<T>(value): T;
```

Converts the ISO date strings of `recordedAt`, `start` and `end` fields back to `Date`s, recursively.

#### Type Parameters [#type-parameters-10]

| Type Parameter |
| ------ |
| <a id="type-parameter-t-13"></a> `T` |

#### Parameters [#parameters-146]

| Parameter | Type |
| ------ | ------ |
| `value` | `T` |

#### Returns [#returns-254]

`T`

***

### setDeviceSecretStorage() [#setdevicesecretstorage]

```ts
function setDeviceSecretStorage(next): void;
```

Sets the durable storage used for device secrets; pass `undefined` to keep them in memory only.

#### Parameters [#parameters-147]

| Parameter | Type |
| ------ | ------ |
| `next` | [`DeviceSecretStorage`](#devicesecretstorage) \| `undefined` |

#### Returns [#returns-255]

`void`

***

### standardBloodPressureDevice() [#standardbloodpressuredevice]

```ts
function standardBloodPressureDevice(params): CustomDeviceDefinition;
```

Declares a Bluetooth SIG blood pressure profile device.

#### Parameters [#parameters-148]

| Parameter | Type |
| ------ | ------ |
| `params` | `StandardDeviceParams` |

#### Returns [#returns-256]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### standardGlucoseDevice() [#standardglucosedevice]

```ts
function standardGlucoseDevice(params): CustomDeviceDefinition;
```

Declares a Bluetooth SIG glucose profile device.

#### Parameters [#parameters-149]

| Parameter | Type |
| ------ | ------ |
| `params` | `StandardDeviceParams` |

#### Returns [#returns-257]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### standardHeartRateDevice() [#standardheartratedevice]

```ts
function standardHeartRateDevice(params): CustomDeviceDefinition;
```

Heart Rate Service 0x180D, Heart Rate Measurement 0x2A37.

Both heart-rate layouts are declared. A contact-not-detected frame is idle, so it cannot
become a false reading while the strap is off the body. RR intervals, a list of any
length, are read from the frame by the decorator and reported as `rrIntervals`.

#### Parameters [#parameters-150]

| Parameter | Type |
| ------ | ------ |
| `params` | `StandardDeviceParams` |

#### Returns [#returns-258]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### standardPulseOximeterDevice() [#standardpulseoximeterdevice]

```ts
function standardPulseOximeterDevice(params): CustomDeviceDefinition;
```

Pulse Oximeter Service 0x1822, PLX Spot-Check Measurement 0x2A5E.

Saturation and pulse rate are both required by the catalog, which matches the
specification: a spot-check measurement always carries both, at bytes 1-4 whatever the
flags say, so every flags value selects the same fields. The optional ones follow them.

#### Parameters [#parameters-151]

| Parameter | Type |
| ------ | ------ |
| `params` | `StandardDeviceParams` |

#### Returns [#returns-259]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### standardThermometerDevice() [#standardthermometerdevice]

```ts
function standardThermometerDevice(params): CustomDeviceDefinition;
```

Health Thermometer Service 0x1809, Temperature Measurement 0x2A1C.

#### Parameters [#parameters-152]

| Parameter | Type |
| ------ | ------ |
| `params` | `StandardDeviceParams` |

#### Returns [#returns-260]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### standardWeightScaleDevice() [#standardweightscaledevice]

```ts
function standardWeightScaleDevice(params): CustomDeviceDefinition;
```

Weight Scale Service 0x181D, Weight Measurement 0x2A9D.

The reading is a scaled integer rather than a float, so the resolution is applied here.
A weight of 0xFFFF means the measurement failed, so it yields no reading.

#### Parameters [#parameters-153]

| Parameter | Type |
| ------ | ------ |
| `params` | `StandardDeviceParams` |

#### Returns [#returns-261]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### tmbBpMonitor() [#tmbbpmonitor]

```ts
function tmbBpMonitor(advertisedName, params): CustomDeviceDefinition;
```

Declares a Viatom TMB monitor, whose history protocol is separate from the BP3 Lepu flow.

#### Parameters [#parameters-154]

| Parameter | Type |
| ------ | ------ |
| `advertisedName` | `string` |
| `params` | `ViatomBpParams` |

#### Returns [#returns-262]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### toBluetoothError() [#tobluetootherror]

```ts
function toBluetoothError(error): BluetoothError;
```

Wraps any thrown value in a `BluetoothError`, keeping an existing one as is.

#### Parameters [#parameters-155]

| Parameter | Type |
| ------ | ------ |
| `error` | `unknown` |

#### Returns [#returns-263]

[`BluetoothError`](#bluetootherror)

***

### verovalCompactMonitor() [#verovalcompactmonitor]

```ts
function verovalCompactMonitor(advertisedName, params): CustomDeviceDefinition;
```

Declares a compact Veroval blood pressure monitor by its advertised name.

#### Parameters [#parameters-156]

| Parameter | Type |
| ------ | ------ |
| `advertisedName` | `string` |
| `params` | `VerovalBpParams` |

#### Returns [#returns-264]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### verovalFusionMonitor() [#verovalfusionmonitor]

```ts
function verovalFusionMonitor(params?): CustomDeviceDefinition;
```

Declares the Veroval fusion wireless blood-pressure monitor.

#### Parameters [#parameters-157]

| Parameter | Type |
| ------ | ------ |
| `params?` | [`VerovalFusionParams`](#verovalfusionparams) |

#### Returns [#returns-265]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### viatomBpMonitor() [#viatombpmonitor]

```ts
function viatomBpMonitor(advertisedName, params): CustomDeviceDefinition;
```

Declares one monitor of the BP2 series.

`advertisedName` is the name the vendor's SDK matches - `BP2A`, `BP2T` - and the matcher
derived from it excludes every longer name in the family, so a declaration for `BP2`
cannot pick up a `BP2W`.

#### Parameters [#parameters-158]

| Parameter | Type |
| ------ | ------ |
| `advertisedName` | `string` |
| `params` | `ViatomBpParams` |

#### Returns [#returns-266]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### viatomOximeter() [#viatomoximeter]

```ts
function viatomOximeter(advertisedName, params): CustomDeviceDefinition;
```

Declares one oximeter of the range.

The ViHealth wire protocol uses a distinct `AA` request / `55` response envelope. Replies
carry a status byte rather than echoing the opcode, and the sensor state at byte 18 tells
us whether the reading is usable. No-finger and acquiring frames are deliberately idle:
they are normal states while the user puts the ring on, not decoding failures.

#### Parameters [#parameters-159]

| Parameter | Type |
| ------ | ------ |
| `advertisedName` | `string` |
| `params` | `ViatomOximeterParams` |

#### Returns [#returns-267]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### viatomOxyIiMonitor() [#viatomoxyiimonitor]

```ts
function viatomOxyIiMonitor(advertisedName, params?): CustomDeviceDefinition;
```

Declares one model on the dedicated OxyII service and A5 frame.

#### Parameters [#parameters-160]

| Parameter | Type |
| ------ | ------ |
| `advertisedName` | `string` |
| `params?` | `ViatomOxyIiParams` |

#### Returns [#returns-268]

[`CustomDeviceDefinition`](#customdevicedefinition)

***

### visomatComfortSoftBtMonitor() [#visomatcomfortsoftbtmonitor]

```ts
function visomatComfortSoftBtMonitor(params): CustomDeviceDefinition;
```

Declares the visomat comfort soft BT upper-arm monitor.

The monitor uses the Bluetooth SIG Blood Pressure Service and Measurement characteristic,
so the shared profile handles the 0x2A35 measurement without a vendor-specific command or
pairing flow.

#### Parameters [#parameters-161]

| Parameter | Type |
| ------ | ------ |
| `params` | [`VisomatComfortSoftBtParams`](#visomatcomfortsoftbtparams) |

#### Returns [#returns-269]

[`CustomDeviceDefinition`](#customdevicedefinition)

## Interfaces [#interfaces]

### A606Record [#a606record]

A stored glucose record.

#### Properties [#properties-13]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-bloodglucose"></a> `bloodGlucose` | `number` | Blood glucose value as reported by the device. |
| <a id="property-dataposition"></a> `dataPosition` | `number` | Position of the record in the device history. |
| <a id="property-recordedat"></a> `recordedAt` | `Date` | When the reading was taken. |

***

### BackgroundBleManagerOptions [#backgroundblemanageroptions]

Options for `createBackgroundBleManager`.

#### Extends [#extends-13]

- `Pick`\<`BleManagerOptions`, `"restoreStateIdentifier"`\>

#### Properties [#properties-14]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-onrestorestate"></a> `onRestoreState?` | (`state`) => `void` | Called with the restored CoreBluetooth state, or `null` when there is none. |

***

### BackgroundSyncFlushOptions [#backgroundsyncflushoptions]

Options for a flush of the background sync queue.

#### Properties [#properties-15]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-includeexhausted"></a> `includeExhausted?` | `boolean` | Also deliver items that ran out of retries. |
| <a id="property-resetexhausted"></a> `resetExhausted?` | `boolean` | Give exhausted items a fresh set of retries. |
| <a id="property-resetretrybackoff"></a> `resetRetryBackoff?` | `boolean` | Retry items now instead of waiting for their backoff to end. |

***

### BackgroundSyncOptions [#backgroundsyncoptions]

Options for delivering results while the app is in the background.

#### Type Parameters [#type-parameters-11]

| Type Parameter | Default type |
| ------ | ------ |
| <a id="type-parameter-t-3"></a> `T` *extends* [`DeviceKey`](#devicekey) | [`DeviceKey`](#devicekey) |

#### Properties [#properties-16]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-android"></a> `android?` | `object` | Optional Android foreground-service configuration. When present, the service keeps the JS BLE scan process alive while the app is backgrounded. |
| `android.foregroundService?` | [`AndroidBluetoothForegroundServiceOptions`](/native-sdk/reference/background-sync#androidbluetoothforegroundserviceoptions) | Android foreground-service configuration. |
| <a id="property-enabled"></a> `enabled?` | `boolean` | Background delivery is opt-in. |
| <a id="property-getownerkey"></a> `getOwnerKey?` | () => `string` \| `undefined` | Returns the stable, opaque key for the account currently able to accept a result. Required at runtime before queueing or delivering account-owned data. |
| <a id="property-maxretries"></a> `maxRetries?` | `number` | Number of delivery attempts before an item is retained as exhausted. |
| <a id="property-notifications"></a> `notifications?` | `object` | Optional local notification after a queued reading is accepted by onResult. |
| `notifications.body?` | `string` \| ((`result`) => `string`) | Notification body, fixed or built from the result. |
| `notifications.data?` | \| `Record`\<`string`, `string` \| `number` \| `boolean` \| `null`\> \| ((`result`) => \| `Record`\<`string`, `string` \| `number` \| `boolean` \| `null`\> \| `undefined`) | Payload attached to the notification, fixed or built from the result. |
| `notifications.enabled?` | `boolean` | Whether local notifications are shown. |
| `notifications.shouldNotify?` | (`result`) => `boolean` | Return false to suppress the notification for this accepted result. |
| `notifications.title?` | `string` | Notification title. |
| <a id="property-onerror-12"></a> `onError?` | (`error`) => `void` | Called when a corrupt stored queue is moved aside and reset. |
| <a id="property-onresult-12"></a> `onResult` | (`result`) => `Promise`\<`void`\> | Called after a result is persisted. Resolve only after the result is accepted. |
| <a id="property-onresults"></a> `onResults?` | (`results`) => `Promise`\<`void`\> | Takes every result that is due at once, so a device emptying its memory is saved in a few requests rather than one a reading. Resolve only after all of them are accepted. When it rejects, each is delivered by `onResult` on its own, so one that can't be saved doesn't hold back the rest; delivering a result twice must be harmless. |
| <a id="property-restorestateidentifier"></a> `restoreStateIdentifier?` | `string` | iOS restoration identifier. Keep this stable for the lifetime of the app. |
| <a id="property-retrybackoffms"></a> `retryBackoffMs?` | `number` | Base delay for retries. Delays grow exponentially up to the third attempt. |
| <a id="property-serviceuuids"></a> `serviceUUIDs?` | readonly `string`[] | Additional service UUIDs to scan, useful for custom/native device declarations. |
| <a id="property-storage"></a> `storage` | [`BackgroundSyncStorage`](#backgroundsyncstorage) | A durable store that can hold hundreds of KB; `createFileQueueStorage` is provided for Expo. |
| <a id="property-storagekey"></a> `storageKey?` | `string` | Storage key used by the queue. |

***

### BackgroundSyncResult [#backgroundsyncresult]

A queued result being delivered, with its delivery bookkeeping.

#### Extends [#extends-14]

- [`ResultCallback`](#resultcallback)\<`T`\>

#### Type Parameters [#type-parameters-12]

| Type Parameter | Default type |
| ------ | ------ |
| <a id="type-parameter-t-4"></a> `T` *extends* [`DeviceKey`](#devicekey) | [`DeviceKey`](#devicekey) |

#### Properties [#properties-17]

| Property | Type | Description | Overrides | Inherited from |
| ------ | ------ | ------ | ------ | ------ |
| <a id="property-attempt"></a> `attempt` | `number` | Number of delivery attempts so far. | - | - |
| <a id="property-data"></a> `data` | `OmitCaseType`\<[`MeasurementTypeForDevices`](#measurementtypefordevices)\<\[`T`\]\>\> | The measurement. | - | [`ResultCallback`](#resultcallback).[`data`](#property-data-1) |
| <a id="property-devicedata-12"></a> `deviceData` | [`DeviceData`](#devicedata) | Device that produced the result. | - | [`ResultCallback`](#resultcallback).[`deviceData`](#property-devicedata-18) |
| <a id="property-id-12"></a> `id` | `string` | Stable reading identity for idempotent delivery by the application backend. | [`ResultCallback`](#resultcallback).[`id`](#property-id-19) | - |
| <a id="property-legacyid"></a> `legacyId?` | `string` | The id SDKs before 1.16.1 gave this reading, to recognise one they already saved. | - | [`ResultCallback`](#resultcallback).[`legacyId`](#property-legacyid-1) |
| <a id="property-ownerkey"></a> `ownerKey` | `string` | Stable owner that queued this reading; use it instead of the active account when routing. | - | - |
| <a id="property-queuedat"></a> `queuedAt` | `string` | ISO timestamp of when the result was queued. | - | - |
| <a id="property-queueid"></a> `queueId?` | `string` | Queue entry identity; unlike `id`, this changes when a reading is enqueued again. | - | - |
| <a id="property-recordedfor"></a> `recordedFor?` | `string` | The account a series was recorded for. It closes later, perhaps after someone else signs in, and is queued for this account, not for whoever is signed in then. | - | [`ResultCallback`](#resultcallback).[`recordedFor`](#property-recordedfor-1) |
| <a id="property-series"></a> `series?` | [`MeasurementSeries`](#measurementseries) | Every value of a series, for a result that closes one (a streaming device's values over up to an hour). `data` then holds each property's mean, from the series' start. | - | [`ResultCallback`](#resultcallback).[`series`](#property-series-1) |

***

### BackgroundSyncStorage [#backgroundsyncstorage]

Key-value storage the background queue persists to.

#### Properties [#properties-18]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-getitem"></a> `getItem` | (`key`) => `Promise`\<`string` \| `null`\> | Reads the value stored under a key, or `null`. |
| <a id="property-setitem"></a> `setItem` | (`key`, `value`) => `Promise`\<`void`\> | Stores a value under a key. |

***

### BluetoothDevicePickerProps [#bluetoothdevicepickerprops]

Props of [BluetoothDevicePicker](#bluetoothdevicepicker).

#### Extends [#extends-15]

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

#### Properties [#properties-19]

| Property | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ |
| <a id="property-devices"></a> `devices` | readonly [`BTDeviceSelection`](#btdeviceselection)[] | Devices to choose 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 derived device title. | - |
| <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 device the user picks. | - |
| <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. | - |

***

### BluetoothRuntime [#bluetoothruntime]

Shared store and event bus behind the Bluetooth hooks.

#### Properties [#properties-20]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-blemanager"></a> `bleManager?` | `BleManager` | BLE manager the runtime was created with. |
| <a id="property-clearresults"></a> `clearResults` | () => `void` | Clears the results of every device. |
| <a id="property-devices-1"></a> `devices` | readonly [`RuntimeDevice`](#runtimedevice)[] | Known devices. |
| <a id="property-emit"></a> `emit` | \<`K`\>(`event`, `value`) => `void` | Delivers an event to its listeners. |
| <a id="property-flushbackgroundsync"></a> `flushBackgroundSync` | () => `Promise`\<`void`\> | Delivers queued background results; rejects when background sync is not configured. |
| <a id="property-getbackgroundscanenabled"></a> `getBackgroundScanEnabled` | () => `boolean` | Whether background scanning is on. |
| <a id="property-getpaireddeviceids"></a> `getPairedDeviceIds` | (`storageKey`) => readonly `string`[] \| `undefined` | Returns the cached paired device IDs for a storage key, if loaded. |
| <a id="property-getresultconnectionid"></a> `getResultConnectionId` | (`result`) => `number` | Returns the connection counter value a result was received under. |
| <a id="property-getsnapshot"></a> `getSnapshot` | () => [`BluetoothRuntimeSnapshot`](#bluetoothruntimesnapshot) | Returns the current state snapshot. |
| <a id="property-haslisteners"></a> `hasListeners` | (`event`) => `boolean` | Whether anything listens for the event. |
| <a id="property-initializebackgroundscanenabled"></a> `initializeBackgroundScanEnabled` | (`enabled`) => `void` | Sets the initial background scan state; ignored once initialised. |
| <a id="property-loadpaireddeviceids"></a> `loadPairedDeviceIds` | (`storageKey`, `load`) => `Promise`\<readonly `string`[]\> | Loads the paired device IDs once per storage key and caches them. |
| <a id="property-manager"></a> `manager?` | [`BluetoothRuntimeManager`](#bluetoothruntimemanager) | Manager controlling scanning and connections, once set. |
| <a id="property-removedevice"></a> `removeDevice` | (`deviceId`) => `void` | Removes a device. |
| <a id="property-setautoconnect"></a> `setAutoConnect` | (`enabled`, `delayMs?`, `onDeviceSelectionRequired?`) => `void` | Configures automatic connection on the manager. |
| <a id="property-setbackgroundscanenabled"></a> `setBackgroundScanEnabled` | (`enabled`) => `void` | Turns background scanning on or off. |
| <a id="property-setbackgroundsyncflush"></a> `setBackgroundSyncFlush` | (`flush?`) => `void` | Registers the function that delivers queued background results. |
| <a id="property-setbluetoothpermissionstatus"></a> `setBluetoothPermissionStatus` | (`status`) => `void` | Records the Bluetooth permission status. |
| <a id="property-setbluetoothstate"></a> `setBluetoothState` | (`state`) => `void` | Records the Bluetooth adapter state. |
| <a id="property-setdeviceconnectionevent"></a> `setDeviceConnectionEvent` | (`event`) => `void` | Records a connection event on its device. |
| <a id="property-setdeviceresult"></a> `setDeviceResult` | (`result`) => `void` | Records a result on its device, ignoring one already recorded. |
| <a id="property-setdevicestatus"></a> `setDeviceStatus` | (`value`) => `void` | Records a device status. |
| <a id="property-setmanager"></a> `setManager` | (`manager?`) => `void` | Sets or clears the Bluetooth manager. |
| <a id="property-setpaireddeviceids"></a> `setPairedDeviceIds` | (`storageKey`, `ids`) => `void` | Replaces the cached paired device IDs and notifies listeners. |
| <a id="property-subscribe"></a> `subscribe` | \<`K`\>(`event`, `callback`) => () => `void` | Listens for an event; returns an unsubscribe function. |
| <a id="property-subscribestate"></a> `subscribeState` | (`callback`) => () => `void` | Subscribes to state changes; returns an unsubscribe function. |
| <a id="property-upsertdevice"></a> `upsertDevice` | (`device`) => `void` | Adds a device or replaces its handle, keeping its status and results. |

***

### BluetoothRuntimeSnapshot [#bluetoothruntimesnapshot]

Immutable view of the runtime state that hooks subscribe to.

#### Properties [#properties-21]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-backgroundscanenabled"></a> `backgroundScanEnabled` | `boolean` | Whether background scanning is on. |
| <a id="property-bluetoothpermissionstatus"></a> `bluetoothPermissionStatus` | [`BluetoothPermissionStatus`](#bluetoothpermissionstatus) | Bluetooth permission status. |
| <a id="property-bluetoothstate"></a> `bluetoothState` | [`RuntimeBluetoothState`](#runtimebluetoothstate) | Bluetooth adapter state. |
| <a id="property-devices-2"></a> `devices` | readonly [`RuntimeDevice`](#runtimedevice)[] | Known devices. |
| <a id="property-managerready"></a> `managerReady` | `boolean` | Whether the Bluetooth manager has been set. |

***

### BosoMedicusParams [#bosomedicusparams]

Params for declaring a Boso Medicus.

#### Properties [#properties-22]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-id-13"></a> `id?` | `string` | Reported back as deviceData.name for the registered declaration. |
| <a id="property-namematch"></a> `nameMatch?` | `string` \| `RegExp` | Overrides the documented name matcher for firmware or test fixtures. |
| <a id="property-stuckdatatimeoutms"></a> `stuckDataTimeoutMs?` | `number` | Overrides the default settle time for a slower monitor. |

***

### BTManagerOptions [#btmanageroptions]

Options for `BTManager`.

#### Properties [#properties-23]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-autoconnect"></a> `autoConnect?` | `boolean` | Connect one newly discovered device automatically after the scan settles. |
| <a id="property-autoconnectdelayms"></a> `autoConnectDelayMs?` | `number` | Settle time in milliseconds before auto-connecting; defaults to 500. |
| <a id="property-backgroundenabled"></a> `backgroundEnabled?` | `boolean` | Whether scanning runs with the background service filter. |
| <a id="property-cleardevicehistory"></a> `clearDeviceHistory?` | `boolean` | Clear device-held history after it has been downloaded, when supported. |
| <a id="property-clocksync"></a> `clockSync?` | [`ClockSyncOptions`](#clocksyncoptions) | Clock synchronisation settings. |
| <a id="property-deliveredecgfilenames"></a> `deliveredEcgFileNames?` | readonly `string`[] | Names of ECG files already delivered, so they are not downloaded again. |
| <a id="property-deliveredfilenames"></a> `deliveredFileNames?` | readonly `string`[] | Names of stored files already delivered, so they are not downloaded again. |
| <a id="property-getownerkey-1"></a> `getOwnerKey?` | () => `string` \| `undefined` | The signed-in account, which each series is recorded for. |
| <a id="property-ondeviceselectionrequired"></a> `onDeviceSelectionRequired?` | (`selection`) => `void` | Called when more than one supported device is discovered in the settle window. |
| <a id="property-onereadingperconnection"></a> `oneReadingPerConnection?` | `boolean` | Report only the first reading of each connection. |
| <a id="property-recordcursorstorage"></a> `recordCursorStorage?` | [`BackgroundSyncStorage`](#backgroundsyncstorage) | Where a device that hands over its stored records remembers which it already handed over, so the next connection asks only for the others: the newest record a Bluetooth SIG glucose meter sent, and the stored files of a Viatom monitor (ER1, BP2) whose readings `onResult` queued or saved. Use the store your results queue uses. Without it every connection asks for all records. |
| <a id="property-resultpolicies"></a> `resultPolicies?` | `Partial`\<`Record`\<`string`, [`DeviceResultPolicy`](#deviceresultpolicy)\>\> | Result policy per device name. |
| <a id="property-seriesstorage"></a> `seriesStorage?` | [`BackgroundSyncStorage`](#backgroundsyncstorage) | Where series being recorded (a `"series"` result policy) wait, so one survives the app closing; use the store your results queue in. Without it they live in memory, and a closed app loses the series it was recording. |
| <a id="property-serviceuuids-1"></a> `serviceUUIDs?` | readonly `string`[] \| `null` | The services a background scan asks for (see `getBackgroundServiceUUIDs`). A foreground scan stays unfiltered, so every accepted device can be found on screen. |

***

### BTProviderChildWrapperProps [#btproviderchildwrapperprops]

Props the Bluetooth provider passes down to its inner wrapper.

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

- [`BTProviderProps`](#btproviderprops)

#### Type Parameters [#type-parameters-13]

| Type Parameter |
| ------ |
| <a id="type-parameter-t-5"></a> `T` *extends* readonly [`AcceptedDevice`](#accepteddevice)[] |

#### Properties [#properties-24]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-accepteddevices"></a> `acceptedDevices` | `T` | Devices the provider scans for and accepts. |
| <a id="property-autoconnect-1"></a> `autoConnect?` | `boolean` | Connect to a found device automatically. |
| <a id="property-autoconnectdelayms-1"></a> `autoConnectDelayMs?` | `number` | Delay in milliseconds before an automatic connection starts. |
| <a id="property-backgroundsync"></a> `backgroundSync?` | [`BackgroundSyncOptions`](#backgroundsyncoptions)\<`KeyOfAccepted`\<`T`\[`number`\]\>\> | Options for syncing devices in the background. |
| <a id="property-blemanager-1"></a> `bleManager` | `BleManager` | BLE manager used for scanning and connecting. |
| <a id="property-cleardevicehistory-1"></a> `clearDeviceHistory?` | `boolean` | Clear supported device history after it has been downloaded. |
| <a id="property-clocksync-1"></a> `clockSync?` | [`ClockSyncOptions`](#clocksyncoptions) | Options for synchronising device clocks. |
| <a id="property-deliveredecgfilenames-1"></a> `deliveredEcgFileNames?` | readonly `string`[] | Names of ECG files already delivered, so they are not downloaded again. |
| <a id="property-deliveredfilenames-1"></a> `deliveredFileNames?` | readonly `string`[] | Names of stored files already delivered, so they are not downloaded again. |
| <a id="property-onconnectionevent-12"></a> `onConnectionEvent?` | (`data`) => `void` | Called for connection lifecycle events such as pairing or battery. |
| <a id="property-ondevicefound"></a> `onDeviceFound?` | (`device`, `manager`) => `Promise`\<`void`\> | Called when an accepted device is found. |
| <a id="property-ondeviceselectionrequired-1"></a> `onDeviceSelectionRequired?` | (`selection`) => `void` | Called when several devices match and the user must pick one. |
| <a id="property-ondevicestatuschanged-12"></a> `onDeviceStatusChanged?` | (`data`) => `void` | Called when a device status changes. |
| <a id="property-onereadingperconnection-1"></a> `oneReadingPerConnection?` | `boolean` | Report one result per connection, then stay quiet until the next. |
| <a id="property-onerror-13"></a> `onError?` | (`data`) => `void` | Called when a Bluetooth or device error occurs. |
| <a id="property-onresult-13"></a> `onResult?` | (`data`) => `void` | Called when a device produces a result. |
| <a id="property-permissionstatus"></a> `permissionStatus?` | [`BluetoothPermissionStatus`](#bluetoothpermissionstatus) | Current Bluetooth permission status. |
| <a id="property-resultpolicies-1"></a> `resultPolicies?` | `Partial`\<`Record`\<`string`, [`DeviceResultPolicy`](#deviceresultpolicy)\>\> | Result policy per device name. |

***

### BTProviderPermissionFallbackProps [#btproviderpermissionfallbackprops]

Props handed to the permission fallback renderer.

#### Properties [#properties-25]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-opensettings"></a> `openSettings` | () => `void` | Opens the system settings for the app. |
| <a id="property-request"></a> `request` | () => `Promise`\<`boolean`\> | Asks for the permission; resolves to whether it was granted. |
| <a id="property-status"></a> `status` | `"denied"` \| `"blocked"` | Why Bluetooth cannot be used yet. |

***

### BTProviderProps [#btproviderprops]

Props the Bluetooth provider passes down to its inner wrapper.

#### Extends [#extends-16]

- [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops)\<`T`\>

#### Type Parameters [#type-parameters-14]

| Type Parameter |
| ------ |
| <a id="type-parameter-t-6"></a> `T` *extends* readonly [`AcceptedDevice`](#accepteddevice)[] |

#### Properties [#properties-26]

| Property | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ |
| <a id="property-accepteddevices-1"></a> `acceptedDevices` | `T` | Devices the provider scans for and accepts. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`acceptedDevices`](#property-accepteddevices) |
| <a id="property-autoconnect-2"></a> `autoConnect?` | `boolean` | Connect to a found device automatically. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`autoConnect`](#property-autoconnect-1) |
| <a id="property-autoconnectdelayms-2"></a> `autoConnectDelayMs?` | `number` | Delay in milliseconds before an automatic connection starts. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`autoConnectDelayMs`](#property-autoconnectdelayms-1) |
| <a id="property-backgroundsync-1"></a> `backgroundSync?` | [`BackgroundSyncOptions`](#backgroundsyncoptions)\<`KeyOfAccepted`\<`T`\[`number`\]\>\> | Options for syncing devices in the background. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`backgroundSync`](#property-backgroundsync) |
| <a id="property-blemanager-2"></a> `bleManager` | `BleManager` | BLE manager used for scanning and connecting. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`bleManager`](#property-blemanager-1) |
| <a id="property-cleardevicehistory-2"></a> `clearDeviceHistory?` | `boolean` | Clear supported device history after it has been downloaded. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`clearDeviceHistory`](#property-cleardevicehistory-1) |
| <a id="property-clocksync-2"></a> `clockSync?` | [`ClockSyncOptions`](#clocksyncoptions) | Options for synchronising device clocks. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`clockSync`](#property-clocksync-1) |
| <a id="property-deliveredecgfilenames-2"></a> `deliveredEcgFileNames?` | readonly `string`[] | Names of ECG files already delivered, so they are not downloaded again. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`deliveredEcgFileNames`](#property-deliveredecgfilenames-1) |
| <a id="property-deliveredfilenames-2"></a> `deliveredFileNames?` | readonly `string`[] | Names of stored files already delivered, so they are not downloaded again. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`deliveredFileNames`](#property-deliveredfilenames-1) |
| <a id="property-gateonpermission"></a> `gateOnPermission?` | `boolean` | Gate children on the automatic permission request. Defaults to false. | - |
| <a id="property-onaccesspermissionchanged"></a> `onAccessPermissionChanged?` | (`accessPermission`) => `void` | Called when Bluetooth access permission is granted or lost. | - |
| <a id="property-onconnectionevent-13"></a> `onConnectionEvent?` | (`data`) => `void` | Called for connection lifecycle events such as pairing or battery. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`onConnectionEvent`](#property-onconnectionevent-12) |
| <a id="property-ondevicefound-1"></a> `onDeviceFound?` | (`device`, `manager`) => `Promise`\<`void`\> | Called when an accepted device is found. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`onDeviceFound`](#property-ondevicefound) |
| <a id="property-ondeviceselectionrequired-2"></a> `onDeviceSelectionRequired?` | (`selection`) => `void` | Called when several devices match and the user must pick one. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`onDeviceSelectionRequired`](#property-ondeviceselectionrequired-1) |
| <a id="property-ondevicestatuschanged-13"></a> `onDeviceStatusChanged?` | (`data`) => `void` | Called when a device status changes. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`onDeviceStatusChanged`](#property-ondevicestatuschanged-12) |
| <a id="property-onereadingperconnection-2"></a> `oneReadingPerConnection?` | `boolean` | Report one result per connection, then stay quiet until the next. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`oneReadingPerConnection`](#property-onereadingperconnection-1) |
| <a id="property-onerror-14"></a> `onError?` | (`data`) => `void` | Called when a Bluetooth or device error occurs. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`onError`](#property-onerror-13) |
| <a id="property-onresult-14"></a> `onResult?` | (`data`) => `void` | Called when a device produces a result. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`onResult`](#property-onresult-13) |
| <a id="property-permissionfallback"></a> `permissionFallback?` | (`permission`) => `ReactNode` | Callback to be called when the access permission is not granted and the user is asked to open the settings | - |
| <a id="property-permissionstatus-1"></a> `permissionStatus?` | [`BluetoothPermissionStatus`](#bluetoothpermissionstatus) | Current Bluetooth permission status. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`permissionStatus`](#property-permissionstatus) |
| <a id="property-requestpermissiononmount"></a> `requestPermissionOnMount?` | `boolean` | Request permission on mount (default: true). Set false to defer permission and scanning to an app-triggered request. | - |
| <a id="property-resultpolicies-2"></a> `resultPolicies?` | `Partial`\<`Record`\<`string`, [`DeviceResultPolicy`](#deviceresultpolicy)\>\> | Result policy per device name. | [`BTProviderChildWrapperProps`](#btproviderchildwrapperprops).[`resultPolicies`](#property-resultpolicies-1) |

***

### CatalogField [#catalogfield]

The measurement types a declaration may produce, the properties each one accepts, the
canonical unit of every property, and the physiological envelope outside which a decoded
value is treated as a decoding fault rather than a reading.

A measurement type absent from this catalog cannot be declared. ECG's waveform is still
assembled by a device frame handler, but its scalar heart rate can be declared alongside
another reading in a combined frame.

The property names mirror the measurement types in @ovok/core. A typo would otherwise
produce an object the backend silently drops, so it is rejected at registration instead.

`required` marks the properties without which the reading is not that measurement. Every
property in @ovok/core is optional, so a declaration that named only `systolic` would
otherwise compile and then post a blood pressure with no diastolic - a plausible clinical
record of something that was never measured. A "result" case must declare all of them.

#### Properties [#properties-27]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-display"></a> `display?` | `string` | Human-readable label for localized catalog UIs. |
| <a id="property-max"></a> `max` | `number` | Highest decodable value; anything above is treated as a decoding fault. |
| <a id="property-min"></a> `min` | `number` | Lowest decodable value; anything below is treated as a decoding fault. |
| <a id="property-negativeatzero"></a> `negativeAtZero?` | `boolean` | A zero reading is the device's negative result for this analyte. |
| <a id="property-normalmax"></a> `normalMax?` | `number` | Upper bound of the normal range. |
| <a id="property-normalmin"></a> `normalMin?` | `number` | Lower bound of the normal range. |
| <a id="property-qualitative"></a> `qualitative?` | `boolean` | Render this analyte as a qualitative Negative/Positive result. |
| <a id="property-required"></a> `required?` | `boolean` | Whether a result must declare this property. |
| <a id="property-unit"></a> `unit` | `string` | Canonical unit of the property. |

***

### CheckmeBloodPressureRecord [#checkmebloodpressurerecord]

A blood pressure record.

#### Extends [#extends-17]

- [`CheckmeTimestampedRecord`](#checkmetimestampedrecord)

#### Properties [#properties-28]

| Property | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ |
| <a id="property-diastolic"></a> `diastolic` | `number` | Diastolic pressure. | - |
| <a id="property-heartrate"></a> `heartRate` | `number` | Heart rate in beats per minute. | - |
| <a id="property-recordedat-1"></a> `recordedAt` | `Date` | When the record was taken. | [`CheckmeTimestampedRecord`](#checkmetimestampedrecord).[`recordedAt`](#property-recordedat-6) |
| <a id="property-recordname"></a> `recordName` | `string` | Device file name of the record, formatted `YYYYMMDDHHmmss`. | [`CheckmeTimestampedRecord`](#checkmetimestampedrecord).[`recordName`](#property-recordname-5) |
| <a id="property-systolic"></a> `systolic` | `number` | Systolic pressure. | - |

***

### CheckmeDailyRecord [#checkmedailyrecord]

A daily check record.

#### Extends [#extends-18]

- [`CheckmeTimestampedRecord`](#checkmetimestampedrecord)

#### Properties [#properties-29]

| Property | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ |
| <a id="property-bloodoxygen"></a> `bloodOxygen` | `number` | Blood oxygen saturation in percent. | - |
| <a id="property-diastolic-1"></a> `diastolic?` | `number` | Diastolic pressure, when a blood pressure value was recorded. | - |
| <a id="property-heartrate-1"></a> `heartRate` | `number` | Heart rate in beats per minute. | - |
| <a id="property-recordedat-2"></a> `recordedAt` | `Date` | When the record was taken. | [`CheckmeTimestampedRecord`](#checkmetimestampedrecord).[`recordedAt`](#property-recordedat-6) |
| <a id="property-recordname-1"></a> `recordName` | `string` | Device file name of the record, formatted `YYYYMMDDHHmmss`. | [`CheckmeTimestampedRecord`](#checkmetimestampedrecord).[`recordName`](#property-recordname-5) |
| <a id="property-systolic-1"></a> `systolic?` | `number` | Systolic pressure, when a blood pressure value was recorded. | - |

***

### CheckmeEcgFile [#checkmeecgfile]

A decoded ECG recording.

#### Properties [#properties-30]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-diagnosticresult"></a> `diagnosticResult` | `number` | Device-reported diagnostic result code. |
| <a id="property-diagrampoints"></a> `diagramPoints` | `number`[] | Waveform samples in millivolts. |
| <a id="property-duration"></a> `duration` | `number` | Recording duration in seconds. |
| <a id="property-heartrate-2"></a> `heartRate` | `number` | Heart rate in beats per minute. |

***

### CheckmeEcgRecord [#checkmeecgrecord]

An ECG index record.

#### Extends [#extends-19]

- [`CheckmeTimestampedRecord`](#checkmetimestampedrecord)

#### Properties [#properties-31]

| Property | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ |
| <a id="property-recordedat-3"></a> `recordedAt` | `Date` | When the record was taken. | [`CheckmeTimestampedRecord`](#checkmetimestampedrecord).[`recordedAt`](#property-recordedat-6) |
| <a id="property-recordname-2"></a> `recordName` | `string` | Device file name of the record, formatted `YYYYMMDDHHmmss`. | [`CheckmeTimestampedRecord`](#checkmetimestampedrecord).[`recordName`](#property-recordname-5) |
| <a id="property-result"></a> `result` | `number` | Device-reported ECG result code. | - |

***

### CheckmeOxygenRecord [#checkmeoxygenrecord]

A blood oxygen record.

#### Extends [#extends-20]

- [`CheckmeTimestampedRecord`](#checkmetimestampedrecord)

#### Properties [#properties-32]

| Property | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ |
| <a id="property-bloodoxygen-1"></a> `bloodOxygen` | `number` | Blood oxygen saturation in percent. | - |
| <a id="property-heartrate-3"></a> `heartRate` | `number` | Heart rate in beats per minute. | - |
| <a id="property-perfusionindex"></a> `perfusionIndex` | `number` | Perfusion index. | - |
| <a id="property-recordedat-4"></a> `recordedAt` | `Date` | When the record was taken. | [`CheckmeTimestampedRecord`](#checkmetimestampedrecord).[`recordedAt`](#property-recordedat-6) |
| <a id="property-recordname-3"></a> `recordName` | `string` | Device file name of the record, formatted `YYYYMMDDHHmmss`. | [`CheckmeTimestampedRecord`](#checkmetimestampedrecord).[`recordName`](#property-recordname-5) |

***

### CheckmePodRealtimeReading [#checkmepodrealtimereading]

A realtime reading from a Checkme Pod.

#### Properties [#properties-33]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-battery"></a> `battery` | `number` | Battery level. |
| <a id="property-batterystate"></a> `batteryState` | `number` | Battery state code. |
| <a id="property-bloodoxygen-2"></a> `bloodOxygen` | `number` | Blood oxygen saturation in percent. |
| <a id="property-oxygenstate"></a> `oxygenState` | `number` | Oxygen measurement state code. |
| <a id="property-perfusionindex-1"></a> `perfusionIndex` | `number` | Perfusion index. |
| <a id="property-pulserate"></a> `pulseRate` | `number` | Pulse rate in beats per minute. |
| <a id="property-runstatus"></a> `runStatus` | `number` | Device run status code. |
| <a id="property-temperature"></a> `temperature` | `number` | Temperature in degrees Celsius. |
| <a id="property-temperaturestate"></a> `temperatureState` | `number` | Temperature measurement state code. |

***

### CheckmePodResponse [#checkmepodresponse]

A decoded Checkme Pod response.

#### Properties [#properties-34]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-content"></a> `content` | `string`[] | Payload bytes as hex strings. |
| <a id="property-sequence"></a> `sequence` | `number` | Sequence number of the response. |
| <a id="property-state"></a> `state` | `boolean` | Whether the device reported success. |

***

### CheckmePodSequencerParams [#checkmepodsequencerparams]

Params of `CheckmePodSequencer`.

#### Properties [#properties-35]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-now"></a> `now?` | () => `Date` | Clock used to timestamp readings and sync the device; defaults to the system clock. |
| <a id="property-onresult-15"></a> `onResult` | (`result`) => `void` | Called with each decoded measurement. |
| <a id="property-write"></a> `write` | `Omit`\<[`DeviceCommand`](#devicecommand), `"frame"`\> | Where commands are written. |

***

### CheckmeResponse [#checkmeresponse]

A decoded Checkme response.

#### Properties [#properties-36]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-content-1"></a> `content` | `string`[] | Payload bytes as hex strings. |
| <a id="property-head"></a> `head` | `number` | Envelope header byte: `0x55` or `0xa5`. |
| <a id="property-sequence-1"></a> `sequence` | `number` | Sequence number of the response. |
| <a id="property-state-1"></a> `state` | `boolean` | Whether the device reported success. |

***

### CheckmeTemperatureRecord [#checkmetemperaturerecord]

A body temperature record.

#### Extends [#extends-21]

- [`CheckmeTimestampedRecord`](#checkmetimestampedrecord)

#### Properties [#properties-37]

| Property | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ |
| <a id="property-recordedat-5"></a> `recordedAt` | `Date` | When the record was taken. | [`CheckmeTimestampedRecord`](#checkmetimestampedrecord).[`recordedAt`](#property-recordedat-6) |
| <a id="property-recordname-4"></a> `recordName` | `string` | Device file name of the record, formatted `YYYYMMDDHHmmss`. | [`CheckmeTimestampedRecord`](#checkmetimestampedrecord).[`recordName`](#property-recordname-5) |
| <a id="property-temperature-1"></a> `temperature` | `number` | Temperature in degrees Celsius. | - |

***

### CheckmeTimestampedRecord [#checkmetimestampedrecord]

Fields shared by every timestamped Checkme record.

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

- [`CheckmeBloodPressureRecord`](#checkmebloodpressurerecord)
- [`CheckmeDailyRecord`](#checkmedailyrecord)
- [`CheckmeOxygenRecord`](#checkmeoxygenrecord)
- [`CheckmeTemperatureRecord`](#checkmetemperaturerecord)
- [`CheckmeEcgRecord`](#checkmeecgrecord)
- [`PulsebitEcgRecord`](#pulsebitecgrecord)

#### Properties [#properties-38]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-recordedat-6"></a> `recordedAt` | `Date` | When the record was taken. |
| <a id="property-recordname-5"></a> `recordName` | `string` | Device file name of the record, formatted `YYYYMMDDHHmmss`. |

***

### CheckmeTransferParams [#checkmetransferparams]

Params of the Checkme file transfer sequencer.

#### Properties [#properties-39]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-onresult-16"></a> `onResult` | (`result`) => `void` | Called with each decoded measurement. |
| <a id="property-write-1"></a> `write` | `Omit`\<[`DeviceCommand`](#devicecommand), `"frame"`\> | Where commands are written. |

***

### ClockSyncOptions [#clocksyncoptions]

Options controlling device clock synchronisation.

#### Properties [#properties-40]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-enabled-1"></a> `enabled?` | `boolean` | Optional clock writes are enabled by default for verified protocols. |
| <a id="property-now-1"></a> `now?` | () => `Date` | Supplies the time sent to a device. Defaults to the current time. |
| <a id="property-timezone"></a> `timezone?` | [`ClockSyncTimezone`](#clocksynctimezone) | Interprets the supplied Date explicitly; defaults to the local timezone. |

***

### CommandSequencer [#commandsequencer]

Decides what to send a device, and when.

These protocols are self-clocking: the device answers a request, and the answer is what
says which request comes next. A file read walks its offsets that way, and an identity
check gates everything after it on the reply to the first command. Neither can be
expressed by re-sending one fixed frame, which is all the SDK could do before.

At most one command is outstanding at a time. The transport serialises writes, so an
implementation may assume the frame it is answering is the reply to the command it last
returned.

#### Methods [#methods-28]

##### commandProgress()? [#commandprogress-2]

```ts
commandProgress?(frame): "ignored" | "partial" | "complete";
```

Describes whether a frame is ignored, partial, or completes the outstanding command.

###### Parameters [#parameters-162]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |

###### Returns [#returns-270]

`"ignored"` \| `"partial"` \| `"complete"`

##### commandTimeoutMs()? [#commandtimeoutms-2]

```ts
commandTimeoutMs?(): number | undefined;
```

The response timeout for the currently outstanding command, when a protocol needs one.

###### Returns [#returns-271]

`number` \| `undefined`

##### initialCommands() [#initialcommands-8]

```ts
initialCommands():
  | readonly DeviceCommand[]
| Promise<readonly DeviceCommand[]>;
```

Sent once every characteristic is subscribed. Empty starts a device that only listens.

May resolve later, for a first command that depends on state read from storage.

###### Returns [#returns-272]

  \| readonly [`DeviceCommand`](#devicecommand)[]
  \| `Promise`\<readonly [`DeviceCommand`](#devicecommand)[]\>

##### isHistoryTransfer()? [#ishistorytransfer-5]

```ts
isHistoryTransfer?(): boolean;
```

True when accepted results are records downloaded from device history.

###### Returns [#returns-273]

`boolean`

##### isNormalDisconnect()? [#isnormaldisconnect-1]

```ts
isNormalDisconnect?(): boolean;
```

True when a timeout-style disconnect is the device's normal completion signal.

###### Returns [#returns-274]

`boolean`

##### nextCommand() [#nextcommand-8]

```ts
nextCommand(frame, characteristicUuid?): readonly DeviceCommand[] | undefined;
```

Answers one complete frame, with the characteristic it arrived on.

Returning `undefined` sends nothing, which is how a sequencer waits: an unidentified
device is left alone rather than addressed with an opcode that may mean something else
on the hardware actually present.

###### Parameters [#parameters-163]

| Parameter | Type |
| ------ | ------ |
| `frame` | readonly `string`[] |
| `characteristicUuid?` | `string` |

###### Returns [#returns-275]

readonly [`DeviceCommand`](#devicecommand)[] \| `undefined`

##### onCommandTimeout()? [#oncommandtimeout-2]

```ts
onCommandTimeout?(): CommandTimeoutResult;
```

Re-sends the current command or ends the exchange after a response timeout.

###### Returns [#returns-276]

[`CommandTimeoutResult`](#commandtimeoutresult)

##### onServicesDiscovered()? [#onservicesdiscovered]

```ts
onServicesDiscovered?(serviceUuids): void;
```

The declared services discovery found, before `initialCommands`; lets a protocol pick its generation.

###### Parameters [#parameters-164]

| Parameter | Type |
| ------ | ------ |
| `serviceUuids` | readonly `string`[] |

###### Returns [#returns-277]

`void`

***

### CommandTimeoutResult [#commandtimeoutresult]

What to do after a command received no response.

#### Properties [#properties-41]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-commands"></a> `commands?` | readonly [`DeviceCommand`](#devicecommand)[] | Commands to send in place of the timed-out one. |
| <a id="property-terminal"></a> `terminal?` | `boolean` | True when the exchange is over and nothing more is sent. |

***

### CompiledCustomField [#compiledcustomfield]

A validated field spec with every default resolved.

#### Properties [#properties-42]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-byteindexes"></a> `byteIndexes` | `number`[] | Already reordered for the declared byte order. |
| <a id="property-decimals"></a> `decimals?` | `number` | Decimal places the value is rounded to, when set. |
| <a id="property-encoding"></a> `encoding` | [`CustomFieldEncoding`](#customfieldencoding) | How the bytes are decoded into a number. |
| <a id="property-max-1"></a> `max` | `number` | Highest accepted decoded value. |
| <a id="property-min-1"></a> `min` | `number` | Hard accepted range. A decoded value outside it is an error, never a reading. |
| <a id="property-name-1"></a> `name` | `string` | Property name the decoded value is reported under. |
| <a id="property-offset"></a> `offset` | `number` | Value added after scaling. |
| <a id="property-scale"></a> `scale` | `number` | Multiplier applied to the raw value. |
| <a id="property-unit-1"></a> `unit` | `string` | Unit the value is reported in. |

***

### CustomCaseSpec [#customcasespec]

One frame shape the device emits, selected by the monitor's `caseSelectorBytes`.

#### Properties [#properties-43]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-additionalmeasurements"></a> `additionalMeasurements?` | `CustomMeasurementSpec`[] | Further readings the same frame carries. A multi-parameter monitor sends one frame holding a heart rate, an oxygen saturation and a temperature at once. Those are three measurements, not one with nine properties, so each is declared with its own type and its own fields and each is reported separately. Property names must still be unique across the whole frame, because the decoded object is flat. Only meaningful on a "result" case. |
| <a id="property-description"></a> `description?` | `string` | Free-text note describing the frame shape. |
| <a id="property-fields"></a> `fields?` | [`CustomFieldSpec`](#customfieldspec)[] | Required and non-empty for a "result" case, forbidden otherwise. |
| <a id="property-kind"></a> `kind` | [`CustomCaseKind`](#customcasekind) | What this frame shape represents. |
| <a id="property-measurementtypekey"></a> `measurementTypeKey?` | `MeasurementTypeKey` | Required for a "result" case. Must be a type the declarative decoder supports. |
| <a id="property-minlengthbytes"></a> `minLengthBytes?` | `number` | Shortest frame of this shape, when it is longer than the characteristic's minimum. A selector byte often decides how long the frame is: the Bluetooth blood-pressure profile puts a timestamp and a pulse rate behind flag bits, so one shape is seven bytes and another is sixteen. Without this, every case is bounded by the shortest of them and the later fields cannot be declared at all - which is how a pulse rate gets dropped from a device that reports one. Must be at least the characteristic's `frame.minLengthBytes`. A frame that arrives shorter than the case it selected decodes nothing and is reported, not guessed at. |
| <a id="property-repeatedrecords"></a> `repeatedRecords?` | `object` | The frame is a run of fixed-width records, each decoded the same way. A device that hands over its stored history answers one request with every record it holds, back to back. Those are separate readings taken at separate times, so each is reported on its own rather than merged. **Byte indexes are relative to a record, not to the frame**, and are bounds-checked against `recordBytes`. A trailing part-record is ignored: a whole number of records is what the device sends, and half of one is not a reading. |
| `repeatedRecords.from?` | `number` | Byte the first record starts at. Defaults to 0. |
| `repeatedRecords.recordBytes` | `number` | Width of one record. |
| <a id="property-requiresstream"></a> `requiresStream?` | `boolean` | Only accept this result after a stream case started the same measurement session. |
| <a id="property-selector"></a> `selector` | `string` | Concatenated hex of the selector bytes that identifies this frame, e.g. "aa0f0801". Empty string when the characteristic declares no selector and has a single case. |

***

### CustomDeviceDefinition [#customdevicedefinition]

A validated, ready-to-run custom device. Only defineCustomDevice produces one.

#### Properties [#properties-44]

| Property | Modifier | Type | Description |
| ------ | ------ | ------ | ------ |
| <a id="property-custom_device_brand"></a> `[CUSTOM_DEVICE_BRAND]` | `readonly` | `true` | Brand proving the definition came from `defineCustomDevice`. |
| <a id="property-clocksync-3"></a> `clockSync` | `readonly` | [`ClockSyncCapability`](#clocksynccapability) | Whether the device clock can be synchronised. |
| <a id="property-createcommandsequencer"></a> `createCommandSequencer?` | `readonly` | [`CustomSequencerFactory`](#customsequencerfactory) | Replaces the declared `write` with a command sequence the protocol computes at connect time. |
| <a id="property-createframehandler"></a> `createFrameHandler?` | `readonly` | [`CustomFrameHandlerFactory`](#customframehandlerfactory) | Creates per-device state for frames that need a protocol-specific decoder. |
| <a id="property-decoratereading"></a> `decorateReading?` | `readonly` | [`CustomReadingDecorator`](#customreadingdecorator) | Adds protocol metadata that is not a numeric measurement field. |
| <a id="property-fields-1"></a> `fields` | `readonly` | `ReadonlyMap`\<`string`, [`CompiledCustomField`](#compiledcustomfield)\> | Keyed by `${measurementTypeKey}:${fieldName}`, used to bounds-check every reading. |
| <a id="property-framereader"></a> `frameReader?` | `readonly` | `FrameReader` | Optional protocol frame reader for declarations whose notifications may be batched. |
| <a id="property-frames"></a> `frames` | `readonly` | `ReadonlyMap`\<`string`, [`CustomFrameSpec`](#customframespec)\> | Frame declaration of every monitor characteristic, keyed by its 128-bit UUID. |
| <a id="property-id-14"></a> `id` | `readonly` | [`CustomDeviceId`](#customdeviceid) | Identifier of the device. |
| <a id="property-lepu"></a> `lepu?` | `readonly` | [`CustomLepuSpec`](#customlepuspec) | Validated Lepu protocol declaration, with its UUIDs normalised. |
| <a id="property-mainservices"></a> `mainServices` | `readonly` | [`IService`](#iservice)[] | Services of the device, in the form the Bluetooth layer consumes. |
| <a id="property-matchbyservice"></a> `matchByService` | `readonly` | `boolean` | Whether a peripheral without a name is matched by the declared service UUIDs. |
| <a id="property-namematch-1"></a> `nameMatch` | `readonly` | `RegExp` | Matches the advertised BLE name. |
| <a id="property-onereadingperconnection-3"></a> `oneReadingPerConnection` | `readonly` | `boolean` | Whether only one result is reported per connection. |
| <a id="property-preferredmtu"></a> `preferredMtu?` | `readonly` | `number` | MTU to request once connected, when the declaration asked for one. |
| <a id="property-reportsbondedevent"></a> `reportsBondedEvent?` | `readonly` | `boolean` | Emit the bonded connection event after a successful connection. |
| <a id="property-sessionpolicy"></a> `sessionPolicy?` | `readonly` | `CustomSessionPolicy` | How live samples are aggregated when the session ends. |
| <a id="property-spec"></a> `spec` | `readonly` | [`CustomDeviceSpec`](#customdevicespec) | The declaration this definition was built from. |
| <a id="property-stuckdatatimeout"></a> `stuckDataTimeout` | `readonly` | `number` | Milliseconds without a usable frame before the read is abandoned. |
| <a id="property-tmb"></a> `tmb?` | `readonly` | `CustomTmbSpec` | Validated TMB protocol declaration, with its UUIDs normalised. |

***

### CustomDeviceSpec [#customdevicespec]

Plain, JSON-shaped declaration of a Bluetooth device the SDK has no class for.

#### Properties [#properties-45]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-clocksync-4"></a> `clockSync?` | [`ClockSyncCapability`](#clocksynccapability) | Declares the clock capability when a custom protocol has been verified. |
| <a id="property-id-15"></a> `id?` | `string` | Reported back as deviceData.name. Built-in names are reserved. |
| <a id="property-lepu-1"></a> `lepu?` | [`CustomLepuSpec`](#customlepuspec) | Declares the Lepu/Viatom framed protocol, which brings its own frame reader and its own command sequence. A declaration with this needs no `services[].write`: commands are built rather than written down, and are addressed through `lepu.write`. |
| <a id="property-matchbyservice-1"></a> `matchByService?` | `boolean` | Match by one of this declaration's service UUIDs when the peripheral has no name. |
| <a id="property-namematch-2"></a> `nameMatch?` | `string` \| `RegExp` | Advertised BLE name. Omit for a service-matched declaration. |
| <a id="property-onereadingperconnection-4"></a> `oneReadingPerConnection?` | `boolean` | Report one result, then stay quiet until the next connection. |
| <a id="property-preferredmtu-1"></a> `preferredMtu?` | `number` | MTU to ask for once connected. A larger one carries a frame in fewer notifications and a command in fewer writes. Omit it to keep whatever the platform negotiates. |
| <a id="property-services"></a> `services` | [`CustomServiceSpec`](#customservicespec)[] | Services the device exposes and the frames its characteristics emit. |
| <a id="property-sessionpolicy-1"></a> `sessionPolicy?` | `CustomSessionPolicy` | Aggregate valid live samples into one result when the session ends. |
| <a id="property-stuckdatatimeoutms-1"></a> `stuckDataTimeoutMs` | `number` | Milliseconds without a usable frame before the read is abandoned. 1000-6000000. |
| <a id="property-tmb-1"></a> `tmb?` | `CustomTmbSpec` | Declares the TMB blood-pressure history protocol used by Viatom BP families. |

***

### CustomFieldSpec [#customfieldspec]

One measurement property read out of a frame at fixed byte offsets.

The property `name` and `unit` are checked at registration against the measurement
catalog for the case's measurementTypeKey. A name the SDK does not know, or a unit
that is not the canonical one, is rejected - it would otherwise produce a measurement
the backend silently drops, or a number in the wrong unit.

#### Properties [#properties-46]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-byteindexes-1"></a> `byteIndexes` | `number`[] | Byte offsets into the frame, in the order the device puts them on the wire. |
| <a id="property-byteorder"></a> `byteOrder?` | [`CustomByteOrder`](#custombyteorder) | Defaults to "big". Use "little" when the least significant byte comes first. |
| <a id="property-decimals-1"></a> `decimals?` | `number` | Round the result to this many decimals. 0-6. |
| <a id="property-encoding-1"></a> `encoding?` | [`CustomFieldEncoding`](#customfieldencoding) | Defaults to "uint". |
| <a id="property-max-2"></a> `max?` | `number` | Narrower accepted range than the catalog default. Must sit inside it. |
| <a id="property-min-2"></a> `min?` | `number` | Narrower accepted range than the catalog default. Must sit inside it. |
| <a id="property-name-2"></a> `name` | `string` | Property on the emitted measurement, e.g. "systolic". Must exist for the case's type. |
| <a id="property-offset-1"></a> `offset?` | `number` | Added after `scale`. Defaults to 0. |
| <a id="property-scale-1"></a> `scale?` | `number` | Multiplied onto the raw value. Defaults to 1. Use it for unit and resolution conversion. |
| <a id="property-unit-2"></a> `unit` | `string` | Canonical unit for `name`. Declaring any other unit fails registration. |

***

### CustomFrameSpec [#customframespec]

How a notification buffer is recognised as a complete frame.

A declared frame must be header aligned: the SDK never scans forward for the header,
because the field offsets are absolute. A buffer that does not start with the header
is never parsed - it fails the stuck-data timeout instead of producing a shifted reading.

#### Properties [#properties-47]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-checksum"></a> `checksum?` | `CustomChecksumSpec` | How the frame proves it arrived intact. Optional because some devices genuinely send none, but a declaration without one accepts whatever the radio delivered. Declare it wherever the device has one. |
| <a id="property-header"></a> `header?` | `string`[] | Required leading bytes as hex, e.g. ["aa", "55"]. |
| <a id="property-length"></a> `length?` | `object` | An in-frame length field, when the device has one. |
| `length.byteOrder` | [`CustomByteOrder`](#custombyteorder) | Byte order of the length field. |
| `length.index` | `number` | Byte offset of the length field. |
| `length.overheadBytes` | `number` | Bytes in the frame the length field does not count (header, checksum, ...). |
| `length.widthBytes` | `1` \| `2` | Width of the length field in bytes. |
| <a id="property-minlengthbytes-1"></a> `minLengthBytes` | `number` | Shortest buffer that may be parsed. Every byte index the declaration reads - case selectors and fields alike - must be inside this length, which is checked at registration. |

***

### CustomLepuSpec [#customlepuspec]

Declares that a device speaks the Lepu/Viatom framed protocol.

The whole family shares one frame - `start | cmd | ~cmd | type | seq | len | payload |
crc8` - one checksum, and one generic opcode space. What it does not share is the meaning
of the low opcodes: `0x08` polls realtime data on a BP2, starts a blood-pressure
measurement on an AirBp and starts an ECG on a Lepod. A frame built for the wrong one is
still well formed, so nothing in the protocol catches a driver bound to the wrong
hardware.

That is why `pollCommand` may not be declared without `expectedDeviceTypes`. Registration
refuses it, because a poll with nobody to check it against is exactly the mis-binding the
gate exists to prevent.

#### Properties [#properties-48]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-clocksyncprotocol"></a> `clockSyncProtocol?` | `"bp2"` \| `"bp3"` | Clock payload format used before INFO, when clock synchronization is enabled. |
| <a id="property-ecgfiledecoder"></a> `ecgFileDecoder?` | `"viatom-compressed"` \| `"raw-int16"` | Decoder used for stored ECG files. Omit this when the format is not verified. `raw-int16` is the former name of `viatom-compressed` and decodes the same way. |
| <a id="property-expecteddevicetypes"></a> `expectedDeviceTypes` | `number`[] | The models this declaration was written for, as the device reports them in its information reply. A device reporting anything else is never polled. These values are only ever observed on hardware. The vendor's own SDK binds a driver from the advertised name and never reads the model back, so there is no table of them to copy - which is what `pollCommand` being optional is for. |
| <a id="property-filetransfer"></a> `fileTransfer?` | `"ecg"` \| `"bp2"` \| `"bp3"` | Download and report each stored file using the verified decoder for that device family. |
| <a id="property-manufacturerdataprotocol"></a> `manufacturerDataProtocol?` | `"viatom-oxygen"` | Selects the OxyII service and framing when the advertisement says protocol V2. |
| <a id="property-pollcommand"></a> `pollCommand?` | `number` | The opcode to poll with, once the device has proved it is one of those models. Leaving it out is a working mode, not an omission: the device is asked what it is, the answer is reported, and nothing else is sent. That is how a model number is learned in the first place, and it is safe on hardware nobody has identified yet. |
| <a id="property-pollintervalms"></a> `pollIntervalMs?` | `number` | Delay before each realtime poll, for devices with a fixed polling cadence. |
| <a id="property-protocol"></a> `protocol?` | `"v2"` \| `"viatom-oxygen"` | Protocol variant spoken by the device. |
| <a id="property-pulsewave"></a> `pulseWave?` | `boolean` | Asks a `viatom-oxygen` oximeter for its pulse wave (`0x1B`, 125 Hz) and, unless its first answer shows it has none, polls that instead of realtime parameters. The wave is recorded only for a device whose `bloodOxygenPulseRate` result policy is `"series"`, as series of up to five minutes. Its answer carries saturation and pulse rate at the same offsets as realtime parameters, so declare cases for it too. |
| <a id="property-recordingstatus"></a> `recordingStatus?` | `object` | How a recorder reports its open recording in each poll answer. Entering the saved state reads the stored ECG files again, and the recording can be stopped on request. |
| `recordingStatus.byteIndex` | `number` | The run-status byte's index in the poll answer, header included; its low nibble is the state. |
| `recordingStatus.leadOffState` | `number` | Low-nibble state while the electrodes have no contact and the recording stays open. |
| `recordingStatus.minimumStoredSeconds` | `number` | The shortest recording the device stores when it is stopped. |
| `recordingStatus.recordingState` | `number` | Low-nibble state while recording. |
| `recordingStatus.savedState` | `number` | Low-nibble state once the recording has been stored. |
| `recordingStatus.secondsByteIndex` | `number` | Where the seconds recorded so far sit in the poll answer, u32 little-endian. |
| `recordingStatus.stopCommand` | `number` | The opcode that stops the recording, storing it when it is long enough. |
| `recordingStatus.waveform?` | `object` | Where a poll answer carries the ECG samples taken since the last one, for live display and chunks. |
| `recordingStatus.waveform.countByteIndex` | `number` | Index of the u16 little-endian sample count, header included; int16 samples follow it. |
| `recordingStatus.waveform.millivoltsPerCount` | `number` | Millivolts per sample count. |
| `recordingStatus.waveform.noSignalCount?` | `number` | The count that means no signal, stored as 0 mV. |
| `recordingStatus.waveform.sampleRateHz` | `number` | Samples per second. |
| <a id="property-rejectencryptionatbytes"></a> `rejectEncryptionAtBytes?` | `number`[] | Manufacturer-data byte indexes whose high nibble of 2 means encryption is required, for protocols without the handshake; the standard protocol runs the handshake instead. |
| <a id="property-requeststartbyte"></a> `requestStartByte?` | `string` | The leading byte used when building a request. Defaults to the first start byte. |
| <a id="property-setclockbeforeinfo"></a> `setClockBeforeInfo?` | `boolean` | Sends the Viatom oximeter clock command before the information request. |
| <a id="property-startbytes"></a> `startBytes` | `string`[] | The frame's leading byte. Most of the family uses `a5`, a smaller group `55`, and a few accept either and settle on one at runtime - so it is a list. |
| <a id="property-write-2"></a> `write` | `object` | Where commands are written. The service must be one this declaration also monitors. |
| `write.characteristicUuid` | `string` | UUID of the characteristic commands are written to. |
| `write.serviceUuid` | `string` | UUID of the service holding the write characteristic. |
| <a id="property-writewithoutresponse"></a> `writeWithoutResponse?` | `boolean` | Sends the command through the write-without-response characteristic. |

***

### CustomMonitorSpec [#custommonitorspec]

A notify/indicate characteristic and the frames it emits.

#### Properties [#properties-49]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-cases"></a> `cases` | [`CustomCaseSpec`](#customcasespec)[] | Frame shapes the characteristic can emit. |
| <a id="property-caseselectorbytes"></a> `caseSelectorBytes?` | `number`[] | Byte offsets whose concatenated hex picks the case. Omit only when the characteristic has exactly one case whose selector is the empty string. |
| <a id="property-frame"></a> `frame` | [`CustomFrameSpec`](#customframespec) | How a complete frame is recognised on this characteristic. |
| <a id="property-uuid"></a> `uuid` | `string` | UUID of the notify or indicate characteristic. |

***

### CustomSequencerContext [#customsequencercontext]

What a declaration's command sequencer is told about the device it is about to drive.

#### Properties [#properties-50]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-deviceid"></a> `deviceId` | `string` | Platform identifier of the BLE device. |
| <a id="property-recordcursorstorage-1"></a> `recordCursorStorage?` | [`BackgroundSyncStorage`](#backgroundsyncstorage) | Where the manager keeps what must outlive a connection, when it was given a store. |

***

### CustomServiceSpec [#customservicespec]

A GATT service of a custom device and its monitored characteristics.

#### Properties [#properties-51]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-monitor"></a> `monitor` | [`CustomMonitorSpec`](#custommonitorspec)[] | Notify or indicate characteristics to subscribe to. |
| <a id="property-uuid-1"></a> `uuid` | `string` | UUID of the service. |
| <a id="property-write-3"></a> `write?` | `object` | A single static command written after connect and after every processed frame. A device that needs a handshake, a challenge response or a command sequence cannot be declared and still needs a device class. |
| `write.commandHex` | `string` | Command bytes as hex. |
| `write.uuid` | `string` | UUID of the characteristic the command is written to. |
| `write.when?` | `"every-frame"` \| `"connect"` | "every-frame" (the default) polls: the command goes out after connect and after every processed frame. "connect" sends it once after connect, for a request that is answered by a stream of frames - re-sending it after each one would restart the stream. |

***

### DeviceCommand [#devicecommand]

One write to a device.

The frame is the whole command, in hex bytes, and is addressed to a characteristic rather
than left to be inferred from the service that happens to declare a write. A device with
more than one writable characteristic - a control point and a data channel, say - cannot
be driven at all when the target is implied.

Bytes rather than a hex string, because the transport splits a command that exceeds the
negotiated MTU. Splitting a string is a byte boundary the caller has to remember to
double; splitting an array cannot land inside a byte.

#### Properties [#properties-52]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-characteristicuuid"></a> `characteristicUuid` | `string` | UUID of the characteristic to write to. |
| <a id="property-delaybeforewritems"></a> `delayBeforeWriteMs?` | `number` | Optional pause before this command is written. Some peripherals need a short settling window after notifications are enabled or after acknowledging a page of records. |
| <a id="property-frame-1"></a> `frame` | readonly `string`[] | Command bytes, one hex string per byte. |
| <a id="property-serviceuuid"></a> `serviceUuid` | `string` | UUID of the service holding the characteristic. |
| <a id="property-withoutresponse"></a> `withoutResponse?` | `boolean` | Write without waiting for the device to acknowledge it. Some devices expose a write-without-response characteristic and nothing else, and a with-response write to one of those fails rather than degrading - the property simply is not there. It is the characteristic that decides this, not a preference, so it is declared alongside the one being written to. |

***

### DeviceConnectionEvent [#deviceconnectionevent]

Connection lifecycle event of a device.

#### Properties [#properties-53]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-batterylevel"></a> `batteryLevel?` | `number` | Battery percentage when the device exposes the standard Battery Service. |
| <a id="property-clockat"></a> `clockAt?` | `Date` | Local time written to a device clock, when the protocol reports an acknowledgement. |
| <a id="property-devicedata-13"></a> `deviceData` | [`DeviceData`](#devicedata) | Device the event relates to. |
| <a id="property-kind-1"></a> `kind` | [`DeviceConnectionEventKind`](#deviceconnectioneventkind) | What happened. |
| <a id="property-pairingcoderequired"></a> `pairingCodeRequired?` | `boolean` | True when the platform is waiting for the user to confirm or enter a pairing code. |
| <a id="property-phoneutcoffsetminutes"></a> `phoneUtcOffsetMinutes?` | `number` | Phone's UTC offset in minutes east of UTC at the clock write. |
| <a id="property-progress"></a> `progress?` | `object` | Progress for a history transfer when the protocol exposes record counts. |
| `progress.current` | `number` | Records transferred so far. |
| `progress.total?` | `number` | Total records, when known. |
| <a id="property-recording"></a> `recording?` | `object` | A recorder's open recording, on a `recording` event; absent once the recording has ended. Sent when it starts, when the electrodes lose or regain contact, and when it becomes long enough to be stored. |
| `recording.leadOffSince?` | `Date` | When the electrodes lost contact, while they have none; the recording stays open until it is stopped. An app can offer to stop it once this is old enough, as the vendor app does. |
| `recording.seconds` | `number` | Seconds recorded so far. |
| `recording.storesOnStop` | `boolean` | Stopping now stores the recording; a shorter one is discarded by the device. |

***

### DeviceMeasurementMap [#devicemeasurementmap]

Maps each integrated device to the measurement shapes it reports.

#### Properties [#properties-54]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-ad-bpm"></a> `A&D BPM` | `BloodPressureMeasurement` | Measurements reported by "A&D BPM". |
| <a id="property-ad-bpm-cts"></a> `A&D BPM CTS` | `BloodPressureMeasurement` | Measurements reported by "A&D BPM CTS". |
| <a id="property-ad-scale"></a> `A&D Scale` | `BodyWeightMeasurement` | Measurements reported by "A&D Scale". |
| <a id="property-alivecor"></a> `alivecor` | `never` | Measurements reported by "alivecor". |
| <a id="property-aoj-bpm"></a> `AOJ BPM` | `BloodPressureMeasurement` | Measurements reported by "AOJ BPM". |
| <a id="property-aoj-bpm-fff0"></a> `AOJ BPM FFF0` | `BloodPressureMeasurement` | Measurements reported by "AOJ BPM FFF0". |
| <a id="property-aoj-20a"></a> `AOJ-20A` | `BodyTemperatureMeasurement` | Measurements reported by "AOJ-20A". |
| <a id="property-aoj-70b"></a> `AOJ-70B` | `PulseOximeterMeasurement` | Measurements reported by "AOJ-70B". |
| <a id="property-ap-20"></a> `AP-20` | `PulseOximeterMeasurement` | Measurements reported by "AP-20". |
| <a id="property-ap-20-wps"></a> `AP-20-WPS` | `PulseOximeterMeasurement` | Measurements reported by "AP-20-WPS". |
| <a id="property-bbsm-bs1"></a> `BBSM BS1` | `BabySleepMeasurement` | Measurements reported by "BBSM BS1". |
| <a id="property-bbsm-s3"></a> `BBSM S3` | `PulseOximeterMeasurement` | Measurements reported by "BBSM S3". |
| <a id="property-bc01"></a> `BC01` | `UrineAnalyzeMeasurement` | Measurements reported by "BC01". |
| <a id="property-bgm"></a> `BGM` | `BloodGlucoseMeasurement` | Measurements reported by "BGM". |
| <a id="property-bioland-bgm"></a> `Bioland-BGM` | `BloodGlucoseMeasurement` | Measurements reported by "Bioland-BGM". |
| <a id="property-bp2"></a> `BP2` | `BloodPressureMeasurement` \| `EcgMeasurement` | Measurements reported by "BP2". |
| <a id="property-bpm-188"></a> `BPM-188` | `BloodPressureMeasurement` | Measurements reported by "BPM-188". |
| <a id="property-bpw1"></a> `BPW1` | `BloodPressureMeasurement` | Measurements reported by "BPW1". |
| <a id="property-checkme"></a> `Checkme` | \| `BloodPressureMeasurement` \| `BodyTemperatureMeasurement` \| `PulseOximeterMeasurement` \| `EcgMeasurement` \| `CheckmeHeartRateMeasurement` | Measurements reported by "Checkme". |
| <a id="property-checkme-ex"></a> `Checkme EX` | `EcgMeasurement` | Measurements reported by "Checkme EX". |
| <a id="property-checkme-pod"></a> `Checkme Pod` | `BodyTemperatureMeasurement` \| `PulseOximeterMeasurement` | Measurements reported by "Checkme Pod". |
| <a id="property-checkme-pod-wps"></a> `Checkme Pod-WPS` | `BodyTemperatureMeasurement` \| `PulseOximeterMeasurement` | Measurements reported by "Checkme Pod-WPS". |
| <a id="property-checkmele"></a> `CheckmeLE` | `EcgMeasurement` | Measurements reported by "CheckmeLE". |
| <a id="property-cmed"></a> `cmed` | `never` | Measurements reported by "cmed". |
| <a id="property-cofoe-bpm"></a> `Cofoe BPM` | `BloodPressureMeasurement` | Measurements reported by "Cofoe BPM". |
| <a id="property-cofoe-bpm-history"></a> `Cofoe BPM History` | `BloodPressureMeasurement` | Measurements reported by "Cofoe BPM History". |
| <a id="property-cofoe-glucometer"></a> `Cofoe Glucometer` | `BloodGlucoseMeasurement` | Measurements reported by "Cofoe Glucometer". |
| <a id="property-cofoe-glucometer-cgh25"></a> `Cofoe Glucometer CGH25` | `BloodGlucoseMeasurement` | Measurements reported by "Cofoe Glucometer CGH25". |
| <a id="property-cofoe-thermometer"></a> `Cofoe Thermometer` | `BodyTemperatureMeasurement` | Measurements reported by "Cofoe Thermometer". |
| <a id="property-f4"></a> `F4` | `BodyWeightMeasurement` | Measurements reported by "F4". |
| <a id="property-famidoc-bpm"></a> `Famidoc BPM` | `BloodPressureMeasurement` | Measurements reported by "Famidoc BPM". |
| <a id="property-famidoc-contact-thermometer"></a> `Famidoc Contact Thermometer` | `BodyTemperatureMeasurement` | Measurements reported by "Famidoc Contact Thermometer". |
| <a id="property-famidoc-ir-thermometer"></a> `Famidoc IR Thermometer` | `BodyTemperatureMeasurement` | Measurements reported by "Famidoc IR Thermometer". |
| <a id="property-fora-ir20"></a> `FORA IR20` | `never` | Measurements reported by "FORA IR20". |
| <a id="property-fora-w550"></a> `FORA W550` | `never` | Measurements reported by "FORA W550". |
| <a id="property-gbs-2012-b"></a> `GBS-2012-B` | `BodyWeightMeasurement` | Measurements reported by "GBS-2012-B". |
| <a id="property-genial-t31"></a> `Genial-T31` | `BodyTemperatureMeasurement` | Measurements reported by "Genial-T31". |
| <a id="property-glucocheck"></a> `GlucoCheck` | `BloodGlucoseMeasurement` | Measurements reported by "GlucoCheck". |
| <a id="property-joytech-bpm"></a> `Joytech BPM` | `BloodPressureMeasurement` | Measurements reported by "Joytech BPM". |
| <a id="property-joytech-thermometer"></a> `Joytech Thermometer` | `BodyTemperatureMeasurement` | Measurements reported by "Joytech Thermometer". |
| <a id="property-jumper-bpm"></a> `Jumper BPM` | `BloodPressureMeasurement` | Measurements reported by "Jumper BPM". |
| <a id="property-jumper-oximeter"></a> `Jumper Oximeter` | `PulseOximeterMeasurement` | Measurements reported by "Jumper Oximeter". |
| <a id="property-jumper-thermometer"></a> `Jumper Thermometer` | `BodyTemperatureMeasurement` | Measurements reported by "Jumper Thermometer". |
| <a id="property-le-s5"></a> `Le S5` | `BodyWeightMeasurement` | Measurements reported by "Le S5". |
| <a id="property-lepu-f4-scale"></a> `Lepu F4 scale` | `BodyWeightMeasurement` | Measurements reported by "Lepu F4 scale". |
| <a id="property-lepu-f5-scale"></a> `Lepu F5 scale` | `BodyWeightMeasurement` | Measurements reported by "Lepu F5 scale". |
| <a id="property-lpm311"></a> `LPM311` | `LipidPanelMeasurement` | Measurements reported by "LPM311". |
| <a id="property-mambo-a5"></a> `Mambo A5` | `PulseOximeterMeasurement` | Measurements reported by "Mambo A5". |
| <a id="property-mysense"></a> `mySense` | `BodyTemperatureMeasurement` | Measurements reported by "mySense". |
| <a id="property-oxyfit"></a> `Oxyfit` | `PulseOximeterMeasurement` | Measurements reported by "Oxyfit". |
| <a id="property-oxysmart"></a> `OxySmart` | `PulseOximeterMeasurement` | Measurements reported by "OxySmart". |
| <a id="property-pc-100"></a> `PC-100` | `BloodPressureMeasurement` \| `PulseOximeterMeasurement` | Measurements reported by "PC-100". |
| <a id="property-pc-68b"></a> `PC-68B` | `PulseOximeterMeasurement` | Measurements reported by "PC-68B". |
| <a id="property-pc300"></a> `PC300` | \| `BloodPressureMeasurement` \| `BodyTemperatureMeasurement` \| `BloodGlucoseMeasurement` \| `PulseOximeterMeasurement` \| `EcgMeasurement` | Measurements reported by "PC300". |
| <a id="property-pc80b"></a> `PC80B` | `EcgMeasurement` | Measurements reported by "PC80B". |
| <a id="property-pf10aw-me"></a> `PF10AW-ME` | `PulseOximeterMeasurement` | Measurements reported by "PF10AW-ME". |
| <a id="property-pf10bw-ve"></a> `PF10BW-VE` | `PulseOximeterMeasurement` | Measurements reported by "PF10BW-VE". |
| <a id="property-pm10"></a> `PM10` | `EcgMeasurement` | Measurements reported by "PM10". |
| <a id="property-poctorm3102"></a> `PoctorM3102` | `BloodGlucoseMeasurement` \| `UrineAnalyzeMeasurement` | Measurements reported by "PoctorM3102". |
| <a id="property-pulmo80b"></a> `PULMO80B` | `never` | Measurements reported by "PULMO80B". |
| <a id="property-pulsebit-ex"></a> `Pulsebit EX` | `EcgMeasurement` | Measurements reported by "Pulsebit EX". |
| <a id="property-r20"></a> `R20` | `RespiratoryTherapyMeasurement` | Measurements reported by "R20". |
| <a id="property-r200"></a> `R200` | `RespiratoryTherapyMeasurement` | Measurements reported by "R200". |
| <a id="property-sa10aw-pu"></a> `SA10AW-PU` | `PulseOximeterMeasurement` | Measurements reported by "SA10AW-PU". |
| <a id="property-sp-20"></a> `SP-20` | `PulseOximeterMeasurement` | Measurements reported by "SP-20". |
| <a id="property-sp-20-ble"></a> `SP-20-BLE` | `PulseOximeterMeasurement` | Measurements reported by "SP-20-BLE". |
| <a id="property-sp-20-wps"></a> `SP-20-WPS` | `PulseOximeterMeasurement` | Measurements reported by "SP-20-WPS". |
| <a id="property-taidoc-bpm"></a> `TaiDoc BPM` | `BloodPressureMeasurement` | Measurements reported by "TaiDoc BPM". |
| <a id="property-taidoc-multi"></a> `TaiDoc Multi` | `BloodPressureMeasurement` \| `BloodGlucoseMeasurement` | Measurements reported by "TaiDoc Multi". |
| <a id="property-taidoc-oximeter"></a> `TaiDoc Oximeter` | `PulseOximeterMeasurement` | Measurements reported by "TaiDoc Oximeter". |
| <a id="property-taidoc-scale"></a> `TaiDoc Scale` | `BodyWeightMeasurement` | Measurements reported by "TaiDoc Scale". |
| <a id="property-taidoc-td1107"></a> `TAIDOC TD1107` | `never` | Measurements reported by "TAIDOC TD1107". |
| <a id="property-taidoc-td4216"></a> `TAIDOC TD4216` | `BloodGlucoseMeasurement` | Measurements reported by "TAIDOC TD4216". |
| <a id="property-taidoc-thermometer"></a> `TaiDoc Thermometer` | `BodyTemperatureMeasurement` | Measurements reported by "TaiDoc Thermometer". |
| <a id="property-temp"></a> `TEMP` | `never` | Measurements reported by "TEMP". |
| <a id="property-transtek-a6-bpm"></a> `Transtek A6 BPM` | `BloodPressureMeasurement` | Measurements reported by "Transtek A6 BPM". |
| <a id="property-transtek-bpm"></a> `Transtek BPM` | `BloodPressureMeasurement` | Measurements reported by "Transtek BPM". |
| <a id="property-transtek-scale"></a> `Transtek Scale` | `BodyWeightMeasurement` | Measurements reported by "Transtek Scale". |
| <a id="property-transtek-scale-1525"></a> `Transtek Scale 1525` | `BodyWeightMeasurement` | Measurements reported by "Transtek Scale 1525". |
| <a id="property-transtek-tracker"></a> `Transtek Tracker` | `ActivityStepCountMeasurement` | Measurements reported by "Transtek Tracker". |
| <a id="property-trasense-s9"></a> `Trasense S9` | `ActivityHeartRateMeasurement` \| `ActivityStepCountMeasurement` | Measurements reported by "Trasense S9". |
| <a id="property-two"></a> `two` | `never` | Measurements reported by "two". |
| <a id="property-veroval-activity"></a> `Veroval Activity` | `ActivityHeartRateMeasurement` \| `ActivityStepCountMeasurement` | Measurements reported by "Veroval Activity". |
| <a id="property-veroval-duo-control"></a> `Veroval duo control` | `BloodPressureMeasurement` | Measurements reported by "Veroval duo control". |
| <a id="property-veroval-ecg"></a> `Veroval ECG` | `BloodPressureMeasurement` \| `VerovalEcgMeasurement` | Measurements reported by "Veroval ECG". |
| <a id="property-wbp-02"></a> `WBP-02` | `BloodPressureMeasurement` | Measurements reported by "WBP-02". |
| <a id="property-yonker-80b"></a> `Yonker 80B` | `PulseOximeterMeasurement` | Measurements reported by "Yonker 80B". |
| <a id="property-yonker-bpm"></a> `Yonker BPM` | `BloodPressureMeasurement` | Measurements reported by "Yonker BPM". |
| <a id="property-yonker-oximeter"></a> `Yonker Oximeter` | `PulseOximeterMeasurement` | Measurements reported by "Yonker Oximeter". |
| <a id="property-yonker-scale"></a> `Yonker Scale` | `BodyWeightMeasurement` | Measurements reported by "Yonker Scale". |
| <a id="property-yonker-thermometer"></a> `Yonker Thermometer` | `BodyTemperatureMeasurement` | Measurements reported by "Yonker Thermometer". |
| <a id="property-zh-sg-a606"></a> `ZH-SG-A606` | `BloodGlucoseMeasurement` | Measurements reported by "ZH-SG-A606". |

***

### DeviceResultPolicy [#deviceresultpolicy]

Result policy of one device.

#### Properties [#properties-55]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-acceptedmemoryslots"></a> `acceptedMemorySlots?` | readonly `number`[] | The device users whose readings are reported, by memory slot (a multi-user device reports its user as `memorySlot`, starting at 1). Readings of other users are dropped; a reading that names no device user is kept. Without it every user's readings are reported. |
| <a id="property-bymeasurement"></a> `byMeasurement?` | `Partial`\<`Record`\<`MeasurementTypeKey`, [`ResultPolicy`](#resultpolicy)\>\> | Policy overrides per measurement type. |
| <a id="property-default"></a> `default?` | [`ResultPolicy`](#resultpolicy) | Policy for measurement types without their own entry. |

***

### DeviceSecretStorage [#devicesecretstorage]

Per-device secrets a protocol receives once, at pairing, and needs on every later
connection - a Transtek monitor's 32-bit password is one.

Secrets are kept in memory for the app session. Give the SDK somewhere durable with
`setDeviceSecretStorage` (a SecureStore-backed adapter is a good fit), or a device paired
in one app session has to be paired again after the app restarts.

#### Properties [#properties-56]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-getitem-1"></a> `getItem` | (`key`) => `Promise`\<`string` \| `null`\> | Reads the stored value for a key, or `null` if absent. |
| <a id="property-setitem-1"></a> `setItem` | (`key`, `value`) => `Promise`\<`void`\> | Stores a value under a key. |

***

### DeviceStatusChangeCallback [#devicestatuschangecallback]

Payload delivered when a device status changes.

#### Properties [#properties-57]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-devicedata-14"></a> `deviceData` | [`DeviceData`](#devicedata) | Device whose status changed. |
| <a id="property-measurementtypekey-1"></a> `measurementTypeKey?` | `MeasurementTypeKey` | Measurement type the status relates to, when known. |
| <a id="property-status-1"></a> `status` | [`DeviceStatus`](#devicestatus) | New status. |

***

### DeviceWaveform [#devicewaveform]

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

#### Properties [#properties-58]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-at"></a> `at` | `Date` | When the answer carrying them arrived. |
| <a id="property-devicedata-15"></a> `deviceData` | [`DeviceData`](#devicedata) | Device the samples came from. |
| <a id="property-millivoltspercount"></a> `millivoltsPerCount` | `number` | Millivolts per sample count. |
| <a id="property-sampleratehz"></a> `sampleRateHz` | `number` | Samples per second. |
| <a id="property-samples"></a> `samples` | readonly `number`[] | Raw sample counts, oldest first. |

***

### EcgCalibration [#ecgcalibration]

Maps digital ECG samples to physical microvolts.

#### Properties [#properties-59]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-digitalmaximum"></a> `digitalMaximum` | `number` | Highest digital sample value. |
| <a id="property-digitalminimum"></a> `digitalMinimum` | `number` | Lowest digital sample value. |
| <a id="property-physicalmaximummicrovolts"></a> `physicalMaximumMicrovolts` | `number` | Physical value of the highest digital sample, in microvolts. |
| <a id="property-physicalminimummicrovolts"></a> `physicalMinimumMicrovolts` | `number` | Physical value of the lowest digital sample, in microvolts. |

***

### ErrorCallback [#errorcallback]

Payload delivered to the error handler.

#### Properties [#properties-60]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-code-1"></a> `code?` | [`BluetoothErrorCode`](#bluetootherrorcode) | Stable machine-readable code for every normalized native/SDK failure. |
| <a id="property-devicedata-16"></a> `deviceData?` | [`DeviceData`](#devicedata) | Device the error relates to, when known. |
| <a id="property-error"></a> `error` | `string` \| `Error` \| [`BluetoothError`](#bluetootherror) | Measurement translation keys remain compatible with existing consumers. |

***

### FakeBleDevice [#fakebledevice]

A fake GATT device and the handles that drive it.

#### Properties [#properties-61]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-device-12"></a> `device` | `Device` | The fake device to hand to code under test. |
| <a id="property-disconnect"></a> `disconnect` | () => `Promise`\<`void`\> | Disconnects the device and notifies disconnect listeners. |
| <a id="property-emitcharacteristic"></a> `emitCharacteristic` | (`serviceUuid`, `characteristicUuid`, `value`) => `void` | Delivers a notification value to everything monitoring the characteristic. |

***

### FakeBleDeviceOptions [#fakebledeviceoptions]

Options for `createFakeBleDevice`.

#### Properties [#properties-62]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-characteristics"></a> `characteristics?` | `Record`\<`string`, `string`\> | Characteristic values readable on the device, keyed `serviceUuid/characteristicUuid`. |
| <a id="property-id-16"></a> `id` | `string` | Device identifier; also the default name. |
| <a id="property-localname"></a> `localName?` | `string` | Advertised local name; defaults to `name`. |
| <a id="property-manufacturerdata"></a> `manufacturerData?` | `string` | Manufacturer data; defaults to an empty string. |
| <a id="property-mtu"></a> `mtu?` | `number` | Initial MTU; defaults to 23. |
| <a id="property-name-3"></a> `name?` | `string` | Advertised name; defaults to `id`. |
| <a id="property-serviceuuids-2"></a> `serviceUUIDs?` | readonly `string`[] | Advertised service UUIDs; defaults to none. |

***

### FakeBleManager [#fakeblemanager]

A deterministic BLE manager for hook and scan integration tests. No hardware is used.

#### Properties [#properties-63]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-createdevice"></a> `createDevice` | (`options`) => [`FakeBleDevice`](#fakebledevice) | Creates a fake GATT device. |
| <a id="property-emitdevice"></a> `emitDevice` | (`device`) => `void` | Reports a device to the active scan. |
| <a id="property-emiterror"></a> `emitError` | (`error`) => `void` | Reports a scan error to the active scan. |
| <a id="property-getscannedserviceuuids"></a> `getScannedServiceUUIDs` | () => readonly `string`[] \| `null` | Service UUID filter of the last scan, or `null` if unfiltered or none started. |
| <a id="property-manager-1"></a> `manager` | `BleManager` | The fake manager to hand to code under test. |
| <a id="property-setstate"></a> `setState` | (`state`) => `void` | Changes the adapter state and notifies state listeners. |
| <a id="property-stopdevicescan"></a> `stopDeviceScan` | () => `void` | Stops the active scan. |

***

### FakeBleManagerOptions [#fakeblemanageroptions]

Options for `createFakeBleManager`.

#### Properties [#properties-64]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-devices-3"></a> `devices?` | readonly `Device`[] | Devices reported immediately when a scan starts. |
| <a id="property-state-2"></a> `state?` | `State` | Initial Bluetooth adapter state; defaults to powered on. |

***

### GlucoseRecordDetails [#glucoserecorddetails]

What a Bluetooth SIG glucose meter says about a record, added to the reading beside
`bloodGlucose`, which is always in mg/dL.

Properties the frame does not carry are absent.

#### Properties [#properties-65]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-outofrange"></a> `outOfRange?` | `"low"` \| `"high"` | The meter says the result lies beyond what it can measure. `bloodGlucose` is then the edge of its range, not a measurement; do not store or chart it as a value. |
| <a id="property-reportedunit"></a> `reportedUnit?` | [`GlucoseReportedUnit`](#glucosereportedunit) | The unit the meter reported; `bloodGlucose` keeps its precision when converted back. |
| <a id="property-samplelocation"></a> `sampleLocation?` | [`GlucoseSampleLocation`](#glucosesamplelocation) | Where the sample was taken. |
| <a id="property-sensorstatus"></a> `sensorStatus?` | readonly [`GlucoseSensorWarning`](#glucosesensorwarning)[] | Conditions the meter flagged that leave the value usable. |
| <a id="property-sequencenumber"></a> `sequenceNumber?` | `number` | The meter's own number for the record. It counts up, so it tells records apart. |
| <a id="property-specimen"></a> `specimen?` | [`GlucoseSpecimenType`](#glucosespecimentype) | What the sample was taken from. |

***

### ~~HealthImportAdapter~~ [#healthimportadapter]

#### Deprecated [#deprecated]

Import HealthImportAdapter from @ovok/native/data-sync instead.

#### Type Parameters [#type-parameters-15]

| Type Parameter | Default type |
| ------ | ------ |
| <a id="type-parameter-ttype"></a> `TType` *extends* `string` | `string` |

#### Properties [#properties-66]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-getstatus"></a> ~~`getStatus`~~ | (`type`) => `Promise`\<`"unsupported"` \| `"refused"` \| `"authorized"` \| `"shouldRequest"`\> | Returns the access status of a data type. |
| <a id="property-request-1"></a> ~~`request`~~ | (`types`, `background`) => `Promise`\<`void`\> | Requests access to the data types, optionally for background delivery. |

***

### IBTManagedDevice [#ibtmanageddevice]

Minimal contract of a device the Bluetooth manager can connect and disconnect.

#### Properties [#properties-67]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-connect"></a> `connect` | () => `Promise`\<`void`\> | Opens the connection to the device. |
| <a id="property-disconnect-1"></a> `disconnect` | () => `Promise`\<`void`\> | Closes the connection to the device. |
| <a id="property-id-17"></a> `id` | `string` | Identifier of the managed device. |

***

### IMedicalDevice [#imedicaldevice]

Declares which GATT services an integrated device uses.

#### Properties [#properties-68]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-devicename"></a> `deviceName` | [`IntegratedDevices`](#integrateddevices) | The integrated device being described. |
| <a id="property-mainservice"></a> `mainService` | [`IService`](#iservice)[] | Services used to talk to the device. |

***

### IService [#iservice]

A GATT service of an integrated device and its characteristics.

#### Properties [#properties-69]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-monitoruuids"></a> `monitorUuids` | `IMonitorCharacteristic`[] | Notify or indicate characteristics to subscribe to. |
| <a id="property-optional"></a> `optional?` | `boolean` | Present on only some hardware revisions. Its monitors are skipped when discovery does not find it, instead of reporting a subscription error, so one class can declare every generation of a protocol and use whichever the connected device has. |
| <a id="property-uuid-2"></a> `uuid` | `string` | UUID of the service. |
| <a id="property-writeuuid"></a> `writeUuid?` | `IWriteCharacteristic` | Characteristic commands are written to. |

***

### LepuDeviceInfo [#lepudeviceinfo]

What a Lepu device says it is, in answer to `GET_INFO`.

#### Properties [#properties-70]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-branchcode"></a> `branchCode` | `string` | Vendor branch code. |
| <a id="property-devicetype"></a> `deviceType` | `number` | The model, as a number. What a driver checks before addressing the hardware. |
| <a id="property-protocolmaxlength"></a> `protocolMaxLength` | `number` | The largest payload the device will accept, which bounds a file read's chunks. |
| <a id="property-serialnumber"></a> `serialNumber` | `string` | Device serial number. |

***

### LepuDeviceParams [#lepudeviceparams]

Describes one Lepu/Viatom family product for `lepuDevice`.

#### Properties [#properties-71]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-cases-1"></a> `cases` | [`CustomCaseSpec`](#customcasespec)[] | Frame cases that decode the product's payloads. |
| <a id="property-caseselectorbytes-1"></a> `caseSelectorBytes?` | `number`[] | Byte offsets that pick the case. The command byte at index 1 is the usual choice, and products that answer one command with several shapes add the byte that distinguishes them. |
| <a id="property-clocksync-5"></a> `clockSync?` | [`ClockSyncCapability`](#clocksynccapability) | Declares the device clock capability when the protocol has been verified. |
| <a id="property-clocksyncprotocol-1"></a> `clockSyncProtocol?` | `"bp2"` \| `"bp3"` | Clock payload format used before INFO, when clock synchronization is enabled. |
| <a id="property-createframehandler-1"></a> `createFrameHandler?` | [`CustomFrameHandlerFactory`](#customframehandlerfactory) | Replaces the default frame handler with a custom one. |
| <a id="property-decoratereading-1"></a> `decorateReading?` | [`CustomReadingDecorator`](#customreadingdecorator) | Adjusts each decoded reading before it is reported. |
| <a id="property-ecgfiledecoder-1"></a> `ecgFileDecoder?` | `"viatom-compressed"` \| `"raw-int16"` | Decoder used for stored ECG files. Omit this when the format is not verified. |
| <a id="property-expecteddevicetypes-1"></a> `expectedDeviceTypes?` | `number`[] | The models this declaration was written for, as the device reports them. Required to poll, and only ever learned from hardware: declare the device without a `pollCommand` first, connect, and read the model it reports. |
| <a id="property-filetransfer-1"></a> `fileTransfer?` | `"ecg"` \| `"bp2"` \| `"bp3"` | Stored-file transfer protocol the product uses. |
| <a id="property-id-18"></a> `id?` | `string` | Reported back as deviceData.name, and must not collide with a built-in device. |
| <a id="property-manufacturerdataprotocol-1"></a> `manufacturerDataProtocol?` | `"viatom-oxygen"` | Selects the OxyII service and framing from the manufacturer's advertisement. |
| <a id="property-minlengthbytes-2"></a> `minLengthBytes` | `number` | Shortest frame any declared case may be read from. The seven-byte header and the trailing checksum are part of it, so a one-byte payload is nine. |
| <a id="property-namematch-3"></a> `nameMatch?` | `string` \| `RegExp` | The name the hardware advertises. |
| <a id="property-pollcommand-1"></a> `pollCommand?` | `number` | The opcode to poll with once the device has proved it is one of those models. Leave it out and the device identifies itself and nothing more. That is the safe first connection to hardware nobody has identified, because the low opcodes in this family act - one inflates a cuff, another starts an ECG - and mean different things on different products. |
| <a id="property-pollintervalms-1"></a> `pollIntervalMs?` | `number` | Delay before each realtime poll, for devices with a fixed polling cadence. |
| <a id="property-protocol-1"></a> `protocol?` | `"v2"` \| `"viatom-oxygen"` | The protocol variant behind the shared Viatom service. |
| <a id="property-pulsewave-1"></a> `pulseWave?` | `boolean` | Polls a legacy oximeter's pulse wave in place of its realtime parameters, when it serves one. |
| <a id="property-recordingstatus-1"></a> `recordingStatus?` | `object` | How a recorder reports its open recording; see `CustomLepuSpec`. |
| `recordingStatus.byteIndex` | `number` | The run-status byte's index in the poll answer, header included; its low nibble is the state. |
| `recordingStatus.leadOffState` | `number` | Low-nibble state while the electrodes have no contact and the recording stays open. |
| `recordingStatus.minimumStoredSeconds` | `number` | The shortest recording the device stores when it is stopped. |
| `recordingStatus.recordingState` | `number` | Low-nibble state while recording. |
| `recordingStatus.savedState` | `number` | Low-nibble state once the recording has been stored. |
| `recordingStatus.secondsByteIndex` | `number` | Where the seconds recorded so far sit in the poll answer, u32 little-endian. |
| `recordingStatus.stopCommand` | `number` | The opcode that stops the recording, storing it when it is long enough. |
| `recordingStatus.waveform?` | `object` | Where a poll answer carries the ECG samples taken since the last one, for live display and chunks. |
| `recordingStatus.waveform.countByteIndex` | `number` | Index of the u16 little-endian sample count, header included; int16 samples follow it. |
| `recordingStatus.waveform.millivoltsPerCount` | `number` | Millivolts per sample count. |
| `recordingStatus.waveform.noSignalCount?` | `number` | The count that means no signal, stored as 0 mV. |
| `recordingStatus.waveform.sampleRateHz` | `number` | Samples per second. |
| <a id="property-rejectencryptionatbytes-1"></a> `rejectEncryptionAtBytes?` | `number`[] | Manufacturer-data byte indexes whose high nibble of 2 requires encryption. |
| <a id="property-sessionpolicy-2"></a> `sessionPolicy?` | `CustomSessionPolicy` | Aggregate valid live samples when the protocol describes a session. |
| <a id="property-setclockbeforeinfo-1"></a> `setClockBeforeInfo?` | `boolean` | Sends the Viatom oximeter clock command before INFO. |
| <a id="property-stuckdatatimeoutms-2"></a> `stuckDataTimeoutMs?` | `number` | Time in milliseconds without data before the connection is treated as stuck; defaults to 60 seconds. |
| <a id="property-transport"></a> `transport?` | `"standard"` \| `"standardSmallMtu"` \| `"aw1"` \| `"ding"` \| `"aiTele"` | Which characteristics the product exposes. Nearly all of them are "standard". |
| <a id="property-v2"></a> `v2?` | `object` | Additional OxyII monitor cases, selected by manufacturer-data protocol V2. |
| `v2.cases` | [`CustomCaseSpec`](#customcasespec)[] | Frame cases for the additional OxyII monitor. |
| `v2.caseSelectorBytes?` | `number`[] | Byte offsets that pick the case. |
| `v2.minLengthBytes` | `number` | Shortest frame the additional cases may be read from. |
| <a id="property-writewithoutresponse-1"></a> `writeWithoutResponse?` | `boolean` | Uses write-without-response, as the Viatom oximeter characteristic requires. |

***

### LepuFile [#lepufile]

A file read from a Lepu device.

#### Properties [#properties-72]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-bytes"></a> `bytes` | `Uint8Array` | File bytes. |
| <a id="property-name-4"></a> `name` | `string` | File name on the device. |

***

### LepuFileTransferParams [#lepufiletransferparams]

Params of a Lepu file transfer.

#### Properties [#properties-73]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-acceptfile"></a> `acceptFile?` | (`name`) => `boolean` | Files this transfer knows how to decode; rejected names are never opened. |
| <a id="property-aftertransfer"></a> `afterTransfer?` | () => readonly [`DeviceCommand`](#devicecommand)[] | Commands to start after history has been exhausted, such as live polling. |
| <a id="property-builder"></a> `builder` | `LepuCommandBuilder` | Builds this connection's frames. One per connection: it carries a sequence number. |
| <a id="property-maxfilebytes"></a> `maxFileBytes?` | `number` | Largest file accepted, in bytes; larger transfers are refused. |
| <a id="property-onerror-15"></a> `onError` | (`reason`) => `void` | Called with why a transfer stopped. Required, so a failed read cannot pass unseen. |
| <a id="property-onfile"></a> `onFile` | (`file`) => `void` | Called once per file, and only after its length was confirmed exactly. |
| <a id="property-onfilelist"></a> `onFileList?` | (`names`) => `void` | Called with every name the device lists, before any is opened. |
| <a id="property-onprogress"></a> `onProgress?` | (`progress`) => `void` | Called as each chunk lands, for a long file with a person waiting on it. |
| <a id="property-skipfiles"></a> `skipFiles?` | `ReadonlySet`\<`string`\> | Files the app has already persisted and does not want again. |
| <a id="property-write-4"></a> `write` | `Omit`\<[`DeviceCommand`](#devicecommand), `"frame"`\> | The characteristic commands are written to. |

***

### MeasurementSeries [#measurementseries]

One kind of measurement a streaming device sent at a fixed interval: one value per slot for each measured
property, `null` for a slot nothing arrived in. It has the shape of @ovok/core's `MeasurementSeries`, which
`seriesObservations` saves as sampled data.

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

- [`OpenSeries`](#openseries)

#### Properties [#properties-74]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-measurementtypekey-2"></a> `measurementTypeKey` | `MeasurementTypeKey` | Measurement type the series holds. |
| <a id="property-periodms"></a> `periodMs` | `number` | Milliseconds from one slot to the next. |
| <a id="property-start"></a> `start` | `Date` | When the first slot starts. |
| <a id="property-values"></a> `values` | `Partial`\<`Record`\<`string`, `ReadonlyArray`\<`number` \| `null`\>\>\> | By measured property, one value per slot. |

***

### OpenSeries [#openseries]

A series still being recorded: what a screen shows while a device streams.

#### Extends [#extends-22]

- [`MeasurementSeries`](#measurementseries)

#### Properties [#properties-75]

| Property | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ |
| <a id="property-devicedata-17"></a> `deviceData` | [`DeviceData`](#devicedata) | Device that is streaming the series. | - |
| <a id="property-latest"></a> `latest` | `Partial`\<`Record`\<`string`, `number`\>\> | The last value of each property. | - |
| <a id="property-measurementtypekey-3"></a> `measurementTypeKey` | `MeasurementTypeKey` | Measurement type the series holds. | [`MeasurementSeries`](#measurementseries).[`measurementTypeKey`](#property-measurementtypekey-2) |
| <a id="property-periodms-1"></a> `periodMs` | `number` | Milliseconds from one slot to the next. | [`MeasurementSeries`](#measurementseries).[`periodMs`](#property-periodms) |
| <a id="property-start-1"></a> `start` | `Date` | When the first slot starts. | [`MeasurementSeries`](#measurementseries).[`start`](#property-start) |
| <a id="property-updatedat"></a> `updatedAt` | `Date` | When the last value arrived. | - |
| <a id="property-values-1"></a> `values` | `Partial`\<`Record`\<`string`, `ReadonlyArray`\<`number` \| `null`\>\>\> | By measured property, one value per slot. | [`MeasurementSeries`](#measurementseries).[`values`](#property-values) |

***

### PairedDeviceStorage [#paireddevicestorage]

Key-value storage the paired device list persists to.

#### Properties [#properties-76]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-getitem-2"></a> `getItem` | (`key`) => `Promise`\<`string` \| `null`\> | Reads the value stored under a key, or `null`. |
| <a id="property-setitem-2"></a> `setItem` | (`key`, `value`) => `Promise`\<`void`\> | Stores a value under a key. |

***

### PulsebitEcgRecord [#pulsebitecgrecord]

A Pulsebit or Checkme EX ECG index record.

#### Extends [#extends-23]

- [`CheckmeTimestampedRecord`](#checkmetimestampedrecord)

#### Properties [#properties-77]

| Property | Type | Description | Inherited from |
| ------ | ------ | ------ | ------ |
| <a id="property-heartrate-4"></a> `heartRate` | `number` | Heart rate in beats per minute. | - |
| <a id="property-recordedat-7"></a> `recordedAt` | `Date` | When the record was taken. | [`CheckmeTimestampedRecord`](#checkmetimestampedrecord).[`recordedAt`](#property-recordedat-6) |
| <a id="property-recordname-6"></a> `recordName` | `string` | Device file name of the record, formatted `YYYYMMDDHHmmss`. | [`CheckmeTimestampedRecord`](#checkmetimestampedrecord).[`recordName`](#property-recordname-5) |

***

### RawBluetoothAccess [#rawbluetoothaccess]

Direct GATT access to a connected device.

#### Properties [#properties-78]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-read"></a> `read` | (`serviceUUID`, `characteristicUUID`) => `Promise`\<`Characteristic`\> | Reads a characteristic. |
| <a id="property-write-5"></a> `write` | (`serviceUUID`, `characteristicUUID`, `base64Value`, `withResponse?`) => `Promise`\<`Characteristic`\> | Writes a base64 value to a characteristic, with or without a response. |

***

### RecordedBleFrame [#recordedbleframe]

One captured notification frame.

#### Properties [#properties-79]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-characteristicuuid-1"></a> `characteristicUUID` | `string` | UUID of the characteristic the frame arrived on. |
| <a id="property-delayms"></a> `delayMs?` | `number` | Optional delay used by replay tests; defaults to zero. |
| <a id="property-value"></a> `value` | `string` | Frame payload. |

***

### ResultCallback [#resultcallback]

Payload delivered to the result handler.

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

- [`BackgroundSyncResult`](#backgroundsyncresult)

#### Type Parameters [#type-parameters-16]

| Type Parameter |
| ------ |
| <a id="type-parameter-t-7"></a> `T` *extends* [`DeviceKey`](#devicekey) |

#### Properties [#properties-80]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-data-1"></a> `data` | `OmitCaseType`\<[`MeasurementTypeForDevices`](#measurementtypefordevices)\<\[`T`\]\>\> | The measurement. |
| <a id="property-devicedata-18"></a> `deviceData` | [`DeviceData`](#devicedata) | Device that produced the result. |
| <a id="property-id-19"></a> `id` | `string` | Stable identity derived from the peripheral and recorded reading. |
| <a id="property-legacyid-1"></a> `legacyId?` | `string` | The id SDKs before 1.16.1 gave this reading, to recognise one they already saved. |
| <a id="property-recordedfor-1"></a> `recordedFor?` | `string` | The account a series was recorded for. It closes later, perhaps after someone else signs in, and is queued for this account, not for whoever is signed in then. |
| <a id="property-series-1"></a> `series?` | [`MeasurementSeries`](#measurementseries) | Every value of a series, for a result that closes one (a streaming device's values over up to an hour). `data` then holds each property's mean, from the series' start. |

***

### RuntimeDevice [#runtimedevice]

A discovered device with its latest status, results and events.

#### Properties [#properties-81]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-device-13"></a> `device` | `object` | Handle used to connect to or disconnect from the device. |
| `device.connect` | () => `Promise`\<`void`\> | Opens the connection to the device. |
| `device.deviceData` | [`DeviceData`](#devicedata) | Identity of the device. |
| `device.disconnect` | () => `Promise`\<`void`\> | Closes the connection to the device. |
| `device.id` | `string` | Identifier of the device. |
| <a id="property-devicedata-19"></a> `deviceData` | [`DeviceData`](#devicedata) | Identity of the device. |
| <a id="property-events"></a> `events?` | readonly [`DeviceConnectionEvent`](#deviceconnectionevent)[] | Recent connection events, oldest first. |
| <a id="property-id-20"></a> `id` | `string` | Identifier of the device. |
| <a id="property-latestresult"></a> `latestResult?` | [`RuntimeResult`](#runtimeresult) | Most recent result. |
| <a id="property-results"></a> `results?` | readonly [`RuntimeResult`](#runtimeresult)[] | Recent results, oldest first. |
| <a id="property-status-2"></a> `status?` | [`DeviceStatus`](#devicestatus) | Latest reported status. |

***

### RuntimeEventMap [#runtimeeventmap]

Event names the runtime emits, with their payloads.

#### Properties [#properties-82]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-connection"></a> `connection` | [`DeviceConnectionEvent`](#deviceconnectionevent) | A connection lifecycle event occurred. |
| <a id="property-devicefound"></a> `deviceFound` | [`RuntimeDevice`](#runtimedevice) | An accepted device was found. |
| <a id="property-error-1"></a> `error` | [`ErrorCallback`](#errorcallback) | A Bluetooth or device error occurred. |
| <a id="property-paireddevices"></a> `pairedDevices` | `object` | The paired device list stored under `storageKey` changed. |
| `pairedDevices.storageKey` | `string` | Storage key of the changed list. |
| <a id="property-result-1"></a> `result` | [`RuntimeResult`](#runtimeresult) | A device produced a result. |
| <a id="property-status-3"></a> `status` | [`DeviceStatusChangeCallback`](#devicestatuschangecallback) | A device status changed. |
| <a id="property-waveform"></a> `waveform` | [`DeviceWaveform`](#devicewaveform) | A recording device sent live ECG samples; for display, never stored. |

***

### UseBackgroundSyncOptions [#usebackgroundsyncoptions]

Options for `useBackgroundSync`.

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

- [`BackgroundSyncSettingProps`](/native-sdk/reference/ui#backgroundsyncsettingprops)

#### Properties [#properties-83]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-canenable"></a> `canEnable?` | () => `Promise`\<`boolean`\> | Checked before turning sync on; resolve `false` to mark it restricted. |
| <a id="property-enabled-2"></a> `enabled?` | `boolean` | Initial state; defaults to off. |
| <a id="property-onenabledchange"></a> `onEnabledChange?` | (`enabled`) => `void` \| `Promise`\<`void`\> | Called before the new state is applied, for example to persist it. |

***

### UseBluetoothPermissionOptions [#usebluetoothpermissionoptions]

Options for `useBluetoothPermission`.

#### Properties [#properties-84]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-onpermissionchanged"></a> `onPermissionChanged?` | (`granted`) => `void` | Called with whether permission is granted after each request. |
| <a id="property-onrequesterror"></a> `onRequestError?` | (`error`) => `void` | Called when a permission request throws. |
| <a id="property-requestonmount"></a> `requestOnMount?` | `boolean` | Ask for permission as soon as the hook mounts. |
| <a id="property-requestpermission"></a> `requestPermission?` | () => `Promise`\<`boolean`\> | Replaces the default permission request. |

***

### UseBluetoothStateOptions [#usebluetoothstateoptions]

Options for `useBluetoothState`.

#### Properties [#properties-85]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-blemanager-3"></a> `bleManager?` | `BleManager` | BLE manager whose state is mirrored into the runtime, when not the provider's own. |
| <a id="property-requestpermission-1"></a> `requestPermission?` | () => `Promise`\<`boolean`\> | Replaces the default permission request. |

***

### UseBTDeviceOptions [#usebtdeviceoptions]

Options for `useBTDevice`.

#### Properties [#properties-86]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-allowrawaccess"></a> `allowRawAccess?` | `boolean` | Expose `raw` GATT access to the device. |
| <a id="property-autoconnect-3"></a> `autoConnect?` | `boolean` | Connect to the selected device automatically. |
| <a id="property-id-21"></a> `id?` | `string` | Selects one device by ID when several match. |

***

### UseMeasurementsOptions [#usemeasurementsoptions]

Options for `useMeasurements`.

#### Properties [#properties-87]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-maxresults"></a> `maxResults?` | `number` | Most recent results to keep; defaults to 100. |
| <a id="property-policy"></a> `policy?` | [`ResultPolicy`](#resultpolicy) | Which results to keep; defaults to `"all"`. |

***

### UseNearbyDeviceOfferOptions [#usenearbydeviceofferoptions]

Options for `useNearbyDeviceOffer`.

#### Properties [#properties-88]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-declinedstoragekey"></a> `declinedStorageKey?` | `string` | Storage key of the declined device list. |
| <a id="property-enabled-3"></a> `enabled?` | `boolean` | Whether devices are offered; defaults to true. |
| <a id="property-onerror-16"></a> `onError?` | (`error`, `device?`) => `void` | Called when pairing fails. |
| <a id="property-onpaired"></a> `onPaired?` | (`device`) => `void` | Called after the user accepts and the device is paired. |
| <a id="property-shouldoffer"></a> `shouldOffer?` | (`device`) => `boolean` | Filters which devices may be offered. |
| <a id="property-storage-1"></a> `storage` | [`PairedDeviceStorage`](#paireddevicestorage) | Where the paired device IDs are persisted. |
| <a id="property-storagekey-1"></a> `storageKey?` | `string` | Storage key of the paired device list. |

***

### UsePairedDevicesOptions [#usepaireddevicesoptions]

Options for `usePairedDevices`.

#### Properties [#properties-89]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-autopair"></a> `autoPair?` | `boolean` | Connect to paired devices automatically when they are found. |
| <a id="property-storage-2"></a> `storage` | [`PairedDeviceStorage`](#paireddevicestorage) | Where the paired device IDs are persisted. |
| <a id="property-storagekey-2"></a> `storageKey?` | `string` | Storage key; defaults to `DEFAULT_PAIRED_DEVICE_STORAGE_KEY`. |

***

### VerovalFusionParams [#verovalfusionparams]

Params for declaring a Veroval Fusion.

#### Properties [#properties-90]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-id-22"></a> `id?` | `string` | Reported back as deviceData.name for the registered declaration. |
| <a id="property-namematch-4"></a> `nameMatch?` | `string` \| `RegExp` | Overrides the product-name matcher for firmware variants or test fixtures. |
| <a id="property-stuckdatatimeoutms-3"></a> `stuckDataTimeoutMs?` | `number` | Overrides the default settle time for a slower monitor. |

***

### ViatomEcgRecording [#viatomecgrecording]

A decoded ER1/ER2 recording.

#### Properties [#properties-91]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-duration-1"></a> `duration` | `number` | Recording duration in seconds. |
| <a id="property-samples-1"></a> `samples` | `number`[] | Waveform samples in millivolts. |

***

### VisomatComfortSoftBtParams [#visomatcomfortsoftbtparams]

Params for declaring a Visomat Comfort Soft BT.

#### Properties [#properties-92]

| Property | Type | Description |
| ------ | ------ | ------ |
| <a id="property-id-23"></a> `id?` | `string` | Reported back as deviceData.name for the registered declaration. |
| <a id="property-namematch-5"></a> `nameMatch?` | `string` \| `RegExp` | Overrides the product-name matcher for firmware variants or test fixtures. |
| <a id="property-stuckdatatimeoutms-4"></a> `stuckDataTimeoutMs?` | `number` | Overrides the default settle time for a slower monitor. |

## Type Aliases [#type-aliases]

### AcceptedDevice [#accepteddevice]

```ts
type AcceptedDevice =
  | IntegratedDevices
  | CustomDeviceDefinition;
```

An entry of BTProvider's `acceptedDevices`: a built-in device, or a declared one.

***

### BackgroundSyncStatus [#backgroundsyncstatus]

```ts
type BackgroundSyncStatus = "on" | "off" | "restricted" | "blocked";
```

Background sync state: on, off, restricted by the system, or blocked by an error.

***

### BluetoothPermissionStatus [#bluetoothpermissionstatus]

```ts
type BluetoothPermissionStatus = "unknown" | "granted" | "denied" | "blocked";
```

Bluetooth permission state: unknown, granted, denied, or blocked (denied permanently).

***

### BluetoothRuntimeManager [#bluetoothruntimemanager]

```ts
type BluetoothRuntimeManager = Pick<BTManager<readonly never[]>,
  | "setBackgroundScanEnabled"
  | "pauseScan"
  | "resumeScan"
  | "forget"
  | "disconnectDevice"
  | "stopRecording"
  | "keepConnecting"
| "setAutoConnect">;
```

The subset of `BTManager` the runtime controls.

***

### BluetoothState [#bluetoothstate]

```ts
type BluetoothState = "on" | "off" | "unauthorized" | "unsupported";
```

Bluetooth adapter state as seen by the app.

***

### BTDeviceFilter [#btdevicefilter]

```ts
type BTDeviceFilter =
  | DeviceKey
  | Omit<DeviceFilter, "where"> & object;
```

Which connected or nearby devices to follow: a model key (`deviceData.name` or `.model`), or a
filter over what the device is (any `DeviceFilter` field, matched against its catalog product)
and its state. `{ kind: "weight-scale" }`, `{ manufacturer: "HARTMANN", status: DeviceStatus.CONNECTED }`.
A device whose parser serves several products counts as the one its advertised name identifies,
else as its parser's product.

***

### BTDeviceSelection [#btdeviceselection]

```ts
type BTDeviceSelection = Pick<BTManagedDevice, "id" | "device" | "deviceData" | "connect">;
```

A discovered device offered for selection: its id, BLE device, data and `connect`.

***

### CheckmeMeasurement [#checkmemeasurement]

```ts
type CheckmeMeasurement =
  | BloodPressureMeasurement
  | EcgMeasurement
  | PulseOximeterMeasurement
  | BodyTemperatureMeasurement
  | {
  heartRate?: number;
  measurementTypeKey: MeasurementTypeKey.heartRate;
  recordedAt?: Date;
};
```

A measurement reported by a Checkme device.

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

`BloodPressureMeasurement`

***

`EcgMeasurement`

***

`PulseOximeterMeasurement`

***

`BodyTemperatureMeasurement`

***

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

```ts
{
  heartRate?: number;
  measurementTypeKey: MeasurementTypeKey.heartRate;
  recordedAt?: Date;
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `heartRate?` | `number` | Heart rate in beats per minute. |
| `measurementTypeKey` | `MeasurementTypeKey.heartRate` | Measurement type of the reading. |
| `recordedAt?` | `Date` | When the reading was taken. |

***

### CheckmePodMeasurement [#checkmepodmeasurement]

```ts
type CheckmePodMeasurement =
  | PulseOximeterMeasurement
  | {
  bodyTemp: number;
  measurementTypeKey: MeasurementTypeKey.temperature;
  recordedAt: Date;
};
```

A measurement reported by a Checkme Pod: pulse oximetry or body temperature.

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

`PulseOximeterMeasurement`

***

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

```ts
{
  bodyTemp: number;
  measurementTypeKey: MeasurementTypeKey.temperature;
  recordedAt: Date;
}
```

| Name | Type | Description |
| ------ | ------ | ------ |
| `bodyTemp` | `number` | Body temperature in degrees Celsius. |
| `measurementTypeKey` | `MeasurementTypeKey.temperature` | Measurement type of the reading. |
| `recordedAt` | `Date` | When the reading was taken. |

***

### CheckmePodResult [#checkmepodresult]

```ts
type CheckmePodResult = MeasurementWithCaseType<MeasurementTypeForDevices<[CHECKME_POD]>> & object;
```

A Checkme Pod measurement tagged with its case type.

#### Type Declaration [#type-declaration]

| Name | Type | Description |
| ------ | ------ | ------ |
| `caseType` | `CaseType` | Frame case that produced the measurement. |

***

### ClockSyncCapability [#clocksynccapability]

```ts
type ClockSyncCapability = "supported" | "unsupported" | "unknown";
```

Whether a device clock can be synchronised.

***

### ClockSyncTimezone [#clocksynctimezone]

```ts
type ClockSyncTimezone = "local" | "utc";
```

Timezone used to interpret the time sent to a device.

***

### CustomByteOrder [#custombyteorder]

```ts
type CustomByteOrder = "big" | "little";
```

Order in which the declared byte indexes are assembled into a single value.
"big" keeps the declared order, "little" reverses it.

***

### CustomCaseKind [#customcasekind]

```ts
type CustomCaseKind = "result" | "stream" | "idle" | "event";
```

The three frame roles a declared device may use.

- "result" a completed reading; its fields are decoded, bounds-checked and reported
- "stream" the device is mid-measurement; moves the device into MEASURING
- "idle"   anything else the device emits (heartbeats, menu state); moves it back to CONNECTED
- "event"  a stateful frame handled by the device declaration; it carries no declarative reading

The stateful roles the built-in device classes use (dependent, sn, error) are deliberately
not available to declarations - they require a device class.

***

### CustomDeviceId [#customdeviceid]

```ts
type CustomDeviceId = string & object;
```

Identifier of a device registered through defineCustomDevice.
Branded so it never silently collapses into the IntegratedDevices union.

#### Type Declaration [#type-declaration-1]

| Name | Type | Description |
| ------ | ------ | ------ |
| `[customDeviceIdBrand]` | `true` | Type-level brand; never present at runtime. |

***

### CustomFieldEncoding [#customfieldencoding]

```ts
type CustomFieldEncoding = "uint" | "int" | "sfloat" | "float" | "ascii" | "decimal-pair";
```

How the assembled bytes of a custom field are turned into a number.

- "uint"   unsigned integer, 1-6 bytes
- "int"    two's complement signed integer, 1-6 bytes
- "sfloat" IEEE-11073 16-bit SFLOAT, exactly 2 bytes (standard GATT vitals)
- "float"  IEEE-11073 32-bit FLOAT, exactly 4 bytes (standard GATT thermometer)
- "ascii"  decimal digits written as text, one digit per byte
- "decimal-pair" whole degrees followed by hundredths, e.g. 0x24 0x2f = 36.47

"ascii" is not a numeric encoding at all: the bytes are characters, so `"120"` arrives as
0x31 0x32 0x30. Serial-derived devices report whole records this way. Digits read
left to right, so the field may not be declared little-endian - reversing them would
turn 120 into 21.

***

### CustomFrameHandler [#customframehandler]

```ts
type CustomFrameHandler = (params) => void;
```

Handles one decoded frame of a device that needs a protocol-specific decoder.

#### Parameters [#parameters-165]

| Parameter | Type |
| ------ | ------ |
| `params` | `CustomFrameHandlerParams` |

#### Returns [#returns-278]

`void`

***

### CustomFrameHandlerFactory [#customframehandlerfactory]

```ts
type CustomFrameHandlerFactory = () => CustomFrameHandler;
```

Creates the per-device `CustomFrameHandler`.

#### Returns [#returns-279]

[`CustomFrameHandler`](#customframehandler)

***

### CustomMeasurement [#custommeasurement]

```ts
type CustomMeasurement =
  | BloodPressureMeasurement
  | BodyWeightMeasurement
  | BodyTemperatureMeasurement
  | BloodGlucoseMeasurement
  | PulseOximeterMeasurement
  | HeartRateMeasurement
  | EcgMeasurement
  | RespiratoryRateMeasurement
  | UrineAnalyzeMeasurement;
```

The measurement shapes a custom-device declaration may report. Its decoder fields are
checked against the measurement catalog at registration, so this union can preserve the
same measurementTypeKey discrimination as results from built-in devices.

***

### CustomReadingDecorator [#customreadingdecorator]

```ts
type CustomReadingDecorator = (reading, frame?, recordOffset?) => MeasurementWithCaseType<Measurement> | null;
```

Adds metadata to a validated reading; `null` withholds it, for a frame that is not a patient reading.

#### Parameters [#parameters-166]

| Parameter | Type |
| ------ | ------ |
| `reading` | `MeasurementWithCaseType`\<`Measurement`\> |
| `frame?` | readonly `string`[] |
| `recordOffset?` | `number` |

#### Returns [#returns-280]

`MeasurementWithCaseType`\<`Measurement`\> \| `null`

***

### CustomSequencerFactory [#customsequencerfactory]

```ts
type CustomSequencerFactory = (context) => CommandSequencer;
```

Creates the command sequencer of one connection, for a declaration whose commands depend on the device or on stored state.

#### Parameters [#parameters-167]

| Parameter | Type |
| ------ | ------ |
| `context` | [`CustomSequencerContext`](#customsequencercontext) |

#### Returns [#returns-281]

[`CommandSequencer`](#commandsequencer)

***

### DeviceConnectionEventKind [#deviceconnectioneventkind]

```ts
type DeviceConnectionEventKind =
  | "pairing"
  | "connected"
  | "bonded"
  | "history-download"
  | "battery"
  | "device-identified"
  | "clock-synchronized"
  | "recording";
```

Kind of connection lifecycle event.

***

### DeviceData [#devicedata]

```ts
type DeviceData = object;
```

Identity and capabilities of a discovered or connected device.

#### Properties [#properties-93]

##### clockSync? [#clocksync]

```ts
clockSync?: ClockSyncCapability;
```

Whether the device clock can be synchronised.

##### hardwareAddress? [#hardwareaddress]

```ts
hardwareAddress?: string;
```

Device-reported address (available after identity); bind per patient and never log.

##### id [#id]

```ts
id: string;
```

Platform identifier of the peripheral.

##### localName [#localname]

```ts
localName: string;
```

Name the peripheral advertises.

##### manufacturerData [#manufacturerdata]

```ts
manufacturerData: string;
```

Advertised manufacturer data.

##### manufacturerName? [#manufacturername]

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

Manufacturer name reported by the device.

##### measurementTypes [#measurementtypes]

```ts
measurementTypes: MeasurementTypeKey[];
```

What the connected parser measures, set when the connection starts.

##### model? [#model]

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

Model reported by the device.

##### name [#name]

```ts
name: DeviceKey;
```

Integrated or custom device the peripheral was matched to.

##### sn [#sn]

```ts
sn: string;
```

Serial number reported by the device.

##### variant? [#variant]

```ts
variant?: object;
```

The brand and model the advertised name identified, when a parser serves several products.

###### manufacturer [#manufacturer]

```ts
manufacturer: string;
```

Brand the advertised name identified.

###### model [#model-1]

```ts
model: string;
```

Model the advertised name identified.

***

### DeviceKey [#devicekey]

```ts
type DeviceKey =
  | IntegratedDevices
  | CustomDeviceId;
```

Anything the SDK can report as deviceData.name: a built-in device, or a declared one.

***

### DeviceKeyOf [#devicekeyof]

```ts
type DeviceKeyOf<T> = KeyOfAccepted<T[number]>;
```

The device keys an `acceptedDevices` list can report.

#### Type Parameters [#type-parameters-17]

| Type Parameter |
| ------ |
| <a id="type-parameter-t-8"></a> `T` *extends* readonly [`AcceptedDevice`](#accepteddevice)[] |

***

### DeviceVariant [#devicevariant]

```ts
type DeviceVariant = object;
```

One brand and model that a built-in parser or a Bluetooth SIG profile decodes.

A built-in parser finds the product by `nameMatch`, so it is required there. A SIG profile
finds it by service, and `nameMatch` only names it; a row without one is listed in the
catalog but never labels a connected device.

#### Properties [#properties-94]

##### device [#device]

```ts
device:
  | IntegratedDevices
  | StandardProfileId;
```

The built-in parser or SIG profile that decodes the product.

##### manufacturer [#manufacturer-1]

```ts
manufacturer: string;
```

Manufacturer of the product.

##### model [#model-2]

```ts
model: string;
```

The product name; also the name of its `SUPPORTED_DEVICES` entry.

##### nameMatch? [#namematch]

```ts
nameMatch?: RegExp;
```

Matches the advertised name of the product.

***

### GlucoseReportedUnit [#glucosereportedunit]

```ts
type GlucoseReportedUnit = "mg/dL" | "mmol/L";
```

The unit the meter displayed the concentration in.

***

### GlucoseSampleLocation [#glucosesamplelocation]

```ts
type GlucoseSampleLocation = "finger" | "alternateSite" | "earlobe";
```

Where on the body the sample was taken.

***

### GlucoseSensorWarning [#glucosesensorwarning]

```ts
type GlucoseSensorWarning = "batteryLow" | "temperatureTooHigh" | "temperatureTooLow" | "timeFault";
```

A condition the meter flagged on a record that does not make its value unusable.

***

### GlucoseSpecimenType [#glucosespecimentype]

```ts
type GlucoseSpecimenType =
  | "capillaryWholeBlood"
  | "capillaryPlasma"
  | "venousWholeBlood"
  | "venousPlasma"
  | "arterialWholeBlood"
  | "arterialPlasma"
  | "undeterminedWholeBlood"
  | "undeterminedPlasma"
  | "interstitialFluid";
```

What a glucose sample was taken from. Control-solution tests are never reported.

***

### LepuCommandValue [#lepucommandvalue]

```ts
type LepuCommandValue = typeof LepuCommand[keyof typeof LepuCommand];
```

Any Lepu command code.

***

### LepuTransportName [#leputransportname]

```ts
type LepuTransportName = keyof typeof lepuTransports;
```

Name of a transport group in `lepuTransports`.

***

### MeasurementFeedbackKey [#measurementfeedbackkey]

```ts
type MeasurementFeedbackKey = typeof MeasurementFeedbackKey[keyof typeof MeasurementFeedbackKey];
```

The translation keys a failed measurement reports, as `BluetoothError.translationKey` (and its
message): compare against these rather than the strings, and translate them in the app.

***

### MeasurementForDevice [#measurementfordevice]

```ts
type MeasurementForDevice<K> = K extends IntegratedDevices ? DeviceMeasurementMap[K] : CustomMeasurement;
```

A built-in device has a measurement type the SDK knows statically. A device registered
through defineCustomDevice reports the catalog-checked properties its declaration named.

#### Type Parameters [#type-parameters-18]

| Type Parameter |
| ------ |
| <a id="type-parameter-k"></a> `K` *extends* [`DeviceKey`](#devicekey) |

***

### MeasurementTypeForDevices [#measurementtypefordevices]

```ts
type MeasurementTypeForDevices<T> = MeasurementForDevice<T[number]> & object;
```

Measurement shape reported by any of the given devices, tagged with its case type.

#### Type Parameters [#type-parameters-19]

| Type Parameter |
| ------ |
| <a id="type-parameter-t-9"></a> `T` *extends* readonly [`DeviceKey`](#devicekey)[] |

#### Type Declaration [#type-declaration-2]

| Name | Type | Description |
| ------ | ------ | ------ |
| `caseType` | `CaseType` | Frame case the measurement was decoded from. |

***

### NearbyDevice [#nearbydevice]

```ts
type NearbyDevice = DeviceData;
```

Identity of a nearby device.

***

### NearbyDeviceOfferStatus [#nearbydeviceofferstatus]

```ts
type NearbyDeviceOfferStatus = "idle" | "offered" | "pairing" | "paired" | "error";
```

Where a nearby device offer is in its lifecycle.

***

### RecordedFrameSink [#recordedframesink]

```ts
type RecordedFrameSink = (frame) => void | Promise<void>;
```

Receives each frame as it is replayed.

#### Parameters [#parameters-168]

| Parameter | Type |
| ------ | ------ |
| `frame` | [`RecordedBleFrame`](#recordedbleframe) |

#### Returns [#returns-282]

`void` \| `Promise`\<`void`\>

***

### ResultCallbackData [#resultcallbackdata]

```ts
type ResultCallbackData<T> = OmitCaseType<MeasurementTypeForDevices<[T]>>;
```

Measurement payload for the given device, without its case type.

#### Type Parameters [#type-parameters-20]

| Type Parameter |
| ------ |
| <a id="type-parameter-t-10"></a> `T` *extends* [`DeviceKey`](#devicekey) |

***

### ResultPolicy [#resultpolicy]

```ts
type ResultPolicy =
  | "all"
  | "daily-totals-only"
  | "first-reading-per-kind-per-connection"
  | "series";
```

Rule deciding which readings of a device are reported.

***

### ResultPolicyByMeasurement [#resultpolicybymeasurement]

```ts
type ResultPolicyByMeasurement = Partial<Record<MeasurementTypeKey, ResultPolicy>>;
```

Result policy per measurement type.

***

### RuntimeBluetoothState [#runtimebluetoothstate]

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

Bluetooth adapter state; `unknown` until first reported.

***

### RuntimeConnectionEvent [#runtimeconnectionevent]

```ts
type RuntimeConnectionEvent = DeviceConnectionEvent;
```

Connection lifecycle event reported by the Bluetooth runtime.

***

### RuntimeError [#runtimeerror]

```ts
type RuntimeError = ErrorCallback;
```

Error reported by the Bluetooth runtime.

***

### RuntimeEvent [#runtimeevent]

```ts
type RuntimeEvent = keyof RuntimeEventMap;
```

Name of an event the runtime emits.

***

### RuntimeResult [#runtimeresult]

```ts
type RuntimeResult = ResultCallback<DeviceKey>;
```

Typed union exposed when a host listens to every accepted device.

***

### StandardProfileId [#standardprofileid]

```ts
type StandardProfileId =
  | "standard-blood-pressure"
  | "standard-blood-glucose"
  | "standard-body-temperature"
  | "standard-heart-rate"
  | "standard-body-weight"
  | "standard-blood-oxygen-pulse-rate";
```

The id of a Bluetooth SIG profile declaration, `standard-<measurement type>`.

***

### VerovalBloodPressureReading [#verovalbloodpressurereading]

```ts
type VerovalBloodPressureReading = MeasurementWithCaseType<Measurement> & object;
```

A blood pressure reading with the flags a Veroval monitor reports.

#### Type Declaration [#type-declaration-3]

| Name | Type | Description |
| ------ | ------ | ------ |
| `atrialFibrillation?` | `boolean` | The device flagged atrial fibrillation during the reading. |
| `restingMeasurement?` | `boolean` | The device flagged the reading as taken in its resting mode. |
| `tripleMeasurement?` | `boolean` | The device flagged the reading as part of a triple measurement. |

***

### VerovalDuoControlMeasurement [#verovalduocontrolmeasurement]

```ts
type VerovalDuoControlMeasurement = BloodPressureMeasurement & object;
```

A blood pressure reading from a Duo Control monitor.

#### Type Declaration [#type-declaration-4]

| Name | Type | Description |
| ------ | ------ | ------ |
| `irregularHeartbeat?` | `boolean` | Whether the monitor marked the reading as an irregular heartbeat. |
| `memorySlot` | `1` \| `2` | Memory slot (user) the monitor stored the reading in. |
| `recordedAt` | `Date` | The timestamp stored in the monitor, rather than the download time. |

## Enumerations [#enumerations]

### BluetoothErrorCode [#bluetootherrorcode]

Stable machine-readable codes for Bluetooth failures.

#### Enumeration Members [#enumeration-members]

| Enumeration Member | Value | Description |
| ------ | ------ | ------ |
| <a id="enumeration-member-background_sync"></a> `BACKGROUND_SYNC` | `"bluetooth.background-sync"` | Background synchronisation failed. |
| <a id="enumeration-member-connection_failed"></a> `CONNECTION_FAILED` | `"bluetooth.connection-failed"` | Connecting to or staying connected to the device failed. |
| <a id="enumeration-member-device_error"></a> `DEVICE_ERROR` | `"bluetooth.device-error"` | The device reported an error. |
| <a id="enumeration-member-discovery_failed"></a> `DISCOVERY_FAILED` | `"bluetooth.discovery-failed"` | Service or characteristic discovery failed. |
| <a id="enumeration-member-frame_invalid"></a> `FRAME_INVALID` | `"bluetooth.frame-invalid"` | A received frame was malformed or failed its checksum. |
| <a id="enumeration-member-measurement_failed"></a> `MEASUREMENT_FAILED` | `"bluetooth.measurement-failed"` | The measurement did not complete. |
| <a id="enumeration-member-pairing_required"></a> `PAIRING_REQUIRED` | `"bluetooth.pairing-required"` | The device requires pairing, bonding or authentication. |
| <a id="enumeration-member-permission_denied"></a> `PERMISSION_DENIED` | `"bluetooth.permission-denied"` | Bluetooth permission was denied or not granted. |
| <a id="enumeration-member-powered_off"></a> `POWERED_OFF` | `"bluetooth.powered-off"` | Bluetooth is turned off. |
| <a id="enumeration-member-scan_failed"></a> `SCAN_FAILED` | `"bluetooth.scan-failed"` | Scanning for devices failed. |
| <a id="enumeration-member-unknown"></a> `UNKNOWN` | `"bluetooth.unknown"` | The failure could not be classified. |
| <a id="enumeration-member-unsupported"></a> `UNSUPPORTED` | `"bluetooth.unsupported"` | Bluetooth is not supported on this device. |

***

### DeviceStatus [#devicestatus]

Connection and measurement state of a device.

#### Enumeration Members [#enumeration-members-1]

| Enumeration Member | Value | Description |
| ------ | ------ | ------ |
| <a id="enumeration-member-connected"></a> `CONNECTED` | `"Connected"` | The device is connected. |
| <a id="enumeration-member-disconnected"></a> `DISCONNECTED` | `"Disconnected"` | The device is disconnected. |
| <a id="enumeration-member-low_battery"></a> `LOW_BATTERY` | `"LowBattery"` | The device reported a low battery. |
| <a id="enumeration-member-measuring"></a> `MEASURING` | `"Measuring"` | The device is taking a measurement. |

***

### IntegratedDevices [#integrateddevices]

Bluetooth devices the SDK ships support for; each value is the device name.

#### Enumeration Members [#enumeration-members-2]

| Enumeration Member | Value | Description |
| ------ | ------ | ------ |
| <a id="enumeration-member-alive_cor"></a> `ALIVE_COR` | `"alivecor"` | Device advertised as "alivecor". |
| <a id="enumeration-member-and_bpm"></a> `AND_BPM` | `"A&D BPM"` | Device advertised as "A&D BPM". |
| <a id="enumeration-member-and_bpm_cts"></a> `AND_BPM_CTS` | `"A&D BPM CTS"` | Device advertised as "A&D BPM CTS". |
| <a id="enumeration-member-and_scale"></a> `AND_SCALE` | `"A&D Scale"` | Device advertised as "A&D Scale". |
| <a id="enumeration-member-andesfittemp"></a> `ANDESFITTEMP` | `"TEMP"` | Device advertised as "TEMP". |
| <a id="enumeration-member-aoj_70b"></a> `AOJ_70B` | `"AOJ-70B"` | Device advertised as "AOJ-70B". |
| <a id="enumeration-member-aoj_bpm"></a> `AOJ_BPM` | `"AOJ BPM"` | Device advertised as "AOJ BPM". |
| <a id="enumeration-member-aoj_bpm_fff0"></a> `AOJ_BPM_FFF0` | `"AOJ BPM FFF0"` | Device advertised as "AOJ BPM FFF0". |
| <a id="enumeration-member-aoj20a"></a> `AOJ20A` | `"AOJ-20A"` | Device advertised as "AOJ-20A". |
| <a id="enumeration-member-ap20"></a> `AP20` | `"AP-20"` | Device advertised as "AP-20". |
| <a id="enumeration-member-ap20_wps"></a> `AP20_WPS` | `"AP-20-WPS"` | Device advertised as "AP-20-WPS". |
| <a id="enumeration-member-bbsm_s3"></a> `BBSM_S3` | `"BBSM S3"` | Device advertised as "BBSM S3". |
| <a id="enumeration-member-bc01"></a> `BC01` | `"BC01"` | Device advertised as "BC01". |
| <a id="enumeration-member-bgm"></a> `BGM` | `"BGM"` | Device advertised as "BGM". |
| <a id="enumeration-member-bioland_bgm"></a> `BIOLAND_BGM` | `"Bioland-BGM"` | Device advertised as "Bioland-BGM". |
| <a id="enumeration-member-bp2"></a> `BP2` | `"BP2"` | Device advertised as "BP2". |
| <a id="enumeration-member-bpm188"></a> `BPM188` | `"BPM-188"` | Device advertised as "BPM-188". |
| <a id="enumeration-member-bpw1"></a> `BPW1` | `"BPW1"` | Device advertised as "BPW1". |
| <a id="enumeration-member-checkme"></a> `CHECKME` | `"Checkme"` | Device advertised as "Checkme". |
| <a id="enumeration-member-checkme_ex"></a> `CHECKME_EX` | `"Checkme EX"` | Device advertised as "Checkme EX". |
| <a id="enumeration-member-checkme_le"></a> `CHECKME_LE` | `"CheckmeLE"` | Device advertised as "CheckmeLE". |
| <a id="enumeration-member-checkme_pod"></a> `CHECKME_POD` | `"Checkme Pod"` | Device advertised as "Checkme Pod". |
| <a id="enumeration-member-checkme_pod_wps"></a> `CHECKME_POD_WPS` | `"Checkme Pod-WPS"` | Device advertised as "Checkme Pod-WPS". |
| <a id="enumeration-member-clevertemp"></a> `CLEVERTEMP` | `"TAIDOC TD1107"` | Device advertised as "TAIDOC TD1107". |
| <a id="enumeration-member-cmed"></a> `CMED` | `"cmed"` | Device advertised as "cmed". |
| <a id="enumeration-member-cofoe_bpm"></a> `COFOE_BPM` | `"Cofoe BPM"` | Device advertised as "Cofoe BPM". |
| <a id="enumeration-member-cofoe_bpm_history"></a> `COFOE_BPM_HISTORY` | `"Cofoe BPM History"` | Device advertised as "Cofoe BPM History". |
| <a id="enumeration-member-cofoe_glucometer"></a> `COFOE_GLUCOMETER` | `"Cofoe Glucometer"` | Device advertised as "Cofoe Glucometer". |
| <a id="enumeration-member-cofoe_glucometer_cgh25"></a> `COFOE_GLUCOMETER_CGH25` | `"Cofoe Glucometer CGH25"` | Device advertised as "Cofoe Glucometer CGH25". |
| <a id="enumeration-member-cofoe_thermometer"></a> `COFOE_THERMOMETER` | `"Cofoe Thermometer"` | Device advertised as "Cofoe Thermometer". |
| <a id="enumeration-member-cosinuss"></a> `COSINUSS` | `"two"` | Device advertised as "two". |
| <a id="enumeration-member-f4"></a> `F4` | `"F4"` | Device advertised as "F4". |
| <a id="enumeration-member-famidoc_bpm"></a> `FAMIDOC_BPM` | `"Famidoc BPM"` | Device advertised as "Famidoc BPM". |
| <a id="enumeration-member-famidoc_contact_thermometer"></a> `FAMIDOC_CONTACT_THERMOMETER` | `"Famidoc Contact Thermometer"` | Device advertised as "Famidoc Contact Thermometer". |
| <a id="enumeration-member-famidoc_ir_thermometer"></a> `FAMIDOC_IR_THERMOMETER` | `"Famidoc IR Thermometer"` | Device advertised as "Famidoc IR Thermometer". |
| <a id="enumeration-member-fora_scale"></a> `FORA_SCALE` | `"FORA W550"` | Device advertised as "FORA W550". |
| <a id="enumeration-member-foratemp"></a> `FORATEMP` | `"FORA IR20"` | Device advertised as "FORA IR20". |
| <a id="enumeration-member-genial_t31"></a> `GENIAL_T31` | `"Genial-T31"` | Device advertised as "Genial-T31". |
| <a id="enumeration-member-glucocheck"></a> `GLUCOCHECK` | `"GlucoCheck"` | Device advertised as "GlucoCheck". |
| <a id="enumeration-member-joytech_bpm"></a> `JOYTECH_BPM` | `"Joytech BPM"` | Device advertised as "Joytech BPM". |
| <a id="enumeration-member-joytech_thermometer"></a> `JOYTECH_THERMOMETER` | `"Joytech Thermometer"` | Device advertised as "Joytech Thermometer". |
| <a id="enumeration-member-jumper_bpm"></a> `JUMPER_BPM` | `"Jumper BPM"` | Device advertised as "Jumper BPM". |
| <a id="enumeration-member-jumper_oximeter"></a> `JUMPER_OXIMETER` | `"Jumper Oximeter"` | Device advertised as "Jumper Oximeter". |
| <a id="enumeration-member-jumper_thermometer"></a> `JUMPER_THERMOMETER` | `"Jumper Thermometer"` | Device advertised as "Jumper Thermometer". |
| <a id="enumeration-member-lepu_f4_scale"></a> `LEPU_F4_SCALE` | `"Lepu F4 scale"` | Device advertised as "Lepu F4 scale". |
| <a id="enumeration-member-lepu_f5_scale"></a> `LEPU_F5_SCALE` | `"Lepu F5 scale"` | Device advertised as "Lepu F5 scale". |
| <a id="enumeration-member-lpm311"></a> `LPM311` | `"LPM311"` | Device advertised as "LPM311". |
| <a id="enumeration-member-mambo_a5"></a> `MAMBO_A5` | `"Mambo A5"` | Device advertised as "Mambo A5". |
| <a id="enumeration-member-mysense"></a> `MYSENSE` | `"mySense"` | Device advertised as "mySense". |
| <a id="enumeration-member-pc100"></a> `PC100` | `"PC-100"` | Device advertised as "PC-100". |
| <a id="enumeration-member-pc300"></a> `PC300` | `"PC300"` | Device advertised as "PC300". |
| <a id="enumeration-member-pc60wf"></a> `PC60WF` | `"OxySmart"` | Device advertised as "OxySmart". |
| <a id="enumeration-member-pc68b"></a> `PC68B` | `"PC-68B"` | Device advertised as "PC-68B". |
| <a id="enumeration-member-pc80b"></a> `PC80B` | `"PC80B"` | Device advertised as "PC80B". |
| <a id="enumeration-member-pf10aw_me"></a> `PF10AW_ME` | `"PF10AW-ME"` | Device advertised as "PF10AW-ME". |
| <a id="enumeration-member-pf10bw_ve"></a> `PF10BW_VE` | `"PF10BW-VE"` | Device advertised as "PF10BW-VE". |
| <a id="enumeration-member-pm10"></a> `PM10` | `"PM10"` | Device advertised as "PM10". |
| <a id="enumeration-member-poctor_m3102"></a> `POCTOR_M3102` | `"PoctorM3102"` | Device advertised as "PoctorM3102". |
| <a id="enumeration-member-pulsebit_ex"></a> `PULSEBIT_EX` | `"Pulsebit EX"` | Device advertised as "Pulsebit EX". |
| <a id="enumeration-member-rpm_scale"></a> `RPM_SCALE` | `"GBS-2012-B"` | Device advertised as "GBS-2012-B". |
| <a id="enumeration-member-s5"></a> `S5` | `"Le S5"` | Device advertised as "Le S5". |
| <a id="enumeration-member-sa10aw_pu"></a> `SA10AW_PU` | `"SA10AW-PU"` | Device advertised as "SA10AW-PU". |
| <a id="enumeration-member-sp_20"></a> `SP_20` | `"SP-20"` | Device advertised as "SP-20". |
| <a id="enumeration-member-sp_20_ble"></a> `SP_20_BLE` | `"SP-20-BLE"` | Device advertised as "SP-20-BLE". |
| <a id="enumeration-member-sp_20_wps"></a> `SP_20_WPS` | `"SP-20-WPS"` | Device advertised as "SP-20-WPS". |
| <a id="enumeration-member-sp80b"></a> `SP80B` | `"PULMO80B"` | Device advertised as "PULMO80B". |
| <a id="enumeration-member-spo2"></a> `SPO2` | `"Oxyfit"` | Device advertised as "Oxyfit". |
| <a id="enumeration-member-taidoc_bpm"></a> `TAIDOC_BPM` | `"TaiDoc BPM"` | Device advertised as "TaiDoc BPM". |
| <a id="enumeration-member-taidoc_glucose"></a> `TAIDOC_GLUCOSE` | `"TAIDOC TD4216"` | Device advertised as "TAIDOC TD4216". |
| <a id="enumeration-member-taidoc_multi"></a> `TAIDOC_MULTI` | `"TaiDoc Multi"` | Device advertised as "TaiDoc Multi". |
| <a id="enumeration-member-taidoc_oximeter"></a> `TAIDOC_OXIMETER` | `"TaiDoc Oximeter"` | Device advertised as "TaiDoc Oximeter". |
| <a id="enumeration-member-taidoc_scale"></a> `TAIDOC_SCALE` | `"TaiDoc Scale"` | Device advertised as "TaiDoc Scale". |
| <a id="enumeration-member-taidoc_thermometer"></a> `TAIDOC_THERMOMETER` | `"TaiDoc Thermometer"` | Device advertised as "TaiDoc Thermometer". |
| <a id="enumeration-member-transtek_a6_bpm"></a> `TRANSTEK_A6_BPM` | `"Transtek A6 BPM"` | Device advertised as "Transtek A6 BPM". |
| <a id="enumeration-member-transtek_bpm"></a> `TRANSTEK_BPM` | `"Transtek BPM"` | Device advertised as "Transtek BPM". |
| <a id="enumeration-member-transtek_scale"></a> `TRANSTEK_SCALE` | `"Transtek Scale"` | Device advertised as "Transtek Scale". |
| <a id="enumeration-member-transtek_scale_1525"></a> `TRANSTEK_SCALE_1525` | `"Transtek Scale 1525"` | Device advertised as "Transtek Scale 1525". |
| <a id="enumeration-member-transtek_tracker"></a> `TRANSTEK_TRACKER` | `"Transtek Tracker"` | Device advertised as "Transtek Tracker". |
| <a id="enumeration-member-trasense_s9"></a> `TRASENSE_S9` | `"Trasense S9"` | Device advertised as "Trasense S9". |
| <a id="enumeration-member-veroval_activity"></a> `VEROVAL_ACTIVITY` | `"Veroval Activity"` | Device advertised as "Veroval Activity". |
| <a id="enumeration-member-veroval_duo_control"></a> `VEROVAL_DUO_CONTROL` | `"Veroval duo control"` | Device advertised as "Veroval duo control". |
| <a id="enumeration-member-veroval_ecg"></a> `VEROVAL_ECG` | `"Veroval ECG"` | Device advertised as "Veroval ECG". |
| <a id="enumeration-member-viatom_bbsm_bs1"></a> `VIATOM_BBSM_BS1` | `"BBSM BS1"` | Device advertised as "BBSM BS1". |
| <a id="enumeration-member-viatom_r20"></a> `VIATOM_R20` | `"R20"` | Device advertised as "R20". |
| <a id="enumeration-member-viatom_r200"></a> `VIATOM_R200` | `"R200"` | Device advertised as "R200". |
| <a id="enumeration-member-wbp_02"></a> `WBP_02` | `"WBP-02"` | Device advertised as "WBP-02". |
| <a id="enumeration-member-yonker_80b"></a> `YONKER_80B` | `"Yonker 80B"` | Device advertised as "Yonker 80B". |
| <a id="enumeration-member-yonker_bpm"></a> `YONKER_BPM` | `"Yonker BPM"` | Device advertised as "Yonker BPM". |
| <a id="enumeration-member-yonker_oximeter"></a> `YONKER_OXIMETER` | `"Yonker Oximeter"` | Device advertised as "Yonker Oximeter". |
| <a id="enumeration-member-yonker_scale"></a> `YONKER_SCALE` | `"Yonker Scale"` | Device advertised as "Yonker Scale". |
| <a id="enumeration-member-yonker_thermometer"></a> `YONKER_THERMOMETER` | `"Yonker Thermometer"` | Device advertised as "Yonker Thermometer". |
| <a id="enumeration-member-zh_sg_a606"></a> `ZH_SG_A606` | `"ZH-SG-A606"` | Device advertised as "ZH-SG-A606". |

## Variables [#variables]

### A606\_NOTIFY [#a606_notify]

```ts
const A606_NOTIFY: "0000ff02-0000-1000-8000-00805f9b34fb" = "0000ff02-0000-1000-8000-00805f9b34fb";
```

Characteristic UUID that replies are notified on.

***

### A606\_SERVICE [#a606_service]

```ts
const A606_SERVICE: "0000ff00-0000-1000-8000-00805f9b34fb" = "0000ff00-0000-1000-8000-00805f9b34fb";
```

GATT service UUID of the A606.

***

### A606\_WRITE [#a606_write]

```ts
const A606_WRITE: "0000ff01-0000-1000-8000-00805f9b34fb" = "0000ff01-0000-1000-8000-00805f9b34fb";
```

Characteristic UUID that commands are written to.

***

### a606MainServices [#a606mainservices]

```ts
const a606MainServices: IService[];
```

ZH-SG's fixed GATT profile and its 16-byte stored glucose record.

***

### AOJ\_COMMAND [#aoj_command]

```ts
const AOJ_COMMAND: object;
```

Command opcodes sent to AOJ devices.

#### Type Declaration [#type-declaration-5]

| Name | Type | Default value | Description |
| ------ | ------ | ------ | ------ |
| <a id="property-clear_history"></a> `CLEAR_HISTORY` | `212` | `0xd4` | Clears the stored history. |
| <a id="property-get_history"></a> `GET_HISTORY` | `211` | `0xd3` | Requests the stored history. |
| <a id="property-get_info"></a> `GET_INFO` | `213` | `0xd5` | Requests device information. |
| <a id="property-set_time"></a> `SET_TIME` | `210` | `0xd2` | Sets the device clock. |

***

### AOJ\_RESPONSE [#aoj_response]

```ts
const AOJ_RESPONSE: object;
```

Response opcodes sent by AOJ devices.

#### Type Declaration [#type-declaration-6]

| Name | Type | Default value | Description |
| ------ | ------ | ------ | ------ |
| <a id="property-clear_history-1"></a> `CLEAR_HISTORY` | `196` | `0xc4` | Reply to a history clear. |
| <a id="property-get_info-1"></a> `GET_INFO` | `197` | `0xc5` | Reply to an information request. |
| <a id="property-history"></a> `HISTORY` | `195` | `0xc3` | A stored history record. |
| <a id="property-set_time-1"></a> `SET_TIME` | `194` | `0xc2` | Reply to a clock set. |

***

### aojMainServices [#aojmainservices]

```ts
const aojMainServices: IService[];
```

The GATT service AOJ devices are monitored and written through.

***

### BOSO\_MEDICUS\_NAME\_MATCH [#boso_medicus_name_match]

```ts
const BOSO_MEDICUS_NAME_MATCH: RegExp;
```

The boso medicus system uses the Bluetooth SIG Blood Pressure Service and Measurement
characteristic. Its vendor-specific identity is the advertised name, which carries a
six-character hexadecimal suffix, for example `boso medicus 312B5D`.

***

### BP3\_MODEL\_NAMES [#bp3_model_names]

```ts
const BP3_MODEL_NAMES: readonly string[];
```

The names the BP3 range advertises.

Seventeen products differing in cuff, casing, or display rather than in protocol, so declaring the
range is one line per name:

```typescript
const bp3Devices = BP3_MODEL_NAMES.map((name) =>
  viatomBpMonitor(name, { id: `viatom-${name.toLowerCase()}` }),
);
```

***

### CHECKME\_NOTIFY [#checkme_notify]

```ts
const CHECKME_NOTIFY: "0734594a-a8e7-4b1a-a6b1-cd5243059a57" = "0734594a-a8e7-4b1a-a6b1-cd5243059a57";
```

Characteristic UUID that responses are notified on.

***

### CHECKME\_SERVICE [#checkme_service]

```ts
const CHECKME_SERVICE: "14839ac4-7d7e-415c-9a42-167340cf2339" = "14839ac4-7d7e-415c-9a42-167340cf2339";
```

GATT service UUID of Checkme devices.

***

### CHECKME\_WRITE [#checkme_write]

```ts
const CHECKME_WRITE: "8b00ace7-eb0b-49b0-bbe9-9aee0a26e1a3" = "8b00ace7-eb0b-49b0-bbe9-9aee0a26e1a3";
```

Characteristic UUID that commands are written to.

***

### CheckmeCommand [#checkmecommand-1]

```ts
const CheckmeCommand: object;
```

Command codes of the Checkme protocol.

#### Type Declaration [#type-declaration-7]

| Name | Type | Default value | Description |
| ------ | ------ | ------ | ------ |
| <a id="property-info"></a> `info` | `20` | `0x14` | Requests device information. |
| <a id="property-ping"></a> `ping` | `21` | `0x15` | Keep-alive ping. |
| <a id="property-readcontent"></a> `readContent` | `4` | `0x04` | Reads the next chunk of the open file. |
| <a id="property-readend"></a> `readEnd` | `5` | `0x05` | Closes the open file. |
| <a id="property-readstart"></a> `readStart` | `3` | `0x03` | Opens a file for reading. |
| <a id="property-syncparameters"></a> `syncParameters` | `22` | `0x16` | Synchronises device parameters such as the clock. |

***

### CheckmeListType [#checkmelisttype]

```ts
const CheckmeListType: object;
```

File list identifiers that can be read from a Checkme device.

#### Type Declaration [#type-declaration-8]

| Name | Type | Default value | Description |
| ------ | ------ | ------ | ------ |
| <a id="property-bloodpressure"></a> `bloodPressure` | `3` | `3` | Blood pressure records. |
| <a id="property-daily"></a> `daily` | `0` | `0` | Daily check records. |
| <a id="property-ecg"></a> `ecg` | `1` | `1` | ECG records. |
| <a id="property-oxygen"></a> `oxygen` | `2` | `2` | Blood oxygen records. |
| <a id="property-temperature-2"></a> `temperature` | `5` | `5` | Temperature records. |
| <a id="property-user"></a> `user` | `8` | `8` | User profile list. |

***

### checkmeMainServices [#checkmemainservices]

```ts
const checkmeMainServices: IService[];
```

The GATT service Checkme devices are monitored through.

***

### CheckmePodCommand [#checkmepodcommand-1]

```ts
const CheckmePodCommand: object;
```

Command codes of the Checkme Pod protocol.

#### Type Declaration [#type-declaration-9]

| Name | Type | Default value | Description |
| ------ | ------ | ------ | ------ |
| <a id="property-info-1"></a> `info` | `20` | `0x14` | Requests device information. |
| <a id="property-realtimedata"></a> `realtimeData` | `32` | `0x20` | Requests the realtime reading. |
| <a id="property-syncparameters-1"></a> `syncParameters` | `22` | `0x16` | Synchronises device parameters such as the clock. |

***

### checkmePodMainServices [#checkmepodmainservices]

```ts
const checkmePodMainServices: IService[];
```

The GATT service Checkme Pod devices are monitored and written through.

***

### DEFAULT\_CALIBRATION [#default_calibration]

```ts
const DEFAULT_CALIBRATION: object;
```

The calibration the recording is read with.

This is the EDF convention - a linear map from counts onto a physical range - and the
device states its own in the header it sends before the curve. These are the values the
vendor's app falls back to, and are what the SDK uses until a header supplies otherwise:
the full signed sixteen-bit range spans plus or minus 27.68 mV.

#### Type Declaration [#type-declaration-10]

| Name | Type | Default value | Description |
| ------ | ------ | ------ | ------ |
| <a id="property-digitalmaximum-1"></a> `digitalMaximum` | `32767` | `32_767` | Highest digital sample value. |
| <a id="property-digitalminimum-1"></a> `digitalMinimum` | `-32768` | `-32_768` | Lowest digital sample value. |
| <a id="property-physicalmaximummicrovolts-1"></a> `physicalMaximumMicrovolts` | `27680` | `27_680` | Physical value of the highest digital sample, in microvolts. |
| <a id="property-physicalminimummicrovolts-1"></a> `physicalMinimumMicrovolts` | `-27680` | `-27_680` | Physical value of the lowest digital sample, in microvolts. |

***

### DEFAULT\_PAIRED\_DEVICE\_STORAGE\_KEY [#default_paired_device_storage_key]

```ts
const DEFAULT_PAIRED_DEVICE_STORAGE_KEY: "@ovok/native/paired-devices" = "@ovok/native/paired-devices";
```

Storage key used when none is given.

***

### DEFAULT\_QUEUE\_KEY [#default_queue_key]

```ts
const DEFAULT_QUEUE_KEY: "@ovok/native/background-sync/results" = "@ovok/native/background-sync/results";
```

Default storage key of the queue.

***

### DEFAULT\_RESTORE\_STATE\_IDENTIFIER [#default_restore_state_identifier]

```ts
const DEFAULT_RESTORE_STATE_IDENTIFIER: "com.ovok.native.background-sync" = "com.ovok.native.background-sync";
```

Default CoreBluetooth state restoration identifier.

***

### DEVICE\_VARIANTS [#device_variants]

```ts
const DEVICE_VARIANTS: readonly DeviceVariant[];
```

Every known brand and model variant, in lookup order.

***

### ER1\_MODEL\_NAMES [#er1_model_names]

```ts
const ER1_MODEL_NAMES: readonly string[];
```

The names the ER1 recorders advertise.

***

### ER2\_MODEL\_NAMES [#er2_model_names]

```ts
const ER2_MODEL_NAMES: readonly string[];
```

The names the ER2 recorders advertise, all of them on the small-MTU link.

***

### ER3\_MODEL\_NAMES [#er3_model_names]

```ts
const ER3_MODEL_NAMES: readonly string[];
```

The ER3 family is identified separately from the ER1/ER2 opcode family.

***

### GENIAL\_T31\_CID\_ACK [#genial_t31_cid_ack]

```ts
const GENIAL_T31_CID_ACK: string[];
```

Frame that acknowledges the device's identification.

***

### GENIAL\_T31\_CONNECT [#genial_t31_connect]

```ts
const GENIAL_T31_CONNECT: string[];
```

Frame that opens the session.

***

### GENIAL\_T31\_NOTIFY [#genial_t31_notify]

```ts
const GENIAL_T31_NOTIFY: "0000fff1-0000-1000-8000-00805f9b34fb" = "0000fff1-0000-1000-8000-00805f9b34fb";
```

Characteristic UUID that readings are notified on.

***

### GENIAL\_T31\_SERVICE [#genial_t31_service]

```ts
const GENIAL_T31_SERVICE: "00001809-0000-1000-8000-00805f9b34fb" = "00001809-0000-1000-8000-00805f9b34fb";
```

GATT service UUID of the Genial T31.

***

### GENIAL\_T31\_WRITE [#genial_t31_write]

```ts
const GENIAL_T31_WRITE: "0000fff2-0000-1000-8000-00805f9b34fb" = "0000fff2-0000-1000-8000-00805f9b34fb";
```

Characteristic UUID that commands are written to.

***

### genialT31MainServices [#genialt31mainservices]

```ts
const genialT31MainServices: IService[];
```

The GATT service the Genial T31 is monitored and written through.

***

### LEPOD\_MODEL\_NAMES [#lepod_model_names]

```ts
const LEPOD_MODEL_NAMES: readonly string[];
```

The names the Lepod range advertises.

***

### LEPU\_CATALOG\_EXCLUDED\_DEVICE\_NAMES [#lepu_catalog_excluded_device_names]

```ts
const LEPU_CATALOG_EXCLUDED_DEVICE_NAMES: readonly string[];
```

Fetal-doppler and massager names from the vendor vocabulary, kept out of the SDK catalog.

***

### LEPU\_CATALOG\_HIDDEN\_DEVICE\_NAMES [#lepu_catalog_hidden_device_names]

```ts
const LEPU_CATALOG_HIDDEN_DEVICE_NAMES: readonly string[];
```

Advertisement aliases that identify a product but are not customer-facing model names.

***

### LEPU\_DEVICE\_NAMES [#lepu_device_names]

```ts
const LEPU_DEVICE_NAMES: readonly string[];
```

The names the Lepu/Viatom family advertises, as its own SDK matches them.

Taken from the vendor's `getDeviceModel`, a 732-line cascade of substring checks that is
the whole of how that SDK decides which product it is talking to. The order there matters,
because 27 of these names are a prefix of another - `BP2` of `BP2A`, `BP2T`, `BP2W` and
three more - so a check that ran in the wrong order would bind a BP2W as a BP2 and poll it
with an opcode written for different hardware.

It is that function's vocabulary, not a catalogue of everything the vendor sells: a few
products - the ER3 and the M12 among them - are identified elsewhere in that app and never
reach this list. The first-word names below are compared against the complete first token of
the advertisement, not as an open-ended prefix: `O2` must not claim `O2Ring`, and `BabyO2`
must not claim `BabyO2N`.

They are held here as a flat vocabulary rather than an ordered cascade, because
`lepuNameMatch` derives the exclusions from the list itself. Adding a name automatically
narrows every name it extends, which an ordered list would leave to whoever inserted it.

***

### LEPU\_FIRST\_WORD\_DEVICE\_NAMES [#lepu_first_word_device_names]

```ts
const LEPU_FIRST_WORD_DEVICE_NAMES: readonly string[];
```

Names the vendor matches by the complete first word of the advertisement.

***

### LepuCommand [#lepucommand]

```ts
const LepuCommand: object;
```

The commands every Lepu device understands.

These are the generic opcodes, shared across the whole family. Device-specific opcodes live
below 0x40 and belong with their driver, because the same number means different things on
different hardware - 0x08 polls realtime data on a BP2 and starts a measurement on others.
That collision is why this module holds only the opcodes that are genuinely common, and why
a driver must never assume a low opcode is safe to send to an unidentified device.

#### Type Declaration [#type-declaration-11]

| Name | Type | Default value | Description |
| ------ | ------ | ------ | ------ |
| <a id="property-echo"></a> `ECHO` | `224` | `0xe0` | Link keepalive and round-trip test. Inert. |
| <a id="property-get_battery"></a> `GET_BATTERY` | `228` | `0xe4` | Reads the battery level. |
| <a id="property-get_file_list"></a> `GET_FILE_LIST` | `241` | `0xf1` | Enumerate the records stored on the device. |
| <a id="property-get_info-2"></a> `GET_INFO` | `225` | `0xe1` | Device information, including the model string. Inert and identical family-wide, which makes it the one command safe to send before a device has been identified - and therefore the way to confirm what something is before addressing it with an opcode that means something else on the wrong hardware. |
| <a id="property-read_file_data"></a> `READ_FILE_DATA` | `243` | `0xf3` | Fetch the next chunk of the file being read. |
| <a id="property-read_file_end"></a> `READ_FILE_END` | `244` | `0xf4` | End the read and release the device's file handle. |
| <a id="property-read_file_start"></a> `READ_FILE_START` | `242` | `0xf2` | Begin a read: a 20-byte payload of file name plus a 32-bit offset. |
| <a id="property-set_time-2"></a> `SET_TIME` | `236` | `0xec` | Sets the device's local wall clock before history is requested. |

***

### LepuResponseType [#lepuresponsetype-1]

```ts
const LepuResponseType: object;
```

What a Lepu device says about the request it just answered.

Only `SUCCESS` means the payload holds what was asked for. Every other value is an error
whose payload is not the requested data, so a reply has to be checked before it is
decoded - otherwise a refusal is read as a reading, out of whatever bytes happen to
follow the header.

#### Type Declaration [#type-declaration-12]

| Name | Type | Default value | Description |
| ------ | ------ | ------ | ------ |
| <a id="property-command_format_error"></a> `COMMAND_FORMAT_ERROR` | `252` | `0xfc` | The command was malformed. |
| <a id="property-command_not_supported"></a> `COMMAND_NOT_SUPPORTED` | `253` | `0xfd` | The opcode is unknown to this firmware, which is how a feature is detected. |
| <a id="property-crc_error"></a> `CRC_ERROR` | `2` | `0x02` | The device rejected our checksum. |
| <a id="property-decrypt_failed"></a> `DECRYPT_FAILED` | `243` | `0xf3` | The device could not decrypt the request. |
| <a id="property-device_busy"></a> `DEVICE_BUSY` | `251` | `0xfb` | Mid-measurement or otherwise occupied. Worth backing off rather than giving up. |
| <a id="property-error-2"></a> `ERROR` | `255` | `0xff` | A generic error. |
| <a id="property-file_not_found"></a> `FILE_NOT_FOUND` | `224` | `0xe0` | The requested file does not exist. |
| <a id="property-file_read_failed"></a> `FILE_READ_FAILED` | `225` | `0xe1` | The file could not be read. |
| <a id="property-file_write_failed"></a> `FILE_WRITE_FAILED` | `226` | `0xe2` | The file could not be written. |
| <a id="property-parameter_illegal"></a> `PARAMETER_ILLEGAL` | `241` | `0xf1` | The request parameter was rejected. |
| <a id="property-permission_denied"></a> `PERMISSION_DENIED` | `242` | `0xf2` | The device denied permission. |
| <a id="property-request-2"></a> `REQUEST` | `0` | `0x00` | A request, phone to device. Never seen on a reply. |
| <a id="property-success"></a> `SUCCESS` | `1` | `0x01` | The request succeeded; the payload holds the requested data. |

***

### lepuTransports [#leputransports]

```ts
const lepuTransports: object;
```

The characteristics each group of products exposes, read from the vendor's own managers.

`standard` and `aw1` match the vendor's published SDK reference exactly, and `standard`
also matches the SDK's existing BP2 driver, which has run against hardware on precisely
these UUIDs. `ding` and `aiTele` were read from an OEM build and the vendor documents no
product on them, so they are the two entries here that nothing independent confirms.

#### Type Declaration [#type-declaration-13]

| Name | Type | Default value | Description |
| ------ | ------ | ------ | ------ |
| <a id="property-aitele"></a> `aiTele` | `object` | - | OEM-build characteristics that the vendor does not document. |
| `aiTele.notifyUuid` | `"00002760-08c2-11e1-9073-0e8ac72e5402"` | `AI_TELE_NOTIFY` | Characteristic UUID that notifications arrive on. |
| `aiTele.preferredMtu` | `247` | `PREFERRED_MTU` | MTU to request once connected. |
| `aiTele.serviceUuid` | `"00002760-08c2-11e1-9073-0e8ac72e5450"` | `AI_TELE_SERVICE` | GATT service UUID. |
| `aiTele.writeUuid` | `"00002760-08c2-11e1-9073-0e8ac72e5401"` | `AI_TELE_WRITE` | Characteristic UUID that commands are written to. |
| <a id="property-aw1"></a> `aw1` | `object` | - | The characteristics of O2Ring S, the PF-10 wearables and the BBSM bands. |
| `aw1.notifyUuid` | `"e8fb0003-a14b-98f9-831b-4e2941d01248"` | `AW1_NOTIFY` | Characteristic UUID that notifications arrive on. |
| `aw1.preferredMtu` | `247` | `PREFERRED_MTU` | MTU to request once connected. |
| `aw1.serviceUuid` | `"e8fb0001-a14b-98f9-831b-4e2941d01248"` | `AW1_SERVICE` | GATT service UUID. |
| `aw1.writeUuid` | `"e8fb0002-a14b-98f9-831b-4e2941d01248"` | `AW1_WRITE` | Characteristic UUID that commands are written to. |
| <a id="property-ding"></a> `ding` | `object` | - | OEM-build characteristics that the vendor does not document. |
| `ding.notifyUuid` | `"0000fe62-0000-1000-8000-00805f9b34fb"` | `DING_NOTIFY` | Characteristic UUID that notifications arrive on. |
| `ding.preferredMtu` | `247` | `PREFERRED_MTU` | MTU to request once connected. |
| `ding.serviceUuid` | `"0000fe60-0000-1000-8000-00805f9b34fb"` | `DING_SERVICE` | GATT service UUID. |
| `ding.writeUuid` | `"0000fe61-0000-1000-8000-00805f9b34fb"` | `DING_WRITE` | Characteristic UUID that commands are written to. |
| <a id="property-standard"></a> `standard` | `object` | - | The characteristics nearly every product in the family exposes. |
| `standard.notifyUuid` | `"0734594a-a8e7-4b1a-a6b1-cd5243059a57"` | `STANDARD_NOTIFY` | Characteristic UUID that notifications arrive on. |
| `standard.preferredMtu` | `247` | `PREFERRED_MTU` | MTU to request once connected. |
| `standard.serviceUuid` | `"14839ac4-7d7e-415c-9a42-167340cf2339"` | `STANDARD_SERVICE` | GATT service UUID. |
| `standard.writeUuid` | `"8b00ace7-eb0b-49b0-bbe9-9aee0a26e1a3"` | `STANDARD_WRITE` | Characteristic UUID that commands are written to. |
| <a id="property-standardsmallmtu"></a> `standardSmallMtu` | `object` | - | The same characteristics on a link that will not grow past the minimum. |
| `standardSmallMtu.notifyUuid` | `"0734594a-a8e7-4b1a-a6b1-cd5243059a57"` | `STANDARD_NOTIFY` | Characteristic UUID that notifications arrive on. |
| `standardSmallMtu.preferredMtu` | `23` | `MINIMUM_MTU` | MTU to request once connected. |
| `standardSmallMtu.serviceUuid` | `"14839ac4-7d7e-415c-9a42-167340cf2339"` | `STANDARD_SERVICE` | GATT service UUID. |
| `standardSmallMtu.writeUuid` | `"8b00ace7-eb0b-49b0-bbe9-9aee0a26e1a3"` | `STANDARD_WRITE` | Characteristic UUID that commands are written to. |

***

### MeasurementFeedbackKey [#measurementfeedbackkey-1]

```ts
const MeasurementFeedbackKey: object;
```

The translation keys a failed measurement reports, as `BluetoothError.translationKey` (and its
message): compare against these rather than the strings, and translate them in the app.

#### Type Declaration [#type-declaration-14]

| Name | Type | Default value | Description |
| ------ | ------ | ------ | ------ |
| <a id="property-command_timeout"></a> `COMMAND_TIMEOUT` | `"feedback-messages.measurement.command-timeout"` | `"feedback-messages.measurement.command-timeout"` | The device did not answer a command in time. |
| <a id="property-corrupt_frame"></a> `CORRUPT_FRAME` | `"feedback-messages.measurement.corrupt-frame-error"` | `"feedback-messages.measurement.corrupt-frame-error"` | A frame from the device was corrupt. |
| <a id="property-device_error"></a> `DEVICE_ERROR` | `"feedback-messages.measurement.device-error"` | `"feedback-messages.measurement.device-error"` | The device reported an error. |
| <a id="property-device_interrupted"></a> `DEVICE_INTERRUPTED` | `"feedback-messages.measurement.device-interrupted"` | `"feedback-messages.measurement.device-interrupted"` | The measurement was interrupted. |
| <a id="property-disturb_detected"></a> `DISTURB_DETECTED` | `"feedback-messages.measurement.disturb-detected-error"` | `"feedback-messages.measurement.disturb-detected-error"` | Movement or interference disturbed the measurement. |
| <a id="property-insufficient_data_length"></a> `INSUFFICIENT_DATA_LENGTH` | `"feedback-messages.measurement.insufficient-data-length"` | `"feedback-messages.measurement.insufficient-data-length"` | A frame was too short to decode. |
| <a id="property-lead_off"></a> `LEAD_OFF` | `"feedback-messages.measurement.lead-off-error"` | `"feedback-messages.measurement.lead-off-error"` | An ECG lead was not in contact. |
| <a id="property-loose_sleeve"></a> `LOOSE_SLEEVE` | `"feedback-messages.measurement.loose-sleeve-error"` | `"feedback-messages.measurement.loose-sleeve-error"` | The cuff sleeve was loose. |
| <a id="property-poor_waveform"></a> `POOR_WAVEFORM` | `"feedback-messages.measurement.poor-waveform-error"` | `"feedback-messages.measurement.poor-waveform-error"` | The waveform quality was too poor. |
| <a id="property-stuck"></a> `STUCK` | `"feedback-messages.measurement.stuck-error"` | `"feedback-messages.measurement.stuck-error"` | The device stopped sending mid-measurement (or mid-transfer, after a reading already arrived). |
| <a id="property-weak_signal"></a> `WEAK_SIGNAL` | `"feedback-messages.measurement.weak-signal-error"` | `"feedback-messages.measurement.weak-signal-error"` | The signal was too weak to measure. |

***

### measurementFieldCatalog [#measurementfieldcatalog]

```ts
const measurementFieldCatalog: Readonly<Partial<Record<MeasurementTypeKey, Readonly<Record<string, CatalogField>>>>>;
```

The catalog of declarable properties per measurement type.

***

### TMB\_MODEL\_NAMES [#tmb_model_names]

```ts
const TMB_MODEL_NAMES: readonly string[];
```

Advertised names of the TMB blood pressure monitors.

***

### TRASENSE\_S9\_NOTIFY [#trasense_s9_notify]

```ts
const TRASENSE_S9_NOTIFY: "0000fff2-0000-1000-8000-00805f9b34fb" = "0000fff2-0000-1000-8000-00805f9b34fb";
```

Characteristic UUID that replies are notified on.

***

### TRASENSE\_S9\_SERVICE [#trasense_s9_service]

```ts
const TRASENSE_S9_SERVICE: "0000fff0-0000-1000-8000-00805f9b34fb" = "0000fff0-0000-1000-8000-00805f9b34fb";
```

GATT service UUID of the Trasense S9.

***

### TRASENSE\_S9\_WRITE [#trasense_s9_write]

```ts
const TRASENSE_S9_WRITE: "0000fff1-0000-1000-8000-00805f9b34fb" = "0000fff1-0000-1000-8000-00805f9b34fb";
```

Characteristic UUID that commands are written to.

***

### VEROVAL\_ACTIVITY\_BOND\_WRITE [#veroval_activity_bond_write]

```ts
const VEROVAL_ACTIVITY_BOND_WRITE: "2610fc01-494d-494c-4544-55544954414c" = "2610fc01-494d-494c-4544-55544954414c";
```

Characteristic UUID written to when bonding.

***

### VEROVAL\_ACTIVITY\_NOTIFY [#veroval_activity_notify]

```ts
const VEROVAL_ACTIVITY_NOTIFY: "2610fc03-494d-494c-4544-55544954414c" = "2610fc03-494d-494c-4544-55544954414c";
```

Characteristic UUID that replies are notified on.

***

### VEROVAL\_ACTIVITY\_SECONDARY\_NOTIFY [#veroval_activity_secondary_notify]

```ts
const VEROVAL_ACTIVITY_SECONDARY_NOTIFY: "2610fc04-494d-494c-4544-55544954414c" = "2610fc04-494d-494c-4544-55544954414c";
```

Second characteristic UUID that replies are notified on.

***

### VEROVAL\_ACTIVITY\_SERVICE [#veroval_activity_service]

```ts
const VEROVAL_ACTIVITY_SERVICE: "2610fc00-494d-494c-4544-55544954414c" = "2610fc00-494d-494c-4544-55544954414c";
```

GATT service UUID of the Veroval activity tracker.

***

### VEROVAL\_ACTIVITY\_WRITE [#veroval_activity_write]

```ts
const VEROVAL_ACTIVITY_WRITE: "2610fc02-494d-494c-4544-55544954414c" = "2610fc02-494d-494c-4544-55544954414c";
```

Characteristic UUID that commands are written to.

***

### VEROVAL\_BP\_MODEL\_NAMES [#veroval_bp_model_names]

```ts
const VEROVAL_BP_MODEL_NAMES: readonly string[];
```

The names these monitors advertise.

***

### VEROVAL\_ECG\_SAMPLE\_RATE\_HZ [#veroval_ecg_sample_rate_hz]

```ts
const VEROVAL_ECG_SAMPLE_RATE_HZ: 128 = 128;
```

How fast the device samples.

Not taken on trust: the vendor's own plotting step works out to two two-hundred-and-fifty
sixths of a second, and its transfer is thirty-four segments of sixteen packets of sixteen
bytes - which is 256 bytes, 128 samples, one second per segment. Both say 128 Hz.

***

### VEROVAL\_FUSION\_NAME\_MATCH [#veroval_fusion_name_match]

```ts
const VEROVAL_FUSION_NAME_MATCH: RegExp;
```

The exact advertised name used by the Veroval fusion monitor.

***

### VIATOM\_ECG\_MILLIVOLTS\_PER\_COUNT [#viatom_ecg_millivolts_per_count]

```ts
const VIATOM_ECG_MILLIVOLTS_PER_COUNT: 0.002467 = 0.002467;
```

Millivolts represented by one sample count.

***

### VIATOM\_ECG\_SAMPLE\_RATE\_HZ [#viatom_ecg_sample_rate_hz]

```ts
const VIATOM_ECG_SAMPLE_RATE_HZ: 125 = 125;
```

ECG sample rate in hertz.

***

### VIATOM\_OXIMETER\_NAMES [#viatom_oximeter_names]

```ts
const VIATOM_OXIMETER_NAMES: readonly string[];
```

The names the oximeter range advertises.

```typescript
const oximeters = VIATOM_OXIMETER_NAMES.map((name) =>
  viatomOximeter(name, { id: `viatom-${name.toLowerCase()}` }),
);
```

***

### VIATOM\_OXYII\_NAMES [#viatom_oxyii_names]

```ts
const VIATOM_OXYII_NAMES: readonly string[];
```

ViHealth models handled by its dedicated OxyII/AW1 transport.

These are selected by the vendor's model-to-interface switch rather than
by the legacy O2 interface used by the rest of this file.

***

### VISOMAT\_COMFORT\_SOFT\_BT\_NAME\_MATCH [#visomat_comfort_soft_bt_name_match]

```ts
const VISOMAT_COMFORT_SOFT_BT_NAME_MATCH: RegExp;
```

The product name used by the visomat comfort soft BT monitor while advertising.

## References [#references]

### CHECKME\_POD\_NOTIFY [#checkme_pod_notify]

Renames and re-exports [CHECKME_NOTIFY](#checkme_notify)

***

### CHECKME\_POD\_SERVICE [#checkme_pod_service]

Renames and re-exports [CHECKME_SERVICE](#checkme_service)

***

### CHECKME\_POD\_WRITE [#checkme_pod_write]

Renames and re-exports [CHECKME_WRITE](#checkme_write)
