Skip to content

Data Types and Events ​

Choose which data types the device streams live or stores for later, then handle samples and events in your delegate.

Collecting data ​

When starting data collection, provide two lists. The first selects data streamed to your application while the device is connected. The second selects data the device records in its memory whenever it does not stream live: while disconnected, and while connected when the first list is empty or after stopCollect(). Retrieve it later through synchronization.

An optional third list, events, selects the events delivered live. Each call replaces all lists. An empty second list, which Python uses when you omit it, turns off offline recording unless events lists ACTIVITY. Unsupported data types or events make collect() fail before sending the command. A failed collect() keeps the events of the previous one.

python
from aidlab import DataType, DeviceEventType

async def did_connect(self, device):
    await device.collect(
        [DataType.RESPIRATION_RATE, DataType.SKIN_TEMPERATURE],
        [],
        events=[DeviceEventType.WEAR_STATE],
    )
kotlin
override fun didConnect(device: Device) {
    lifecycleScope.launch {
        device.collect(
            EnumSet.of(DataType.RESPIRATION_RATE, DataType.SKIN_TEMPERATURE),
            EnumSet.noneOf(DataType::class.java),
            EnumSet.of(DeviceEventType.WEAR_STATE),
        )
    }
}
swift
func didConnect(_ device: Device) {
    Task {
        _ = try await device.collect(
            dataTypes: [.respirationRate, .skinTemperature],
            dataTypesToStore: [],
            events: [.wearState]
        )
    }
}
dart
@override
Future<void> didConnect(Device device) async {
    await device.collect(
        [DataType.respirationRate, DataType.skinTemperature],
        [],
        events: [DeviceEventType.wearState],
    );
}
csharp
using UnityEngine;

public class MyAidlab : MonoBehaviour {
    void Start() {
        Aidlab.AidlabSDK.init();
        var sdk = FindAnyObjectByType<Aidlab.AidlabSDK>();
        if (sdk != null) {
            sdk.SetCollectSignals(
                new[] { Aidlab.Signal.RespirationRate, Aidlab.Signal.Temperature },
                System.Array.Empty<Aidlab.Signal>(),
                new[] { Aidlab.DeviceEventType.WearState }
            );
        }
    }
}

The device neither streams nor stores measurement samples while its wear state is DETACHED. Wear-state events continue when it is detached. Listen for these events and wait until the device reports that it is properly worn before relying on measurements.

Available data types include:

Data typeDescriptionMinimum firmware
ECG (Electrocardiogram)Samples in volts (±0.4 V input range, 24-bit) capturing heart electrical activity.1.0.0
RespirationBreathing waveform in Ohms, enough to plot a breathing curve.1.0.0
Skin TemperatureSkin temp in °C; stabilizes in ~5–15 min (touch sensor).1.0.0
StepsSteps counted since the previous update.2.1.0
RRR–R intervals from ECG, in milliseconds.2.1.0
Respiration RateBreaths per minute.2.1.0
Body PositionFor lying posture: prone, supine, left side, right side, unknown.2.2.0
Heart RateBPM calculated from the 9 most recent heartbeat intervals.2.2.0
Sound VolumeEstimated ambient sound level in dB; raw audio is not exposed.2.2.5
OrientationQuaternion (qw, qx, qy, qz) and Z–Y–X Euler angles in degrees from accelerometer and gyroscope fusion. Chest frame: +X forward, +Y right, +Z toward the feet; level frame +Z down. Yaw is relative to the start of collection and drifts. Aidlab 1 and Aidmed One use this frame from firmware 3.7.113.2.2.6
Motion9-axis IMU: accel (ax, ay, az) in g (default range ±4 g), gyro (gx, gy, gz) in deg/s (±2000 dps), mag (mx, my, mz) in µT (±4900 µT); with Orientation powers workout classifier.2.2.6
PressureNasal cannula airflow (measured as pressure in mPa; Aidmed One only)3.2.23
Electrodermal ActivitySkin conductance in µS (resistance in Ω when available), sampled once per second.4.0.0
GPSLatitude/longitude, altitude, speed (m/s), heading, HDOP.4.0.0

Sample rates per data type are listed on the support page: Measurements range and accuracy.

Receiving samples ​

Each data sample invokes its handler. Timestamps represent capture time in milliseconds since the Unix epoch (1970-01-01T00:00:00Z). Samples from a single signal are emitted in capture order. When combining multiple signals or live and historical data, sort samples by timestamp.

Delivery timing ​

Continuous signals may arrive in batches. Aidlab and Aidmed One usually send about 250 ms of samples at a time; Aidlab 2 sends one-second batches for high-rate signals. Events such as heart rate updates and wear-state changes may arrive separately.

Batching does not change the sampling rate. Use each sample's capture timestamp to align signals or compare them with external events. Bluetooth and system scheduling may delay delivery.

Key callback signatures by platform:

python
async def did_connect(self, device): ...
def did_disconnect(self, device, reason): ...
def did_receive_battery_level(self, device, soc): ...
def did_receive_ecg(self, device, ts, value): ...
def did_receive_respiration(self, device, ts, value): ...
def did_receive_respiration_rate(self, device, ts, value): ...
def did_receive_skin_temperature(self, device, ts, value): ...
def did_receive_heart_rate(self, device, ts, bpm): ...
def did_receive_rr(self, device, ts, rr): ...
def did_receive_steps(self, device, ts, steps): ...
def did_receive_signal_quality(self, device, ts, quality): ...
def did_receive_accelerometer(self, device, ts, ax, ay, az): ...
def did_receive_gyroscope(self, device, ts, gx, gy, gz): ...
def did_receive_magnetometer(self, device, ts, mx, my, mz): ...
def did_receive_quaternion(self, device, ts, qw, qx, qy, qz): ...
def did_receive_orientation(self, device, ts, roll, pitch, yaw): ...
def did_receive_body_position(self, device, ts, body_position): ...
def did_receive_sound_volume(self, device, ts, value): ...
def did_receive_pressure(self, device, ts, value): ...
def did_receive_eda(self, device, ts, conductance): ...  # Firmware 4.0.0+
def did_receive_gps(self, device, ts, lat, lon, alt, speed, heading, hdop): ...  # Firmware 4.0.0+
def did_receive_event(self, device, event): ...
def did_receive_error(self, device, error): ...
def sync_state_did_change(self, device, state): ...
def did_receive_unsynchronized_size(self, device, size, throughput): ...
def did_receive_past_ecg(self, device, ts, value): ...
def did_receive_past_respiration(self, device, ts, value): ...
def did_receive_past_eda(self, device, ts, conductance): ...
def did_receive_past_gps(self, device, ts, lat, lon, alt, speed, heading, hdop): ...
kotlin
fun didConnect(device: Device)
fun didDisconnect(device: Device, reason: DisconnectReason)
fun didReceiveBatteryLevel(device: Device, soc: Int)
fun didReceiveECG(device: Device, timestamp: Long, value: Float)
fun didReceiveRespiration(device: Device, timestamp: Long, value: Float)
fun didReceiveRespirationRate(device: Device, timestamp: Long, value: Int)
fun didReceiveSkinTemperature(device: Device, timestamp: Long, value: Float)
fun didReceiveHeartRate(device: Device, timestamp: Long, heartRate: Int)
fun didReceiveRr(device: Device, timestamp: Long, rr: Int)
fun didReceiveSteps(device: Device, timestamp: Long, value: Long)
fun didReceiveSignalQuality(device: Device, timestamp: Long, quality: Int)
fun didReceiveAccelerometer(device: Device, timestamp: Long, ax: Float, ay: Float, az: Float)
fun didReceiveGyroscope(device: Device, timestamp: Long, gx: Float, gy: Float, gz: Float)
fun didReceiveMagnetometer(device: Device, timestamp: Long, mx: Float, my: Float, mz: Float)
fun didReceiveQuaternion(device: Device, timestamp: Long, qw: Float, qx: Float, qy: Float, qz: Float)
fun didReceiveOrientation(device: Device, timestamp: Long, roll: Float, pitch: Float, yaw: Float)
fun didReceiveBodyPosition(device: Device, timestamp: Long, bodyPosition: BodyPosition)
fun didReceiveSoundVolume(device: Device, timestamp: Long, value: Int)
fun didReceivePressure(device: Device, timestamp: Long, value: Int)
fun didReceiveEDA(device: Device, timestamp: Long, conductance: Float) // Firmware 4.0.0+
fun didReceiveGPS(device: Device, timestamp: Long, latitude: Double, longitude: Double, altitude: Double, speed: Float, heading: Float, hdop: Float) // Firmware 4.0.0+
fun didReceiveEvent(device: Device, event: DeviceEvent)
fun didReceiveError(device: Device, error: AidlabError)
fun syncStateDidChange(device: Device, state: SyncState)
fun didReceiveUnsynchronizedSize(device: Device, unsynchronizedSize: Long, syncBytesPerSecond: Float)
fun didReceivePastECG(device: Device, timestamp: Long, value: Float)
fun didReceivePastRespiration(device: Device, timestamp: Long, value: Float)
fun didReceivePastEDA(device: Device, timestamp: Long, conductance: Float)
fun didReceivePastGPS(device: Device, timestamp: Long, latitude: Double, longitude: Double, altitude: Double, speed: Float, heading: Float, hdop: Float)
swift
func didConnect(_ device: Device)
func didDisconnect(_ device: Device, reason: DisconnectReason)
func didReceiveBatteryLevel(_ device: Device, stateOfCharge: UInt8)
func didReceiveECG(_ device: Device, timestamp: UInt64, value: Float)
func didReceiveRespiration(_ device: Device, timestamp: UInt64, value: Float)
func didReceiveRespirationRate(_ device: Device, timestamp: UInt64, value: UInt32)
func didReceiveSkinTemperature(_ device: Device, timestamp: UInt64, value: Float)
func didReceiveHeartRate(_ device: Device, timestamp: UInt64, heartRate: Int32)
func didReceiveRr(_ device: Device, timestamp: UInt64, rr: Int32)
func didReceiveSteps(_ device: Device, timestamp: UInt64, value: UInt64)
func didReceiveSignalQuality(_ device: Device, timestamp: UInt64, value: UInt8)
func didReceiveAccelerometer(_ device: Device, timestamp: UInt64, ax: Float, ay: Float, az: Float)
func didReceiveGyroscope(_ device: Device, timestamp: UInt64, gx: Float, gy: Float, gz: Float)
func didReceiveMagnetometer(_ device: Device, timestamp: UInt64, mx: Float, my: Float, mz: Float)
func didReceiveQuaternion(_ device: Device, timestamp: UInt64, qw: Float, qx: Float, qy: Float, qz: Float)
func didReceiveOrientation(_ device: Device, timestamp: UInt64, roll: Float, pitch: Float, yaw: Float)
func didReceiveBodyPosition(_ device: Device, timestamp: UInt64, bodyPosition: BodyPosition)
func didReceiveSoundVolume(_ device: Device, timestamp: UInt64, soundVolume: UInt16)
func didReceivePressure(_ device: Device, timestamp: UInt64, value: Int32)
func didReceiveEDA(_ device: Device, timestamp: UInt64, conductance: Float) // Firmware 4.0.0+
func didReceiveGPS(_ device: Device, timestamp: UInt64, latitude: Double, longitude: Double, altitude: Double, speed: Float, heading: Float, hdop: Float) // Firmware 4.0.0+
func didReceiveEvent(_ device: Device, event: any DeviceEvent)
func didReceiveError(_ device: Device, error: AidlabError)
func syncStateDidChange(_ device: Device, state: SyncState)
func didReceiveUnsynchronizedSize(_ device: Device, unsynchronizedSize: UInt32, syncBytesPerSecond: Float)
func didReceivePastECG(_ device: Device, timestamp: UInt64, value: Float)
func didReceivePastRespiration(_ device: Device, timestamp: UInt64, value: Float)
func didReceivePastEDA(_ device: Device, timestamp: UInt64, conductance: Float)
func didReceivePastGPS(_ device: Device, timestamp: UInt64, latitude: Double, longitude: Double, altitude: Double, speed: Float, heading: Float, hdop: Float)
dart
Future<void> didConnect(Device device);
void didDisconnect(Device device, DisconnectReason reason);
void didReceiveBatteryLevel(Device device, int stateOfCharge);
void didReceiveECG(Device device, int timestamp, double value);
void didReceiveRespiration(Device device, int timestamp, double value);
void didReceiveRespirationRate(Device device, int timestamp, int value);
void didReceiveSkinTemperature(Device device, int timestamp, double value);
void didReceiveHeartRate(Device device, int timestamp, int heartRate);
void didReceiveRr(Device device, int timestamp, int rr);
void didReceiveSteps(Device device, int timestamp, int steps);
void didReceiveSignalQuality(Device device, int timestamp, int value);
void didReceiveAccelerometer(Device device, int timestamp, double ax, double ay, double az);
void didReceiveGyroscope(Device device, int timestamp, double gx, double gy, double gz);
void didReceiveMagnetometer(Device device, int timestamp, double mx, double my, double mz);
void didReceiveQuaternion(Device device, int timestamp, double qw, double qx, double qy, double qz);
void didReceiveOrientation(Device device, int timestamp, double roll, double pitch, double yaw);
void didReceiveBodyPosition(Device device, int timestamp, BodyPosition bodyPosition);
void didReceiveSoundVolume(Device device, int timestamp, int value);
void didReceivePressure(Device device, int timestamp, int value);
void didReceiveEDA(Device device, int timestamp, double conductance); // Firmware 4.0.0+
void didReceiveGPS(Device device, int timestamp, double lat, double lon, double alt, double speed, double heading, double hdop); // Firmware 4.0.0+
void didReceiveEvent(Device device, DeviceEvent event);
void didReceiveError(Device device, AidlabError error);
void syncStateDidChange(Device device, SyncState state);
void didReceiveUnsynchronizedSize(Device device, int unsynchronizedSize, double syncBytesPerSecond);
void didReceivePastECG(Device device, int timestamp, double value);
void didReceivePastRespiration(Device device, int timestamp, double value);
void didReceivePastEDA(Device device, int timestamp, double conductance);
void didReceivePastGPS(Device device, int timestamp, double lat, double lon, double alt, double speed, double heading, double hdop);
csharp
using UnityEngine;

public class MyAidlab : MonoBehaviour {
    void Start() {
        Aidlab.AidlabSDK.init();

        // Subscribe to updates (callbacks run on Unity main thread).
        Aidlab.AidlabSDK.aidlabDelegate.respiration.Subscribe(OnRespiration);
        Aidlab.AidlabSDK.aidlabDelegate.eda.Subscribe(OnEda);
    }

    private void OnRespiration() {
        var ts = Aidlab.AidlabSDK.aidlabDelegate.respiration.timestamp;
        var value = Aidlab.AidlabSDK.aidlabDelegate.respiration.value;
        Debug.Log($"Respiration @ {ts}: {value}");
    }

    private void OnEda() {
        var ts = Aidlab.AidlabSDK.aidlabDelegate.eda.timestamp;
        var value = Aidlab.AidlabSDK.aidlabDelegate.eda.value;
        Debug.Log($"EDA @ {ts}: {value}");
    }
}

Events ​

List the events to deliver live in the events of collect(), which adds the data each one needs. Events read through synchronization are always delivered. All events arrive through didReceiveEvent (did_receive_event in Python); synchronized ones have isPast (is_past) set.

EventIn eventsMinimum firmware
WearStateEventWEAR_STATE, with ECG, respiration, heart rate, RR or respiration rate collected live.1.0.0
ActivityEventACTIVITY. Adds activity (still, walking, running, automotive, cycling) to live and stored data.2.1.0
ExerciseEventEXERCISE. Adds motion and orientation to live data; exercises come only from live data.2.2.6
PressureWearStateEventPRESSURE_WEAR_STATE (Aidmed One). Adds pressure to live data.3.2.23
UserEventUSER, with any data type collected live.3.4.43
EcgEventECG4.0.0
SleepEventSLEEP4.0.0

ECG and SLEEP run the analysis on the device while it is worn, whatever data you collect. Their events arrive live while the device streams live data, otherwise through synchronization.

Each SleepEvent is one stage period of a night: period is WAKE (2), LIGHT (3), DEEP (4) or REM (5), the codes of HealthKit sleep analysis. The periods arrive once the night closes. A night is its periods: sleep onset is the start of the first and the final wake the end of the last.

All events carry a start timestamp in Unix milliseconds, an optional endTimestamp (end_timestamp), an optional confidence from 0 to 1, and isPast (is_past). A moment has an end equal to its start; an ongoing period has no end.

python
from aidlab import WearStateEvent, ExerciseEvent

def did_receive_event(self, device, event):
    if isinstance(event, WearStateEvent):
        print(event.wear_state, event.timestamp, event.is_past)
    elif isinstance(event, ExerciseEvent):
        print(event.exercise, event.timestamp, event.is_past)
kotlin
override fun didReceiveEvent(device: Device, event: DeviceEvent) {
    when (event) {
        is WearStateEvent -> println("${event.wearState} at ${event.timestamp}, past=${event.isPast}")
        is ExerciseEvent -> println("${event.exercise} at ${event.timestamp}, past=${event.isPast}")
        else -> Unit
    }
}
swift
func didReceiveEvent(_ device: Device, event: any DeviceEvent) {
    if let wear = event as? WearStateEvent {
        print(wear.wearState, wear.timestamp, wear.isPast)
    } else if let exercise = event as? ExerciseEvent {
        print(exercise.exercise, exercise.timestamp, exercise.isPast)
    }
}
dart
@override
void didReceiveEvent(Device device, DeviceEvent event) {
  if (event is WearStateEvent) {
    print('${event.wearState} at ${event.timestamp}, past=${event.isPast}');
  } else if (event is ExerciseEvent) {
    print('${event.exercise} at ${event.timestamp}, past=${event.isPast}');
  }
}