Graph Footer: Cache State History (#5499)

* Cache State History for entity

* State history reset on config change

* Fetching

* reviews

* Merge fixes

* Remove file again ?
This commit is contained in:
Zack Arnett 2020-04-22 05:33:49 -04:00 committed by GitHub
parent 2b76b3887e
commit 1c1f9a6a89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 34 deletions

View File

@ -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<number[][]> => {
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;
};

View File

@ -9,14 +9,18 @@ import {
TemplateResult, TemplateResult,
} from "lit-element"; } from "lit-element";
import { HomeAssistant } from "../../../types"; 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 "@polymer/paper-spinner/paper-spinner";
import "../components/hui-graph-base"; import "../components/hui-graph-base";
import { LovelaceHeaderFooter } from "../types"; import { LovelaceHeaderFooter } from "../types";
import { GraphHeaderFooterConfig } 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 MINUTE = 60000;
const DAY = 86400000;
@customElement("hui-graph-header-footer") @customElement("hui-graph-header-footer")
export class HuiGraphHeaderFooter extends LitElement export class HuiGraphHeaderFooter extends LitElement
@ -33,6 +37,10 @@ export class HuiGraphHeaderFooter extends LitElement
private _date?: Date; private _date?: Date;
private _stateHistory?: HassEntity[];
private _fetching = false;
public setConfig(config: GraphHeaderFooterConfig): void { public setConfig(config: GraphHeaderFooterConfig): void {
if (!config?.entity || config.entity.split(".")[0] !== "sensor") { if (!config?.entity || config.entity.split(".")[0] !== "sensor") {
throw new Error( throw new Error(
@ -83,16 +91,25 @@ export class HuiGraphHeaderFooter extends LitElement
`; `;
} }
protected firstUpdated(): void { protected shouldUpdate(changedProps: PropertyValues): boolean {
this._date = new Date(); return hasConfigOrEntityChanged(this, changedProps);
} }
protected updated(changedProps: PropertyValues) { protected updated(changedProps: PropertyValues) {
if (!this._config || !this.hass) { if (
!this._config ||
!this.hass ||
(this._fetching && !changedProps.has("_config"))
) {
return; return;
} }
if (changedProps.has("_config")) { if (changedProps.has("_config")) {
const oldConfig = changedProps.get("_config") as GraphHeaderFooterConfig;
if (!oldConfig || oldConfig.entity !== this._config.entity) {
this._stateHistory = [];
}
this._getCoordinates(); this._getCoordinates();
} else if (Date.now() - this._date!.getTime() >= MINUTE) { } else if (Date.now() - this._date!.getTime() >= MINUTE) {
this._getCoordinates(); this._getCoordinates();
@ -100,14 +117,45 @@ export class HuiGraphHeaderFooter extends LitElement
} }
private async _getCoordinates(): Promise<void> { private async _getCoordinates(): Promise<void> {
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.hass!,
this._config!.entity, 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!, this._config!.hours_to_show!,
500,
this._config!.detail! this._config!.detail!
); );
this._date = new Date(); this._date = endTime;
this._fetching = false;
} }
static get styles(): CSSResult { static get styles(): CSSResult {