mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-09-21 11:15:18 -04:00
184 lines
8.8 KiB
HTML
184 lines
8.8 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en" dir="ltr">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Measurement & Formatting</title>
|
||
<link rel="stylesheet" href="../styles/docs.css">
|
||
</head>
|
||
<body data-page="measurement" data-locale="en">
|
||
<pre class="markdown-content"># Measurement & Formatting
|
||
|
||
How the Meshtastic Android/KMP app formats numbers, units, and locale-sensitive values.
|
||
|
||
## Overview
|
||
|
||
All measurement data transmitted by Meshtastic nodes uses **metric units** (meters, °C, hPa, m/s, etc.). The app converts and formats these values for display using two core utilities:
|
||
|
||
Utility | Location | Purpose |
|
||
---|---|---|
|
||
`MetricFormatter` | `core/common/.../util/MetricFormatter.kt` | Converts and formats physical measurements (temperature, pressure, speed, etc.) |
|
||
`NumberFormatter` | `core/common/.../util/NumberFormatter.kt` | Decimal formatting: `format` follows the OS locale, `formatInvariant` keeps a fixed dot separator |
|
||
`MeasureFormatting` | `core/common/.../util/MeasureFormatting.kt` | Pairs a fixed English unit symbol with a locale-formatted number, for the units that convert |
|
||
|
||
Both live in `org.meshtastic.core.common.util` and are available to all KMP targets (Android, Desktop, iOS).
|
||
|
||
## MetricFormatter API
|
||
|
||
`MetricFormatter` is a Kotlin `object` with pure functions for each measurement type:
|
||
|
||
```kotlin
|
||
object MetricFormatter {
|
||
fun temperature(celsius: Float, isFahrenheit: Boolean): String
|
||
fun voltage(volts: Float, decimalPlaces: Int = 2): String
|
||
fun current(milliAmps: Float, decimalPlaces: Int = 1): String
|
||
fun percent(value: Float, decimalPlaces: Int = 1): String
|
||
fun humidity(value: Float): String
|
||
fun pressure(hPa: Float, decimalPlaces: Int = 1): String
|
||
fun snr(value: Float?, decimalPlaces: Int = 1): String
|
||
fun rssi(value: Int?): String
|
||
fun degreeSymbol(isFahrenheit: Boolean): String
|
||
fun percent(value: Int): String
|
||
fun windSpeed(metersPerSecond: Float, isImperial: Boolean, decimalPlaces: Int = 1): String
|
||
fun rainfall(millimeters: Float, isImperial: Boolean, decimalPlaces: Int = 1): String
|
||
fun weight(kilograms: Float, isImperial: Boolean, decimalPlaces: Int = 2): String
|
||
}
|
||
|
||
`snr` and `rssi` take a nullable reading and render the `—` placeholder when it is absent.
|
||
```
|
||
|
||
### Usage
|
||
|
||
```kotlin
|
||
// Temperature — Fahrenheit conversion is handled automatically
|
||
MetricFormatter.temperature(22.5f, isFahrenheit = true) // "72.5°F"
|
||
MetricFormatter.temperature(22.5f, isFahrenheit = false) // "22.5°C"
|
||
|
||
// Signal metrics
|
||
MetricFormatter.snr(-5.2f) // "-5.2 dB"
|
||
MetricFormatter.rssi(-97) // "-97 dBm"
|
||
|
||
// Environment
|
||
MetricFormatter.pressure(1013.25f) // "1013.3 hPa"
|
||
MetricFormatter.humidity(65.0f) // "65%"
|
||
MetricFormatter.windSpeed(3.7f, isImperial = false) // "13.3 km/h"
|
||
MetricFormatter.windSpeed(3.7f, isImperial = true) // "8.3 mph"
|
||
MetricFormatter.rainfall(12.3f, isImperial = false) // "12.3 mm"
|
||
MetricFormatter.rainfall(12.3f, isImperial = true) // "0.5 in"
|
||
|
||
// Power
|
||
MetricFormatter.voltage(3.95f) // "3.95 V"
|
||
MetricFormatter.current(125.0f) // "125.0 mA"
|
||
```
|
||
|
||
## NumberFormatter
|
||
|
||
`NumberFormatter` has two halves, and picking the wrong one is the mistake to avoid:
|
||
|
||
```kotlin
|
||
object NumberFormatter {
|
||
fun format(value: Double, decimalPlaces: Int): String // follows the OS locale
|
||
fun format(value: Float, decimalPlaces: Int): String // follows the OS locale
|
||
fun formatInvariant(value: Double, decimalPlaces: Int): String // fixed dot separator
|
||
}
|
||
```
|
||
|
||
**Use |