Reduce refresh rate on K2, add refresh rate setting (#117)
* Reduce refresh rate on K2, add refresh rate setting * Set default k2 update interval to 2s
This commit is contained in:
parent
21d06aab3a
commit
c4a23ce456
@ -93,11 +93,10 @@ tasks.register("generateManifest") {
|
||||
"latestVersionCode" to android.defaultConfig.versionCode,
|
||||
"developer" to "github.com/timklge",
|
||||
"description" to "Open-source extension that provides headwind direction, wind speed, forecast and other weather data fields.",
|
||||
"releaseNotes" to "* Fix weather data download from Open-Meteo via iOS companion app (thx @keefar!)\n" +
|
||||
"releaseNotes" to "* Reduce refresh rate on K2, add refresh rate setting\n" +
|
||||
"* Fix weather data download from Open-Meteo via iOS companion app (thx @keefar!)\n" +
|
||||
"* Remove custom wind speed unit setting and always use imperial / metric as set in profile\n" +
|
||||
"* Add relative grade, relative elevation gain data fields\n" +
|
||||
"* Fix precipitation forecast field\n" +
|
||||
"* Interpolate between forecasted and current weather data\n" +
|
||||
"* Add OpenWeatherMap support contributed by lockevod\n",
|
||||
"screenshotUrls" to listOf(
|
||||
"https://github.com/timklge/karoo-headwind/releases/latest/download/preview1.png",
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package de.timklge.karooheadwind
|
||||
|
||||
import de.timklge.karooheadwind.datatypes.GpsCoordinates
|
||||
import io.hammerhead.karooext.KarooSystemService
|
||||
import io.hammerhead.karooext.models.HardwareType
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
@ -62,6 +64,30 @@ data class HeadwindStats(
|
||||
}
|
||||
|
||||
|
||||
enum class RefreshRate(val id: String, val k2Ms: Long, val k3Ms: Long) {
|
||||
FAST("fast", 1_000L, 500L),
|
||||
STANDARD("medium", 2_000L, 1_000L),
|
||||
SLOW("slow", 5_000L, 3_000L),
|
||||
MINIMUM("minimum", 10_000L, 10_000L);
|
||||
|
||||
fun getDescription(karooSystemService: KarooSystemService): String {
|
||||
return if (karooSystemService.hardwareType == HardwareType.K2) {
|
||||
when (this) {
|
||||
FAST -> "Fast (1s)"
|
||||
STANDARD -> "Standard (2s)"
|
||||
SLOW -> "Slow (5s)"
|
||||
MINIMUM -> "Minimum (10s)"
|
||||
}
|
||||
} else {
|
||||
when (this) {
|
||||
FAST -> "Fastest"
|
||||
STANDARD -> "Standard (1s)"
|
||||
SLOW -> "Slow (3s)"
|
||||
MINIMUM -> "Minimum (10s)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class HeadwindSettings(
|
||||
@ -74,7 +100,8 @@ data class HeadwindSettings(
|
||||
val lastUpdateRequested: Long? = null,
|
||||
val showDistanceInForecast: Boolean = true,
|
||||
val weatherProvider: WeatherDataProvider = WeatherDataProvider.OPEN_METEO,
|
||||
val openWeatherMapApiKey: String = ""
|
||||
val openWeatherMapApiKey: String = "",
|
||||
val refreshRate: RefreshRate = RefreshRate.STANDARD,
|
||||
){
|
||||
companion object {
|
||||
val defaultSettings = Json.encodeToString(HeadwindSettings())
|
||||
@ -85,8 +112,6 @@ data class HeadwindSettings(
|
||||
}
|
||||
}
|
||||
|
||||
//added openweathermap.org
|
||||
|
||||
@Serializable
|
||||
enum class WeatherDataProvider(val id: String, val label: String) {
|
||||
OPEN_METEO("open-meteo", "OpenMeteo"),
|
||||
|
||||
@ -194,7 +194,7 @@ abstract class ForecastDataType(private val karooSystem: KarooSystemService, typ
|
||||
context.streamCurrentForecastWeatherData(),
|
||||
settingsAndProfileStream,
|
||||
context.streamWidgetSettings(),
|
||||
karooSystem.getHeadingFlow(context).throttle(60_000L),
|
||||
karooSystem.getHeadingFlow(context).throttle(3 * 60_000L),
|
||||
karooSystem.streamUpcomingRoute().distinctUntilChanged { old, new ->
|
||||
val oldDistance = old?.distanceAlongRoute
|
||||
val newDistance = new?.distanceAlongRoute
|
||||
@ -202,7 +202,7 @@ abstract class ForecastDataType(private val karooSystem: KarooSystemService, typ
|
||||
if (oldDistance == null && newDistance == null) return@distinctUntilChanged true
|
||||
if (oldDistance == null || newDistance == null) return@distinctUntilChanged false
|
||||
|
||||
abs(oldDistance - newDistance) < 500
|
||||
abs(oldDistance - newDistance) < 1_000
|
||||
}
|
||||
) { weatherData, settings, widgetSettings, heading, upcomingRoute ->
|
||||
StreamData(
|
||||
|
||||
@ -13,12 +13,14 @@ import de.timklge.karooheadwind.WindDirectionIndicatorSetting
|
||||
import de.timklge.karooheadwind.getRelativeHeadingFlow
|
||||
import de.timklge.karooheadwind.streamCurrentWeatherData
|
||||
import de.timklge.karooheadwind.streamSettings
|
||||
import de.timklge.karooheadwind.throttle
|
||||
import io.hammerhead.karooext.KarooSystemService
|
||||
import io.hammerhead.karooext.extension.DataTypeImpl
|
||||
import io.hammerhead.karooext.internal.Emitter
|
||||
import io.hammerhead.karooext.internal.ViewEmitter
|
||||
import io.hammerhead.karooext.models.DataPoint
|
||||
import io.hammerhead.karooext.models.DataType
|
||||
import io.hammerhead.karooext.models.HardwareType
|
||||
import io.hammerhead.karooext.models.StreamState
|
||||
import io.hammerhead.karooext.models.UpdateGraphicConfig
|
||||
import io.hammerhead.karooext.models.ViewConfig
|
||||
@ -29,6 +31,7 @@ import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.emitAll
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.roundToInt
|
||||
@ -139,7 +142,9 @@ class HeadwindDirectionDataType(
|
||||
}
|
||||
|
||||
val viewJob = CoroutineScope(Dispatchers.IO).launch {
|
||||
flow.collect { streamData ->
|
||||
val refreshRate = karooSystem.getRefreshRateInMilliseconds(context)
|
||||
|
||||
flow.throttle(refreshRate).collect { streamData ->
|
||||
Log.d(KarooHeadwindExtension.TAG, "Updating headwind direction view")
|
||||
|
||||
val errorCode = streamData.bearing.let { if(it < 0) it.toInt() else null }
|
||||
@ -177,4 +182,15 @@ class HeadwindDirectionDataType(
|
||||
const val ERROR_NO_WEATHER_DATA = -2
|
||||
const val ERROR_APP_NOT_SET_UP = -3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun KarooSystemService.getRefreshRateInMilliseconds(context: Context): Long {
|
||||
val refreshRate = context.streamSettings(this).first().refreshRate
|
||||
val isK2 = hardwareType == HardwareType.K2
|
||||
|
||||
return if (isK2){
|
||||
refreshRate.k2Ms
|
||||
} else {
|
||||
refreshRate.k3Ms
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import de.timklge.karooheadwind.streamCurrentWeatherData
|
||||
import de.timklge.karooheadwind.streamDataFlow
|
||||
import de.timklge.karooheadwind.streamSettings
|
||||
import de.timklge.karooheadwind.streamUserProfile
|
||||
import de.timklge.karooheadwind.throttle
|
||||
import io.hammerhead.karooext.KarooSystemService
|
||||
import io.hammerhead.karooext.extension.DataTypeImpl
|
||||
import io.hammerhead.karooext.internal.ViewEmitter
|
||||
@ -73,14 +74,7 @@ class TailwindAndRideSpeedDataType(
|
||||
) : DataTypeImpl("karoo-headwind", "tailwind-and-ride-speed") {
|
||||
private val glance = GlanceRemoteViews()
|
||||
|
||||
data class StreamData(val headingResponse: HeadingResponse,
|
||||
val absoluteWindDirection: Double?,
|
||||
val windSpeed: Double?,
|
||||
val settings: HeadwindSettings?,
|
||||
val rideSpeed: Double? = null,
|
||||
val isImperial: Boolean? = null)
|
||||
|
||||
private fun previewFlow(profileFlow: Flow<UserProfile>): Flow<de.timklge.karooheadwind.datatypes.TailwindDataType.StreamData> {
|
||||
private fun previewFlow(profileFlow: Flow<UserProfile>): Flow<StreamData> {
|
||||
return flow {
|
||||
val profile = profileFlow.first()
|
||||
|
||||
@ -137,7 +131,8 @@ class TailwindAndRideSpeedDataType(
|
||||
val viewJob = CoroutineScope(Dispatchers.IO).launch {
|
||||
emitter.onNext(ShowCustomStreamState("", null))
|
||||
|
||||
flow.collect { streamData ->
|
||||
val refreshRate = karooSystem.getRefreshRateInMilliseconds(context)
|
||||
flow.throttle(refreshRate).collect { streamData ->
|
||||
Log.d(KarooHeadwindExtension.TAG, "Updating headwind direction view")
|
||||
|
||||
val value = (streamData.headingResponse as? HeadingResponse.Value)?.diff
|
||||
|
||||
@ -19,6 +19,7 @@ import de.timklge.karooheadwind.streamCurrentWeatherData
|
||||
import de.timklge.karooheadwind.streamDataFlow
|
||||
import de.timklge.karooheadwind.streamSettings
|
||||
import de.timklge.karooheadwind.streamUserProfile
|
||||
import de.timklge.karooheadwind.throttle
|
||||
import io.hammerhead.karooext.KarooSystemService
|
||||
import io.hammerhead.karooext.extension.DataTypeImpl
|
||||
import io.hammerhead.karooext.internal.ViewEmitter
|
||||
@ -115,7 +116,8 @@ class TailwindDataType(
|
||||
val viewJob = CoroutineScope(Dispatchers.IO).launch {
|
||||
emitter.onNext(ShowCustomStreamState("", null))
|
||||
|
||||
flow.collect { streamData ->
|
||||
val refreshRate = karooSystem.getRefreshRateInMilliseconds(context)
|
||||
flow.throttle(refreshRate).collect { streamData ->
|
||||
Log.d(KarooHeadwindExtension.TAG, "Updating tailwind direction view")
|
||||
|
||||
val value = (streamData.headingResponse as? HeadingResponse.Value)?.diff
|
||||
|
||||
@ -39,11 +39,11 @@ import androidx.compose.ui.window.Dialog
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import de.timklge.karooheadwind.HeadwindSettings
|
||||
import de.timklge.karooheadwind.KarooHeadwindExtension
|
||||
import de.timklge.karooheadwind.RefreshRate
|
||||
import de.timklge.karooheadwind.RoundLocationSetting
|
||||
import de.timklge.karooheadwind.WeatherDataProvider
|
||||
import de.timklge.karooheadwind.WindDirectionIndicatorSetting
|
||||
import de.timklge.karooheadwind.WindDirectionIndicatorTextSetting
|
||||
import de.timklge.karooheadwind.WindUnit
|
||||
import de.timklge.karooheadwind.datatypes.GpsCoordinates
|
||||
import de.timklge.karooheadwind.saveSettings
|
||||
import de.timklge.karooheadwind.streamSettings
|
||||
@ -63,6 +63,7 @@ fun SettingsScreen(onFinish: () -> Unit) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val karooSystem = remember { KarooSystemService(ctx) }
|
||||
|
||||
var refreshRateSetting by remember { mutableStateOf(RefreshRate.STANDARD) }
|
||||
var selectedWindDirectionIndicatorTextSetting by remember {
|
||||
mutableStateOf(
|
||||
WindDirectionIndicatorTextSetting.HEADWIND_SPEED
|
||||
@ -73,6 +74,7 @@ fun SettingsScreen(onFinish: () -> Unit) {
|
||||
WindDirectionIndicatorSetting.HEADWIND_DIRECTION
|
||||
)
|
||||
}
|
||||
|
||||
var selectedRoundLocationSetting by remember { mutableStateOf(RoundLocationSetting.KM_3) }
|
||||
var forecastKmPerHour by remember { mutableStateOf("20") }
|
||||
var forecastMilesPerHour by remember { mutableStateOf("12") }
|
||||
@ -93,6 +95,7 @@ fun SettingsScreen(onFinish: () -> Unit) {
|
||||
showDistanceInForecast = settings.showDistanceInForecast
|
||||
selectedWeatherProvider = settings.weatherProvider
|
||||
openWeatherMapApiKey = settings.openWeatherMapApiKey
|
||||
refreshRateSetting = settings.refreshRate
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,7 +123,8 @@ fun SettingsScreen(onFinish: () -> Unit) {
|
||||
forecastedKmPerHour = forecastKmPerHour.toIntOrNull()?.coerceIn(5, 50) ?: 20,
|
||||
showDistanceInForecast = showDistanceInForecast,
|
||||
weatherProvider = selectedWeatherProvider,
|
||||
openWeatherMapApiKey = openWeatherMapApiKey
|
||||
openWeatherMapApiKey = openWeatherMapApiKey,
|
||||
refreshRate = refreshRateSetting,
|
||||
)
|
||||
|
||||
saveSettings(ctx, newSettings)
|
||||
@ -147,15 +151,26 @@ fun SettingsScreen(onFinish: () -> Unit) {
|
||||
.verticalScroll(rememberScrollState())
|
||||
.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||
) {
|
||||
val refreshRateDropdownOptions = RefreshRate.entries.toList().map { unit -> DropdownOption(unit.id, unit.getDescription(karooSystem)) }
|
||||
val refreshRateSelection by remember(refreshRateSetting) {
|
||||
mutableStateOf(refreshRateDropdownOptions.find { option -> option.id == refreshRateSetting.id }!!)
|
||||
}
|
||||
Dropdown(
|
||||
label = "Refresh Rate",
|
||||
options = refreshRateDropdownOptions,
|
||||
selected = refreshRateSelection
|
||||
) { selectedOption ->
|
||||
refreshRateSetting =
|
||||
RefreshRate.entries.find { unit -> unit.id == selectedOption.id }!!
|
||||
}
|
||||
|
||||
val windDirectionIndicatorSettingDropdownOptions =
|
||||
WindDirectionIndicatorSetting.entries.toList()
|
||||
.map { unit -> DropdownOption(unit.id, unit.label) }
|
||||
WindDirectionIndicatorSetting.entries.toList().map { unit -> DropdownOption(unit.id, unit.label) }
|
||||
val windDirectionIndicatorSettingSelection by remember(selectedWindDirectionIndicatorSetting) {
|
||||
mutableStateOf(windDirectionIndicatorSettingDropdownOptions.find { option -> option.id == selectedWindDirectionIndicatorSetting.id }!!)
|
||||
}
|
||||
Dropdown(
|
||||
label = "Wind direction indicator",
|
||||
label = "Wind Direction Indicator",
|
||||
options = windDirectionIndicatorSettingDropdownOptions,
|
||||
selected = windDirectionIndicatorSettingSelection
|
||||
) { selectedOption ->
|
||||
@ -172,7 +187,7 @@ fun SettingsScreen(onFinish: () -> Unit) {
|
||||
mutableStateOf(windDirectionIndicatorTextSettingDropdownOptions.find { option -> option.id == selectedWindDirectionIndicatorTextSetting.id }!!)
|
||||
}
|
||||
Dropdown(
|
||||
label = "Text on headwind indicator",
|
||||
label = "Text on Headwind Indicator",
|
||||
options = windDirectionIndicatorTextSettingDropdownOptions,
|
||||
selected = windDirectionIndicatorTextSettingSelection
|
||||
) { selectedOption ->
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user