From 84cd710b60c24c29d67afb91ae3521a445fd723c Mon Sep 17 00:00:00 2001 From: Sese Schneider Date: Thu, 9 Mar 2023 13:01:42 +0100 Subject: [PATCH] fix: Power factor display precision when using local number formats --- src/energy-overview-card.ts | 68 +++++++++++++++++++++++-------------- src/types.ts | 19 +++++++---- 2 files changed, 56 insertions(+), 31 deletions(-) diff --git a/src/energy-overview-card.ts b/src/energy-overview-card.ts index 4ba608a..bf0bc9d 100644 --- a/src/energy-overview-card.ts +++ b/src/energy-overview-card.ts @@ -5,7 +5,7 @@ import {customElement, property, state} from "lit/decorators"; import {unsafeHTML} from 'lit/directives/unsafe-html.js'; import {HomeAssistant} from "custom-card-helpers"; import {version} from "../package.json"; -import {EnergyOverviewConfig, EnergyOverviewEntityUI} from "./types"; +import {EnergyOverviewConfig, EnergyOverviewEntityState, EnergyOverviewEntityUI} from "./types"; import {clamp, intersperse} from "./helper/util"; import {formatNumber, getNumberFormatOptions} from "./helper/format-number"; import { @@ -144,16 +144,11 @@ export class EnergyOverviewCard extends LitElement { const entities: Array = []; this._config.entities.forEach((entity) => { entities.push({ - power: this._formatNumber(entity.power, '0')!, - power_unit: this._extractUnit(entity.power, UnitOfPower.WATT), - current: this._formatNumber(entity.current), - current_unit: this._extractUnit(entity.current, UnitOfElectricCurrent.AMPERE), - voltage: this._formatNumber(entity.voltage), - voltage_unit: this._extractUnit(entity.voltage, UnitOfElectricPotential.VOLT), - frequency: this._formatNumber(entity.frequency), - frequency_unit: this._extractUnit(entity.frequency, UnitOfFrequency.HERTZ), - power_factor: this._formatNumber(entity.power_factor), - power_factor_unit: this._extractUnit(entity.power_factor, ''), + power: this._getState(entity.power, UnitOfPower.WATT, '0')!, + current: this._getState(entity.current, UnitOfElectricCurrent.AMPERE), + voltage: this._getState(entity.voltage, UnitOfElectricPotential.VOLT), + frequency: this._getState(entity.frequency, UnitOfFrequency.HERTZ), + power_factor: this._getState(entity.power_factor, ''), name: entity.name ? entity.name : '', color: entity.color ? entity.color : 'var(--energy-grid-consumption-color)', label_trailing: entity.label_trailing ? entity.label_trailing : '', @@ -177,9 +172,9 @@ export class EnergyOverviewCard extends LitElement { ${entities.map((entity, i) => { /* Power calculation */ - const configPower = parseFloat(entity.power); + const configPower = entity.power.value!; let powerValue: number; - switch (entity.power_unit) { + switch (entity.power.unit) { case UnitOfPower.KILO_WATT: powerValue = 1000 * configPower; break; @@ -193,14 +188,22 @@ export class EnergyOverviewCard extends LitElement { } /* Power factor calculation */ - let powerFactor: string | undefined; + let powerFactorDisplay: string | undefined; if (entity.power_factor) { - const pf = parseFloat(entity.power_factor); + const pf = entity.power_factor.value; // power factor is realistically never at 1%, we can safely assume it's a percentage - if ((pf < -1 || pf > 1) || entity.power_factor_unit === PERCENTAGE) { - powerFactor = entity.power_factor; + if ((pf < -1 || pf > 1) || entity.power_factor.unit === PERCENTAGE) { + powerFactorDisplay = entity.power_factor.display; } else { - powerFactor = `${Math.round(pf * 100)}`; + // subtract 2 because of the multiplication by 100 + let precision = (entity.power_factor.precision ?? 0) - 2; + // default to 0 precision in case of negative values + precision = precision >= 0 ? precision : 0; + powerFactorDisplay = formatNumber( + pf * 100, + this.hass!.locale, + {maximumFractionDigits: precision, minimumFractionDigits: precision}, + ); } } @@ -233,13 +236,13 @@ export class EnergyOverviewCard extends LitElement { ${unsafeHTML((() => { const elements: Array = []; if (entity.voltage) { - elements.push(`${entity.voltage} ${entity.voltage_unit}`); + elements.push(`${entity.voltage.display} ${entity.voltage.unit}`); } if (entity.current) { - elements.push(`${entity.current} ${entity.current_unit}`); + elements.push(`${entity.current.display} ${entity.current.unit}`); } if (entity.frequency) { - elements.push(`${entity.frequency} ${entity.frequency_unit}`); + elements.push(`${entity.frequency.display} ${entity.frequency.unit}`); } return intersperse( @@ -250,12 +253,12 @@ export class EnergyOverviewCard extends LitElement { ` : ``} - ${powerFactor ? html` + ${powerFactorDisplay ? html` ` : ``}
@@ -292,6 +295,21 @@ export class EnergyOverviewCard extends LitElement { `; } + private _getState( + entity: string | undefined, + fallbackUnit: string, + fallbackValue?: string, + ) { + const stateObj = entity ? this.hass!.states[entity] : undefined; + if (!stateObj && !fallbackValue) return undefined; + return { + value: parseFloat(stateObj ? stateObj.state : fallbackValue!), + unit: this._extractUnit(entity, fallbackUnit), + display: this._formatNumber(entity, fallbackValue), + precision: entity ? (this.hass as any).entities[entity]?.display_precision : undefined, + }; + } + private _extractUnit(entity: string | undefined, fallback: string) { return entity ? this.hass!.states[entity].attributes.unit_of_measurement ?? fallback : fallback; } diff --git a/src/types.ts b/src/types.ts index ef40aab..8487458 100644 --- a/src/types.ts +++ b/src/types.ts @@ -20,12 +20,19 @@ export interface EnergyOverviewEntity { animation?: EnergyOverviewAnimation; } -export interface EnergyOverviewEntityUI extends EnergyOverviewEntity { - power_unit: string; - current_unit: string; - voltage_unit: string; - frequency_unit: string; - power_factor_unit: string; +export interface EnergyOverviewEntityState { + value: number, + unit: string; + display: string; + precision?: number; +} + +export interface EnergyOverviewEntityUI extends Omit { + power: EnergyOverviewEntityState; + current: EnergyOverviewEntityState | undefined; + voltage: EnergyOverviewEntityState | undefined; + frequency: EnergyOverviewEntityState | undefined; + power_factor: EnergyOverviewEntityState | undefined; } export interface EnergyOverviewConfig {