diff --git a/src/panels/lovelace/cards/hui-statistics-graph-card.ts b/src/panels/lovelace/cards/hui-statistics-graph-card.ts index 4eb32f77e6..100ffa64d6 100644 --- a/src/panels/lovelace/cards/hui-statistics-graph-card.ts +++ b/src/panels/lovelace/cards/hui-statistics-graph-card.ts @@ -11,6 +11,7 @@ import "../../../components/ha-tooltip"; import { getEnergyDataCollection, getSuggestedPeriod, + validateEnergyCollectionKey, } from "../../../data/energy"; import type { Statistics, @@ -157,6 +158,10 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard { throw new Error("You must include at least one entity"); } + if (config.energy_date_selection && config.collection_key) { + validateEnergyCollectionKey(config.collection_key); + } + this._entities = config.entities ? processConfigEntities(config.entities, false) : []; @@ -265,12 +270,13 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard { } private get _period() { - return ( - this._config?.period ?? - (this._energyStart && this._energyEnd - ? getSuggestedPeriod(this._energyStart, this._energyEnd) - : undefined) - ); + const period = this._config?.period; + const autoMode = period === "auto"; + return this._energyStart && this._energyEnd && (!period || autoMode) + ? getSuggestedPeriod(this._energyStart, this._energyEnd) + : autoMode + ? undefined + : period; } protected render() { diff --git a/src/panels/lovelace/cards/types.ts b/src/panels/lovelace/cards/types.ts index 89b71ae66f..08a6de1b69 100644 --- a/src/panels/lovelace/cards/types.ts +++ b/src/panels/lovelace/cards/types.ts @@ -4,7 +4,11 @@ import type { HaDurationData } from "../../../components/ha-duration-input"; import type { EnergySourceByType } from "../../../data/energy"; import type { ActionConfig } from "../../../data/lovelace/config/action"; import type { LovelaceCardConfig } from "../../../data/lovelace/config/card"; -import type { Statistic, StatisticType } from "../../../data/recorder"; +import type { + Statistic, + StatisticPeriod, + StatisticType, +} from "../../../data/recorder"; import type { MediaSelectorValue } from "../../../data/selector"; import type { TimeFormat } from "../../../data/translation"; import type { ForecastType } from "../../../data/weather"; @@ -458,11 +462,10 @@ export interface HistoryGraphCardConfig extends LovelaceCardConfig { } export interface StatisticsGraphCardConfig extends EnergyCardBaseConfig { - title?: string; entities: (EntityConfig | string)[]; unit?: string; days_to_show?: number; - period?: "5minute" | "hour" | "day" | "month"; + period?: "auto" | StatisticPeriod; stat_types?: StatisticType | StatisticType[]; chart_type?: "line" | "bar"; min_y_axis?: number; diff --git a/src/panels/lovelace/editor/config-elements/hui-statistics-graph-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-statistics-graph-card-editor.ts index 7416f7bf34..4baa2e90b9 100644 --- a/src/panels/lovelace/editor/config-elements/hui-statistics-graph-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-statistics-graph-card-editor.ts @@ -63,20 +63,26 @@ const cardConfigStruct = assign( literal("week"), literal("month"), literal("year"), + literal("auto"), ]) ), chart_type: optional(union([literal("bar"), literal("line")])), stat_types: optional(union([array(statTypeStruct), statTypeStruct])), unit: optional(string()), hide_legend: optional(boolean()), + expand_legend: optional(boolean()), logarithmic_scale: optional(boolean()), min_y_axis: optional(number()), max_y_axis: optional(number()), fit_y_data: optional(boolean()), + energy_date_selection: optional(boolean()), + collection_key: optional(string()), }) ); const periods = ["5minute", "hour", "day", "week", "month", "year"] as const; +const energyPeriods = [...periods, "auto"] as const; + const stat_types = [ "mean", "min", @@ -131,7 +137,9 @@ export class HuiStatisticsGraphCardEditor localize: LocalizeFunc, statisticIds: string[] | undefined, metaDatas: StatisticsMetaData[] | undefined, - showFitOption: boolean + showFitOption: boolean, + hiddenLegend: boolean, + enableDateSelect: boolean ) => { const units = new Set(); metaDatas?.forEach((metaData) => { @@ -150,31 +158,89 @@ export class HuiStatisticsGraphCardEditor name: "", type: "grid", schema: [ + { + name: "", + type: "grid", + schema: [ + { + name: "chart_type", + required: true, + type: "select", + options: [ + [ + "line", + localize( + `ui.panel.lovelace.editor.card.statistics-graph.chart_type_labels.line` + ), + ], + [ + "bar", + localize( + `ui.panel.lovelace.editor.card.statistics-graph.chart_type_labels.bar` + ), + ], + ], + }, + ...(!enableDateSelect + ? ([ + { + name: "days_to_show", + default: DEFAULT_DAYS_TO_SHOW, + selector: { number: { min: 1, mode: "box" } }, + }, + ] as HaFormSchema[]) + : []), + ], + }, { name: "period", required: true, selector: { select: { - options: periods.map((period) => ({ - value: period, - label: localize( - `ui.panel.lovelace.editor.card.statistics-graph.periods.${period}` - ), - disabled: - period === "5minute" && - // External statistics don't support 5-minute statistics. - statisticIds?.some((statistic_id) => - isExternalStatistic(statistic_id) + mode: "list", + options: (enableDateSelect ? energyPeriods : periods).map( + (period) => ({ + value: period, + label: localize( + `ui.panel.lovelace.editor.card.statistics-graph.periods.${period}` ), - })), + disabled: + // External statistics don't support 5-minute statistics. + period === "5minute" && + statisticIds?.some((statistic_id) => + isExternalStatistic(statistic_id) + ), + }) + ), }, }, }, + ], + }, + { + name: "", + type: "grid", + schema: [ + ...(enableDateSelect + ? ([ + { + type: "string", + name: "collection_key", + required: false, + }, + ] as HaFormSchema[]) + : []), { - name: "days_to_show", - default: DEFAULT_DAYS_TO_SHOW, - selector: { number: { min: 1, mode: "box" } }, + name: "energy_date_selection", + required: false, + selector: { boolean: {} }, }, + ], + }, + { + name: "", + type: "grid", + schema: [ { name: "stat_types", required: true, @@ -199,25 +265,6 @@ export class HuiStatisticsGraphCardEditor }, }, }, - { - name: "chart_type", - required: true, - type: "select", - options: [ - [ - "line", - localize( - `ui.panel.lovelace.editor.card.statistics-graph.chart_type_labels.line` - ), - ], - [ - "bar", - localize( - `ui.panel.lovelace.editor.card.statistics-graph.chart_type_labels.bar` - ), - ], - ], - }, { name: "", type: "grid", @@ -232,48 +279,56 @@ export class HuiStatisticsGraphCardEditor required: false, selector: { number: { mode: "box", step: "any" } }, }, + ...(showFitOption + ? [ + { + name: "fit_y_data", + required: false, + selector: { boolean: {} }, + }, + ] + : []), + { + name: "logarithmic_scale", + required: false, + selector: { boolean: {} }, + }, + { + name: "hide_legend", + required: false, + selector: { boolean: {} }, + }, + ...(!hiddenLegend + ? [ + { + name: "expand_legend", + required: false, + selector: { boolean: {} }, + }, + ] + : []), ], }, - - ...(showFitOption - ? [ - { - name: "fit_y_data", - required: false, - selector: { boolean: {} }, - }, - ] - : []), - - { - name: "hide_legend", - required: false, - selector: { boolean: {} }, - }, - { - name: "logarithmic_scale", - required: false, - selector: { boolean: {} }, - }, ], }, + ...(units.size > 1 + ? [ + { + name: "unit", + required: false, + selector: { + select: { + options: Array.from(units).map((unit) => ({ + value: unit, + label: unit, + })), + }, + }, + }, + ] + : []), ]; - if (units.size > 1) { - (schema[1] as any).schema.push({ - name: "unit", - required: false, - selector: { - select: { - options: Array.from(units).map((unit) => ({ - value: unit, - label: unit, - })), - }, - }, - }); - } - return schema; } ); @@ -288,7 +343,9 @@ export class HuiStatisticsGraphCardEditor this._configEntities, this._metaDatas, this._config!.min_y_axis !== undefined || - this._config!.max_y_axis !== undefined + this._config!.max_y_axis !== undefined, + !!this._config!.hide_legend, + !!this._config!.energy_date_selection ); const configured_stat_types = this._config!.stat_types ? ensureArray(this._config.stat_types) @@ -299,7 +356,7 @@ export class HuiStatisticsGraphCardEditor ); const data = { chart_type: "line", - period: "hour", + period: this._config!.energy_date_selection ? "auto" : "hour", ...this._config, stat_types: configured_stat_types, }; @@ -314,6 +371,7 @@ export class HuiStatisticsGraphCardEditor .data=${data} .schema=${schema} .computeLabel=${this._computeLabelCallback} + .computeHelper=${this._computeHelperCallback} @value-changed=${this._valueChanged} > { + switch (schema.name) { + case "collection_key": + return this.hass!.localize( + `ui.panel.lovelace.editor.card.generic.collection_key_description` + ); + default: + return undefined; + } + }; + private _computeLabelCallback = (schema) => { switch (schema.name) { case "chart_type": @@ -391,6 +460,7 @@ export class HuiStatisticsGraphCardEditor case "period": case "unit": case "hide_legend": + case "expand_legend": case "logarithmic_scale": case "min_y_axis": case "max_y_axis": diff --git a/src/translations/en.json b/src/translations/en.json index 2574cd92cc..858bba2c5d 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -8960,16 +8960,18 @@ "bar": "Bar" }, "periods": { + "auto": "Auto", + "5minute": "5 minutes", "hour": "Hour", "day": "Day", - "month": "Month", "week": "Week", - "year": "Year", - "5minute": "5 minutes" + "month": "Month", + "year": "Year" }, "pick_statistic": "Add a statistic", "picked_statistic": "Statistic", "hide_legend": "Hide legend", + "expand_legend": "Expanded legend", "logarithmic_scale": "Logarithmic scale", "min_y_axis": "Y axis minimum", "max_y_axis": "Y axis maximum", @@ -9033,9 +9035,9 @@ "auto": "Auto", "live": "Live" }, - "energy_date_selection": "Link to energy date selector", - "collection_key": "Energy collection name", - "collection_key_description": "Optionally connect a collection of date selection, statistics graphs and energy cards. All cards with matching key will respond to the connected date selection card. Any card on this dashboard with no key will automatically be linked together.", + "energy_date_selection": "Link to energy card collection", + "collection_key": "Energy card collection key", + "collection_key_description": "Optionally connect a collection of date picker, statistics graph and energy cards. Cards with matching key will respond to any connected date picker card. Any energy card on this dashboard with no key will automatically be linked together.", "double_tap_action": "Double tap behavior", "entities": "Entities", "entity": "Entity",