From 5cf8b3970308109f877edc9caccb96a07ab1c04f Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Wed, 9 Jul 2025 04:06:47 -0700 Subject: [PATCH] Coerce all energy distribution values to the same unit (#26117) --- src/data/energy.ts | 24 +++++++++---- .../energy/hui-energy-distribution-card.ts | 35 ++++++++++++++---- test/data/energy.test.ts | 36 +++++++++++++++++-- 3 files changed, 79 insertions(+), 16 deletions(-) diff --git a/src/data/energy.ts b/src/data/energy.ts index 3510c92125..073ed41c7f 100644 --- a/src/data/energy.ts +++ b/src/data/energy.ts @@ -1109,21 +1109,31 @@ export const computeConsumptionSingle = (data: { export const formatConsumptionShort = ( hass: HomeAssistant, consumption: number | null, - unit: string + unit: string, + targetUnit?: string ): string => { - if (!consumption) { - return `0 ${unit}`; - } const units = ["Wh", "kWh", "MWh", "GWh", "TWh"]; let pickedUnit = unit; - let val = consumption; + let val = consumption || 0; + let targetUnitIndex = -1; + if (targetUnit) { + targetUnitIndex = units.findIndex((u) => u === targetUnit); + } let unitIndex = units.findIndex((u) => u === unit); if (unitIndex >= 0) { - while (Math.abs(val) < 1 && unitIndex > 0) { + while ( + targetUnitIndex > -1 + ? targetUnitIndex < unitIndex + : Math.abs(val) < 1 && unitIndex > 0 + ) { val *= 1000; unitIndex--; } - while (Math.abs(val) >= 1000 && unitIndex < units.length - 1) { + while ( + targetUnitIndex > -1 + ? targetUnitIndex > unitIndex + : Math.abs(val) >= 1000 && unitIndex < units.length - 1 + ) { val /= 1000; unitIndex++; } diff --git a/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts b/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts index 60a0a801db..9d5491572e 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts @@ -255,6 +255,20 @@ class HuiEnergyDistrubutionCard (batteryFromGrid || 0) + (batteryToGrid || 0); + // Coerce all energy numbers to the same unit (the biggest) + const maxEnergy = Math.max( + lowCarbonEnergy || 0, + totalSolarProduction || 0, + returnedToGrid || 0, + totalFromGrid || 0, + totalHomeConsumption, + totalBatteryIn || 0, + totalBatteryOut || 0 + ); + const targetEnergyUnit = formatConsumptionShort(this.hass, maxEnergy, "kWh") + .split(" ") + .pop(); + return html`
@@ -281,7 +295,8 @@ class HuiEnergyDistrubutionCard ${formatConsumptionShort( this.hass, lowCarbonEnergy, - "kWh" + "kWh", + targetEnergyUnit )} @@ -300,7 +315,8 @@ class HuiEnergyDistrubutionCard ${formatConsumptionShort( this.hass, totalSolarProduction, - "kWh" + "kWh", + targetEnergyUnit )}
` @@ -396,7 +412,8 @@ class HuiEnergyDistrubutionCard >${formatConsumptionShort( this.hass, returnedToGrid, - "kWh" + "kWh", + targetEnergyUnit )} ` : ""} @@ -409,7 +426,8 @@ class HuiEnergyDistrubutionCard : ""}${formatConsumptionShort( this.hass, totalFromGrid, - "kWh" + "kWh", + targetEnergyUnit )} @@ -432,7 +450,8 @@ class HuiEnergyDistrubutionCard ${formatConsumptionShort( this.hass, totalHomeConsumption, - "kWh" + "kWh", + targetEnergyUnit )} ${homeSolarCircumference !== undefined || homeLowCarbonCircumference !== undefined @@ -535,7 +554,8 @@ class HuiEnergyDistrubutionCard >${formatConsumptionShort( this.hass, totalBatteryIn, - "kWh" + "kWh", + targetEnergyUnit )} @@ -546,7 +566,8 @@ class HuiEnergyDistrubutionCard >${formatConsumptionShort( this.hass, totalBatteryOut, - "kWh" + "kWh", + targetEnergyUnit )} diff --git a/test/data/energy.test.ts b/test/data/energy.test.ts index 02d8fe170e..f7fe5605a3 100644 --- a/test/data/energy.test.ts +++ b/test/data/energy.test.ts @@ -70,8 +70,10 @@ describe("Energy Short Format Test", () => { const hass = { locale: defaultLocale } as HomeAssistant; it("No Unit conversion", () => { assert.strictEqual(formatConsumptionShort(hass, 0, "Wh"), "0 Wh"); - assert.strictEqual(formatConsumptionShort(hass, 0, "kWh"), "0 kWh"); - assert.strictEqual(formatConsumptionShort(hass, 0, "GWh"), "0 GWh"); + assert.strictEqual(formatConsumptionShort(hass, 0, "kWh"), "0 Wh"); + assert.strictEqual(formatConsumptionShort(hass, 0, "kWh", "kWh"), "0 kWh"); + assert.strictEqual(formatConsumptionShort(hass, 0, "GWh"), "0 Wh"); + assert.strictEqual(formatConsumptionShort(hass, 0, "GWh", "GWh"), "0 GWh"); assert.strictEqual(formatConsumptionShort(hass, 0, "gal"), "0 gal"); assert.strictEqual( @@ -139,6 +141,36 @@ describe("Energy Short Format Test", () => { "-1.23 Wh" ); }); + it("Conversion with target unit", () => { + assert.strictEqual( + formatConsumptionShort(hass, 0.00012, "kWh", "Wh"), + "0.12 Wh" + ); + assert.strictEqual( + formatConsumptionShort(hass, 0.00012, "kWh", "kWh"), + "0 kWh" + ); + assert.strictEqual( + formatConsumptionShort(hass, 0.01012, "kWh", "kWh"), + "0.01 kWh" + ); + assert.strictEqual( + formatConsumptionShort(hass, 0.00012, "kWh", "MWh"), + "0 MWh" + ); + assert.strictEqual( + formatConsumptionShort(hass, 10.12345, "kWh", "kWh"), + "10.1 kWh" + ); + assert.strictEqual( + formatConsumptionShort(hass, 10.12345, "kWh", "ZZZZZWh"), + "10.1 kWh" + ); + assert.strictEqual( + formatConsumptionShort(hass, 151234.5678, "kWh", "MWh"), + "151 MWh" + ); + }); }); describe("Energy Usage Calculation Tests", () => {