Skip to content

Commit 55c3878

Browse files
authored
Added cycling pedaling cadence and power (#4 from jgillich)
1 parent aa71511 commit 55c3878

24 files changed

Lines changed: 1101 additions & 20 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## [0.0.16](https://github.com/vitoksmile/HealthKMP/releases/tag/0.0.16)
4+
5+
- Added **cycling pedaling cadence** data type
6+
- Added **power** data type
7+
38
## [0.0.15](https://github.com/vitoksmile/HealthKMP/releases/tag/0.0.15)
49

510
Breaking change:

README.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,33 @@ HealthKMP supports:
2323
Note that for Android, the target device **needs** to have [Google Fit](https://www.google.com/fit/) or [Health Connect](https://health.google/health-connect-android/) installed.
2424

2525
## Supported data types (iOS, watchOS, Android)
26+
2627
- Blood glucose
2728
- Blood pressure
2829
- Body fat
2930
- Body temperature
31+
- Cycling pedaling cadence
3032
- Exercise (segments, laps, routes)
3133
- Heart rate
3234
- Height
3335
- Lean body mass
36+
- Power
3437
- Sleep
3538
- Steps
3639
- Weight
3740

3841
## Supported units
42+
3943
- Blood glucose: mmol/L, mg/dL
4044
- Length: meters, kilometers, miles, inches, feet
4145
- Mass: grams, kilograms, milligrams, micrograms, ounces, pounds
46+
- Power: watts, kilocalories per day
4247
- Percentage: e.g. 100%, 89.62%
4348
- Pressure: millimeters of Mercury (mmHg)
4449
- Temperature: Celsius, Fahrenheit
4550

4651
## Supported regional preferences
52+
4753
- Temperature: Celsius, Fahrenheit
4854

4955
## Requesting permission
@@ -65,6 +71,7 @@ SwiftUI is used for watchOS app.
6571
First add the dependency to your project:
6672

6773
settings.gradle.kts:
74+
6875
```kotlin
6976
dependencyResolutionManagement {
7077
repositories {
@@ -74,20 +81,22 @@ dependencyResolutionManagement {
7481
```
7582

7683
build.gradle:
84+
7785
```kotlin
7886
sourceSets {
7987
val commonMain by getting {
8088
dependencies {
81-
implementation("com.viktormykhailiv:health-kmp:0.0.15")
89+
implementation("com.viktormykhailiv:health-kmp:0.0.16")
8290
}
8391
}
8492
}
8593
```
8694

8795
or use version catalog:
96+
8897
```
8998
[versions]
90-
health = "0.0.15"
99+
health = "0.0.16"
91100
92101
[libraries]
93102
health = { module = "com.viktormykhailiv:health-kmp", version.ref = "health" }
@@ -96,6 +105,7 @@ health = { module = "com.viktormykhailiv:health-kmp", version.ref = "health" }
96105
```
97106

98107
build.gradle:
108+
99109
```
100110
implementation(libs.health)
101111
```
@@ -403,7 +413,7 @@ health.writeData(
403413
recorded, unique identifier of data, and device information associated with the data.
404414

405415
```kotlin
406-
fun generateMetadata() : Metadata {
416+
fun generateMetadata(): Metadata {
407417
return Metadata.manualEntry(
408418
id = Uuid.random().toString(),
409419
device = Device.getLocalDevice(),
@@ -418,7 +428,7 @@ HealthKMP is Swift compatible and can be added as package dependency to Xcode pr
418428
### Add the package dependency
419429

420430
1. In Xcode, choose **File | Add Package Dependencies**.
421-
431+
422432
2. In the search field, enter `https://github.com/vitoksmile/HealthKMP-SPM`:
423433

424434
<img src=readme/swift-package-manager.png width=640 />

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ RELEASE_SIGNING_ENABLED=true
1515

1616
GROUP=com.viktormykhailiv
1717
POM_ARTIFACT_ID=health-kmp
18-
VERSION_NAME=0.0.15
18+
VERSION_NAME=0.0.16
1919

2020
POM_NAME=HealthKMP
2121
POM_DESCRIPTION=Wrapper for HealthKit on iOS and Google Fit and Health Connect on Android

health/api/health.api

Lines changed: 150 additions & 0 deletions
Large diffs are not rendered by default.

health/api/health.klib.api

Lines changed: 187 additions & 0 deletions
Large diffs are not rendered by default.

health/src/androidMain/kotlin/com/viktormykhailiv/kmp/health/Aggregation.kt

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,48 @@ package com.viktormykhailiv.kmp.health
33
import androidx.health.connect.client.aggregate.AggregateMetric
44
import androidx.health.connect.client.aggregate.AggregationResult
55
import androidx.health.connect.client.records.BloodPressureRecord
6+
import androidx.health.connect.client.records.CyclingPedalingCadenceRecord
67
import androidx.health.connect.client.records.HeartRateRecord
78
import androidx.health.connect.client.records.HeightRecord
9+
import androidx.health.connect.client.records.PowerRecord
810
import androidx.health.connect.client.records.SleepSessionRecord
911
import androidx.health.connect.client.records.StepsRecord
1012
import androidx.health.connect.client.records.WeightRecord
1113
import com.viktormykhailiv.kmp.health.HealthDataType.BloodGlucose
1214
import com.viktormykhailiv.kmp.health.HealthDataType.BloodPressure
1315
import com.viktormykhailiv.kmp.health.HealthDataType.BodyFat
1416
import com.viktormykhailiv.kmp.health.HealthDataType.BodyTemperature
17+
import com.viktormykhailiv.kmp.health.HealthDataType.CyclingPedalingCadence
1518
import com.viktormykhailiv.kmp.health.HealthDataType.Exercise
1619
import com.viktormykhailiv.kmp.health.HealthDataType.HeartRate
1720
import com.viktormykhailiv.kmp.health.HealthDataType.Height
1821
import com.viktormykhailiv.kmp.health.HealthDataType.LeanBodyMass
22+
import com.viktormykhailiv.kmp.health.HealthDataType.Power
1923
import com.viktormykhailiv.kmp.health.HealthDataType.Sleep
2024
import com.viktormykhailiv.kmp.health.HealthDataType.Steps
2125
import com.viktormykhailiv.kmp.health.HealthDataType.Weight
2226
import com.viktormykhailiv.kmp.health.aggregate.BloodGlucoseAggregatedRecord
2327
import com.viktormykhailiv.kmp.health.aggregate.BloodPressureAggregatedRecord
2428
import com.viktormykhailiv.kmp.health.aggregate.BodyFatAggregatedRecord
2529
import com.viktormykhailiv.kmp.health.aggregate.BodyTemperatureAggregatedRecord
30+
import com.viktormykhailiv.kmp.health.aggregate.CyclingPedalingCadenceAggregatedRecord
2631
import com.viktormykhailiv.kmp.health.aggregate.HeartRateAggregatedRecord
2732
import com.viktormykhailiv.kmp.health.aggregate.HeightAggregatedRecord
2833
import com.viktormykhailiv.kmp.health.aggregate.LeanBodyMassAggregatedRecord
34+
import com.viktormykhailiv.kmp.health.aggregate.PowerAggregatedRecord
2935
import com.viktormykhailiv.kmp.health.aggregate.SleepAggregatedRecord
3036
import com.viktormykhailiv.kmp.health.aggregate.StepsAggregatedRecord
3137
import com.viktormykhailiv.kmp.health.aggregate.WeightAggregatedRecord
38+
import com.viktormykhailiv.kmp.health.units.BloodGlucose as BloodGlucoseUnit
3239
import com.viktormykhailiv.kmp.health.units.Mass
3340
import com.viktormykhailiv.kmp.health.units.Temperature
34-
import com.viktormykhailiv.kmp.health.units.BloodGlucose as BloodGlucoseUnit
3541
import com.viktormykhailiv.kmp.health.units.kilograms
3642
import com.viktormykhailiv.kmp.health.units.meters
3743
import com.viktormykhailiv.kmp.health.units.millimetersOfMercury
3844
import com.viktormykhailiv.kmp.health.units.percent
39-
import kotlin.time.Instant
45+
import com.viktormykhailiv.kmp.health.units.watts
4046
import kotlin.time.Duration.Companion.seconds
47+
import kotlin.time.Instant
4148
import kotlin.time.toKotlinDuration
4249

4350
/**
@@ -65,6 +72,13 @@ internal fun HealthDataType.toAggregateMetrics(): Set<AggregateMetric<Any>> = wh
6572
BodyTemperature ->
6673
throw IllegalArgumentException("Aggregated BodyTemperature is not supported and must be aggregated manually")
6774

75+
CyclingPedalingCadence ->
76+
setOf(
77+
CyclingPedalingCadenceRecord.RPM_AVG,
78+
CyclingPedalingCadenceRecord.RPM_MIN,
79+
CyclingPedalingCadenceRecord.RPM_MAX
80+
)
81+
6882
is Exercise ->
6983
throw IllegalArgumentException("Aggregated Exercise is not supported and must be aggregated manually")
7084

@@ -77,6 +91,9 @@ internal fun HealthDataType.toAggregateMetrics(): Set<AggregateMetric<Any>> = wh
7791
LeanBodyMass ->
7892
throw IllegalArgumentException("Aggregated LeanBodyMass is not supported and must be aggregated manually")
7993

94+
Power ->
95+
setOf(PowerRecord.POWER_AVG, PowerRecord.POWER_MIN, PowerRecord.POWER_MAX)
96+
8097
Sleep ->
8198
setOf(SleepSessionRecord.SLEEP_DURATION_TOTAL)
8299

@@ -129,6 +146,16 @@ internal fun AggregationResult.toHealthAggregatedRecord(
129146
is BodyTemperature ->
130147
throw IllegalArgumentException("Aggregated BodyTemperature is not supported and must be aggregated manually")
131148

149+
is CyclingPedalingCadence -> {
150+
CyclingPedalingCadenceAggregatedRecord(
151+
startTime = startTime,
152+
endTime = endTime,
153+
avg = get(CyclingPedalingCadenceRecord.RPM_AVG) ?: 0.0,
154+
min = get(CyclingPedalingCadenceRecord.RPM_MIN) ?: 0.0,
155+
max = get(CyclingPedalingCadenceRecord.RPM_MAX) ?: 0.0,
156+
)
157+
}
158+
132159
is Exercise ->
133160
throw IllegalArgumentException("Aggregated Exercise is not supported and must be aggregated manually")
134161

@@ -155,6 +182,16 @@ internal fun AggregationResult.toHealthAggregatedRecord(
155182
is LeanBodyMass ->
156183
throw IllegalArgumentException("Aggregated LeanBodyMass is not supported and must be aggregated manually")
157184

185+
is Power -> {
186+
PowerAggregatedRecord(
187+
startTime = startTime,
188+
endTime = endTime,
189+
avg = get(PowerRecord.POWER_AVG)?.toPower() ?: 0.watts,
190+
min = get(PowerRecord.POWER_MIN)?.toPower() ?: 0.watts,
191+
max = get(PowerRecord.POWER_MAX)?.toPower() ?: 0.watts,
192+
)
193+
}
194+
158195
is Sleep -> {
159196
SleepAggregatedRecord(
160197
startTime = startTime,

health/src/androidMain/kotlin/com/viktormykhailiv/kmp/health/HealthConnectDataType.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import androidx.health.connect.client.records.BloodGlucoseRecord
55
import androidx.health.connect.client.records.BloodPressureRecord
66
import androidx.health.connect.client.records.BodyFatRecord
77
import androidx.health.connect.client.records.BodyTemperatureRecord
8+
import androidx.health.connect.client.records.CyclingPedalingCadenceRecord
89
import androidx.health.connect.client.records.ExerciseSessionRecord
910
import androidx.health.connect.client.records.HeartRateRecord
1011
import androidx.health.connect.client.records.HeightRecord
1112
import androidx.health.connect.client.records.LeanBodyMassRecord
13+
import androidx.health.connect.client.records.PowerRecord
1214
import androidx.health.connect.client.records.Record
1315
import androidx.health.connect.client.records.SleepSessionRecord
1416
import androidx.health.connect.client.records.StepsRecord
@@ -21,6 +23,8 @@ import com.viktormykhailiv.kmp.health.HealthDataType.Exercise
2123
import com.viktormykhailiv.kmp.health.HealthDataType.HeartRate
2224
import com.viktormykhailiv.kmp.health.HealthDataType.Height
2325
import com.viktormykhailiv.kmp.health.HealthDataType.LeanBodyMass
26+
import com.viktormykhailiv.kmp.health.HealthDataType.CyclingPedalingCadence
27+
import com.viktormykhailiv.kmp.health.HealthDataType.Power
2428
import com.viktormykhailiv.kmp.health.HealthDataType.Sleep
2529
import com.viktormykhailiv.kmp.health.HealthDataType.Steps
2630
import com.viktormykhailiv.kmp.health.HealthDataType.Weight
@@ -35,6 +39,8 @@ internal fun HealthDataType.toRecordType(): KClass<out Record> = when (this) {
3539

3640
BodyTemperature -> BodyTemperatureRecord::class
3741

42+
CyclingPedalingCadence -> CyclingPedalingCadenceRecord::class
43+
3844
is Exercise -> ExerciseSessionRecord::class
3945

4046
HeartRate -> HeartRateRecord::class
@@ -43,6 +49,8 @@ internal fun HealthDataType.toRecordType(): KClass<out Record> = when (this) {
4349

4450
LeanBodyMass -> LeanBodyMassRecord::class
4551

52+
Power -> PowerRecord::class
53+
4654
Sleep -> SleepSessionRecord::class
4755

4856
Steps -> StepsRecord::class

health/src/androidMain/kotlin/com/viktormykhailiv/kmp/health/legacy/GoogleFitDataType.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import com.viktormykhailiv.kmp.health.HealthDataType.Exercise
1111
import com.viktormykhailiv.kmp.health.HealthDataType.HeartRate
1212
import com.viktormykhailiv.kmp.health.HealthDataType.Height
1313
import com.viktormykhailiv.kmp.health.HealthDataType.LeanBodyMass
14+
import com.viktormykhailiv.kmp.health.HealthDataType.CyclingPedalingCadence
15+
import com.viktormykhailiv.kmp.health.HealthDataType.Power
1416
import com.viktormykhailiv.kmp.health.HealthDataType.Sleep
1517
import com.viktormykhailiv.kmp.health.HealthDataType.Steps
1618
import com.viktormykhailiv.kmp.health.HealthDataType.Weight
@@ -44,6 +46,8 @@ internal fun HealthDataType.toDataType(): DataType = when (this) {
4446

4547
BodyTemperature -> throw IllegalArgumentException("BodyTemperature is not supported")
4648

49+
CyclingPedalingCadence -> throw IllegalArgumentException("PedalingCadence is not supported")
50+
4751
is Exercise -> throw IllegalArgumentException("Exercise is not supported")
4852

4953
HeartRate -> DataType.TYPE_HEART_RATE_BPM
@@ -52,6 +56,8 @@ internal fun HealthDataType.toDataType(): DataType = when (this) {
5256

5357
LeanBodyMass -> throw IllegalArgumentException("LeanBodyMass is not supported")
5458

59+
Power -> throw IllegalArgumentException("Power is not supported")
60+
5561
Sleep -> DataType.TYPE_SLEEP_SEGMENT
5662

5763
Steps -> DataType.TYPE_STEP_COUNT_DELTA

health/src/androidMain/kotlin/com/viktormykhailiv/kmp/health/legacy/mapping.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import android.content.Context
44
import com.google.android.gms.fitness.data.DataPoint
55
import com.google.android.gms.fitness.data.DataSet
66
import com.google.android.gms.fitness.data.DataSource
7-
import com.google.android.gms.fitness.data.Device as FitnessDevice
87
import com.google.android.gms.fitness.data.Field
98
import com.google.android.gms.fitness.data.SleepStages
109
import com.viktormykhailiv.kmp.health.HealthDataType
@@ -16,6 +15,8 @@ import com.viktormykhailiv.kmp.health.HealthDataType.Exercise
1615
import com.viktormykhailiv.kmp.health.HealthDataType.HeartRate
1716
import com.viktormykhailiv.kmp.health.HealthDataType.Height
1817
import com.viktormykhailiv.kmp.health.HealthDataType.LeanBodyMass
18+
import com.viktormykhailiv.kmp.health.HealthDataType.CyclingPedalingCadence
19+
import com.viktormykhailiv.kmp.health.HealthDataType.Power
1920
import com.viktormykhailiv.kmp.health.HealthDataType.Sleep
2021
import com.viktormykhailiv.kmp.health.HealthDataType.Steps
2122
import com.viktormykhailiv.kmp.health.HealthDataType.Weight
@@ -35,8 +36,9 @@ import com.viktormykhailiv.kmp.health.records.metadata.getLocalDevice
3536
import com.viktormykhailiv.kmp.health.units.Length
3637
import com.viktormykhailiv.kmp.health.units.Mass
3738
import com.viktormykhailiv.kmp.health.units.percent
38-
import kotlin.time.Instant
3939
import java.util.concurrent.TimeUnit
40+
import kotlin.time.Instant
41+
import com.google.android.gms.fitness.data.Device as FitnessDevice
4042

4143
internal fun List<DataPoint>.toHealthRecords(type: HealthDataType): List<HealthRecord> {
4244
return when (type) {
@@ -59,6 +61,9 @@ internal fun List<DataPoint>.toHealthRecords(type: HealthDataType): List<HealthR
5961
is BodyTemperature ->
6062
throw IllegalArgumentException("BodyTemperature is not supported")
6163

64+
is CyclingPedalingCadence ->
65+
throw IllegalArgumentException("PedalingCadence is not supported")
66+
6267
is Exercise ->
6368
throw IllegalArgumentException("Exercise is not supported")
6469

@@ -93,6 +98,9 @@ internal fun List<DataPoint>.toHealthRecords(type: HealthDataType): List<HealthR
9398
is LeanBodyMass ->
9499
throw IllegalArgumentException("LeanBodyMass is not supported")
95100

101+
is Power ->
102+
throw IllegalArgumentException("Power is not supported")
103+
96104
is Sleep -> {
97105
val metadata = firstOrNull().toMetadata()
98106
map { dataPoint ->

0 commit comments

Comments
 (0)