mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-07-02 17:35:36 -04:00
feat(lora): default US region to LongTurbo preset (#6009)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -73,3 +73,16 @@ fun LoRaRegionPresetMap?.repairPresetFor(region: RegionCode, current: ModemPrese
|
||||
else -> constraint.presets.firstOrNull() ?: current
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The app's built-in default modem presets for regions whose default differs from the global [ChannelOption.DEFAULT].
|
||||
* Mirrors the per-region defaults newer firmware advertises in [LoRaRegionPresetMap], so the default channel and a
|
||||
* fresh setup over old firmware (which sends no map) land on the same preset a new node would.
|
||||
*/
|
||||
private val REGION_DEFAULT_PRESETS = mapOf(RegionCode.US to ModemPreset.LONG_TURBO)
|
||||
|
||||
/**
|
||||
* The app's preferred default preset for [region], or `null` when it has no region-specific default and the caller
|
||||
* should fall back to [ChannelOption.DEFAULT] / the current preset.
|
||||
*/
|
||||
fun defaultPresetFor(region: RegionCode): ModemPreset? = REGION_DEFAULT_PRESETS[region]
|
||||
|
||||
@@ -138,4 +138,10 @@ class LoRaRegionPresetsTest {
|
||||
)
|
||||
assertEquals(ModemPreset.MEDIUM_FAST, oddMap.repairPresetFor(RegionCode.US, ModemPreset.SHORT_FAST))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `region default preset is LongTurbo for US and absent for other regions`() {
|
||||
assertEquals(ModemPreset.LONG_TURBO, defaultPresetFor(RegionCode.US))
|
||||
assertNull(defaultPresetFor(RegionCode.EU_868))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ import org.jetbrains.compose.resources.stringResource
|
||||
import org.koin.compose.viewmodel.koinViewModel
|
||||
import org.meshtastic.core.model.Channel
|
||||
import org.meshtastic.core.model.ConnectionState
|
||||
import org.meshtastic.core.model.defaultPresetFor
|
||||
import org.meshtastic.core.model.util.getChannelUrl
|
||||
import org.meshtastic.core.navigation.Route
|
||||
import org.meshtastic.core.resources.Res
|
||||
@@ -198,8 +199,15 @@ fun ChannelScreen(
|
||||
messageRes = Res.string.are_you_sure_change_default,
|
||||
onConfirm = {
|
||||
Logger.d { "Switching back to default channel" }
|
||||
// The default channel takes the region's preferred preset (e.g. US -> LongTurbo) so its derived name,
|
||||
// hash, and frequency match what a freshly-set-up node in that region would use.
|
||||
val preset = defaultPresetFor(viewModel.region) ?: Channel.default.loraConfig.modem_preset
|
||||
val lora =
|
||||
(Channel.default.loraConfig).copy(region = viewModel.region, tx_enabled = viewModel.txEnabled)
|
||||
Channel.default.loraConfig.copy(
|
||||
region = viewModel.region,
|
||||
modem_preset = preset,
|
||||
tx_enabled = viewModel.txEnabled,
|
||||
)
|
||||
installSettings(Channel.default.settings, lora)
|
||||
showResetDialog = false
|
||||
},
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.meshtastic.core.model.ChannelOption
|
||||
import org.meshtastic.core.model.RegionInfo
|
||||
import org.meshtastic.core.model.RegionPresetConstraint
|
||||
import org.meshtastic.core.model.constraintFor
|
||||
import org.meshtastic.core.model.defaultPresetFor
|
||||
import org.meshtastic.core.model.numChannels
|
||||
import org.meshtastic.core.model.repairPresetFor
|
||||
import org.meshtastic.core.resources.Res
|
||||
@@ -70,6 +71,7 @@ import org.meshtastic.feature.settings.radio.RadioConfigViewModel
|
||||
import org.meshtastic.feature.settings.util.hopLimits
|
||||
import org.meshtastic.proto.Config
|
||||
import org.meshtastic.proto.Config.LoRaConfig.ModemPreset
|
||||
import org.meshtastic.proto.Config.LoRaConfig.RegionCode
|
||||
|
||||
private val SPREAD_FACTOR_RANGE = 7..12
|
||||
private val CODING_RATE_RANGE = 5..8
|
||||
@@ -159,10 +161,22 @@ fun LoRaConfigScreen(viewModel: RadioConfigViewModel, onBack: () -> Unit) {
|
||||
items = RegionInfo.entries.map { it.regionCode to it.description },
|
||||
selectedItem = formState.value.region,
|
||||
onItemSelected = { region ->
|
||||
val freshSetup = formState.value.region == RegionCode.UNSET
|
||||
// When the region changes, snap the preset to the region's default if the current one is
|
||||
// no longer legal there (R7); a no-op when the region is unconstrained.
|
||||
val repaired = regionPresetMap.repairPresetFor(region, formState.value.modem_preset)
|
||||
formState.value = formState.value.copy(region = region, modem_preset = repaired)
|
||||
// At fresh setup (region was UNSET) adopt the region's advertised default rather than keeping
|
||||
// a merely-legal preset: the firmware map's default when present, else the app's built-in
|
||||
// default (e.g. US -> LongTurbo on pre-2.8 firmware that sends no map).
|
||||
val preset =
|
||||
if (freshSetup) {
|
||||
regionPresetMap.constraintFor(region)?.defaultPreset
|
||||
?: defaultPresetFor(region)
|
||||
?: repaired
|
||||
} else {
|
||||
repaired
|
||||
}
|
||||
formState.value = formState.value.copy(region = region, modem_preset = preset)
|
||||
},
|
||||
)
|
||||
HorizontalDivider()
|
||||
|
||||
Reference in New Issue
Block a user