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