Skip to content

Commit

Permalink
fix: Power factor display precision when using local number formats
Browse files Browse the repository at this point in the history
  • Loading branch information
Sese-Schneider committed Mar 9, 2023
1 parent 4ce89f4 commit 84cd710
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 31 deletions.
68 changes: 43 additions & 25 deletions src/energy-overview-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -144,16 +144,11 @@ export class EnergyOverviewCard extends LitElement {
const entities: Array<EnergyOverviewEntityUI> = [];
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 : '',
Expand All @@ -177,9 +172,9 @@ export class EnergyOverviewCard extends LitElement {
<ha-card>
${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;
Expand All @@ -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},
);
}
}
Expand Down Expand Up @@ -233,13 +236,13 @@ export class EnergyOverviewCard extends LitElement {
${unsafeHTML((() => {
const elements: Array<String> = [];
if (entity.voltage) {
elements.push(`<span class="secondary voltage">${entity.voltage}</span>&nbsp;<span class="secondary voltage-unit">${entity.voltage_unit}</span>`);
elements.push(`<span class="secondary voltage">${entity.voltage.display}</span>&nbsp;<span class="secondary voltage-unit">${entity.voltage.unit}</span>`);
}
if (entity.current) {
elements.push(`<span class="secondary current">${entity.current}</span>&nbsp;<span class="secondary current-unit">${entity.current_unit}</span>`);
elements.push(`<span class="secondary current">${entity.current.display}</span>&nbsp;<span class="secondary current-unit">${entity.current.unit}</span>`);
}
if (entity.frequency) {
elements.push(`<span class="secondary frequency">${entity.frequency}</span>&nbsp;<span class="secondary frequency-unit">${entity.frequency_unit}</span>`);
elements.push(`<span class="secondary frequency">${entity.frequency.display}</span>&nbsp;<span class="secondary frequency-unit">${entity.frequency.unit}</span>`);
}
return intersperse(
Expand All @@ -250,12 +253,12 @@ export class EnergyOverviewCard extends LitElement {
</div>`
: ``}
<div class="metadata-center">
<span class="secondary power">${entity.power}</span>&nbsp;<span
class="secondary power-unit">${entity.power_unit}</span>
<span class="secondary power">${entity.power.display}</span>&nbsp;<span
class="secondary power-unit">${entity.power.unit}</span>
</div>
${powerFactor ? html`
${powerFactorDisplay ? html`
<div class="metadata-right">
<span class="secondary power-factor">${powerFactor}</span>&nbsp;<span
<span class="secondary power-factor">${powerFactorDisplay}</span>&nbsp;<span
class="secondary power-factor-unit">${PERCENTAGE}</span></div>` : ``}
</div>
<div class="main">
Expand Down Expand Up @@ -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 <EnergyOverviewEntityState>{
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;
}
Expand Down
19 changes: 13 additions & 6 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<EnergyOverviewEntity, 'power' | 'current' | 'voltage' | 'frequency' | 'power_factor'> {
power: EnergyOverviewEntityState;
current: EnergyOverviewEntityState | undefined;
voltage: EnergyOverviewEntityState | undefined;
frequency: EnergyOverviewEntityState | undefined;
power_factor: EnergyOverviewEntityState | undefined;
}

export interface EnergyOverviewConfig {
Expand Down

0 comments on commit 84cd710

Please sign in to comment.