mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
refactor(time): Centralize time handling with kotlinx-datetime (#4545)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
da04448dee
commit
5ca2ab4695
86 changed files with 993 additions and 663 deletions
|
|
@ -33,6 +33,8 @@ import org.meshtastic.core.database.model.Node
|
|||
import org.meshtastic.core.di.CoroutineDispatchers
|
||||
import org.meshtastic.core.model.util.bearing
|
||||
import org.meshtastic.core.model.util.latLongToMeter
|
||||
import org.meshtastic.core.model.util.nowMillis
|
||||
import org.meshtastic.core.model.util.nowSeconds
|
||||
import org.meshtastic.core.model.util.toDistanceString
|
||||
import org.meshtastic.core.ui.component.precisionBitsToMeters
|
||||
import org.meshtastic.proto.Config
|
||||
|
|
@ -47,7 +49,6 @@ import kotlin.math.sqrt
|
|||
private const val ALIGNMENT_TOLERANCE_DEGREES = 5f
|
||||
private const val FULL_CIRCLE_DEGREES = 360f
|
||||
private const val BEARING_FORMAT = "%.0f°"
|
||||
private const val MILLIS_PER_SECOND = 1000
|
||||
private const val SECONDS_PER_HOUR = 3600
|
||||
private const val SECONDS_PER_MINUTE = 60
|
||||
private const val HUNDRED = 100f
|
||||
|
|
@ -192,17 +193,12 @@ constructor(
|
|||
val loc = locationState.location ?: return heading
|
||||
val baseHeading = heading ?: return null
|
||||
val geomagnetic =
|
||||
GeomagneticField(
|
||||
loc.latitude.toFloat(),
|
||||
loc.longitude.toFloat(),
|
||||
loc.altitude.toFloat(),
|
||||
System.currentTimeMillis(),
|
||||
)
|
||||
GeomagneticField(loc.latitude.toFloat(), loc.longitude.toFloat(), loc.altitude.toFloat(), nowMillis)
|
||||
return (baseHeading + geomagnetic.declination + FULL_CIRCLE_DEGREES) % FULL_CIRCLE_DEGREES
|
||||
}
|
||||
|
||||
private fun formatElapsed(timestampSec: Long): String {
|
||||
val nowSec = System.currentTimeMillis() / MILLIS_PER_SECOND
|
||||
val nowSec = nowSeconds
|
||||
val diff = maxOf(0, nowSec - timestampSec)
|
||||
val hours = diff / SECONDS_PER_HOUR
|
||||
val minutes = (diff % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import androidx.compose.ui.graphics.drawscope.Stroke
|
|||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.meshtastic.core.model.util.nowMillis
|
||||
import org.meshtastic.core.ui.icon.MeshtasticIcons
|
||||
import org.meshtastic.core.ui.icon.Refresh
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
|
|
@ -56,7 +57,7 @@ fun CooldownIconButton(
|
|||
progress.snapTo(0f)
|
||||
return@LaunchedEffect
|
||||
}
|
||||
val timeSinceLast = System.currentTimeMillis() - cooldownTimestamp
|
||||
val timeSinceLast = nowMillis - cooldownTimestamp
|
||||
if (timeSinceLast < cooldownDuration) {
|
||||
val remainingTime = cooldownDuration - timeSinceLast
|
||||
progress.snapTo(remainingTime / cooldownDuration.toFloat())
|
||||
|
|
@ -106,7 +107,7 @@ fun CooldownOutlinedIconButton(
|
|||
progress.snapTo(0f)
|
||||
return@LaunchedEffect
|
||||
}
|
||||
val timeSinceLast = System.currentTimeMillis() - cooldownTimestamp
|
||||
val timeSinceLast = nowMillis - cooldownTimestamp
|
||||
if (timeSinceLast < cooldownDuration) {
|
||||
val remainingTime = cooldownDuration - timeSinceLast
|
||||
progress.snapTo(remainingTime / cooldownDuration.toFloat())
|
||||
|
|
@ -146,7 +147,7 @@ fun CooldownOutlinedIconButton(
|
|||
@Composable
|
||||
private fun CooldownOutlinedIconButtonPreview() {
|
||||
AppTheme {
|
||||
CooldownOutlinedIconButton(onClick = {}, cooldownTimestamp = System.currentTimeMillis() - 15000L) {
|
||||
CooldownOutlinedIconButton(onClick = {}, cooldownTimestamp = nowMillis - 15000L) {
|
||||
Icon(imageVector = MeshtasticIcons.Refresh, contentDescription = null)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
|||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.model.util.nowSeconds
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.node_sort_last_heard
|
||||
import org.meshtastic.core.ui.R
|
||||
|
|
@ -34,13 +35,14 @@ import org.meshtastic.core.ui.util.formatAgo
|
|||
fun LastHeardInfo(
|
||||
modifier: Modifier = Modifier,
|
||||
lastHeard: Int,
|
||||
showLabel: Boolean = true,
|
||||
contentColor: Color = MaterialTheme.colorScheme.onSurface,
|
||||
) {
|
||||
IconInfo(
|
||||
modifier = modifier,
|
||||
icon = ImageVector.vectorResource(id = R.drawable.ic_antenna_24),
|
||||
contentDescription = stringResource(Res.string.node_sort_last_heard),
|
||||
label = stringResource(Res.string.node_sort_last_heard),
|
||||
label = if (showLabel) stringResource(Res.string.node_sort_last_heard) else null,
|
||||
text = formatAgo(lastHeard),
|
||||
contentColor = contentColor,
|
||||
)
|
||||
|
|
@ -49,5 +51,5 @@ fun LastHeardInfo(
|
|||
@PreviewLightDark
|
||||
@Composable
|
||||
private fun LastHeardInfoPreview() {
|
||||
AppTheme { LastHeardInfo(lastHeard = (System.currentTimeMillis() / 1000).toInt() - 8600) }
|
||||
AppTheme { LastHeardInfo(lastHeard = nowSeconds.toInt() - 8600) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import kotlinx.coroutines.launch
|
|||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.meshtastic.core.model.Position
|
||||
import org.meshtastic.core.model.TelemetryType
|
||||
import org.meshtastic.core.model.util.nowMillis
|
||||
import org.meshtastic.core.service.ServiceRepository
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.neighbor_info
|
||||
|
|
@ -83,7 +84,7 @@ class NodeRequestActions @Inject constructor(private val serviceRepository: Serv
|
|||
try {
|
||||
val packetId = serviceRepository.meshService?.packetId ?: return@launch
|
||||
serviceRepository.meshService?.requestNeighborInfo(packetId, destNum)
|
||||
_lastRequestNeighborTimes.update { it + (destNum to System.currentTimeMillis()) }
|
||||
_lastRequestNeighborTimes.update { it + (destNum to nowMillis) }
|
||||
_effects.emit(
|
||||
NodeRequestEffect.ShowFeedback(
|
||||
Res.string.requesting_from,
|
||||
|
|
@ -146,7 +147,7 @@ class NodeRequestActions @Inject constructor(private val serviceRepository: Serv
|
|||
try {
|
||||
val packetId = serviceRepository.meshService?.packetId ?: return@launch
|
||||
serviceRepository.meshService?.requestTraceroute(packetId, destNum)
|
||||
_lastTracerouteTimes.update { it + (destNum to System.currentTimeMillis()) }
|
||||
_lastTracerouteTimes.update { it + (destNum to nowMillis) }
|
||||
_effects.emit(
|
||||
NodeRequestEffect.ShowFeedback(Res.string.requesting_from, listOf(Res.string.traceroute, longName)),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -61,6 +61,9 @@ import com.patrykandpatrick.vico.compose.cartesian.CartesianDrawingContext
|
|||
import com.patrykandpatrick.vico.compose.cartesian.data.CartesianValueFormatter
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.model.util.TimeConstants
|
||||
import org.meshtastic.core.model.util.toDate
|
||||
import org.meshtastic.core.model.util.toInstant
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.close
|
||||
import org.meshtastic.core.strings.delete
|
||||
|
|
@ -70,7 +73,7 @@ import org.meshtastic.core.strings.snr
|
|||
import org.meshtastic.core.ui.icon.Delete
|
||||
import org.meshtastic.core.ui.icon.MeshtasticIcons
|
||||
import java.text.DateFormat
|
||||
import java.util.Date
|
||||
import kotlin.time.Duration.Companion.days
|
||||
|
||||
object CommonCharts {
|
||||
val DATE_TIME_FORMAT: DateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM)
|
||||
|
|
@ -99,15 +102,15 @@ object CommonCharts {
|
|||
|
||||
/** A dynamic [CartesianValueFormatter] that adjusts the time format based on the visible X range. */
|
||||
val dynamicTimeFormatter = CartesianValueFormatter { context, value, _ ->
|
||||
val date = Date((value * MS_PER_SEC.toDouble()).toLong())
|
||||
val date = (value * MS_PER_SEC.toDouble()).toLong().toInstant().toDate()
|
||||
val xLength = context.ranges.xLength
|
||||
val zoom = if (context is CartesianDrawingContext) context.zoom else 1f
|
||||
val visibleSpan = xLength / zoom
|
||||
|
||||
when {
|
||||
visibleSpan <= 3600 -> TIME_SECONDS_FORMAT.format(date) // < 1 hour visible
|
||||
visibleSpan <= 86400 * 2 -> TIME_MINUTE_FORMAT.format(date) // < 2 days visible
|
||||
visibleSpan <= 86400 * 14 -> {
|
||||
visibleSpan <= TimeConstants.ONE_HOUR.inWholeSeconds -> TIME_SECONDS_FORMAT.format(date) // < 1 hour visible
|
||||
visibleSpan <= 2.days.inWholeSeconds -> TIME_MINUTE_FORMAT.format(date) // < 2 days visible
|
||||
visibleSpan <= 14.days.inWholeSeconds -> {
|
||||
// < 2 weeks visible: separate date and time with a newline
|
||||
val dateStr = DATE_FORMAT.format(date)
|
||||
val timeStr = TIME_MINUTE_FORMAT.format(date)
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ import com.patrykandpatrick.vico.compose.cartesian.rememberVicoScrollState
|
|||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.model.TelemetryType
|
||||
import org.meshtastic.core.model.util.formatUptime
|
||||
import org.meshtastic.core.model.util.nowSeconds
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.air_util_definition
|
||||
import org.meshtastic.core.strings.air_utilization
|
||||
|
|
@ -352,7 +353,7 @@ private fun DeviceMetricsChart(
|
|||
@PreviewLightDark
|
||||
@Composable
|
||||
private fun DeviceMetricsChartPreview() {
|
||||
val now = (System.currentTimeMillis() / 1000).toInt()
|
||||
val now = nowSeconds.toInt()
|
||||
val telemetries =
|
||||
List(20) { i ->
|
||||
Telemetry(
|
||||
|
|
@ -468,7 +469,7 @@ private fun DeviceMetricsCard(telemetry: Telemetry, isSelected: Boolean, onClick
|
|||
@PreviewLightDark
|
||||
@Composable
|
||||
private fun DeviceMetricsCardPreview() {
|
||||
val now = (System.currentTimeMillis() / 1000).toInt()
|
||||
val now = nowSeconds.toInt()
|
||||
val telemetry =
|
||||
Telemetry(
|
||||
time = now,
|
||||
|
|
@ -488,7 +489,7 @@ private fun DeviceMetricsCardPreview() {
|
|||
@PreviewLightDark
|
||||
@Composable
|
||||
private fun DeviceMetricsScreenPreview() {
|
||||
val now = (System.currentTimeMillis() / 1000).toInt()
|
||||
val now = nowSeconds.toInt()
|
||||
val telemetries =
|
||||
List(24) { i ->
|
||||
Telemetry(
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||
import com.meshtastic.core.strings.getString
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.model.TelemetryType
|
||||
import org.meshtastic.core.model.util.nowSeconds
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.current
|
||||
import org.meshtastic.core.strings.env_metrics_log
|
||||
|
|
@ -431,8 +432,7 @@ private fun PreviewEnvironmentMetricsContent() {
|
|||
radiation = 0.15f,
|
||||
gas_resistance = 1200.0f,
|
||||
)
|
||||
val fakeTelemetry =
|
||||
Telemetry(time = (System.currentTimeMillis() / 1000).toInt(), environment_metrics = fakeEnvMetrics)
|
||||
val fakeTelemetry = Telemetry(time = nowSeconds.toInt(), environment_metrics = fakeEnvMetrics)
|
||||
MaterialTheme {
|
||||
Surface { EnvironmentMetricsContent(telemetry = fakeTelemetry, environmentDisplayFahrenheit = false) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ import com.meshtastic.core.strings.getString
|
|||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.model.TelemetryType
|
||||
import org.meshtastic.core.model.util.formatUptime
|
||||
import org.meshtastic.core.model.util.nowSeconds
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.disk_free_indexed
|
||||
import org.meshtastic.core.strings.free_memory
|
||||
|
|
@ -129,7 +130,7 @@ fun HostMetricsLogScreen(metricsViewModel: MetricsViewModel = hiltViewModel(), o
|
|||
@Composable
|
||||
fun HostMetricsItem(modifier: Modifier = Modifier, telemetry: Telemetry) {
|
||||
val hostMetrics = telemetry.host_metrics
|
||||
val time = telemetry.time * CommonCharts.MS_PER_SEC
|
||||
val time = telemetry.time.toLong() * CommonCharts.MS_PER_SEC
|
||||
Card(
|
||||
modifier = modifier.fillMaxWidth().padding(vertical = 4.dp).combinedClickable(onClick = { /* Handle click */ }),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp),
|
||||
|
|
@ -281,6 +282,6 @@ private fun HostMetricsItemPreview() {
|
|||
load15 = 19,
|
||||
user_string = "test",
|
||||
)
|
||||
val logs = Telemetry(time = (System.currentTimeMillis() / 1000).toInt(), host_metrics = hostMetrics)
|
||||
val logs = Telemetry(time = nowSeconds.toInt(), host_metrics = hostMetrics)
|
||||
AppTheme { HostMetricsItem(telemetry = logs) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ import org.meshtastic.core.model.DataPacket
|
|||
import org.meshtastic.core.model.TelemetryType
|
||||
import org.meshtastic.core.model.evaluateTracerouteMapAvailability
|
||||
import org.meshtastic.core.model.util.UnitConversions
|
||||
import org.meshtastic.core.model.util.nowSeconds
|
||||
import org.meshtastic.core.model.util.toDate
|
||||
import org.meshtastic.core.model.util.toInstant
|
||||
import org.meshtastic.core.navigation.NodesRoutes
|
||||
import org.meshtastic.core.service.ServiceRepository
|
||||
import org.meshtastic.core.strings.Res
|
||||
|
|
@ -207,7 +210,7 @@ constructor(
|
|||
combine(_state, environmentState) { state, envState ->
|
||||
val stateOldest = state.oldestTimestampSeconds()
|
||||
val envOldest = envState.environmentMetrics.minOfOrNull { (it.time ?: 0).toLong() }?.takeIf { it > 0 }
|
||||
val oldest = listOfNotNull(stateOldest, envOldest).minOrNull() ?: (System.currentTimeMillis() / 1000L)
|
||||
val oldest = listOfNotNull(stateOldest, envOldest).minOrNull() ?: nowSeconds
|
||||
TimeFrame.entries.filter { it.isAvailable(oldest) }
|
||||
}
|
||||
.stateInWhileSubscribed(TimeFrame.entries)
|
||||
|
|
@ -519,7 +522,7 @@ constructor(
|
|||
val dateFormat = SimpleDateFormat("\"yyyy-MM-dd\",\"HH:mm:ss\"", Locale.getDefault())
|
||||
|
||||
positions.forEach { position ->
|
||||
val rxDateTime = dateFormat.format((position.time ?: 0).toLong() * 1000L)
|
||||
val rxDateTime = dateFormat.format(((position.time ?: 0).toLong() * 1000L).toInstant().toDate())
|
||||
val latitude = (position.latitude_i ?: 0) * 1e-7
|
||||
val longitude = (position.longitude_i ?: 0) * 1e-7
|
||||
val altitude = position.altitude
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ import org.jetbrains.compose.resources.stringResource
|
|||
import org.meshtastic.core.database.entity.MeshLog
|
||||
import org.meshtastic.core.model.TelemetryType
|
||||
import org.meshtastic.core.model.util.formatUptime
|
||||
import org.meshtastic.core.model.util.toDate
|
||||
import org.meshtastic.core.model.util.toInstant
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.ble_devices
|
||||
import org.meshtastic.core.strings.no_pax_metrics_logs
|
||||
|
|
@ -72,7 +74,6 @@ import org.meshtastic.core.ui.theme.GraphColors.Orange
|
|||
import org.meshtastic.core.ui.theme.GraphColors.Purple
|
||||
import org.meshtastic.feature.node.detail.NodeRequestEffect
|
||||
import java.text.DateFormat
|
||||
import java.util.Date
|
||||
import org.meshtastic.proto.Paxcount as ProtoPaxcount
|
||||
|
||||
private enum class PaxSeries(val color: Color, val legendRes: StringResource) {
|
||||
|
|
@ -198,7 +199,7 @@ fun PaxMetricsScreen(metricsViewModel: MetricsViewModel = hiltViewModel(), onNav
|
|||
val graphData =
|
||||
paxMetrics
|
||||
.map {
|
||||
val t = (it.first.received_date / 1000).toInt()
|
||||
val t = (it.first.received_date / CommonCharts.MS_PER_SEC).toInt()
|
||||
Triple(t, it.second.ble ?: 0, it.second.wifi ?: 0)
|
||||
}
|
||||
.sortedBy { it.first }
|
||||
|
|
@ -212,7 +213,7 @@ fun PaxMetricsScreen(metricsViewModel: MetricsViewModel = hiltViewModel(), onNav
|
|||
titleRes = Res.string.pax_metrics_log,
|
||||
nodeName = state.node?.user?.long_name ?: "",
|
||||
data = paxMetrics,
|
||||
timeProvider = { (it.first.received_date / 1000).toDouble() },
|
||||
timeProvider = { (it.first.received_date / CommonCharts.MS_PER_SEC).toDouble() },
|
||||
snackbarHostState = snackbarHostState,
|
||||
onRequestTelemetry = { metricsViewModel.requestTelemetry(TelemetryType.PAX) },
|
||||
controlPart = {
|
||||
|
|
@ -254,8 +255,8 @@ fun PaxMetricsScreen(metricsViewModel: MetricsViewModel = hiltViewModel(), onNav
|
|||
log = log,
|
||||
pax = pax,
|
||||
dateFormat = dateFormat,
|
||||
isSelected = (log.received_date / 1000).toDouble() == selectedX,
|
||||
onClick = { onCardClick((log.received_date / 1000).toDouble()) },
|
||||
isSelected = (log.received_date / CommonCharts.MS_PER_SEC).toDouble() == selectedX,
|
||||
onClick = { onCardClick((log.received_date / CommonCharts.MS_PER_SEC).toDouble()) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -297,7 +298,7 @@ fun PaxMetricsItem(log: MeshLog, pax: ProtoPaxcount, dateFormat: DateFormat, isS
|
|||
) {
|
||||
Column(modifier = Modifier.fillMaxWidth().padding(12.dp)) {
|
||||
Text(
|
||||
text = dateFormat.format(Date(log.received_date)),
|
||||
text = dateFormat.format(log.received_date.toInstant().toDate()),
|
||||
style = MaterialTheme.typography.titleMediumEmphasized,
|
||||
textAlign = TextAlign.End,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||
import com.meshtastic.core.strings.getString
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.model.util.metersIn
|
||||
import org.meshtastic.core.model.util.nowSeconds
|
||||
import org.meshtastic.core.model.util.toString
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.alt
|
||||
|
|
@ -270,7 +271,7 @@ private val testPosition =
|
|||
longitude_i = -953698040,
|
||||
altitude = 1230,
|
||||
sats_in_view = 7,
|
||||
time = (System.currentTimeMillis() / 1000).toInt(),
|
||||
time = nowSeconds.toInt(),
|
||||
)
|
||||
|
||||
@Preview(showBackground = true)
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ import org.jetbrains.compose.resources.pluralStringResource
|
|||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.model.fullRouteDiscovery
|
||||
import org.meshtastic.core.model.getTracerouteResponse
|
||||
import org.meshtastic.core.model.util.nowMillis
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.routing_error_no_response
|
||||
import org.meshtastic.core.strings.traceroute
|
||||
|
|
@ -279,7 +280,7 @@ private fun TracerouteItemPreview() {
|
|||
val time =
|
||||
DateUtils.formatDateTime(
|
||||
LocalContext.current,
|
||||
System.currentTimeMillis(),
|
||||
nowMillis,
|
||||
DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_SHOW_TIME or DateUtils.FORMAT_ABBREV_ALL,
|
||||
)
|
||||
AppTheme {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package org.meshtastic.feature.node.model
|
||||
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.meshtastic.core.model.util.nowSeconds
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.all_time
|
||||
import org.meshtastic.core.strings.one_hour_short
|
||||
|
|
@ -35,7 +36,7 @@ enum class TimeFrame(val strRes: StringResource, val seconds: Long) {
|
|||
ALL_TIME(Res.string.all_time, 0),
|
||||
;
|
||||
|
||||
fun timeThreshold(now: Long = System.currentTimeMillis() / 1000L): Long {
|
||||
fun timeThreshold(now: Long = nowSeconds): Long {
|
||||
if (this == ALL_TIME) return 0
|
||||
return now - seconds
|
||||
}
|
||||
|
|
@ -44,7 +45,7 @@ enum class TimeFrame(val strRes: StringResource, val seconds: Long) {
|
|||
* Checks if this time frame is relevant given the oldest available data point. We show the option if the data
|
||||
* extends at least into this timeframe.
|
||||
*/
|
||||
fun isAvailable(oldestTimestampSeconds: Long, now: Long = System.currentTimeMillis() / 1000L): Boolean {
|
||||
fun isAvailable(oldestTimestampSeconds: Long, now: Long = nowSeconds): Boolean {
|
||||
if (this == ALL_TIME || this == ONE_HOUR) return true
|
||||
val rangeSeconds = now - oldestTimestampSeconds
|
||||
return rangeSeconds >= seconds
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.meshtastic.feature.node.metrics
|
|||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.meshtastic.core.model.util.nowSeconds
|
||||
import org.meshtastic.proto.EnvironmentMetrics
|
||||
import org.meshtastic.proto.Telemetry
|
||||
|
||||
|
|
@ -26,7 +27,7 @@ class EnvironmentMetricsStateTest {
|
|||
|
||||
@Test
|
||||
fun `environmentMetricsForGraphing correctly calculates times`() {
|
||||
val now = (System.currentTimeMillis() / 1000).toInt()
|
||||
val now = nowSeconds.toInt()
|
||||
val metrics =
|
||||
listOf(
|
||||
Telemetry(time = now - 100, environment_metrics = EnvironmentMetrics(temperature = 20f)),
|
||||
|
|
@ -42,7 +43,7 @@ class EnvironmentMetricsStateTest {
|
|||
|
||||
@Test
|
||||
fun `environmentMetricsForGraphing handles valid zero temperatures`() {
|
||||
val now = (System.currentTimeMillis() / 1000).toInt()
|
||||
val now = nowSeconds.toInt()
|
||||
val metrics = listOf(Telemetry(time = now, environment_metrics = EnvironmentMetrics(temperature = 0.0f)))
|
||||
val state = EnvironmentMetricsState(metrics)
|
||||
val result = state.environmentMetricsForGraphing()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue