41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
/**
|
|||
|
|
* format.ts — shared metric value formatting helpers for the Energy view.
|
||
|
|
*
|
||
|
|
* Rules (from M5 polish requirements):
|
||
|
|
* - device_class === "energy" → 3 decimal places (kWh values need precision)
|
||
|
|
* - everything else → 2 decimal places
|
||
|
|
* - null / undefined / NaN → placeholder "—"
|
||
|
|
* - missing metric metadata → default 2 decimal places
|
||
|
|
*/
|
||
|
|
|
||
|
|
import type { MetricInfo } from './hooks'
|
||
|
|
|
||
|
|
/** Placeholder shown when a value is unavailable. */
|
||
|
|
export const VALUE_PLACEHOLDER = '—'
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Format a numeric metric value for display.
|
||
|
|
*
|
||
|
|
* @param value The raw value from the API payload (any type; non-numeric → "—").
|
||
|
|
* @param metric Optional metric metadata from /metrics. When absent, falls back
|
||
|
|
* to 2 decimal places.
|
||
|
|
* @returns A formatted string ready for display (e.g. "230.25" or "—").
|
||
|
|
*/
|
||
|
|
export function formatMetricValue(
|
||
|
|
value: unknown,
|
||
|
|
metric?: MetricInfo | null,
|
||
|
|
): string {
|
||
|
|
// Guard: null / undefined
|
||
|
|
if (value === null || value === undefined) return VALUE_PLACEHOLDER
|
||
|
|
|
||
|
|
const n = Number(value)
|
||
|
|
|
||
|
|
// Guard: NaN or non-finite
|
||
|
|
if (!Number.isFinite(n)) return VALUE_PLACEHOLDER
|
||
|
|
|
||
|
|
// Determine decimal places from device_class.
|
||
|
|
const decimals = metric?.device_class === 'energy' ? 3 : 2
|
||
|
|
|
||
|
|
return n.toFixed(decimals)
|
||
|
|
}
|