mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 11:46:42 +00:00
Integrate Statistic Card with Energy Date Picker (#23794)
* Support energy-date-selection for statistic card * reuse period key
This commit is contained in:
parent
af7bb85667
commit
d919e8d333
@ -1,4 +1,4 @@
|
|||||||
import type { HassEntity } from "home-assistant-js-websocket";
|
import type { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
import type { CSSResultGroup, PropertyValues } from "lit";
|
import type { CSSResultGroup, PropertyValues } from "lit";
|
||||||
import { LitElement, css, html, nothing } from "lit";
|
import { LitElement, css, html, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
@ -9,6 +9,7 @@ import { formatNumber } from "../../../common/number/format_number";
|
|||||||
import "../../../components/ha-alert";
|
import "../../../components/ha-alert";
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import "../../../components/ha-state-icon";
|
import "../../../components/ha-state-icon";
|
||||||
|
import { getEnergyDataCollection } from "../../../data/energy";
|
||||||
import type { StatisticsMetaData } from "../../../data/recorder";
|
import type { StatisticsMetaData } from "../../../data/recorder";
|
||||||
import {
|
import {
|
||||||
fetchStatistic,
|
fetchStatistic,
|
||||||
@ -31,6 +32,8 @@ import type {
|
|||||||
import type { HuiErrorCard } from "./hui-error-card";
|
import type { HuiErrorCard } from "./hui-error-card";
|
||||||
import type { EntityCardConfig, StatisticCardConfig } from "./types";
|
import type { EntityCardConfig, StatisticCardConfig } from "./types";
|
||||||
|
|
||||||
|
export const PERIOD_ENERGY = "energy_date_selection";
|
||||||
|
|
||||||
@customElement("hui-statistic-card")
|
@customElement("hui-statistic-card")
|
||||||
export class HuiStatisticCard extends LitElement implements LovelaceCard {
|
export class HuiStatisticCard extends LitElement implements LovelaceCard {
|
||||||
public static async getConfigElement(): Promise<LovelaceCardEditor> {
|
public static async getConfigElement(): Promise<LovelaceCardEditor> {
|
||||||
@ -70,15 +73,52 @@ export class HuiStatisticCard extends LitElement implements LovelaceCard {
|
|||||||
|
|
||||||
@state() private _error?: string;
|
@state() private _error?: string;
|
||||||
|
|
||||||
|
private _energySub?: UnsubscribeFunc;
|
||||||
|
|
||||||
|
@state() private _energyStart?: Date;
|
||||||
|
|
||||||
|
@state() private _energyEnd?: Date;
|
||||||
|
|
||||||
private _interval?: number;
|
private _interval?: number;
|
||||||
|
|
||||||
private _footerElement?: HuiErrorCard | LovelaceHeaderFooter;
|
private _footerElement?: HuiErrorCard | LovelaceHeaderFooter;
|
||||||
|
|
||||||
public disconnectedCallback() {
|
public disconnectedCallback() {
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
|
this._unsubscribeEnergy();
|
||||||
clearInterval(this._interval);
|
clearInterval(this._interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
if (this._config?.period === PERIOD_ENERGY) {
|
||||||
|
this._subscribeEnergy();
|
||||||
|
} else {
|
||||||
|
this._setFetchStatisticTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _subscribeEnergy() {
|
||||||
|
if (!this._energySub) {
|
||||||
|
this._energySub = getEnergyDataCollection(this.hass!, {
|
||||||
|
key: this._config?.collection_key,
|
||||||
|
}).subscribe((data) => {
|
||||||
|
this._energyStart = data.start;
|
||||||
|
this._energyEnd = data.end;
|
||||||
|
this._fetchStatistic();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _unsubscribeEnergy() {
|
||||||
|
if (this._energySub) {
|
||||||
|
this._energySub();
|
||||||
|
this._energySub = undefined;
|
||||||
|
}
|
||||||
|
this._energyStart = undefined;
|
||||||
|
this._energyEnd = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
public setConfig(config: StatisticCardConfig): void {
|
public setConfig(config: StatisticCardConfig): void {
|
||||||
if (!config.entity) {
|
if (!config.entity) {
|
||||||
throw new Error("Entity must be specified");
|
throw new Error("Entity must be specified");
|
||||||
@ -99,8 +139,6 @@ export class HuiStatisticCard extends LitElement implements LovelaceCard {
|
|||||||
|
|
||||||
this._config = config;
|
this._config = config;
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
this._fetchStatistic();
|
|
||||||
this._fetchMetadata();
|
|
||||||
|
|
||||||
if (this._config.footer) {
|
if (this._config.footer) {
|
||||||
this._footerElement = createHeaderFooterElement(this._config.footer);
|
this._footerElement = createHeaderFooterElement(this._config.footer);
|
||||||
@ -174,7 +212,9 @@ export class HuiStatisticCard extends LitElement implements LovelaceCard {
|
|||||||
if (
|
if (
|
||||||
changedProps.has("_value") ||
|
changedProps.has("_value") ||
|
||||||
changedProps.has("_metadata") ||
|
changedProps.has("_metadata") ||
|
||||||
changedProps.has("_error")
|
changedProps.has("_error") ||
|
||||||
|
changedProps.has("_energyStart") ||
|
||||||
|
changedProps.has("_energyEnd")
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -184,6 +224,46 @@ export class HuiStatisticCard extends LitElement implements LovelaceCard {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected willUpdate(changedProps: PropertyValues) {
|
||||||
|
super.willUpdate(changedProps);
|
||||||
|
if (!this._config || !changedProps.has("_config")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const oldConfig = changedProps.get("_config") as
|
||||||
|
| StatisticCardConfig
|
||||||
|
| undefined;
|
||||||
|
|
||||||
|
if (this.hass) {
|
||||||
|
if (this._config.period === PERIOD_ENERGY && !this._energySub) {
|
||||||
|
this._subscribeEnergy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this._config.period !== PERIOD_ENERGY && this._energySub) {
|
||||||
|
this._unsubscribeEnergy();
|
||||||
|
this._setFetchStatisticTimer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
this._config.period === PERIOD_ENERGY &&
|
||||||
|
this._energySub &&
|
||||||
|
changedProps.has("_config") &&
|
||||||
|
oldConfig?.collection_key !== this._config.collection_key
|
||||||
|
) {
|
||||||
|
this._unsubscribeEnergy();
|
||||||
|
this._subscribeEnergy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
changedProps.has("_config") &&
|
||||||
|
oldConfig?.entity !== this._config.entity
|
||||||
|
) {
|
||||||
|
this._fetchMetadata().then(() => {
|
||||||
|
this._setFetchStatisticTimer();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected firstUpdated() {
|
protected firstUpdated() {
|
||||||
this._fetchStatistic();
|
this._fetchStatistic();
|
||||||
this._fetchMetadata();
|
this._fetchMetadata();
|
||||||
@ -210,20 +290,31 @@ export class HuiStatisticCard extends LitElement implements LovelaceCard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _fetchStatistic() {
|
private _setFetchStatisticTimer() {
|
||||||
if (!this.hass || !this._config) {
|
this._fetchStatistic();
|
||||||
return;
|
// statistics are created every hour
|
||||||
}
|
|
||||||
clearInterval(this._interval);
|
clearInterval(this._interval);
|
||||||
|
if (this._config?.period !== PERIOD_ENERGY) {
|
||||||
this._interval = window.setInterval(
|
this._interval = window.setInterval(
|
||||||
() => this._fetchStatistic(),
|
() => this._fetchStatistic(),
|
||||||
5 * 1000 * 60
|
5 * 1000 * 60
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _fetchStatistic() {
|
||||||
|
if (!this.hass || !this._config) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const stats = await fetchStatistic(
|
const stats = await fetchStatistic(
|
||||||
this.hass,
|
this.hass,
|
||||||
this._config.entity,
|
this._config.entity,
|
||||||
this._config.period
|
this._energyStart && this._energyEnd
|
||||||
|
? { fixed_period: { start: this._energyStart, end: this._energyEnd } }
|
||||||
|
: typeof this._config?.period === "object"
|
||||||
|
? this._config?.period
|
||||||
|
: {}
|
||||||
);
|
);
|
||||||
this._value = stats[this._config!.stat_type];
|
this._value = stats[this._config!.stat_type];
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
|
@ -379,11 +379,13 @@ export interface StatisticsGraphCardConfig extends EnergyCardBaseConfig {
|
|||||||
export interface StatisticCardConfig extends LovelaceCardConfig {
|
export interface StatisticCardConfig extends LovelaceCardConfig {
|
||||||
name?: string;
|
name?: string;
|
||||||
entities: (EntityConfig | string)[];
|
entities: (EntityConfig | string)[];
|
||||||
period: {
|
period:
|
||||||
|
| {
|
||||||
fixed_period?: { start: string; end: string };
|
fixed_period?: { start: string; end: string };
|
||||||
calendar?: { period: string; offset: number };
|
calendar?: { period: string; offset: number };
|
||||||
rolling_window?: { duration: HaDurationData; offset: HaDurationData };
|
rolling_window?: { duration: HaDurationData; offset: HaDurationData };
|
||||||
};
|
}
|
||||||
|
| "energy_date_selection";
|
||||||
stat_type: keyof Statistic;
|
stat_type: keyof Statistic;
|
||||||
theme?: string;
|
theme?: string;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ const cardConfigStruct = assign(
|
|||||||
period: optional(any()),
|
period: optional(any()),
|
||||||
theme: optional(string()),
|
theme: optional(string()),
|
||||||
footer: optional(headerFooterConfigStructs),
|
footer: optional(headerFooterConfigStructs),
|
||||||
|
collection_key: optional(string()),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user