diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f8e41b1..594a42b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -72,7 +72,7 @@ tasks.register("generateManifest") { "latestVersionCode" to android.defaultConfig.versionCode, "developer" to "github.com/timklge", "description" to "Open-source extension that adds colored power or heart rate progress bars to the edges of the screen, similar to the LEDs on Wahoo computers", - "releaseNotes" to "* Show zero value on bars to indicate sensor availability\n* Fix pedal balance values\n* Add pedal balance data source\n* Add option to split bars", + "releaseNotes" to "* Add gear data sources\n* Show zero value on bars to indicate sensor availability\n* Fix pedal balance values\n* Add pedal balance data source\n* Add option to split bars", "screenshotUrls" to listOf( "$baseUrl/powerbar_min.gif", "$baseUrl/powerbar0.png", diff --git a/app/src/main/kotlin/de/timklge/karoopowerbar/Window.kt b/app/src/main/kotlin/de/timklge/karoopowerbar/Window.kt index 7a28143..e394abf 100644 --- a/app/src/main/kotlin/de/timklge/karoopowerbar/Window.kt +++ b/app/src/main/kotlin/de/timklge/karoopowerbar/Window.kt @@ -189,6 +189,8 @@ class Window( SelectedSource.REMAINING_ROUTE -> streamRouteProgress(SelectedSource.REMAINING_ROUTE, ::getRemainingRouteProgress) SelectedSource.GRADE -> streamGrade() SelectedSource.POWER_BALANCE -> streamBalance() + SelectedSource.FRONT_GEAR -> streamGears(Gears.FRONT) + SelectedSource.REAR_GEAR -> streamGears(Gears.REAR) SelectedSource.NONE -> {} } }) @@ -337,6 +339,58 @@ class Window( } } + enum class Gears(val prefix: String, val dataTypeId: String, val numberFieldId: String, val maxFieldId: String) { + FRONT("F", DataType.Type.SHIFTING_FRONT_GEAR, DataType.Field.SHIFTING_FRONT_GEAR, DataType.Field.SHIFTING_FRONT_GEAR_MAX), + REAR("R", DataType.Type.SHIFTING_REAR_GEAR, DataType.Field.SHIFTING_REAR_GEAR, DataType.Field.SHIFTING_REAR_GEAR_MAX) + } + + private suspend fun streamGears(gears: Gears) { + data class GearsState(val currentGear: Int?, val maxGear: Int?, val colorize: Boolean) + data class StreamState(val settings: PowerbarSettings, val streamState: io.hammerhead.karooext.models.StreamState?) + + val gearsSource = when (gears) { + Gears.FRONT -> SelectedSource.FRONT_GEAR + Gears.REAR -> SelectedSource.REAR_GEAR + } + + combine(context.streamSettings(), karooSystem.streamDataFlow(gears.dataTypeId)) { settings, streamState -> StreamState(settings, streamState) } + .map { (settings, streamState) -> + val valueMap = (streamState as? io.hammerhead.karooext.models.StreamState.Streaming)?.dataPoint?.values + + valueMap?.let { + GearsState(valueMap[gears.numberFieldId]?.toInt(), valueMap[gears.maxFieldId]?.toInt(), settings.useZoneColors) + } + + // if (gears == Gears.FRONT) GearsState(1, 2, settings.useZoneColors) else GearsState(6, 12, settings.useZoneColors) + } + .distinctUntilChanged().collect { gearState -> + val powerbarsWithGearsSource = powerbars.values.filter { it.source == gearsSource } + powerbarsWithGearsSource.forEach { powerbar -> + if (gearState?.currentGear != null) { + val currentGear = gearState.currentGear + val maxGear = gearState.maxGear ?: gearState.currentGear + val progress = remap(currentGear.toDouble(), 1.0, maxGear.toDouble(), 0.0, 1.0) + + powerbar.progressColor = if (gearState.colorize) { + progress?.let { context.getColor(getZone(progress).colorResource) } ?: context.getColor(R.color.zone0) + } else { + context.getColor(R.color.zone0) + } + powerbar.progress = progress + powerbar.label = "${gears.prefix}${currentGear}" + + Log.d(TAG, "Gears ${gears.name}: $currentGear/$maxGear") + } else { + powerbar.progressColor = context.getColor(R.color.zone0) + powerbar.progress = null + powerbar.label = "?" + + Log.d(TAG, "Gears ${gears.name}: Unavailable") + } + } + } + } + private suspend fun streamSpeed(source: SelectedSource, smoothed: Boolean) { val speedFlow = karooSystem.streamDataFlow(if(smoothed) DataType.Type.SMOOTHED_3S_AVERAGE_SPEED else DataType.Type.SPEED) .map { (it as? StreamState.Streaming)?.dataPoint?.singleValue } diff --git a/app/src/main/kotlin/de/timklge/karoopowerbar/Zones.kt b/app/src/main/kotlin/de/timklge/karoopowerbar/Zones.kt index efdfa4e..d816364 100644 --- a/app/src/main/kotlin/de/timklge/karoopowerbar/Zones.kt +++ b/app/src/main/kotlin/de/timklge/karoopowerbar/Zones.kt @@ -36,4 +36,11 @@ fun getZone(userZones: List, value: Int): Zone? { } return null +} + +val zoneList = listOf(Zone.Zone0, Zone.Zone1, Zone.Zone2, Zone.Zone3, Zone.Zone4, Zone.Zone5, Zone.Zone6, Zone.Zone7, Zone.Zone8) + +fun getZone(progress: Double): Zone { + val index = (progress * zoneList.size).toInt().coerceIn(0, zoneList.size - 1) + return zoneList[index] } \ No newline at end of file diff --git a/app/src/main/kotlin/de/timklge/karoopowerbar/screens/MainScreen.kt b/app/src/main/kotlin/de/timklge/karoopowerbar/screens/MainScreen.kt index dea162a..91c1d66 100644 --- a/app/src/main/kotlin/de/timklge/karoopowerbar/screens/MainScreen.kt +++ b/app/src/main/kotlin/de/timklge/karoopowerbar/screens/MainScreen.kt @@ -90,7 +90,9 @@ enum class SelectedSource(val id: String, val label: String) { GRADE("grade", "Grade"), POWER_BALANCE("power_balance", "Power Balance"), ROUTE_PROGRESS("route_progress", "Route Progress"), - REMAINING_ROUTE("route_progress_remaining", "Route Remaining"); + REMAINING_ROUTE("route_progress_remaining", "Route Remaining"), + FRONT_GEAR("front_gear", "Front Gear"), + REAR_GEAR("rear_gear", "Rear Gear"); fun isPower() = this == POWER || this == POWER_3S || this == POWER_10S }