diff --git a/app/build.gradle.kts b/app/build.gradle.kts index d6ef023..289cf01 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -13,8 +13,8 @@ android { applicationId = "de.timklge.karoopowerbar" minSdk = 26 targetSdk = 33 - versionCode = 3 - versionName = "1.1.0" + versionCode = 4 + versionName = "1.1.1" } buildTypes { diff --git a/app/manifest.json b/app/manifest.json index 6b6dde9..34fc2bd 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -3,9 +3,9 @@ "packageName": "de.timklge.karoopowerbar", "iconUrl": "https://github.com/timklge/karoo-powerbar/releases/latest/download/karoo-powerbar.png", "latestApkUrl": "https://github.com/timklge/karoo-powerbar/releases/latest/download/app-release.apk", - "latestVersion": "1.1.0", - "latestVersionCode": 3, + "latestVersion": "1.1.1", + "latestVersionCode": 4, "developer": "timklge", "description": "Adds a colored power bar to the bottom of the screen", - "releaseNotes": "Add options to add secondary power bar and to hide bar when not riding" + "releaseNotes": "Add options to add secondary power bar and to hide bar when not riding. Fix manually set up power/hr zones." } \ No newline at end of file diff --git a/app/src/main/kotlin/de/timklge/karoopowerbar/KarooPowerbarExtension.kt b/app/src/main/kotlin/de/timklge/karoopowerbar/KarooPowerbarExtension.kt index 9ecf3aa..ee5f8f6 100644 --- a/app/src/main/kotlin/de/timklge/karoopowerbar/KarooPowerbarExtension.kt +++ b/app/src/main/kotlin/de/timklge/karoopowerbar/KarooPowerbarExtension.kt @@ -10,7 +10,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch -class KarooPowerbarExtension : KarooExtension("karoo-powerbar", "1.1.0") { +class KarooPowerbarExtension : KarooExtension("karoo-powerbar", "1.1.1") { companion object { const val TAG = "karoo-powerbar" diff --git a/app/src/main/kotlin/de/timklge/karoopowerbar/Window.kt b/app/src/main/kotlin/de/timklge/karoopowerbar/Window.kt index 9ead8ec..d9114f3 100644 --- a/app/src/main/kotlin/de/timklge/karoopowerbar/Window.kt +++ b/app/src/main/kotlin/de/timklge/karoopowerbar/Window.kt @@ -27,6 +27,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import kotlin.math.roundToInt fun remap(value: Double, fromMin: Double, fromMax: Double, toMin: Double, toMax: Double): Double { return (value - fromMin) * (toMax - toMin) / (fromMax - fromMin) + toMin @@ -102,11 +103,11 @@ class Window( Log.i(TAG, "Karoo system service connected: $connected") } - powerbar.progressColor = context.resources.getColor(R.color.zoneAerobic) + powerbar.progressColor = context.resources.getColor(R.color.zone7) powerbar.progress = 0.0 powerbar.invalidate() - Log.i(KarooPowerbarExtension.TAG, "Streaming $selectedSource") + Log.i(TAG, "Streaming $selectedSource") when (selectedSource){ SelectedSource.POWER -> streamPower(PowerStreamSmoothing.RAW) @@ -124,7 +125,7 @@ class Window( } } } catch (e: Exception) { - Log.e(KarooPowerbarExtension.TAG, e.toString()) + Log.e(TAG, e.toString()) } } @@ -139,20 +140,21 @@ class Window( .map { (userProfile, hr) -> StreamData(userProfile, hr) } .distinctUntilChanged() .collect { streamData -> + val value = streamData.value.roundToInt() val color = context.getColor( - streamData.userProfile.getUserHrZone(streamData.value.toInt())?.colorResource - ?: R.color.zoneAerobic + streamData.userProfile.getZone(streamData.userProfile.heartRateZones, value)?.colorResource + ?: R.color.zone7 ) val minHr = streamData.userProfile.restingHr val maxHr = streamData.userProfile.maxHr val progress = - remap(streamData.value, minHr.toDouble(), maxHr.toDouble(), 0.0, 1.0) + remap(value.toDouble(), minHr.toDouble(), maxHr.toDouble(), 0.0, 1.0) powerbar.progressColor = color powerbar.progress = progress powerbar.invalidate() - Log.d(KarooPowerbarExtension.TAG, "Hr: ${streamData.value} min: $minHr max: $maxHr") + Log.d(TAG, "Hr: $value min: $minHr max: $maxHr") } } @@ -173,20 +175,21 @@ class Window( .map { (userProfile, power) -> StreamData(userProfile, power) } .distinctUntilChanged() .collect { streamData -> + val value = streamData.value.roundToInt() val color = context.getColor( - streamData.userProfile.getUserPowerZone(streamData.value.toInt())?.colorResource - ?: R.color.zoneAerobic + streamData.userProfile.getZone(streamData.userProfile.powerZones, value)?.colorResource + ?: R.color.zone7 ) val minPower = streamData.userProfile.powerZones.first().min val maxPower = streamData.userProfile.powerZones.last().min + 50 val progress = - remap(streamData.value, minPower.toDouble(), maxPower.toDouble(), 0.0, 1.0) + remap(value.toDouble(), minPower.toDouble(), maxPower.toDouble(), 0.0, 1.0) powerbar.progressColor = color powerbar.progress = progress powerbar.invalidate() - Log.d(KarooPowerbarExtension.TAG, "Power: ${streamData.value} min: $minPower max: $maxPower") + Log.d(TAG, "Power: ${value} min: $minPower max: $maxPower") } } @@ -197,7 +200,7 @@ class Window( rootView.invalidate() (rootView.parent as ViewGroup).removeAllViews() } catch (e: Exception) { - Log.d(KarooPowerbarExtension.TAG, e.toString()) + Log.d(TAG, e.toString()) } } } \ No newline at end of file diff --git a/app/src/main/kotlin/de/timklge/karoopowerbar/Zones.kt b/app/src/main/kotlin/de/timklge/karoopowerbar/Zones.kt index 3a35ef4..e14bf64 100644 --- a/app/src/main/kotlin/de/timklge/karoopowerbar/Zones.kt +++ b/app/src/main/kotlin/de/timklge/karoopowerbar/Zones.kt @@ -2,38 +2,36 @@ package de.timklge.karoopowerbar import io.hammerhead.karooext.models.UserProfile -enum class PowerZone(val colorResource: Int) { - ACTIVE_RECOVERY(R.color.zoneActiveRecovery), - ENDURANCE(R.color.zoneEndurance), - TEMPO(R.color.zoneTempo), - THRESHOLD(R.color.zoneThreshold), - VO2_MAX(R.color.zoneVO2Max), - AEROBIC_CAPACITY(R.color.zoneAerobic), - ANAEROBIC_CAPACITY(R.color.zoneAnaerobic), +enum class Zone(val colorResource: Int){ + Zone0(R.color.zone0), + Zone1(R.color.zone1), + Zone2(R.color.zone2), + Zone3(R.color.zone3), + Zone4(R.color.zone4), + Zone5(R.color.zone5), + Zone6(R.color.zone6), + Zone7(R.color.zone7), + Zone8(R.color.zone8), } -enum class HrZone(val colorResource: Int) { - ACTIVE_RECOVERY(R.color.zoneActiveRecovery), - ENDURANCE(R.color.zoneEndurance), - TEMPO(R.color.zoneTempo), - THRESHOLD(R.color.zoneThreshold), - VO2_MAX(R.color.zoneAerobic), -} +val zones = mapOf( + 1 to listOf(Zone.Zone7), + 2 to listOf(Zone.Zone1, Zone.Zone7), + 3 to listOf(Zone.Zone1, Zone.Zone3, Zone.Zone7), + 4 to listOf(Zone.Zone1, Zone.Zone3, Zone.Zone5, Zone.Zone7), + 5 to listOf(Zone.Zone1, Zone.Zone2, Zone.Zone3, Zone.Zone5, Zone.Zone7), + 6 to listOf(Zone.Zone1, Zone.Zone2, Zone.Zone3, Zone.Zone5, Zone.Zone7, Zone.Zone8), + 7 to listOf(Zone.Zone1, Zone.Zone2, Zone.Zone3, Zone.Zone5, Zone.Zone6, Zone.Zone7, Zone.Zone8), + 8 to listOf(Zone.Zone0, Zone.Zone1, Zone.Zone2, Zone.Zone3, Zone.Zone5, Zone.Zone6, Zone.Zone7, Zone.Zone8), + 9 to listOf(Zone.Zone0, Zone.Zone1, Zone.Zone2, Zone.Zone3, Zone.Zone4, Zone.Zone5, Zone.Zone6, Zone.Zone7, Zone.Zone8) +) -fun UserProfile.getUserPowerZone(power: Int): PowerZone? { - powerZones.forEachIndexed { index, zone -> - if (power in zone.min..zone.max) { - return PowerZone.entries[index] - } - } +fun UserProfile.getZone(userZones: List, value: Int): Zone? { + val zoneList = zones[userZones.size] ?: return null - return null -} - -fun UserProfile.getUserHrZone(hr: Int): HrZone? { - heartRateZones.forEachIndexed { index, zone -> - if (hr in zone.min..zone.max) { - return HrZone.entries[index] + userZones.forEachIndexed { index, zone -> + if (value in zone.min..zone.max) { + return zoneList.getOrNull(index) ?: Zone.Zone7 } } diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index bfe7ce8..be7bb44 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,11 +3,13 @@ #6200EE #2600B3 - #00B988 - #60EEB2 - #FFF500 - #FB8C65 - #FE581F - #D60404 - #B700A2 + #2386D9 + #00B988 + #60EEB2 + #FFF500 + #FDC84C + #FB8C65 + #FE581F + #D60404 + #B700A2 \ No newline at end of file