diff --git a/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt b/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt index 256049861..f5f2531d3 100644 --- a/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt @@ -7,6 +7,7 @@ import androidx.lifecycle.viewModelScope import com.geeksville.mesh.R import com.geeksville.mesh.TelemetryProtos.Telemetry import com.geeksville.mesh.database.MeshLogRepository +import com.geeksville.mesh.repository.datastore.RadioConfigRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted.Companion.WhileSubscribed @@ -29,6 +30,7 @@ data class MetricsState( val isLoading: Boolean = false, val deviceMetrics: List = emptyList(), val environmentMetrics: List = emptyList(), + val environmentDisplayFahrenheit: Boolean = false, ) { companion object { val Empty = MetricsState() @@ -38,7 +40,8 @@ data class MetricsState( @HiltViewModel class MetricsViewModel @Inject constructor( val nodeDB: NodeDB, - private val meshLogRepository: MeshLogRepository + private val meshLogRepository: MeshLogRepository, + radioConfigRepository: RadioConfigRepository, ) : ViewModel() { private val isLoading = MutableStateFlow(false) @@ -49,11 +52,13 @@ class MetricsViewModel @Inject constructor( isLoading, _deviceMetrics, _environmentMetrics, - ) { isLoading, device, environment -> + radioConfigRepository.deviceProfileFlow, + ) { isLoading, device, environment, profile -> MetricsState( isLoading = isLoading, deviceMetrics = device, environmentMetrics = environment, + environmentDisplayFahrenheit = profile.moduleConfig.telemetry.environmentDisplayFahrenheit, ) }.stateIn( scope = viewModelScope, @@ -76,11 +81,13 @@ class MetricsViewModel @Inject constructor( val deviceList = mutableListOf() val environmentList = mutableListOf() for (telemetry in it) { - if (telemetry.hasDeviceMetrics()) + if (telemetry.hasDeviceMetrics()) { deviceList.add(telemetry) + } /* Avoiding negative outliers */ - if (telemetry.hasEnvironmentMetrics() && telemetry.environmentMetrics.relativeHumidity >= 0f) + if (telemetry.hasEnvironmentMetrics() && telemetry.environmentMetrics.relativeHumidity >= 0f) { environmentList.add(telemetry) + } } _deviceMetrics.value = deviceList _environmentMetrics.value = environmentList diff --git a/app/src/main/java/com/geeksville/mesh/ui/MetricsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/MetricsFragment.kt index e3dbf235f..db73f1695 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/MetricsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/MetricsFragment.kt @@ -70,8 +70,9 @@ class MetricsFragment : ScreenFragment("Metrics"), Logging { savedInstanceState: Bundle? ): View { val nodeNum = arguments?.getInt("nodeNum") - if (nodeNum != null) + if (nodeNum != null) { model.setSelectedNode(nodeNum) + } val nodeName = model.getNodeName(nodeNum ?: 0) @@ -176,7 +177,10 @@ fun MetricsPagerScreen( } else { when (pages[index]) { MetricsPage.DEVICE -> DeviceMetricsScreen(deviceMetrics) - MetricsPage.ENVIRONMENT -> EnvironmentMetricsScreen(environmentMetrics) + MetricsPage.ENVIRONMENT -> EnvironmentMetricsScreen( + environmentMetrics, + state.environmentDisplayFahrenheit + ) } } } diff --git a/app/src/main/java/com/geeksville/mesh/ui/components/EnvironmentMetrics.kt b/app/src/main/java/com/geeksville/mesh/ui/components/EnvironmentMetrics.kt index e49464ccc..23010b166 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/components/EnvironmentMetrics.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/components/EnvironmentMetrics.kt @@ -36,28 +36,53 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import com.geeksville.mesh.R import com.geeksville.mesh.TelemetryProtos.Telemetry +import com.geeksville.mesh.copy import com.geeksville.mesh.ui.components.CommonCharts.LEFT_CHART_SPACING import com.geeksville.mesh.ui.components.CommonCharts.MS_PER_SEC import com.geeksville.mesh.ui.components.CommonCharts.TIME_FORMAT -private val ENVIRONMENT_METRICS_COLORS = listOf(Color.Red, Color.Blue) +private val ENVIRONMENT_METRICS_COLORS = listOf(Color.Red, Color.Blue, Color.Green) @Composable -fun EnvironmentMetricsScreen(telemetries: List) { +fun EnvironmentMetricsScreen(telemetries: List, environmentDisplayFahrenheit: Boolean) { + /* Convert Celsius to Fahrenheit */ + @Suppress("MagicNumber") + fun celsiusToFahrenheit(celsius: Float): Float { + return (celsius * 1.8F) + 32 + } + + val processedTelemetries: List = if (environmentDisplayFahrenheit) { + telemetries.map { telemetry -> + val temperatureFahrenheit = + celsiusToFahrenheit(telemetry.environmentMetrics.temperature) + telemetry.copy { + environmentMetrics = + telemetry.environmentMetrics.copy { temperature = temperatureFahrenheit } + } + } + } else { + telemetries + } + Column { EnvironmentMetricsChart( modifier = Modifier .fillMaxWidth() .fillMaxHeight(fraction = 0.33f), - telemetries = telemetries.reversed() + telemetries = processedTelemetries.reversed(), ) /* Environment Metric Cards */ LazyColumn( modifier = Modifier.fillMaxSize() ) { - items(telemetries) { telemetry -> EnvironmentMetricsCard(telemetry) } + items(processedTelemetries) { telemetry -> + EnvironmentMetricsCard( + telemetry, + environmentDisplayFahrenheit + ) + } } } } @@ -110,7 +135,6 @@ private fun EnvironmentMetricsChart(modifier: Modifier = Modifier, telemetries: val diff = max - min Box(contentAlignment = Alignment.TopStart) { - ChartOverlay( modifier = modifier, graphColor = graphColor, @@ -304,7 +328,7 @@ private fun EnvironmentMetricsChart(modifier: Modifier = Modifier, telemetries: @Suppress("LongMethod") @Composable -private fun EnvironmentMetricsCard(telemetry: Telemetry) { +private fun EnvironmentMetricsCard(telemetry: Telemetry, environmentDisplayFahrenheit: Boolean) { val envMetrics = telemetry.environmentMetrics val time = telemetry.time * MS_PER_SEC Card( @@ -330,9 +354,9 @@ private fun EnvironmentMetricsCard(telemetry: Telemetry) { style = TextStyle(fontWeight = FontWeight.Bold), fontSize = MaterialTheme.typography.button.fontSize ) - + val textFormat = if (environmentDisplayFahrenheit) "%s %.1f°F" else "%s %.1f°C" Text( - text = "%s %.1f°C".format( + text = textFormat.format( stringResource(id = R.string.temperature), envMetrics.temperature ),