MetricFormatter

Centralized metric formatting for display strings. Eliminates duplicated formatString patterns across Node, NodeItem, and metric screens.

Every number here reads in the user's locale; the unit symbols are fixed. Units that vary by locale (wind speed, rainfall, weight) pick their symbol from MeasureUnitKind via formatMeasure; the universal ones (V, mA, dB, dBm, hPa, %, °C) carry theirs inline. Either way the value goes through NumberFormatter.format, so a German reader sees "3,85 V" and "0,0°C".

The one thing that stays locale-independent is anything another system parses — see NumberFormatter.formatInvariant.

Functions

Link copied to clipboard
fun current(milliAmps: Float, decimalPlaces: Int = 1): String
Link copied to clipboard
fun degreeSymbol(isFahrenheit: Boolean): String

The degree symbol for the display unit, for callers that already hold a converted value and only need to label it — chart axes, and the telemetry rows fed by an upstream conversion. Defined here so a symbol has one definition: wind drifted between screens precisely because its unit was written out twice.

Link copied to clipboard
fun humidity(value: Float): String
Link copied to clipboard
fun percent(value: Int): String
fun percent(value: Float, decimalPlaces: Int = 1): String
Link copied to clipboard
fun pressure(hPa: Float, decimalPlaces: Int = 1): String
Link copied to clipboard
fun rainfall(millimeters: Float, isImperial: Boolean, decimalPlaces: Int = 1): String
Link copied to clipboard
fun rssi(value: Int?): String

Formats a received signal strength, or UNKNOWN_VALUE when the radio reported none. 0 dBm is a legitimate reading on some radios, so it must never stand in for a missing one.

Link copied to clipboard
fun snr(value: Float?, decimalPlaces: Int = 1): String

Formats a signal-to-noise ratio, or UNKNOWN_VALUE when the packet carried no measurement. 0 dB is a legitimate reading, so it must never stand in for a missing one.

Link copied to clipboard
fun temperature(celsius: Float, isFahrenheit: Boolean): String
Link copied to clipboard
fun voltage(volts: Float, decimalPlaces: Int = 2): String
Link copied to clipboard
fun weight(kilograms: Float, isImperial: Boolean, decimalPlaces: Int = 2): String
Link copied to clipboard
fun windSpeed(metersPerSecond: Float, isImperial: Boolean, decimalPlaces: Int = 1): String

Wind arrives from the sensor in m/s and is shown in the unit a reader expects for weather: km/h for metric, mph for imperial. m/s is the meteorological observation standard, but public forecasts across most metric regions quote km/h, so that is what the app displays. The charts convert the same way — see chartValue — so a reading reads identically on the node card and on its graph.