ref #5: Set alignment of absolute wind direction field, add preview mode
This commit is contained in:
parent
23dc550e5a
commit
223157a3f8
@ -8,6 +8,7 @@ import androidx.glance.appwidget.ExperimentalGlanceRemoteViewsApi
|
|||||||
import androidx.glance.appwidget.GlanceRemoteViews
|
import androidx.glance.appwidget.GlanceRemoteViews
|
||||||
import de.timklge.karooheadwind.KarooHeadwindExtension
|
import de.timklge.karooheadwind.KarooHeadwindExtension
|
||||||
import de.timklge.karooheadwind.OpenMeteoCurrentWeatherResponse
|
import de.timklge.karooheadwind.OpenMeteoCurrentWeatherResponse
|
||||||
|
import de.timklge.karooheadwind.OpenMeteoData
|
||||||
import de.timklge.karooheadwind.getRelativeHeadingFlow
|
import de.timklge.karooheadwind.getRelativeHeadingFlow
|
||||||
import de.timklge.karooheadwind.screens.HeadwindSettings
|
import de.timklge.karooheadwind.screens.HeadwindSettings
|
||||||
import de.timklge.karooheadwind.streamCurrentWeatherData
|
import de.timklge.karooheadwind.streamCurrentWeatherData
|
||||||
@ -25,8 +26,11 @@ import io.hammerhead.karooext.models.ViewConfig
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.awaitCancellation
|
import kotlinx.coroutines.awaitCancellation
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.flow.mapNotNull
|
import kotlinx.coroutines.flow.mapNotNull
|
||||||
import kotlinx.coroutines.flow.onCompletion
|
import kotlinx.coroutines.flow.onCompletion
|
||||||
import kotlinx.coroutines.launch
|
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<StreamData> {
|
||||||
|
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) {
|
override fun startView(context: Context, config: ViewConfig, emitter: ViewEmitter) {
|
||||||
Log.d(KarooHeadwindExtension.TAG, "Starting headwind direction view with $emitter")
|
Log.d(KarooHeadwindExtension.TAG, "Starting headwind direction view with $emitter")
|
||||||
|
|
||||||
@ -66,21 +85,26 @@ class HeadwindDirectionDataType(
|
|||||||
awaitCancellation()
|
awaitCancellation()
|
||||||
}
|
}
|
||||||
|
|
||||||
data class StreamData(val value: Double, val data: OpenMeteoCurrentWeatherResponse, val settings: HeadwindSettings)
|
val flow = if (config.preview) {
|
||||||
|
previewFlow()
|
||||||
val viewJob = CoroutineScope(Dispatchers.IO).launch {
|
} else {
|
||||||
karooSystem.streamDataFlow(dataTypeId)
|
karooSystem.streamDataFlow(dataTypeId)
|
||||||
.mapNotNull { (it as? StreamState.Streaming)?.dataPoint?.singleValue }
|
.mapNotNull { (it as? StreamState.Streaming)?.dataPoint?.singleValue }
|
||||||
.combine(context.streamCurrentWeatherData()) { value, data -> value to data }
|
.combine(context.streamCurrentWeatherData()) { value, data -> value to data }
|
||||||
.combine(context.streamSettings(karooSystem)) { (value, data), settings -> StreamData(value, data, settings) }
|
.combine(context.streamSettings(karooSystem)) { (value, data), settings ->
|
||||||
.onCompletion {
|
StreamData(value, data.current.windSpeed, settings)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val viewJob = CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
flow.onCompletion {
|
||||||
// Clear view on completion
|
// Clear view on completion
|
||||||
val result = glance.compose(context, DpSize.Unspecified) { }
|
val result = glance.compose(context, DpSize.Unspecified) { }
|
||||||
emitter.updateView(result.remoteViews)
|
emitter.updateView(result.remoteViews)
|
||||||
}
|
}
|
||||||
.collect { streamData ->
|
.collect { streamData ->
|
||||||
Log.d(KarooHeadwindExtension.TAG, "Updating headwind direction view")
|
Log.d(KarooHeadwindExtension.TAG, "Updating headwind direction view")
|
||||||
val windSpeed = streamData.data.current.windSpeed
|
val windSpeed = streamData.windSpeed
|
||||||
val windDirection = streamData.value
|
val windDirection = streamData.value
|
||||||
val headwindSpeed = cos( (windDirection + 180) * Math.PI / 180.0) * windSpeed
|
val headwindSpeed = cos( (windDirection + 180) * Math.PI / 180.0) * windSpeed
|
||||||
val windSpeedText = headwindSpeed.roundToInt().toString()
|
val windSpeedText = headwindSpeed.roundToInt().toString()
|
||||||
|
|||||||
@ -27,6 +27,11 @@ import io.hammerhead.karooext.models.ViewConfig
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.awaitCancellation
|
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.flow.onCompletion
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
@ -39,6 +44,15 @@ class WindDirectionDataType(val karooSystem: KarooSystemService, context: Contex
|
|||||||
return data.current.windDirection
|
return data.current.windDirection
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun previewFlow(): Flow<Double> {
|
||||||
|
return flow {
|
||||||
|
while (true) {
|
||||||
|
emit((0..360).random().toDouble())
|
||||||
|
delay(1_000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalGlanceRemoteViewsApi::class)
|
@OptIn(ExperimentalGlanceRemoteViewsApi::class)
|
||||||
override fun startView(context: Context, config: ViewConfig, emitter: ViewEmitter) {
|
override fun startView(context: Context, config: ViewConfig, emitter: ViewEmitter) {
|
||||||
val configJob = CoroutineScope(Dispatchers.IO).launch {
|
val configJob = CoroutineScope(Dispatchers.IO).launch {
|
||||||
@ -47,37 +61,47 @@ class WindDirectionDataType(val karooSystem: KarooSystemService, context: Contex
|
|||||||
}
|
}
|
||||||
|
|
||||||
val viewJob = CoroutineScope(Dispatchers.IO).launch {
|
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 {
|
.onCompletion {
|
||||||
val result = glance.compose(context, DpSize.Unspecified) { }
|
val result = glance.compose(context, DpSize.Unspecified) { }
|
||||||
emitter.updateView(result.remoteViews)
|
emitter.updateView(result.remoteViews)
|
||||||
}
|
}
|
||||||
.collect {
|
.collect { windBearing ->
|
||||||
val windBearing = (it as? StreamState.Streaming)?.dataPoint?.singleValue?.toInt() ?: 0
|
val windCardinalDirection = ((windBearing % 360) / 45.0).roundToInt() % 8
|
||||||
val windCardinalDirection = ((windBearing % 360) / 45.0).roundToInt() % 8
|
val text = when(windCardinalDirection){
|
||||||
val text = when(windCardinalDirection){
|
0 -> "N"
|
||||||
0 -> "N"
|
1 -> "NE"
|
||||||
1 -> "NE"
|
2 -> "E"
|
||||||
2 -> "E"
|
3 -> "SE"
|
||||||
3 -> "SE"
|
4 -> "S"
|
||||||
4 -> "S"
|
5 -> "SW"
|
||||||
5 -> "SW"
|
6 -> "W"
|
||||||
6 -> "W"
|
7 -> "NW"
|
||||||
7 -> "NW"
|
else -> "N/A"
|
||||||
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 */))
|
|
||||||
}
|
}
|
||||||
}
|
Log.d( KarooHeadwindExtension.TAG,"Updating wind direction view")
|
||||||
emitter.updateView(result.remoteViews)
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user