refactor: updates for 2.2 release

reference https://github.com/meshtastic/protobufs/pull/368
This commit is contained in:
andrekir 2023-08-05 07:04:37 -03:00
parent 0a47b8df3e
commit e9ae0c66d9
5 changed files with 150 additions and 62 deletions

View file

@ -178,9 +178,6 @@ class MockInterface(private val service: RadioInterfaceService) : Logging, IRadi
MeshProtos.FromRadio.newBuilder().apply {
myInfo = MeshProtos.MyNodeInfo.newBuilder().apply {
myNodeNum = MY_NODE
messageTimeoutMsec = 5 * 60 * 1000
firmwareVersion = "1.3.8" // Pretend to be running an older 1.3 version
maxChannels = 8
}.build()
},

View file

@ -123,9 +123,10 @@ class MeshService : Service(), Logging {
"com.geeksville.mesh.service.MeshService"
)
/** The minimmum firmware version we know how to talk to. We'll still be able to talk to 1.0 firmwares but only well enough to ask them to firmware update
/** The minimum firmware version we know how to talk to. We'll still be able
* to talk to 2.0 firmwares but only well enough to ask them to firmware update.
*/
val minDeviceVersion = DeviceVersion("1.3.43")
val minDeviceVersion = DeviceVersion("2.0.21")
}
enum class ConnectionState {
@ -1156,6 +1157,7 @@ class MeshService : Service(), Logging {
MeshProtos.FromRadio.CONFIG_FIELD_NUMBER -> handleDeviceConfig(proto.config)
MeshProtos.FromRadio.MODULECONFIG_FIELD_NUMBER -> handleModuleConfig(proto.moduleConfig)
MeshProtos.FromRadio.QUEUESTATUS_FIELD_NUMBER -> handleQueueStatus(proto.queueStatus)
MeshProtos.FromRadio.METADATA_FIELD_NUMBER -> handleMetadata(proto.metadata)
else -> errormsg("Unexpected FromRadio variant")
}
} catch (ex: InvalidProtocolBufferException) {
@ -1265,6 +1267,7 @@ class MeshService : Service(), Logging {
private var rawMyNodeInfo: MeshProtos.MyNodeInfo? = null
private var rawDeviceMetadata: MeshProtos.DeviceMetadata? = null
/** Regenerate the myNodeInfo model. We call this twice. Once after we receive myNodeInfo from the device
* and again after we have the node DB (which might allow us a better notion of our HwModel.
@ -1274,6 +1277,7 @@ class MeshService : Service(), Logging {
if (myInfo != null) {
val a = radioInterfaceService.getBondedDeviceAddress()
val isBluetoothInterface = a != null && a.startsWith("x")
val firmwareVersion = rawDeviceMetadata?.firmwareVersion.orEmpty()
val nodeNum =
myInfo.myNodeNum // Note: can't use the normal property because myNodeInfo not yet setup
@ -1283,7 +1287,7 @@ class MeshService : Service(), Logging {
val mi = with(myInfo) {
MyNodeInfo(
myNodeNum,
hasGps,
false,
hwModelStr,
firmwareVersion,
firmwareUpdateFilename?.appLoad != null && firmwareUpdateFilename?.littlefs != null,
@ -1292,12 +1296,12 @@ class MeshService : Service(), Logging {
DeviceVersion(firmwareVersion)
),
currentPacketId and 0xffffffffL,
if (messageTimeoutMsec == 0) 5 * 60 * 1000 else messageTimeoutMsec, // constants from current device code
5 * 60 * 1000, // constants from current device code
minAppVersion,
maxChannels,
hasWifi,
channelUtilization,
airUtilTx
8,
false,
0f,
0f,
)
}
newMyNodeInfo = mi
@ -1311,27 +1315,13 @@ class MeshService : Service(), Logging {
/// Track types of devices and firmware versions in use
GeeksvilleApplication.analytics.setUserInfo(
DataPair("firmware", mi.firmwareVersion),
DataPair("has_gps", mi.hasGPS),
DataPair("hw_model", mi.model),
DataPair("dev_error_count", myInfo.errorCount)
)
if (myInfo.errorCode != MeshProtos.CriticalErrorCode.UNSPECIFIED && myInfo.errorCode != MeshProtos.CriticalErrorCode.NONE) {
GeeksvilleApplication.analytics.track(
"dev_error",
DataPair("code", myInfo.errorCode.number),
DataPair("address", myInfo.errorAddress),
// We also include this info, because it is required to correctly decode address from the map file
DataPair("firmware", mi.firmwareVersion),
DataPair("hw_model", mi.model)
)
}
}
}
/**
* Update the nodeinfo (called from either new API version or the old one)
* Update MyNodeInfo (called from either new API version or the old one)
*/
private fun handleMyInfo(myInfo: MeshProtos.MyNodeInfo) {
val packetToSave = MeshLog(
@ -1353,6 +1343,21 @@ class MeshService : Service(), Logging {
}
}
/**
* Update our DeviceMetadata
*/
private fun handleMetadata(metadata: MeshProtos.DeviceMetadata) {
val packetToSave = MeshLog(
UUID.randomUUID().toString(),
"DeviceMetadata",
System.currentTimeMillis(),
metadata.toString()
)
insertMeshLog(packetToSave)
rawDeviceMetadata = metadata
}
/// If we've received our initial config, our radio settings and all of our channels, send any queued packets and broadcast connected to clients
private fun onHasSettings() {

View file

@ -86,6 +86,7 @@ import com.geeksville.mesh.ui.components.config.EditDeviceProfileDialog
import com.geeksville.mesh.ui.components.config.ExternalNotificationConfigItemList
import com.geeksville.mesh.ui.components.config.LoRaConfigItemList
import com.geeksville.mesh.ui.components.config.MQTTConfigItemList
import com.geeksville.mesh.ui.components.config.NeighborInfoConfigItemList
import com.geeksville.mesh.ui.components.config.NetworkConfigItemList
import com.geeksville.mesh.ui.components.config.PacketResponseStateDialog
import com.geeksville.mesh.ui.components.config.PositionConfigItemList
@ -121,26 +122,27 @@ class DeviceSettingsFragment(val node: NodeInfo) : ScreenFragment("Radio Configu
}
}
enum class ConfigDest(val title: String, val route: String, val config: ConfigType) {
DEVICE("Device", "device", ConfigType.DEVICE_CONFIG),
POSITION("Position", "position", ConfigType.POSITION_CONFIG),
POWER("Power", "power", ConfigType.POWER_CONFIG),
NETWORK("Network", "network", ConfigType.NETWORK_CONFIG),
DISPLAY("Display", "display", ConfigType.DISPLAY_CONFIG),
LORA("LoRa", "lora", ConfigType.LORA_CONFIG),
BLUETOOTH("Bluetooth", "bluetooth", ConfigType.BLUETOOTH_CONFIG);
enum class ConfigDest(val title: String, val route: String) {
DEVICE("Device", "device"),
POSITION("Position", "position"),
POWER("Power", "power"),
NETWORK("Network", "network"),
DISPLAY("Display", "display"),
LORA("LoRa", "lora"),
BLUETOOTH("Bluetooth", "bluetooth");
}
enum class ModuleDest(val title: String, val route: String, val config: ModuleConfigType) {
MQTT("MQTT", "mqtt", ModuleConfigType.MQTT_CONFIG),
SERIAL("Serial", "serial", ModuleConfigType.SERIAL_CONFIG),
EXTERNAL_NOTIFICATION("External Notification", "ext_not", ModuleConfigType.EXTNOTIF_CONFIG),
STORE_FORWARD("Store & Forward", "store_forward", ModuleConfigType.STOREFORWARD_CONFIG),
RANGE_TEST("Range Test", "range_test", ModuleConfigType.RANGETEST_CONFIG),
TELEMETRY("Telemetry", "telemetry", ModuleConfigType.TELEMETRY_CONFIG),
CANNED_MESSAGE("Canned Message", "canned_message", ModuleConfigType.CANNEDMSG_CONFIG),
AUDIO("Audio", "audio", ModuleConfigType.AUDIO_CONFIG),
REMOTE_HARDWARE("Remote Hardware", "remote_hardware", ModuleConfigType.REMOTEHARDWARE_CONFIG);
enum class ModuleDest(val title: String, val route: String) {
MQTT("MQTT", "mqtt"),
SERIAL("Serial", "serial"),
EXTERNAL_NOTIFICATION("External Notification", "ext_not"),
STORE_FORWARD("Store & Forward", "store_forward"),
RANGE_TEST("Range Test", "range_test"),
TELEMETRY("Telemetry", "telemetry"),
CANNED_MESSAGE("Canned Message", "canned_message"),
AUDIO("Audio", "audio"),
REMOTE_HARDWARE("Remote Hardware", "remote_hardware"),
NEIGHBOR_INFO("Neighbor Info", "neighbor_info");
}
/**
@ -375,19 +377,19 @@ fun RadioConfigNavHost(node: NodeInfo, viewModel: UIViewModel = viewModel()) {
channelList.clear()
viewModel.getChannel(destNum, 0)
}
is ConfigType -> {
viewModel.getConfig(destNum, configType.number)
is ConfigDest -> {
viewModel.getConfig(destNum, configType.ordinal)
}
ModuleConfigType.CANNEDMSG_CONFIG -> {
ModuleDest.CANNED_MESSAGE -> {
(packetResponseState as PacketResponseState.Loading).total = 2
viewModel.getCannedMessages(destNum)
}
ModuleConfigType.EXTNOTIF_CONFIG -> {
ModuleDest.EXTERNAL_NOTIFICATION -> {
(packetResponseState as PacketResponseState.Loading).total = 2
viewModel.getRingtone(destNum)
}
is ModuleConfigType -> {
viewModel.getModuleConfig(destNum, configType.number)
is ModuleDest -> {
viewModel.getModuleConfig(destNum, configType.ordinal)
}
}
},
@ -651,6 +653,19 @@ fun RadioConfigNavHost(node: NodeInfo, viewModel: UIViewModel = viewModel()) {
}
)
}
composable("neighbor_info") {
NeighborInfoConfigItemList(
neighborInfoConfig = moduleConfig.neighborInfo,
enabled = connected,
focusManager = focusManager,
onSaveClicked = { neighborInfoInput ->
focusManager.clearFocus()
val config = moduleConfig { neighborInfo = neighborInfoInput }
viewModel.setModuleConfig(destNum, config)
moduleConfig = config
}
)
}
}
}
@ -769,13 +784,13 @@ fun RadioSettingsScreen(
item { PreferenceCategory(stringResource(R.string.device_settings)) }
item { NavCard("User", enabled = enabled) { onRouteClick("USER") } }
item { NavCard("Channels", enabled = enabled) { onRouteClick("CHANNELS") } }
items(ConfigDest.values()) { configs ->
NavCard(configs.title, enabled = enabled) { onRouteClick(configs.config) }
items(ConfigDest.values()) { config ->
NavCard(config.title, enabled = enabled) { onRouteClick(config) }
}
item { PreferenceCategory(stringResource(R.string.module_settings)) }
items(ModuleDest.values()) { modules ->
NavCard(modules.title, enabled = enabled) { onRouteClick(modules.config) }
items(ModuleDest.values()) { module ->
NavCard(module.title, enabled = enabled) { onRouteClick(module) }
}
if (isLocal) {

View file

@ -0,0 +1,79 @@
package com.geeksville.mesh.ui.components.config
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material.Divider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusManager
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
import com.geeksville.mesh.ModuleConfigProtos
import com.geeksville.mesh.copy
import com.geeksville.mesh.ui.components.EditTextPreference
import com.geeksville.mesh.ui.components.PreferenceCategory
import com.geeksville.mesh.ui.components.PreferenceFooter
import com.geeksville.mesh.ui.components.SwitchPreference
@Composable
fun NeighborInfoConfigItemList(
neighborInfoConfig: ModuleConfigProtos.ModuleConfig.NeighborInfoConfig,
enabled: Boolean,
focusManager: FocusManager,
onSaveClicked: (ModuleConfigProtos.ModuleConfig.NeighborInfoConfig) -> Unit,
) {
var neighborInfoInput by remember(neighborInfoConfig) { mutableStateOf(neighborInfoConfig) }
LazyColumn(
modifier = Modifier.fillMaxSize()
) {
item { PreferenceCategory(text = "Neighbor Info Config") }
item {
SwitchPreference(title = "Neighbor Info enabled",
checked = neighborInfoInput.enabled,
enabled = enabled,
onCheckedChange = {
neighborInfoInput = neighborInfoInput.copy { this.enabled = it }
})
}
item { Divider() }
item {
EditTextPreference(title = "Update interval (seconds)",
value = neighborInfoInput.updateInterval,
enabled = enabled,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
onValueChanged = {
neighborInfoInput = neighborInfoInput.copy { updateInterval = it }
})
}
item {
PreferenceFooter(
enabled = neighborInfoInput != neighborInfoConfig,
onCancelClicked = {
focusManager.clearFocus()
neighborInfoInput = neighborInfoConfig
},
onSaveClicked = { onSaveClicked(neighborInfoInput) }
)
}
}
}
@Preview(showBackground = true)
@Composable
fun NeighborInfoConfigPreview(){
NeighborInfoConfigItemList(
neighborInfoConfig = ModuleConfigProtos.ModuleConfig.NeighborInfoConfig.getDefaultInstance(),
enabled = true,
focusManager = LocalFocusManager.current,
onSaveClicked = { },
)
}

View file

@ -68,14 +68,6 @@ fun PowerConfigItemList(
onValueChanged = { powerInput = powerInput.copy { waitBluetoothSecs = it } })
}
item {
EditTextPreference(title = "Mesh SDS timeout (seconds)",
value = powerInput.meshSdsTimeoutSecs,
enabled = enabled,
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
onValueChanged = { powerInput = powerInput.copy { meshSdsTimeoutSecs = it } })
}
item {
EditTextPreference(title = "Super deep sleep duration (seconds)",
value = powerInput.sdsSecs,