Measure types
The six measure types in carp_movisens_package, the data types they produce and when the data arrives.
carp_movisens_package has six measure types in the dk.cachet.carp.movisens namespace, which CARP Mobile Sensing (CAMS) collects from a Movisens sensor. Add each one to a protocol as Measure(type: MovisensSamplingPackage.<constant>), in a task that runs on a MovisensDevice:
| Measure type | Constant | Kind | Android | iOS |
|---|---|---|---|---|
dk.cachet.carp.movisens.activity | ACTIVITY | Event-based | Yes | Yes |
dk.cachet.carp.movisens.hr | HR | Event-based | Yes | Yes |
dk.cachet.carp.movisens.eda | EDA | Event-based | Yes | Yes |
dk.cachet.carp.movisens.skin_temperature | SKIN_TEMPERATURE | Event-based | Yes | Yes |
dk.cachet.carp.movisens.respiration | RESPIRATION | Event-based | Yes | Yes |
dk.cachet.carp.movisens.tap_marker | TAP_MARKER | Event-based | Yes | Yes |
All six are event-based; see Event-based and one-time measures. They stream while the sensor is connected, so start them with an ImmediateTrigger. The measures have no sampling configuration.
For the measurement envelope around the data, see Measurements and data.
Measures and data types
A measure type says what to collect, and the data type of each measurement says what it holds. For four measures, the two are the same. ACTIVITY and HR produce several data types:
| Measure | Data type | Data class |
|---|---|---|
ACTIVITY | dk.cachet.carp.movisens.activity.steps | MovisensStepCount |
ACTIVITY | dk.cachet.carp.movisens.activity.body_position | MovisensBodyPosition |
ACTIVITY | dk.cachet.carp.movisens.activity.inclination | MovisensInclination |
ACTIVITY | dk.cachet.carp.movisens.activity.movement_acceleration | MovisensMovementAcceleration |
ACTIVITY | dk.cachet.carp.movisens.activity.met | MovisensMET |
ACTIVITY | dk.cachet.carp.movisens.activity.met_level | MovisensMETLevel |
HR | dk.cachet.carp.movisens.hr.hr_mean | MovisensHR, MovisensHRV and MovisensIsHrvValid |
To select measurements, use the data type, not the measure type, for example in measurementsByType() or in a SamplingEventTrigger. MovisensData has constants for these data types, such as MovisensData.STEPS:
Delays and timestamps
The sensor computes most values over one minute and sends each one 0–84 seconds after measuring it, depending on the sensor and the value. Tap markers arrive without delay. Movisens lists the delay of each signal in Available signals per sensor.
The package does not correct for the delay: timestamp and sensorStartTime both give the phone's time when the value arrived. timestamp is in the phone's local time, without a time zone offset, and sensorStartTime is in microseconds since the epoch.
The package reads only live values. Values that the sensor measures while it is disconnected are not transferred later.
Common fields
Every Movisens data class extends MovisensData, which has these fields:
| Field | Type | Description |
|---|---|---|
timestamp | DateTime | The phone's local time when the value arrived, in ISO 8601 without a time zone offset. |
deviceId | String | Bluetooth ID of the sensor: a MAC address on Android, or on iOS a UUID that differs between phones. |
type | String | The movisens_flutter characteristic that sent the value, such as steps or hrMean. |
Physical activity
ACTIVITY collects the values of the sensor's physical activity service, about once per minute each. Body position, the metabolic equivalent of task (MET) and MET levels depend on the wearer's data in the MovisensDevice. See Add the device to the protocol.
Known issue
CAMS creates the probes when it deploys or restores a study, before it connects the sensor. The activity probe starts only if the sensor's physical activity service is known at that moment, so ACTIVITY collects no data.
The six data classes add these fields to the common fields:
| Field | Type | Description |
|---|---|---|
steps | int | In MovisensStepCount: steps in the last minute. |
bodyPosition | String | In MovisensBodyPosition: the wearer's position, one of unknown, lyingSupine, lyingLeft, lyingProne, lyingRight, upright, sittingUpright, standing and notWorn. |
x, y, z | int | In MovisensInclination: mean inclination of the three body axes, in degrees from 0 to 180. |
movementAcceleration | double | In MovisensMovementAcceleration: intensity of movement in g, where 1 g is 9.81 m/s². |
met | int | In MovisensMET: the MET value, as the raw integer that the sensor sends. |
sedentary, light, moderate, vigorous | int | In MovisensMETLevel: seconds spent at each MET level in the last minute. |
Step count:
Body position:
Time per MET level:
Heart rate and HRV
HR collects the values of the heart rate variability (HRV) service of an EcgMove4, about once per minute each. The package does not collect the beat-by-beat heart rate that the sensor also sends.
Known issue
CAMS creates the probes when it deploys or restores a study, before it connects the sensor. The heart rate probe starts only if the sensor's HRV service is known at that moment, so HR collects no data.
The three data classes add these fields to the common fields:
| Field | Type | Description |
|---|---|---|
hr | int | In MovisensHR, with type hrMean: mean heart rate of the previous 60 seconds, in beats per minute (BPM). |
hrv | int | In MovisensHRV, with type rmssd: the root mean square of successive differences (RMSSD) of the beat intervals, in milliseconds. |
isHrvValid | bool | In MovisensIsHrvValid, with type hrvIsValid: whether the current HRV values are valid. |
All three classes use the data type dk.cachet.carp.movisens.hr.hr_mean. The constants MovisensData.HRV and MovisensData.IS_HRV_VALID exist, but no data uses them. Tell the three apart by the type field, or by class:
Mean heart rate:
RMSSD:
Electrodermal activity
EDA collects the mean skin conductance level (SCL) of an EdaMove4, about once per minute.
MovisensEDA adds this field to the common fields:
| Field | Type | Description |
|---|---|---|
edaSclMean | double | Mean skin conductance level in microsiemens (µS). |
Skin temperature
SKIN_TEMPERATURE collects the mean skin temperature of the last minute, about once per minute.
MovisensSkinTemperature adds this field to the common fields:
| Field | Type | Description |
|---|---|---|
skinTemperature | double | Mean skin temperature in °C. |
Respiration
RESPIRATION reads the respiratory movement value of the sensor's respiration service.
Known issue
The respiration probe turns on the notifications of the skin temperature service instead of the respiration service. The sensor then sends no respiration values, so RESPIRATION collects no data.
MovisensRespiration adds this field to the common fields:
| Field | Type | Description |
|---|---|---|
value | int | Respiratory movement. Neither Movisens nor movisens_flutter documents its unit. |
Tap markers
TAP_MARKER reports each tap on the sensor without delay, for example when the participant marks a moment in the day.
MovisensTapMarker adds this field to the common fields:
| Field | Type | Description |
|---|---|---|
tapMarker | int | The marker value that the sensor sends. Movisens does not document its meaning. |
A SamplingEventTrigger with measureType: MovisensSamplingPackage.TAP_MARKER starts a task on every tap. Leave out triggerCondition: Movisens data classes do not support conditions, so a trigger with one never fires.
Data transformers
Registering the package adds transformers to the Open mHealth (OMH) and Fast Healthcare Interoperability Resources (FHIR) formats of CAMS:
| Data type | OMH | FHIR |
|---|---|---|
dk.cachet.carp.movisens.hr.hr_mean | OMHHeartRateDataPoint | FHIRHeartRateObservation |
dk.cachet.carp.movisens.activity.steps | OMHStepCountDataPoint | None |
To store data in one of these formats, set dataFormat on the data endpoint:
Data of the other data types keeps the CARP format. See Data transformation.