1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-04-02 08:33:31 +01:00

Support Energy Collections in Statistics Graph Card Visual Editor (#29628)

* Add date selection keys to statistics-graph editor

Add support for the `energy_date_selection` and `collection_key` entires in the visual statistics-graph card editor, along with validation of the collection key in the statistics-graph's setConfig.

* Add missing option to stats card editor

Was missing the expand_legend config option in the visual editor.

* Tidy statistics graph editor arrangement

1. Group the various settings cleanly.
2. Auto-hide the collections key if energy date picker selection is disabled
3. Auto-hide days to show if a collection is linked

* Add "auto" option for statistics-chart period

When using the energy date picker option, enable the ability to select a period of "auto" which will enable use of the energy systems automatic period selection function.

* Correct hiding days to show

Should be hidden whenever energy_date_selection is true, regardless of collection key to cope with upgrading existing cards for which no key has been set.

* Hide "auto" period on statistics graph card editor
When not using energy, hide the auto option to avoid confusion.

* Swap date selection and collection key order

This keeps the toggle in a consistent location.

* Remove duplicate config key

There is a title? key now in EnergyCardBaseConfig.

* Correct energy_date_selection translation

* Improve collection key description

* Improve terminology for energy card collection
This commit is contained in:
Tom Carpenter
2026-03-13 16:15:53 +00:00
committed by GitHub
parent 14098e0d7e
commit e21f7baa93
4 changed files with 168 additions and 87 deletions

View File

@@ -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() {

View File

@@ -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;

View File

@@ -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<string>();
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}
></ha-form>
<ha-statistics-picker
@@ -384,6 +442,17 @@ export class HuiStatisticsGraphCardEditor
});
}
private _computeHelperCallback = (schema) => {
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":

View File

@@ -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",