diff --git a/src/common/util/throttle.ts b/src/common/util/throttle.ts new file mode 100644 index 0000000000..b267f53b8a --- /dev/null +++ b/src/common/util/throttle.ts @@ -0,0 +1,53 @@ +export const throttle = (callback: Function, wait: number) => { + let isCalled = false; + + return function (...args: any) { + if (!isCalled) { + callback(...args); + isCalled = true; + setTimeout(() => { + isCalled = false; + }, wait); + } + }; +}; + +export const throttleAndQueue = ( + callback: Function, + wait: number, + delay?: number +) => { + let isCalled = false; + let timer: number | undefined; + let delaying = false; + + const processQueue = () => { + if (isCalled) { + callback(); + } + clearInterval(timer); + timer = undefined; + isCalled = false; + }; + + const setUpThrottle = () => { + delaying = false; + + processQueue(); // start immediately on the first invocation + timer = window.setInterval(processQueue, wait); + }; + + return () => { + isCalled = true; + if (timer !== undefined) { + return; + } + + if (delay === undefined) { + setUpThrottle(); + } else if (!delaying) { + delaying = true; + setTimeout(setUpThrottle, delay); + } + }; +}; diff --git a/src/dialogs/more-info/ha-more-info-history.ts b/src/dialogs/more-info/ha-more-info-history.ts index 9ab8b9fe48..3b0d413935 100644 --- a/src/dialogs/more-info/ha-more-info-history.ts +++ b/src/dialogs/more-info/ha-more-info-history.ts @@ -18,6 +18,7 @@ import { getLogbookData, LogbookEntry } from "../../data/logbook"; import "../../panels/logbook/ha-logbook"; import { haStyle } from "../../resources/styles"; import { HomeAssistant } from "../../types"; +import { throttleAndQueue } from "../../common/util/throttle"; @customElement("ha-more-info-history") export class MoreInfoHistory extends LitElement { @@ -35,6 +36,8 @@ export class MoreInfoHistory extends LitElement { private _lastLogbookDate?: Date; + private _throttleHistoryFunction?: Function; + protected render(): TemplateResult { if (!this.entityId) { return html``; @@ -45,7 +48,8 @@ export class MoreInfoHistory extends LitElement { return html``; } - return html` ` - : html`
- ${this.hass.localize("ui.components.logbook.entries_not_found")} -
`}`; + : html` +
+ ${this.hass.localize("ui.components.logbook.entries_not_found")} +
+ `} + `; } protected firstUpdated(): void { @@ -85,21 +92,43 @@ export class MoreInfoHistory extends LitElement { super.updated(changedProps); if (!this.entityId) { clearInterval(this._historyRefreshInterval); + this._stateHistory = undefined; + this._entries = undefined; + this._lastLogbookDate = undefined; + this._throttleHistoryFunction = undefined; + return; } if (changedProps.has("entityId")) { this._stateHistory = undefined; this._entries = undefined; this._lastLogbookDate = undefined; + this._throttleHistoryFunction = undefined; this._getStateHistory(); this._getLogBookData(); - clearInterval(this._historyRefreshInterval); - this._historyRefreshInterval = window.setInterval(() => { - this._getStateHistory(); - this._getLogBookData(); - }, 60 * 1000); + this._throttleHistoryFunction = throttleAndQueue( + () => { + this._getStateHistory(); + this._getLogBookData(); + }, + 10000, + 5000 + ); + return; + } + + if (!changedProps.has("hass")) { + return; + } + + const stateObj = this.hass.states[this.entityId]; + const oldHass = changedProps.get("hass") as HomeAssistant; + const oldStateObj = oldHass.states[this.entityId]; + + if (stateObj !== oldStateObj && this._throttleHistoryFunction) { + this._throttleHistoryFunction(); } } @@ -108,7 +137,7 @@ export class MoreInfoHistory extends LitElement { this.hass!, this.entityId, { - refresh: 60, + refresh: 10, cacheKey: `more_info.${this.entityId}`, hoursToShow: 24, }, @@ -132,7 +161,7 @@ export class MoreInfoHistory extends LitElement { ); if (this._entries) { - this._entries = [...this._entries, ...newEntries]; + this._entries = [...newEntries, ...this._entries]; } else { this._entries = newEntries; }