feat(firmware): Use pio_env to select correct firmware variant (#4244)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
James Rich 2026-01-16 10:51:55 -06:00 committed by GitHub
parent 4a65292bcf
commit 75a3f89f51
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 1426 additions and 152 deletions

View file

@ -91,11 +91,13 @@ fun DeviceDetailsSection(state: MetricsState, modifier: Modifier = Modifier) {
Spacer(modifier = Modifier.height(16.dp))
InsetDivider()
val deviceText =
state.reportedTarget?.let { target -> "${deviceHardware.displayName} ($target)" }
?: deviceHardware.displayName
ListItem(
text = stringResource(Res.string.hardware),
leadingIcon = Icons.Default.Router,
supportingText = deviceHardware.displayName,
supportingText = deviceText,
copyable = true,
trailingIcon = null,
)

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025 Meshtastic LLC
* Copyright (c) 2025-2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -14,7 +14,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.meshtastic.feature.node.metrics
import android.app.Application
@ -33,7 +32,6 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
@ -215,21 +213,25 @@ constructor(
viewModelScope.launch {
if (currentDestNum != null) {
launch {
nodeRepository.nodeDBbyNum
.mapLatest { nodes -> nodes[currentDestNum] to nodes.keys.firstOrNull() }
combine(nodeRepository.nodeDBbyNum, nodeRepository.myNodeInfo) { nodes, myInfo ->
nodes[currentDestNum] to (nodes.keys.firstOrNull() to myInfo)
}
.distinctUntilChanged()
.collect { (node, ourNode) ->
.collect { (node, localData) ->
val (ourNodeNum, myInfo) = localData
// Create a fallback node if not found in database (for hidden clients, etc.)
val actualNode = node ?: createFallbackNode(currentDestNum)
val pioEnv = if (currentDestNum == ourNodeNum) myInfo?.pioEnv else null
val deviceHardware =
actualNode.user.hwModel.safeNumber().let {
deviceHardwareRepository.getDeviceHardwareByModel(it)
deviceHardwareRepository.getDeviceHardwareByModel(it, target = pioEnv)
}
_state.update { state ->
state.copy(
node = actualNode,
isLocal = currentDestNum == ourNode,
isLocal = currentDestNum == ourNodeNum,
deviceHardware = deviceHardware.getOrNull(),
reportedTarget = pioEnv,
)
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025 Meshtastic LLC
* Copyright (c) 2025-2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -14,7 +14,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.meshtastic.feature.node.model
import androidx.compose.ui.unit.Dp
@ -56,6 +55,8 @@ data class MetricsState(
val latestStableFirmware: FirmwareRelease = FirmwareRelease(),
val latestAlphaFirmware: FirmwareRelease = FirmwareRelease(),
val paxMetrics: List<MeshLog> = emptyList(),
/** The PlatformIO environment reported by the device (if known). */
val reportedTarget: String? = null,
) {
fun hasDeviceMetrics() = deviceMetrics.isNotEmpty()