From 1e19799da9dff6edd38acace9c09df2385dd1e14 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Wed, 31 Aug 2022 11:30:50 +0200 Subject: [PATCH] Improve handling of units in energy dashboard (#13454) --- src/components/chart/statistics-chart.ts | 4 +- src/components/entity/ha-statistic-picker.ts | 41 +++++++++++++++---- src/data/energy.ts | 31 ++++++-------- src/data/history.ts | 3 +- .../components/ha-energy-gas-settings.ts | 8 +++- .../dialogs/dialog-energy-battery-settings.ts | 4 +- .../dialogs/dialog-energy-device-settings.ts | 2 +- .../dialogs/dialog-energy-gas-settings.ts | 2 +- .../dialog-energy-grid-flow-settings.ts | 2 +- .../dialogs/dialog-energy-solar-settings.ts | 2 +- .../statistics/developer-tools-statistics.ts | 3 +- .../dialog-statistics-adjust-sum.ts | 4 +- .../energy/hui-energy-distribution-card.ts | 7 +--- .../cards/energy/hui-energy-gas-graph-card.ts | 3 +- .../energy/hui-energy-sources-table-card.ts | 3 +- 15 files changed, 68 insertions(+), 51 deletions(-) diff --git a/src/components/chart/statistics-chart.ts b/src/components/chart/statistics-chart.ts index da1dac1c1d..ece8671a8c 100644 --- a/src/components/chart/statistics-chart.ts +++ b/src/components/chart/statistics-chart.ts @@ -243,8 +243,8 @@ class StatisticsChart extends LitElement { if (!this.unit) { if (unit === undefined) { - unit = meta?.unit_of_measurement; - } else if (unit !== meta?.unit_of_measurement) { + unit = meta?.display_unit_of_measurement; + } else if (unit !== meta?.display_unit_of_measurement) { unit = null; } } diff --git a/src/components/entity/ha-statistic-picker.ts b/src/components/entity/ha-statistic-picker.ts index b1ec9f6a37..a2533c7bb9 100644 --- a/src/components/entity/ha-statistic-picker.ts +++ b/src/components/entity/ha-statistic-picker.ts @@ -31,12 +31,23 @@ export class HaStatisticPicker extends LitElement { @property({ type: Boolean }) public disabled?: boolean; /** - * Show only statistics with these unit of measuments. + * Show only statistics natively stored with these units of measurements. * @type {Array} - * @attr include-unit-of-measurement + * @attr include-statistics-unit-of-measurement */ - @property({ type: Array, attribute: "include-unit-of-measurement" }) - public includeUnitOfMeasurement?: string[]; + @property({ + type: Array, + attribute: "include-statistics-unit-of-measurement", + }) + public includeStatisticsUnitOfMeasurement?: string[]; + + /** + * Show only statistics displayed with these units of measurements. + * @type {Array} + * @attr include-display-unit-of-measurement + */ + @property({ type: Array, attribute: "include-display-unit-of-measurement" }) + public includeDisplayUnitOfMeasurement?: string[]; /** * Show only statistics with these device classes. @@ -86,7 +97,8 @@ export class HaStatisticPicker extends LitElement { private _getStatistics = memoizeOne( ( statisticIds: StatisticsMetaData[], - includeUnitOfMeasurement?: string[], + includeStatisticsUnitOfMeasurement?: string[], + includeDisplayUnitOfMeasurement?: string[], includeDeviceClasses?: string[], entitiesOnly?: boolean ): Array<{ id: string; name: string; state?: HassEntity }> => { @@ -101,9 +113,18 @@ export class HaStatisticPicker extends LitElement { ]; } - if (includeUnitOfMeasurement) { + if (includeStatisticsUnitOfMeasurement) { statisticIds = statisticIds.filter((meta) => - includeUnitOfMeasurement.includes(meta.unit_of_measurement) + includeStatisticsUnitOfMeasurement.includes( + meta.statistics_unit_of_measurement + ) + ); + } + if (includeDisplayUnitOfMeasurement) { + statisticIds = statisticIds.filter((meta) => + includeDisplayUnitOfMeasurement.includes( + meta.display_unit_of_measurement + ) ); } @@ -184,7 +205,8 @@ export class HaStatisticPicker extends LitElement { if (this.hasUpdated) { (this.comboBox as any).items = this._getStatistics( this.statisticIds!, - this.includeUnitOfMeasurement, + this.includeStatisticsUnitOfMeasurement, + this.includeDisplayUnitOfMeasurement, this.includeDeviceClasses, this.entitiesOnly ); @@ -192,7 +214,8 @@ export class HaStatisticPicker extends LitElement { this.updateComplete.then(() => { (this.comboBox as any).items = this._getStatistics( this.statisticIds!, - this.includeUnitOfMeasurement, + this.includeStatisticsUnitOfMeasurement, + this.includeDisplayUnitOfMeasurement, this.includeDeviceClasses, this.entitiesOnly ); diff --git a/src/data/energy.ts b/src/data/energy.ts index 68d18a8e43..f9a2c3d862 100644 --- a/src/data/energy.ts +++ b/src/data/energy.ts @@ -597,7 +597,7 @@ export const getEnergySolarForecasts = (hass: HomeAssistant) => type: "energy/solar_forecast", }); -export const ENERGY_GAS_VOLUME_UNITS = ["m³", "ft³"]; +export const ENERGY_GAS_VOLUME_UNITS = ["m³"]; export const ENERGY_GAS_ENERGY_UNITS = ["kWh"]; export const ENERGY_GAS_UNITS = [ ...ENERGY_GAS_VOLUME_UNITS, @@ -607,18 +607,21 @@ export const ENERGY_GAS_UNITS = [ export type EnergyGasUnit = "volume" | "energy"; export const getEnergyGasUnitCategory = ( - hass: HomeAssistant, - prefs: EnergyPreferences + prefs: EnergyPreferences, + statisticsMetaData: Record = {}, + excludeSource?: string ): EnergyGasUnit | undefined => { for (const source of prefs.energy_sources) { if (source.type !== "gas") { continue; } - - const entity = hass.states[source.stat_energy_from]; - if (entity) { + if (excludeSource && excludeSource === source.stat_energy_from) { + continue; + } + const statisticIdWithMeta = statisticsMetaData[source.stat_energy_from]; + if (statisticIdWithMeta) { return ENERGY_GAS_VOLUME_UNITS.includes( - entity.attributes.unit_of_measurement! + statisticIdWithMeta.display_unit_of_measurement ) ? "volume" : "energy"; @@ -628,7 +631,6 @@ export const getEnergyGasUnitCategory = ( }; export const getEnergyGasUnit = ( - hass: HomeAssistant, prefs: EnergyPreferences, statisticsMetaData: Record = {} ): string | undefined => { @@ -636,18 +638,9 @@ export const getEnergyGasUnit = ( if (source.type !== "gas") { continue; } - const entity = hass.states[source.stat_energy_from]; - if (entity?.attributes.unit_of_measurement) { - // Wh is normalized to kWh by stats generation - return entity.attributes.unit_of_measurement === "Wh" - ? "kWh" - : entity.attributes.unit_of_measurement; - } const statisticIdWithMeta = statisticsMetaData[source.stat_energy_from]; - if (statisticIdWithMeta?.unit_of_measurement) { - return statisticIdWithMeta.unit_of_measurement === "Wh" - ? "kWh" - : statisticIdWithMeta.unit_of_measurement; + if (statisticIdWithMeta?.display_unit_of_measurement) { + return statisticIdWithMeta.display_unit_of_measurement; } } return undefined; diff --git a/src/data/history.ts b/src/data/history.ts index de7f7ccbcd..8337dead32 100644 --- a/src/data/history.ts +++ b/src/data/history.ts @@ -82,7 +82,8 @@ export interface StatisticValue { } export interface StatisticsMetaData { - unit_of_measurement: string; + display_unit_of_measurement: string; + statistics_unit_of_measurement: string; statistic_id: string; source: string; name?: string | null; diff --git a/src/panels/config/energy/components/ha-energy-gas-settings.ts b/src/panels/config/energy/components/ha-energy-gas-settings.ts index e8409b17dd..29b81e2a85 100644 --- a/src/panels/config/energy/components/ha-energy-gas-settings.ts +++ b/src/panels/config/energy/components/ha-energy-gas-settings.ts @@ -133,7 +133,7 @@ export class EnergyGasSettings extends LitElement { private _addSource() { showEnergySettingsGasDialog(this, { - unit: getEnergyGasUnitCategory(this.hass, this.preferences), + unit: getEnergyGasUnitCategory(this.preferences, this.statsMetadata), saveCallback: async (source) => { delete source.unit_of_measurement; await this._savePreferences({ @@ -149,7 +149,11 @@ export class EnergyGasSettings extends LitElement { ev.currentTarget.closest(".row").source; showEnergySettingsGasDialog(this, { source: { ...origSource }, - unit: getEnergyGasUnitCategory(this.hass, this.preferences), + unit: getEnergyGasUnitCategory( + this.preferences, + this.statsMetadata, + origSource.stat_energy_from + ), saveCallback: async (newSource) => { await this._savePreferences({ ...this.preferences, diff --git a/src/panels/config/energy/dialogs/dialog-energy-battery-settings.ts b/src/panels/config/energy/dialogs/dialog-energy-battery-settings.ts index b91e4e3424..0314aefc0d 100644 --- a/src/panels/config/energy/dialogs/dialog-energy-battery-settings.ts +++ b/src/panels/config/energy/dialogs/dialog-energy-battery-settings.ts @@ -67,7 +67,7 @@ export class DialogEnergyBatterySettings = 2 ? this._stats5min : this._statsHour; - const unit = this._params!.statistic.unit_of_measurement; + const unit = this._params!.statistic.display_unit_of_measurement; const rows: TemplateResult[] = []; for (let i = 1; i < data.length; i++) { const stat = data[i]; @@ -221,7 +221,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends LitElement { label="New Value" .hass=${this.hass} .selector=${this._amountSelector( - this._params!.statistic.unit_of_measurement + this._params!.statistic.display_unit_of_measurement )} .value=${this._amount} .disabled=${this._busy} 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 7bc18a6f92..d42863015f 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-distribution-card.ts @@ -315,11 +315,8 @@ class HuiEnergyDistrubutionCard ${formatNumber(gasUsage || 0, this.hass.locale, { maximumFractionDigits: 1, })} - ${getEnergyGasUnit( - this.hass, - prefs, - this._data.statsMetadata - ) || "m³"} + ${getEnergyGasUnit(prefs, this._data.statsMetadata) || + "m³"} diff --git a/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts index 3803a69a23..6ec689b4f8 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts @@ -274,8 +274,7 @@ export class HuiEnergyGasGraphCard ) as GasSourceTypeEnergyPreference[]; this._unit = - getEnergyGasUnit(this.hass, energyData.prefs, energyData.statsMetadata) || - "m³"; + getEnergyGasUnit(energyData.prefs, energyData.statsMetadata) || "m³"; const datasets: ChartDataset<"bar", ScatterDataPoint[]>[] = []; diff --git a/src/panels/lovelace/cards/energy/hui-energy-sources-table-card.ts b/src/panels/lovelace/cards/energy/hui-energy-sources-table-card.ts index 6116c25e4c..ec1c20ee45 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-sources-table-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-sources-table-card.ts @@ -131,8 +131,7 @@ export class HuiEnergySourcesTableCard ); const gasUnit = - getEnergyGasUnit(this.hass, this._data.prefs, this._data.statsMetadata) || - ""; + getEnergyGasUnit(this._data.prefs, this._data.statsMetadata) || ""; const compare = this._data.statsCompare !== undefined;