feat(client): adaptive W/kW display for miner power usage#115
feat(client): adaptive W/kW display for miner power usage#115Schnitzel wants to merge 1 commit intoblock:mainfrom
Conversation
MinerPowerUsage was hardcoding kW as the unit, showing low-wattage miners (e.g. Bitaxe at ~12.5 W) as "0 kW". Adds formatPowerKW which renders values below 1 kW in W (1 decimal) and >= 1 kW in kW (1 decimal). Signed-off-by: Michael Schmid <michael.schmid@amazee.io> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
e836e96 to
e168d81
Compare
There was a problem hiding this comment.
Pull request overview
Adds adaptive power-unit formatting to the client so low-power miners no longer display as 0 kW, aligning fleet UI output with actual kW telemetry values.
Changes:
- Added
formatPowerKWutility to format kW values as eitherW(< 1 kW) orkW(>= 1 kW). - Added unit tests for
formatPowerKW. - Updated
MinerPowerUsageto render power usage with adaptive units instead of hardcodingkW.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| client/src/shared/utils/stringUtils.ts | Adds formatPowerKW helper for adaptive W/kW formatting. |
| client/src/shared/utils/stringUtils.test.ts | Adds test coverage for formatPowerKW. |
| client/src/protoFleet/features/fleetManagement/components/MinerList/MinerPowerUsage.tsx | Switches power usage cell rendering to use adaptive formatting. |
| import MinerMeasurement from "./MinerMeasurement"; | ||
| import UnsupportedMetric from "./UnsupportedMetric"; |
There was a problem hiding this comment.
MinerMeasurement is still imported but no longer used after switching to inline rendering. This will fail linting under @typescript-eslint/no-unused-vars; remove the import or use the component again (e.g., by extending it to support adaptive units).
| /** | ||
| * Formats a power value in kW with adaptive units. | ||
| * Values >= 1 kW are shown in kW (1 decimal place). | ||
| * Values < 1 kW are converted to W (rounded to nearest integer). | ||
| */ | ||
| export const formatPowerKW = (kw: number): { value: string; unit: string } => { | ||
| if (kw >= 1) { | ||
| return { value: separateByCommas(kw.toFixed(1)), unit: "kW" }; | ||
| } | ||
| return { value: separateByCommas((kw * 1000).toFixed(1)), unit: "W" }; |
There was a problem hiding this comment.
The docstring says values < 1 kW are converted to W "(rounded to nearest integer)", but the implementation uses toFixed(1) (one decimal place). Update the comment to match the actual formatting behavior (or adjust the implementation to match the comment).
| if (powerUsage === undefined) return <SkeletonBar className="w-full pr-10" />; | ||
| if (powerUsage === null) return <>{INACTIVE_PLACEHOLDER}</>; | ||
| if (powerUsage.length === 0) return null; | ||
|
|
||
| const latestValue = getLatestMeasurementWithData(powerUsage)?.value; | ||
| if (latestValue === undefined) return <>{INACTIVE_PLACEHOLDER}</>; | ||
|
|
||
| const { value, unit } = formatPowerKW(latestValue); | ||
| return <>{value} {unit}</>; |
There was a problem hiding this comment.
MinerPowerUsage now re-implements the same loading/offline/empty/latest-value logic that already exists in MinerMeasurement. To avoid future drift between measurement cells, consider refactoring MinerMeasurement to accept a formatter (or render prop) so MinerPowerUsage can keep the shared state handling while still using adaptive units.
ankitgoswami
left a comment
There was a problem hiding this comment.
Thanks for the PR!
I agree with the bot about the code duplication. Adding an optional formatValue?: (value: number) => { value: string; unit: string } prop seems like a good idea. Default behavior keeps getDisplayValue(latestValue) + unit. MinerPowerUsage becomes:
Summary
MinerPowerUsagewas hardcodingkWas the unit with no conversion, causing low-wattage miners (e.g. Bitaxe at ~12.5 W) to display as0 kWformatPowerKWutility: values< 1 kWare shown in W (1 decimal place), values>= 1 kWare shown in kW (1 decimal place)<MinerMeasurement unit="kW">call with inline rendering using the adaptive formatterTest plan
formatPowerKWunit tests pass (stringUtils.test.ts)12.5 Winstead of0 kW3.2 kW🤖 Generated with Claude Code