From 1c1f9a6a898bb7f38ea4a7905fafa7421f89d60a Mon Sep 17 00:00:00 2001 From: Zack Arnett Date: Wed, 22 Apr 2020 05:33:49 -0400 Subject: [PATCH] Graph Footer: Cache State History (#5499) * Cache State History for entity * State history reset on config change * Fetching * reviews * Merge fixes * Remove file again ? --- .../common/graph/get-history-coordinates.ts | 28 --------- .../header-footer/hui-graph-header-footer.ts | 60 +++++++++++++++++-- 2 files changed, 54 insertions(+), 34 deletions(-) delete mode 100644 src/panels/lovelace/common/graph/get-history-coordinates.ts diff --git a/src/panels/lovelace/common/graph/get-history-coordinates.ts b/src/panels/lovelace/common/graph/get-history-coordinates.ts deleted file mode 100644 index a8d08cf4ca..0000000000 --- a/src/panels/lovelace/common/graph/get-history-coordinates.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { fetchRecent } from "../../../../data/history"; -import { HomeAssistant } from "../../../../types"; -import { coordinates } from "./coordinates"; - -export const getHistoryCoordinates = async ( - hass: HomeAssistant, - entity: string, - hours: number, - detail: number -): Promise => { - const endTime = new Date(); - const startTime = new Date(); - startTime.setHours(endTime.getHours() - hours); - - const stateHistory = await fetchRecent(hass, entity, startTime, endTime); - - if (stateHistory.length < 1 || stateHistory[0].length < 1) { - return []; - } - - const coords = coordinates(stateHistory[0], hours, 500, detail); - - if (!coords) { - return []; - } - - return coords; -}; diff --git a/src/panels/lovelace/header-footer/hui-graph-header-footer.ts b/src/panels/lovelace/header-footer/hui-graph-header-footer.ts index b82616ba61..05f311fd83 100644 --- a/src/panels/lovelace/header-footer/hui-graph-header-footer.ts +++ b/src/panels/lovelace/header-footer/hui-graph-header-footer.ts @@ -9,14 +9,18 @@ import { TemplateResult, } from "lit-element"; import { HomeAssistant } from "../../../types"; -import { getHistoryCoordinates } from "../common/graph/get-history-coordinates"; +import { HassEntity } from "home-assistant-js-websocket"; import "@polymer/paper-spinner/paper-spinner"; import "../components/hui-graph-base"; import { LovelaceHeaderFooter } from "../types"; import { GraphHeaderFooterConfig } from "./types"; +import { hasConfigOrEntityChanged } from "../common/has-changed"; +import { fetchRecent } from "../../../data/history"; +import { coordinates } from "../common/graph/coordinates"; const MINUTE = 60000; +const DAY = 86400000; @customElement("hui-graph-header-footer") export class HuiGraphHeaderFooter extends LitElement @@ -33,6 +37,10 @@ export class HuiGraphHeaderFooter extends LitElement private _date?: Date; + private _stateHistory?: HassEntity[]; + + private _fetching = false; + public setConfig(config: GraphHeaderFooterConfig): void { if (!config?.entity || config.entity.split(".")[0] !== "sensor") { throw new Error( @@ -83,16 +91,25 @@ export class HuiGraphHeaderFooter extends LitElement `; } - protected firstUpdated(): void { - this._date = new Date(); + protected shouldUpdate(changedProps: PropertyValues): boolean { + return hasConfigOrEntityChanged(this, changedProps); } protected updated(changedProps: PropertyValues) { - if (!this._config || !this.hass) { + if ( + !this._config || + !this.hass || + (this._fetching && !changedProps.has("_config")) + ) { return; } if (changedProps.has("_config")) { + const oldConfig = changedProps.get("_config") as GraphHeaderFooterConfig; + if (!oldConfig || oldConfig.entity !== this._config.entity) { + this._stateHistory = []; + } + this._getCoordinates(); } else if (Date.now() - this._date!.getTime() >= MINUTE) { this._getCoordinates(); @@ -100,14 +117,45 @@ export class HuiGraphHeaderFooter extends LitElement } private async _getCoordinates(): Promise { - this._coordinates = await getHistoryCoordinates( + this._fetching = true; + const endTime = new Date(); + const startTime = + !this._date || !this._stateHistory?.length + ? new Date( + new Date().setHours( + endTime.getHours() - this._config!.hours_to_show! + ) + ) + : this._date; + + if (this._stateHistory!.length) { + this._stateHistory = this._stateHistory!.filter( + (entity) => + endTime.getTime() - new Date(entity.last_changed).getTime() <= DAY + ); + } + + const stateHistory = await fetchRecent( this.hass!, this._config!.entity, + startTime, + endTime, + Boolean(this._stateHistory!.length) + ); + + if (stateHistory.length && stateHistory[0].length) { + this._stateHistory!.push(...stateHistory[0]); + } + + this._coordinates = coordinates( + this._stateHistory, this._config!.hours_to_show!, + 500, this._config!.detail! ); - this._date = new Date(); + this._date = endTime; + this._fetching = false; } static get styles(): CSSResult {