diff --git a/src/components/chart/statistics-chart.ts b/src/components/chart/statistics-chart.ts index b0ee80b917..d187dfa1ea 100644 --- a/src/components/chart/statistics-chart.ts +++ b/src/components/chart/statistics-chart.ts @@ -32,7 +32,7 @@ import { import type { HomeAssistant } from "../../types"; import "./ha-chart-base"; -export type ExtendedStatisticType = StatisticType | "state"; +export type ExtendedStatisticType = StatisticType | "state" | "change"; export const statTypeMap: Record = { mean: "mean", @@ -40,7 +40,9 @@ export const statTypeMap: Record = { max: "max", sum: "sum", state: "sum", + change: "sum", }; + @customElement("statistics-chart") class StatisticsChart extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -361,6 +363,7 @@ class StatisticsChart extends LitElement { let prevDate: Date | null = null; // Process chart data. + let firstSum: number | null = null; let prevSum: number | null = null; stats.forEach((stat) => { const date = new Date(stat.start); @@ -372,12 +375,19 @@ class StatisticsChart extends LitElement { statTypes.forEach((type) => { let val: number | null; if (type === "sum") { - if (prevSum === null) { + if (firstSum === null) { val = 0; - prevSum = stat.sum; + firstSum = stat.sum; } else { - val = (stat.sum || 0) - prevSum; + val = (stat.sum || 0) - firstSum; } + } else if (type === "change") { + if (prevSum === null) { + prevSum = stat.sum; + return; + } + val = (stat.sum || 0) - prevSum; + prevSum = stat.sum; } else { val = stat[type]; } @@ -386,9 +396,6 @@ class StatisticsChart extends LitElement { pushData(date, dataValues); }); - // Add an entry for final values - pushData(endTime, prevValues); - // Concat two arrays Array.prototype.push.apply(totalDataSets, statDataSets); }); diff --git a/src/components/ha-selector/ha-selector-select.ts b/src/components/ha-selector/ha-selector-select.ts index fddb300c7b..4029846998 100644 --- a/src/components/ha-selector/ha-selector-select.ts +++ b/src/components/ha-selector/ha-selector-select.ts @@ -89,23 +89,25 @@ export class HaSelectSelector extends LitElement { !this.value || this.value === "" ? [] : (this.value as string[]); return html` - - ${value?.map( - (item, idx) => - html` - - ${options.find((option) => option.value === item)?.label || - item} - - - ` - )} - + ${value?.length + ? html` + ${value.map( + (item, idx) => + html` + + ${options.find((option) => option.value === item) + ?.label || item} + + + ` + )} + ` + : ""} !option.disabled && !value?.includes(option.value) )} @filter-changed=${this._filterChanged} diff --git a/src/panels/lovelace/cards/hui-statistics-graph-card.ts b/src/panels/lovelace/cards/hui-statistics-graph-card.ts index 0d26c38c3f..6572c82fec 100644 --- a/src/panels/lovelace/cards/hui-statistics-graph-card.ts +++ b/src/panels/lovelace/cards/hui-statistics-graph-card.ts @@ -1,3 +1,4 @@ +import { HassEntity } from "home-assistant-js-websocket"; import { css, CSSResultGroup, @@ -18,6 +19,7 @@ import { StatisticsMetaData, } from "../../../data/recorder"; import { HomeAssistant } from "../../../types"; +import { findEntities } from "../common/find-entities"; import { hasConfigOrEntitiesChanged } from "../common/has-changed"; import { processConfigEntities } from "../common/process-config-entities"; import { LovelaceCard } from "../types"; @@ -30,8 +32,25 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard { return document.createElement("hui-statistics-graph-card-editor"); } - public static getStubConfig(): StatisticsGraphCardConfig { - return { type: "statistics-graph", entities: [] }; + public static getStubConfig( + hass: HomeAssistant, + entities: string[], + entitiesFill: string[] + ): StatisticsGraphCardConfig { + const includeDomains = ["sensor"]; + const maxEntities = 1; + const foundEntities = findEntities( + hass, + maxEntities, + entities, + entitiesFill, + includeDomains, + (stateObj: HassEntity) => "state_class" in stateObj.attributes + ); + return { + type: "statistics-graph", + entities: foundEntities.length ? [foundEntities[0]] : [], + }; } @property({ attribute: false }) public hass?: HomeAssistant; 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 9a9e427601..0f911d8826 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 @@ -23,7 +23,10 @@ import { fireEvent } from "../../../../common/dom/fire_event"; import { ensureArray } from "../../../../common/ensure-array"; import type { LocalizeFunc } from "../../../../common/translations/localize"; import { deepEqual } from "../../../../common/util/deep-equal"; -import { statTypeMap } from "../../../../components/chart/statistics-chart"; +import { + ExtendedStatisticType, + statTypeMap, +} from "../../../../components/chart/statistics-chart"; import "../../../../components/entity/ha-statistics-picker"; import "../../../../components/ha-form/ha-form"; import type { HaFormSchema } from "../../../../components/ha-form/types"; @@ -44,6 +47,7 @@ import { entitiesConfigStruct } from "../structs/entities-struct"; const statTypeStruct = union([ literal("state"), literal("sum"), + literal("change"), literal("min"), literal("max"), literal("mean"), @@ -71,7 +75,14 @@ const cardConfigStruct = assign( ); const periods = ["5minute", "hour", "day", "week", "month"] as const; -const stat_types = ["mean", "min", "max", "sum", "state"] as const; +const stat_types = [ + "mean", + "min", + "max", + "sum", + "state", + "change", +] as ExtendedStatisticType[]; @customElement("hui-statistics-graph-card-editor") export class HuiStatisticsGraphCardEditor @@ -165,6 +176,7 @@ export class HuiStatisticsGraphCardEditor selector: { select: { multiple: true, + mode: "list", options: stat_types.map((stat_type) => ({ value: stat_type, label: localize( @@ -222,13 +234,13 @@ export class HuiStatisticsGraphCardEditor this._metaDatas ); const configured_stat_types = this._config!.stat_types - ? Array.isArray(this._config!.stat_types) - ? this._config!.stat_types - : [this._config!.stat_types] - : stat_types.filter((stat_type) => - this._metaDatas?.every((metaData) => - statisticsMetaHasType(metaData, statTypeMap[stat_type]) - ) + ? ensureArray(this._config.stat_types) + : stat_types.filter( + (stat_type) => + stat_type !== "change" && + this._metaDatas?.every((metaData) => + statisticsMetaHasType(metaData, statTypeMap[stat_type]) + ) ); const data = { chart_type: "line", diff --git a/src/translations/en.json b/src/translations/en.json index abc2776549..4792ad0ee0 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -525,7 +525,8 @@ "max": "max", "mean": "mean", "state": "state", - "sum": "sum" + "sum": "sum", + "change": "change" } }, "service-picker": { @@ -4063,7 +4064,8 @@ "min": "Min", "max": "Max", "state": "State", - "sum": "Sum (change during period)" + "sum": "Sum", + "change": "Change" }, "chart_type": "Chart type", "periods": {