Skip to main content

Retrieve the Data

To set up the bracelet and the Android SDK here are the main steps to implement:

  • Pair and connect to the bracelet
  • Set up the bracelet parameter
  • Set up the automatic data transfer between the Bracelet to the Android SDK database
  • Retrieve the data

Retrieving the data is handled by the Data SDK: Module for storing raw data from the bracelet, and calculating summaries.

What are raw metrics and summaries?

Data Flow

Section bellow describes how it works internally.

BleDevice -> File Transfer -> Raw Metric -> Erase -> Summary + Slots

Retrieving data from the BleDevice via the Data Sdk:

  • File Transfer: This will request the file size, if the size > 0 it will download the requested file with a max of 10 000 bytes.
  • Raw Metric: Map the received data in the Metric object and save in the Metric database. Once the data is saved it is pushed to the matching Manager.metric<TYPE>Updated listener and retrievable via the Manager.metric<TYPE>Repository repository.
  • Erase: Once the data is successfully saved in the metric database, we delete the processed data from the BleDevice with BleDevice.enqueueCommand(request = EraseFileRequest(fileOnWatch, size)
  • Summary + Slots: Once the data is successfully saved in the metric database, the updaters are triggered to recalculate the summaries and slots affected by the new data.

Data SDK Configuration parameters (optionnal)

The Data SDK has 4 parameters with default value.The following documentation will explain how to change these parameters.

slotsIntervalSecs

The interval of slots in the summary generation.

Default value is 60 (seconds)

The minimim value is 60 seconds, if it set to less than 60, it will be overwritten.

It means the summaries will be generated like this

00:00 X steps

00:01 Y steps

00:02 Z steps

etc

The summaries are meant to be daily summaries and not a copy of the raw metrics. Less than 60 seconds interval will overload the database

ppg2ThresholdFileSize

The minimum size of a wiff file for the PPG2 dataDefault value is 500 * 1024 (500kB)

It means the data is sync continuous from the bracelet but the .wiff files are generated when the data is > 500kB. This avoid having lots of files, but it means we have to wait a certain amount of data before retrieving the file.

Put this value to zero to have a continuous .wiff generation, a file will be generated after each sync.

bioZThresholdFileSize

The minimum size of a wiff file for the BioZ dataDefault value is 30 * 1024 (500kB)It means the data is sync continuous from the bracelet but the .wiff files are generated when the data is > 30kB. This avoid having lots of files, but it means we have to wait a certain amount of data before retrieving the file.

Put this value to zero to have a continuous .wiff generation, a file will be generated after each sync.

accThresholdFileSize

The minimum size of a wiff file for the ACC dataDefault value is 30 * 1024 (500kB)It means the data is sync continuous from the bracelet but the .wiff files are generated when the data is > 30kB. This avoid having lots of files, but it means we have to wait a certain amount of data before retrieving the file.Put this value to zero to have a continuous .wiff generation, a file will be generated after each sync.

automaticReconnectIfNeededIntervalMinutes

Do not set, deprecated.

Code example

val dataConfig = DataSdk.Config(slotsIntervalSecs = 1 * 60, ppg2ThresholdFileSize = 0, bioZThresholdFileSize = 0, accThresholdFileSize = 0 ) // Add data config here if needed

val config = CorsanoSdkConfig.Builder()
.addModuleConfig(dfuConfig)
.addModuleConfig(dataConfig)
.build()

CorsanoSdk.initialize(this, config)

Data SDK

After CorsanoSdk is initialized, you can access DataSdk by static method:

DataSdk.getInstance()

Access the database: raw metrics and summaries

The database can be access with the repositories

// Raw data repositories
val metricActivityRepository: MetricActivityRepository
val metricHrvRepository: MetricHrvRepository
val metricPpgRepository: MetricPpgRepository
val metricSleepRepository: MetricSleepRepository
val metricTemperatureRepository: MetricTemperatureRepository
val rawFileRepository: RawFileRepository
val metricEmographyRepository: MetricEmographyRepository

// Summary repositories
val stepsSummaryRepository: StepsSummaryRepository
val heartRateSummaryRepository: HeartRateSummaryRepository
val respirationSummaryRepository: RespirationSummaryRepository
val sleepSummaryRepository: SleepSummaryRepository
val temperatureSummaryRepository: TemperatureSummaryRepository
val spo2SummaryRepository: SpO2SummaryRepository
val emographySummaryRepository: EmographySummaryRepository

Example with the activity data

Get raw metrics
val dataSdkManager = DataSdk.getInstance().getManager()

dataSdkManager?.metricActivityRepository?.getByTimestampRange(TIME_START_MILLI, TIME_STOP_MILLI)
Delete raw metrics

It is important to delete the raw metrics regularly as the amount can grow fast.

For raw metrics with summaries calculation (activity, respiration, temperature, SpO2, heart rate), it is important to keep the current day of data in the database, as the summary calculation is based on the full day of raw metrics.

Keep the last 2 days to make sure the summary calculation is correct in all usecases.

For raw metrics without summaries (PPG), the data can be deleted anytime.

Delete by timestamp range:

dataSdkManager?.metricActivityRepository?.deleteByTimestampRange(TIME_START_MILLI, TIME_STOP_MILLI)

Delete all:

dataSdkManager?.metricActivityRepository?.deleteAll()
Get summary
dataSdkManager?.stepsSummaryRepository?.getByDate("2021-11-10"
Delete summary

The activity summary contains less data than the raw metrics but it is good to delete it as well to free the database memory.

dataSdkManager?.stepsSummaryRepository?.deleteByDate("2021-11-10"
dataSdkManager?.stepsSummaryRepository?.deleteAll(
dataSdkManager?.stepsSummaryRepository?.deleteByTimestampRange(TIME_START_MILLI, TIME_STOP_MILLI)

Full data models description available here

Data events: new data coming after a transfer

The Data SDK will trigger events when new data is available:

  • New Raw metrics
  • Update of the summary

Example with the activity data

Updated summaries are received by subscribing to updaters:


private val stepsSummaryListener = object : ValueUpdated.Listener<StepsSummaryModel> {
override fun onValueUpdated(model: StepsSummaryModel) {
this@DataActivityFragment.view?.findViewById<TextView>(R.id.action_result)?.text =
model.toString()
}
}

fun onStart() {
...

dataSdkManager?.stepsSummaryUpdated?.addListener(stepsSummaryListener)
}


fun onStop() {
...

dataSdkManager?.stepsSummaryUpdated?.removeListener(stepsSummaryListener)
}

Note: Don't forget to unsubscribe

Event on new .wiff file for PPG2/ACC/BioZ

View DataMeasurementFragment.kt in the sample app

Event on sleep process

Where is the sleep processing at, for the current day

View DataSleepFragment.kt in the sample app

enum class SleepProcessResult {
UNKNOWN, // Deprecated
STARTED,
SUCCESS, // sleep has been processed and interpreted, a SleepSummary is available
ERROR_NO_SLEEP_FILE, // sleep cannot be processed because no sleep data from the bracelet has been found or synced
ERROR_SLEEP_FILE_PARSING_WILL_REPROCESS, // sleep processing failed but will retry up to 3 times, 2 minutes between each trial
ERROR_SLEEP_FILE_PARSING_WILL_NOT_REPROCESS; // sleep processing failed and will not retry, no sleep has been interpreted with the bracelet's data

All the code sample for listeners are available in the sample app.