diff --git a/src/data/cached-history.ts b/src/data/cached-history.ts index b74e212071..005610e33c 100644 --- a/src/data/cached-history.ts +++ b/src/data/cached-history.ts @@ -9,7 +9,7 @@ import { HomeAssistant } from "../types"; import { HassEntity } from "home-assistant-js-websocket"; import { LocalizeFunc } from "../common/translations/localize"; -interface CacheConfig { +export interface CacheConfig { refresh: number; cacheKey: string; hoursToShow: number; diff --git a/src/panels/lovelace/cards/hui-history-graph-card.js b/src/panels/lovelace/cards/hui-history-graph-card.js deleted file mode 100644 index cf11b68bb9..0000000000 --- a/src/panels/lovelace/cards/hui-history-graph-card.js +++ /dev/null @@ -1,99 +0,0 @@ -import { html } from "@polymer/polymer/lib/utils/html-tag"; -import { PolymerElement } from "@polymer/polymer/polymer-element"; - -import "../../../components/ha-card"; -import "../../../components/state-history-charts"; -import "../../../data/ha-state-history-data"; - -import { processConfigEntities } from "../common/process-config-entities"; - -class HuiHistoryGraphCard extends PolymerElement { - static async getConfigElement() { - await import( - /* webpackChunkName: "hui-history-graph-card-editor" */ "../editor/config-elements/hui-history-graph-card-editor" - ); - return document.createElement("hui-history-graph-card-editor"); - } - - static getStubConfig() { - return { entities: [] }; - } - - static get template() { - return html` - - - -
- - -
-
- `; - } - - static get properties() { - return { - hass: Object, - _config: Object, - _names: Object, - _entities: Array, - - _stateHistory: Object, - _stateHistoryLoading: Boolean, - _cacheConfig: Object, - }; - } - - getCardSize() { - return 4; - } - - setConfig(config) { - const entities = processConfigEntities(config.entities); - - this._config = config; - - const _entities = []; - const _names = {}; - entities.forEach((entity) => { - _entities.push(entity.entity); - if (entity.name) { - _names[entity.entity] = entity.name; - } - }); - - this.setProperties({ - _cacheConfig: { - cacheKey: _entities.join(), - hoursToShow: config.hours_to_show || 24, - refresh: config.refresh_interval || 0, - }, - _entities, - _names, - }); - } -} - -customElements.define("hui-history-graph-card", HuiHistoryGraphCard); diff --git a/src/panels/lovelace/cards/hui-history-graph-card.ts b/src/panels/lovelace/cards/hui-history-graph-card.ts new file mode 100644 index 0000000000..4618751429 --- /dev/null +++ b/src/panels/lovelace/cards/hui-history-graph-card.ts @@ -0,0 +1,168 @@ +import { + html, + LitElement, + TemplateResult, + customElement, + property, + css, + CSSResult, + PropertyValues, +} from "lit-element"; +import { classMap } from "lit-html/directives/class-map"; + +import "../../../components/ha-card"; +import "../../../components/state-history-charts"; +import "../../../data/ha-state-history-data"; + +import { getRecentWithCache, CacheConfig } from "../../../data/cached-history"; +import { processConfigEntities } from "../common/process-config-entities"; +import { HomeAssistant } from "../../../types"; +import { HistoryGraphCardConfig } from "./types"; +import { LovelaceCard } from "../types"; +import { EntityConfig } from "../entity-rows/types"; + +@customElement("hui-history-graph-card") +export class HuiHistoryGraphCard extends LitElement implements LovelaceCard { + public static async getConfigElement() { + await import( + /* webpackChunkName: "hui-history-graph-card-editor" */ "../editor/config-elements/hui-history-graph-card-editor" + ); + return document.createElement("hui-history-graph-card-editor"); + } + + public static getStubConfig() { + return { entities: [] }; + } + + @property() public hass?: HomeAssistant; + @property() private _stateHistory?: any; + @property() private _config?: HistoryGraphCardConfig; + private _configEntities?: EntityConfig[]; + private _names: { [key: string]: string } = {}; + private _cacheConfig?: CacheConfig; + private _interval?: number; + + public getCardSize(): number { + return 4; + } + + public setConfig(config: HistoryGraphCardConfig): void { + if (!config.entities) { + throw new Error("Entities must be defined"); + } + + if (config.entities && !Array.isArray(config.entities)) { + throw new Error("Entities need to be an array"); + } + + this._config = { theme: "default", ...config }; + this._configEntities = config.entities + ? processConfigEntities(config.entities) + : []; + + const _entities: string[] = []; + + this._configEntities.forEach((entity) => { + _entities.push(entity.entity); + if (entity.name) { + this._names[entity.entity] = entity.name; + } + }); + + this._cacheConfig = { + cacheKey: _entities.join(), + hoursToShow: config.hours_to_show || 24, + refresh: config.refresh_interval || 0, + }; + } + + public disconnectedCallback(): void { + super.disconnectedCallback(); + this._clearInterval(); + } + + protected updated(changedProps: PropertyValues) { + super.updated(changedProps); + if (!this._config || !this.hass || !this._cacheConfig) { + return; + } + + const oldConfig = changedProps.get("_config") as + | HistoryGraphCardConfig + | undefined; + + if (oldConfig !== this._config) { + this._getStateHistory(); + this._clearInterval(); + + if (!this._interval && this._cacheConfig.refresh) { + this._interval = window.setInterval(() => { + this._getStateHistory(); + }, this._cacheConfig.refresh * 1000); + } + } + } + + protected render(): TemplateResult { + if (!this.hass || !this._config) { + return html``; + } + + return html` + +
+ +
+
+ `; + } + + private _getStateHistory(): void { + getRecentWithCache( + this.hass!, + this._cacheConfig!.cacheKey, + this._cacheConfig!, + this.hass!.localize, + this.hass!.language + ).then((stateHistory) => { + this._stateHistory = { + ...this._stateHistory, + ...stateHistory, + }; + }); + } + + private _clearInterval(): void { + if (this._interval) { + window.clearInterval(this._interval); + this._interval = undefined; + } + } + + static get styles(): CSSResult { + return css` + .content { + padding: 16px; + } + .has-header { + padding-top: 0; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-history-graph-card": HuiHistoryGraphCard; + } +} diff --git a/src/panels/lovelace/cards/types.ts b/src/panels/lovelace/cards/types.ts index 141a7874a4..a80103fcf9 100644 --- a/src/panels/lovelace/cards/types.ts +++ b/src/panels/lovelace/cards/types.ts @@ -153,6 +153,13 @@ export interface MediaControlCardConfig extends LovelaceCardConfig { entity: string; } +export interface HistoryGraphCardConfig extends LovelaceCardConfig { + entities: Array; + hours_to_show?: number; + refresh_interval?: number; + title?: string; +} + export interface PictureCardConfig extends LovelaceCardConfig { image?: string; tap_action?: ActionConfig; diff --git a/src/panels/lovelace/editor/config-elements/hui-history-graph-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-history-graph-card-editor.ts index 081466600d..ffa079ca3d 100644 --- a/src/panels/lovelace/editor/config-elements/hui-history-graph-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-history-graph-card-editor.ts @@ -14,10 +14,10 @@ import { EntitiesEditorEvent, EditorTarget } from "../types"; import { HomeAssistant } from "../../../../types"; import { LovelaceCardEditor } from "../../types"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { HistoryGraphCardConfig } from "../../cards/hui-history-graph-card"; import { EntityConfig } from "../../entity-rows/types"; import { processEditorEntities } from "../process-editor-entities"; import { configElementStyle } from "./config-elements-style"; +import { HistoryGraphCardConfig } from "../../cards/types"; const entitiesConfigStruct = struct.union([ {