From 97936676fd842669d083611836685c67d1c17ba1 Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Wed, 17 Sep 2025 17:47:27 -0700 Subject: [PATCH 1/2] Turn on/off position or device telemetry --- .../components/PositionConfigItemList.kt | 48 +++++++++++++++---- .../components/TelemetryConfigItemList.kt | 39 +++++++++++++-- 2 files changed, 76 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt index d8d0eee650..1bc15d1c31 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt @@ -42,7 +42,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.core.location.LocationCompat import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.geeksville.mesh.ConfigProtos import com.geeksville.mesh.ConfigProtos.Config.PositionConfig import com.geeksville.mesh.Position import com.geeksville.mesh.R @@ -105,7 +104,7 @@ fun PositionConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel()) { } @OptIn(ExperimentalPermissionsApi::class) -@Suppress("LongMethod", "CyclomaticComplexMethod") +@Suppress("LongMethod", "CyclomaticComplexMethod", "MagicNumber") @Composable fun PositionConfigItemList( phoneLocation: Location? = null, @@ -125,6 +124,8 @@ fun PositionConfigItemList( } var locationInput by rememberSaveable { mutableStateOf(location) } var positionInput by rememberSaveable { mutableStateOf(positionConfig) } + val maxInt32 = 2147483647 + val defaultBroadcastSecs: Int = 900 LaunchedEffect(phoneLocation) { if (phoneLocation != null) { @@ -145,17 +146,48 @@ fun PositionConfigItemList( } LazyColumn(modifier = Modifier.fillMaxSize()) { item { PreferenceCategory(text = stringResource(R.string.position_config)) } - + item { + SwitchPreference( + title = "Broadcast Position", + checked = positionInput.positionBroadcastSecs < maxInt32, + enabled = enabled, + onCheckedChange = { isChecked -> + positionInput = + positionInput.copy { + positionBroadcastSecs = + if (isChecked) { + if (positionBroadcastSecs >= maxInt32) { + defaultBroadcastSecs + } else { + positionBroadcastSecs + } + } else { + maxInt32 + } + } + }, + ) + } item { EditTextPreference( title = stringResource(R.string.position_broadcast_interval_seconds), value = positionInput.positionBroadcastSecs, - enabled = enabled, + enabled = enabled && positionInput.positionBroadcastSecs < maxInt32, keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }), - onValueChanged = { positionInput = positionInput.copy { positionBroadcastSecs = it } }, + onValueChanged = { + positionInput = + positionInput.copy { + positionBroadcastSecs = it + if (it >= maxInt32) { + positionBroadcastSecs = maxInt32 + } + } + }, ) } + item { HorizontalDivider() } + item { SwitchPreference( title = stringResource(R.string.smart_position_enabled), @@ -249,8 +281,8 @@ fun PositionConfigItemList( title = stringResource(R.string.gps_mode), enabled = enabled, items = - ConfigProtos.Config.PositionConfig.GpsMode.entries - .filter { it != ConfigProtos.Config.PositionConfig.GpsMode.UNRECOGNIZED } + PositionConfig.GpsMode.entries + .filter { it != PositionConfig.GpsMode.UNRECOGNIZED } .map { it to it.name }, selectedItem = positionInput.gpsMode, onItemSelected = { positionInput = positionInput.copy { gpsMode = it } }, @@ -274,7 +306,7 @@ fun PositionConfigItemList( value = positionInput.positionFlags, enabled = enabled, items = - ConfigProtos.Config.PositionConfig.PositionFlags.entries + PositionConfig.PositionFlags.entries .filter { it != PositionConfig.PositionFlags.UNSET && it != PositionConfig.PositionFlags.UNRECOGNIZED } diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/TelemetryConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/TelemetryConfigItemList.kt index de1a2ce53d..d2fe875a75 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/TelemetryConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/TelemetryConfigItemList.kt @@ -30,7 +30,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview -import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel +import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig.TelemetryConfig import com.geeksville.mesh.R @@ -61,6 +61,7 @@ fun TelemetryConfigScreen(viewModel: RadioConfigViewModel = hiltViewModel()) { } @Composable +@Suppress("MagicNumber", "LongMethod") fun TelemetryConfigItemList( telemetryConfig: TelemetryConfig, enabled: Boolean, @@ -68,20 +69,52 @@ fun TelemetryConfigItemList( ) { val focusManager = LocalFocusManager.current var telemetryInput by rememberSaveable { mutableStateOf(telemetryConfig) } + val maxInt32 = 2147483647 + val defaultBroadcastSecs: Int = 1800 LazyColumn(modifier = Modifier.fillMaxSize()) { item { PreferenceCategory(text = stringResource(R.string.telemetry_config)) } + item { + SwitchPreference( + title = "Broadcast Device Metrics", + checked = telemetryInput.deviceUpdateInterval < maxInt32, + enabled = enabled, + onCheckedChange = { isChecked -> + telemetryInput = + telemetryInput.copy { + deviceUpdateInterval = + if (isChecked) { + if (deviceUpdateInterval >= maxInt32) defaultBroadcastSecs else deviceUpdateInterval + } else { + maxInt32 + } + } + }, + ) + } + item { EditTextPreference( title = stringResource(R.string.device_metrics_update_interval_seconds), value = telemetryInput.deviceUpdateInterval, - enabled = enabled, + enabled = enabled && telemetryInput.deviceUpdateInterval < maxInt32, keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }), - onValueChanged = { telemetryInput = telemetryInput.copy { deviceUpdateInterval = it } }, + onValueChanged = { + telemetryInput = + telemetryInput.copy { + deviceUpdateInterval = it + // Update broadcast toggle based on interval value + if (it >= maxInt32) { + deviceUpdateInterval = maxInt32 + } + } + }, ) } + item { HorizontalDivider() } + item { EditTextPreference( title = stringResource(R.string.environment_metrics_update_interval_seconds), From 95c107fe82c33494a8f4c6314c7ccec6ac01bc6a Mon Sep 17 00:00:00 2001 From: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com> Date: Wed, 17 Sep 2025 20:57:35 -0700 Subject: [PATCH 2/2] Fix issues --- .../components/PositionConfigItemList.kt | 15 +++++++-------- .../components/TelemetryConfigItemList.kt | 19 +++++++++++-------- app/src/main/res/values/strings.xml | 2 ++ 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt index 1bc15d1c31..2e1f32958e 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt @@ -124,7 +124,6 @@ fun PositionConfigItemList( } var locationInput by rememberSaveable { mutableStateOf(location) } var positionInput by rememberSaveable { mutableStateOf(positionConfig) } - val maxInt32 = 2147483647 val defaultBroadcastSecs: Int = 900 LaunchedEffect(phoneLocation) { @@ -148,21 +147,21 @@ fun PositionConfigItemList( item { PreferenceCategory(text = stringResource(R.string.position_config)) } item { SwitchPreference( - title = "Broadcast Position", - checked = positionInput.positionBroadcastSecs < maxInt32, + title = stringResource(R.string.broadcast_position), + checked = positionInput.positionBroadcastSecs < Int.MAX_VALUE, enabled = enabled, onCheckedChange = { isChecked -> positionInput = positionInput.copy { positionBroadcastSecs = if (isChecked) { - if (positionBroadcastSecs >= maxInt32) { + if (positionBroadcastSecs >= Int.MAX_VALUE) { defaultBroadcastSecs } else { positionBroadcastSecs } } else { - maxInt32 + Int.MAX_VALUE } } }, @@ -172,14 +171,14 @@ fun PositionConfigItemList( EditTextPreference( title = stringResource(R.string.position_broadcast_interval_seconds), value = positionInput.positionBroadcastSecs, - enabled = enabled && positionInput.positionBroadcastSecs < maxInt32, + enabled = enabled && positionInput.positionBroadcastSecs < Int.MAX_VALUE, keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }), onValueChanged = { positionInput = positionInput.copy { positionBroadcastSecs = it - if (it >= maxInt32) { - positionBroadcastSecs = maxInt32 + if (it >= Int.MAX_VALUE) { + positionBroadcastSecs = Int.MAX_VALUE } } }, diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/TelemetryConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/TelemetryConfigItemList.kt index d2fe875a75..55f88c32ac 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/TelemetryConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/TelemetryConfigItemList.kt @@ -69,7 +69,6 @@ fun TelemetryConfigItemList( ) { val focusManager = LocalFocusManager.current var telemetryInput by rememberSaveable { mutableStateOf(telemetryConfig) } - val maxInt32 = 2147483647 val defaultBroadcastSecs: Int = 1800 LazyColumn(modifier = Modifier.fillMaxSize()) { @@ -77,17 +76,21 @@ fun TelemetryConfigItemList( item { SwitchPreference( - title = "Broadcast Device Metrics", - checked = telemetryInput.deviceUpdateInterval < maxInt32, + title = stringResource(R.string.broadcast_device_metrics), + checked = telemetryInput.deviceUpdateInterval < Int.MAX_VALUE, enabled = enabled, onCheckedChange = { isChecked -> telemetryInput = telemetryInput.copy { deviceUpdateInterval = if (isChecked) { - if (deviceUpdateInterval >= maxInt32) defaultBroadcastSecs else deviceUpdateInterval + if (deviceUpdateInterval >= Int.MAX_VALUE) { + defaultBroadcastSecs + } else { + deviceUpdateInterval + } } else { - maxInt32 + Int.MAX_VALUE } } }, @@ -98,15 +101,15 @@ fun TelemetryConfigItemList( EditTextPreference( title = stringResource(R.string.device_metrics_update_interval_seconds), value = telemetryInput.deviceUpdateInterval, - enabled = enabled && telemetryInput.deviceUpdateInterval < maxInt32, + enabled = enabled && telemetryInput.deviceUpdateInterval < Int.MAX_VALUE, keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }), onValueChanged = { telemetryInput = telemetryInput.copy { deviceUpdateInterval = it // Update broadcast toggle based on interval value - if (it >= maxInt32) { - deviceUpdateInterval = maxInt32 + if (it >= Int.MAX_VALUE) { + deviceUpdateInterval = Int.MAX_VALUE } } }, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 006942df79..261761267d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -818,4 +818,6 @@ Messages from a public internet gateway are forwarded to the local mesh. Due to the zero-hop policy, traffic from the default MQTT server will not propagate further than this device. Icon Meanings Disabling position on the primary channel allows periodic position broadcasts on the first secondary channel with the position enabled, otherwise manual position request required. + Broadcast Position + Broadcast Device Metrics