From 223157a3f85cef9c1c62b8524a3edc17a838fdee Mon Sep 17 00:00:00 2001 From: Tim Kluge Date: Fri, 13 Dec 2024 23:19:20 +0100 Subject: [PATCH] ref #5: Set alignment of absolute wind direction field, add preview mode --- .../datatypes/HeadwindDirectionDataType.kt | 36 +++++++-- .../datatypes/WindDirectionDataType.kt | 76 ++++++++++++------- 2 files changed, 80 insertions(+), 32 deletions(-) diff --git a/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/HeadwindDirectionDataType.kt b/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/HeadwindDirectionDataType.kt index 4408b27..d1e9f75 100644 --- a/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/HeadwindDirectionDataType.kt +++ b/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/HeadwindDirectionDataType.kt @@ -8,6 +8,7 @@ import androidx.glance.appwidget.ExperimentalGlanceRemoteViewsApi import androidx.glance.appwidget.GlanceRemoteViews import de.timklge.karooheadwind.KarooHeadwindExtension import de.timklge.karooheadwind.OpenMeteoCurrentWeatherResponse +import de.timklge.karooheadwind.OpenMeteoData import de.timklge.karooheadwind.getRelativeHeadingFlow import de.timklge.karooheadwind.screens.HeadwindSettings import de.timklge.karooheadwind.streamCurrentWeatherData @@ -25,8 +26,11 @@ import io.hammerhead.karooext.models.ViewConfig import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.awaitCancellation +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.launch @@ -53,6 +57,21 @@ class HeadwindDirectionDataType( } } + data class StreamData(val value: Double, val windSpeed: Double, val settings: HeadwindSettings) + + private fun previewFlow(): Flow { + return flow { + while (true) { + val bearing = (0..360).random().toDouble() + val windSpeed = (-20..20).random() + + emit(StreamData(bearing, windSpeed.toDouble(), HeadwindSettings())) + delay(2_000) + } + } + } + + override fun startView(context: Context, config: ViewConfig, emitter: ViewEmitter) { Log.d(KarooHeadwindExtension.TAG, "Starting headwind direction view with $emitter") @@ -66,21 +85,26 @@ class HeadwindDirectionDataType( awaitCancellation() } - data class StreamData(val value: Double, val data: OpenMeteoCurrentWeatherResponse, val settings: HeadwindSettings) - - val viewJob = CoroutineScope(Dispatchers.IO).launch { + val flow = if (config.preview) { + previewFlow() + } else { karooSystem.streamDataFlow(dataTypeId) .mapNotNull { (it as? StreamState.Streaming)?.dataPoint?.singleValue } .combine(context.streamCurrentWeatherData()) { value, data -> value to data } - .combine(context.streamSettings(karooSystem)) { (value, data), settings -> StreamData(value, data, settings) } - .onCompletion { + .combine(context.streamSettings(karooSystem)) { (value, data), settings -> + StreamData(value, data.current.windSpeed, settings) + } + } + + val viewJob = CoroutineScope(Dispatchers.IO).launch { + flow.onCompletion { // Clear view on completion val result = glance.compose(context, DpSize.Unspecified) { } emitter.updateView(result.remoteViews) } .collect { streamData -> Log.d(KarooHeadwindExtension.TAG, "Updating headwind direction view") - val windSpeed = streamData.data.current.windSpeed + val windSpeed = streamData.windSpeed val windDirection = streamData.value val headwindSpeed = cos( (windDirection + 180) * Math.PI / 180.0) * windSpeed val windSpeedText = headwindSpeed.roundToInt().toString() diff --git a/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/WindDirectionDataType.kt b/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/WindDirectionDataType.kt index 8ec831c..df7184d 100644 --- a/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/WindDirectionDataType.kt +++ b/app/src/main/kotlin/de/timklge/karooheadwind/datatypes/WindDirectionDataType.kt @@ -27,6 +27,11 @@ import io.hammerhead.karooext.models.ViewConfig import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.awaitCancellation +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.launch import kotlin.math.roundToInt @@ -39,6 +44,15 @@ class WindDirectionDataType(val karooSystem: KarooSystemService, context: Contex return data.current.windDirection } + private fun previewFlow(): Flow { + return flow { + while (true) { + emit((0..360).random().toDouble()) + delay(1_000) + } + } + } + @OptIn(ExperimentalGlanceRemoteViewsApi::class) override fun startView(context: Context, config: ViewConfig, emitter: ViewEmitter) { val configJob = CoroutineScope(Dispatchers.IO).launch { @@ -47,37 +61,47 @@ class WindDirectionDataType(val karooSystem: KarooSystemService, context: Contex } val viewJob = CoroutineScope(Dispatchers.IO).launch { - karooSystem.streamDataFlow(dataTypeId) + val flow = if (config.preview){ + previewFlow() + } else { + karooSystem.streamDataFlow(dataTypeId) + .mapNotNull { (it as? StreamState.Streaming)?.dataPoint?.singleValue ?: 0.0 } + } + + flow .onCompletion { val result = glance.compose(context, DpSize.Unspecified) { } emitter.updateView(result.remoteViews) } - .collect { - val windBearing = (it as? StreamState.Streaming)?.dataPoint?.singleValue?.toInt() ?: 0 - val windCardinalDirection = ((windBearing % 360) / 45.0).roundToInt() % 8 - val text = when(windCardinalDirection){ - 0 -> "N" - 1 -> "NE" - 2 -> "E" - 3 -> "SE" - 4 -> "S" - 5 -> "SW" - 6 -> "W" - 7 -> "NW" - else -> "N/A" - } - Log.d( KarooHeadwindExtension.TAG,"Updating wind direction view") - val result = glance.compose(context, DpSize.Unspecified) { - Box(modifier = GlanceModifier.fillMaxSize(), - contentAlignment = Alignment( - vertical = Alignment.Vertical.Top, - horizontal = Alignment.Horizontal.End, - )) { - Text(text, style = TextStyle(color = ColorProvider(Color.Black, Color.White), fontFamily = FontFamily.Monospace, fontSize = TextUnit( - config.textSize.toFloat(), TextUnitType.Sp) /* FIXME: Read data field alignment config, karoo-ext #10 */)) + .collect { windBearing -> + val windCardinalDirection = ((windBearing % 360) / 45.0).roundToInt() % 8 + val text = when(windCardinalDirection){ + 0 -> "N" + 1 -> "NE" + 2 -> "E" + 3 -> "SE" + 4 -> "S" + 5 -> "SW" + 6 -> "W" + 7 -> "NW" + else -> "N/A" } - } - emitter.updateView(result.remoteViews) + Log.d( KarooHeadwindExtension.TAG,"Updating wind direction view") + val result = glance.compose(context, DpSize.Unspecified) { + Box(modifier = GlanceModifier.fillMaxSize(), + contentAlignment = Alignment( + vertical = Alignment.Vertical.Top, + horizontal = when(config.alignment){ + ViewConfig.Alignment.LEFT -> Alignment.Horizontal.Start + ViewConfig.Alignment.CENTER -> Alignment.Horizontal.CenterHorizontally + ViewConfig.Alignment.RIGHT -> Alignment.Horizontal.End + }, + )) { + Text(text, style = TextStyle(color = ColorProvider(Color.Black, Color.White), fontFamily = FontFamily.Monospace, fontSize = TextUnit( + config.textSize.toFloat(), TextUnitType.Sp))) + } + } + emitter.updateView(result.remoteViews) } }