From 416661f3d12e7e188b974af8f159f027cc0b73d7 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Wed, 9 Aug 2023 07:18:57 -0700 Subject: [PATCH] Filter energy grid sources to not allow duplicates (#17381) --- src/components/entity/ha-statistic-picker.ts | 23 +++++++++++++++--- .../components/ha-energy-grid-settings.ts | 24 ++++++++++++------- .../dialog-energy-grid-flow-settings.ts | 22 ++++++++++++++--- .../energy/dialogs/show-dialogs-energy.ts | 4 ++++ 4 files changed, 59 insertions(+), 14 deletions(-) diff --git a/src/components/entity/ha-statistic-picker.ts b/src/components/entity/ha-statistic-picker.ts index 3a46527766fa..830d7c5760f8 100644 --- a/src/components/entity/ha-statistic-picker.ts +++ b/src/components/entity/ha-statistic-picker.ts @@ -79,6 +79,14 @@ export class HaStatisticPicker extends LitElement { @property({ type: Boolean, attribute: "entities-only" }) public entitiesOnly = false; + /** + * List of statistics to be excluded. + * @type {Array} + * @attr exclude-statistics + */ + @property({ type: Array, attribute: "exclude-statistics" }) + public excludeStatistics?: string[]; + @state() private _opened?: boolean; @query("ha-combo-box", true) public comboBox!: HaComboBox; @@ -118,7 +126,8 @@ export class HaStatisticPicker extends LitElement { includeStatisticsUnitOfMeasurement?: string | string[], includeUnitClass?: string | string[], includeDeviceClass?: string | string[], - entitiesOnly?: boolean + entitiesOnly?: boolean, + excludeStatistics?: string[] ): StatisticItem[] => { if (!statisticIds.length) { return [ @@ -163,6 +172,12 @@ export class HaStatisticPicker extends LitElement { const output: StatisticItem[] = []; statisticIds.forEach((meta) => { + if ( + excludeStatistics && + excludeStatistics.includes(meta.statistic_id) + ) { + return; + } const entityState = this.hass.states[meta.statistic_id]; if (!entityState) { if (!entitiesOnly) { @@ -240,7 +255,8 @@ export class HaStatisticPicker extends LitElement { this.includeStatisticsUnitOfMeasurement, this.includeUnitClass, this.includeDeviceClass, - this.entitiesOnly + this.entitiesOnly, + this.excludeStatistics ); } else { this.updateComplete.then(() => { @@ -249,7 +265,8 @@ export class HaStatisticPicker extends LitElement { this.includeStatisticsUnitOfMeasurement, this.includeUnitClass, this.includeDeviceClass, - this.entitiesOnly + this.entitiesOnly, + this.excludeStatistics ); }); } diff --git a/src/panels/config/energy/components/ha-energy-grid-settings.ts b/src/panels/config/energy/components/ha-energy-grid-settings.ts index e2c48c067277..92098fce5e66 100644 --- a/src/panels/config/energy/components/ha-energy-grid-settings.ts +++ b/src/panels/config/energy/components/ha-energy-grid-settings.ts @@ -294,13 +294,13 @@ export class EnergyGridSettings extends LitElement { } private _addFromSource() { + const gridSource = this.preferences.energy_sources.find( + (src) => src.type === "grid" + ) as GridSourceTypeEnergyPreference | undefined; showEnergySettingsGridFlowFromDialog(this, { + grid_source: gridSource, saveCallback: async (flow) => { let preferences: EnergyPreferences; - const gridSource = this.preferences.energy_sources.find( - (src) => src.type === "grid" - ) as GridSourceTypeEnergyPreference | undefined; - if (!gridSource) { preferences = { ...this.preferences, @@ -328,13 +328,13 @@ export class EnergyGridSettings extends LitElement { } private _addToSource() { + const gridSource = this.preferences.energy_sources.find( + (src) => src.type === "grid" + ) as GridSourceTypeEnergyPreference | undefined; showEnergySettingsGridFlowToDialog(this, { + grid_source: gridSource, saveCallback: async (flow) => { let preferences: EnergyPreferences; - const gridSource = this.preferences.energy_sources.find( - (src) => src.type === "grid" - ) as GridSourceTypeEnergyPreference | undefined; - if (!gridSource) { preferences = { ...this.preferences, @@ -364,8 +364,12 @@ export class EnergyGridSettings extends LitElement { private _editFromSource(ev) { const origSource: FlowFromGridSourceEnergyPreference = ev.currentTarget.closest(".row").source; + const gridSource = this.preferences.energy_sources.find( + (src) => src.type === "grid" + ) as GridSourceTypeEnergyPreference | undefined; showEnergySettingsGridFlowFromDialog(this, { source: { ...origSource }, + grid_source: gridSource, metadata: this.statsMetadata?.[origSource.stat_energy_from], saveCallback: async (source) => { const flowFrom = energySourcesByType(this.preferences).grid![0] @@ -392,8 +396,12 @@ export class EnergyGridSettings extends LitElement { private _editToSource(ev) { const origSource: FlowToGridSourceEnergyPreference = ev.currentTarget.closest(".row").source; + const gridSource = this.preferences.energy_sources.find( + (src) => src.type === "grid" + ) as GridSourceTypeEnergyPreference | undefined; showEnergySettingsGridFlowToDialog(this, { source: { ...origSource }, + grid_source: gridSource, metadata: this.statsMetadata?.[origSource.stat_energy_to], saveCallback: async (source) => { const flowTo = energySourcesByType(this.preferences).grid![0].flow_to; diff --git a/src/panels/config/energy/dialogs/dialog-energy-grid-flow-settings.ts b/src/panels/config/energy/dialogs/dialog-energy-grid-flow-settings.ts index be742d36451e..fece7e15ae9f 100644 --- a/src/panels/config/energy/dialogs/dialog-energy-grid-flow-settings.ts +++ b/src/panels/config/energy/dialogs/dialog-energy-grid-flow-settings.ts @@ -49,6 +49,8 @@ export class DialogEnergyGridFlowSettings @state() private _error?: string; + private _excludeList?: string[]; + public async showDialog( params: EnergySettingsGridFlowDialogParams ): Promise { @@ -67,18 +69,31 @@ export class DialogEnergyGridFlowSettings ] ? "statistic" : "no-costs"; - this._pickedDisplayUnit = getDisplayUnit( - this.hass, + + const initialSourceId = this._source[ this._params.direction === "from" ? "stat_energy_from" : "stat_energy_to" - ], + ]; + + this._pickedDisplayUnit = getDisplayUnit( + this.hass, + initialSourceId, params.metadata ); this._energy_units = ( await getSensorDeviceClassConvertibleUnits(this.hass, "energy") ).units; + + this._excludeList = [ + ...(this._params.grid_source?.flow_from?.map( + (entry) => entry.stat_energy_from + ) || []), + ...(this._params.grid_source?.flow_to?.map( + (entry) => entry.stat_energy_to + ) || []), + ].filter((id) => id !== initialSourceId); } public closeDialog(): void { @@ -154,6 +169,7 @@ export class DialogEnergyGridFlowSettings .label=${this.hass.localize( `ui.panel.config.energy.grid.flow_dialog.${this._params.direction}.energy_stat` )} + .excludeStatistics=${this._excludeList} @value-changed=${this._statisticChanged} dialogInitialFocus > diff --git a/src/panels/config/energy/dialogs/show-dialogs-energy.ts b/src/panels/config/energy/dialogs/show-dialogs-energy.ts index c9fea02a61e9..ac04b030870a 100644 --- a/src/panels/config/energy/dialogs/show-dialogs-energy.ts +++ b/src/panels/config/energy/dialogs/show-dialogs-energy.ts @@ -7,6 +7,7 @@ import { FlowFromGridSourceEnergyPreference, FlowToGridSourceEnergyPreference, GasSourceTypeEnergyPreference, + GridSourceTypeEnergyPreference, SolarSourceTypeEnergyPreference, WaterSourceTypeEnergyPreference, } from "../../../../data/energy"; @@ -18,6 +19,7 @@ export interface EnergySettingsGridFlowDialogParams { | FlowToGridSourceEnergyPreference; metadata?: StatisticsMetaData; direction: "from" | "to"; + grid_source?: GridSourceTypeEnergyPreference; saveCallback: ( source: | FlowFromGridSourceEnergyPreference @@ -28,12 +30,14 @@ export interface EnergySettingsGridFlowDialogParams { export interface EnergySettingsGridFlowFromDialogParams { source?: FlowFromGridSourceEnergyPreference; metadata?: StatisticsMetaData; + grid_source?: GridSourceTypeEnergyPreference; saveCallback: (source: FlowFromGridSourceEnergyPreference) => Promise; } export interface EnergySettingsGridFlowToDialogParams { source?: FlowToGridSourceEnergyPreference; metadata?: StatisticsMetaData; + grid_source?: GridSourceTypeEnergyPreference; saveCallback: (source: FlowToGridSourceEnergyPreference) => Promise; }