Fix logbook keeps loading (#24351)

* Logbook loading

* Redo typing

* small fixes

* async/sync fixes
This commit is contained in:
Simon Lamon 2025-03-13 17:18:24 +01:00 committed by GitHub
parent 28c355812c
commit d42bd36a3e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 33 additions and 49 deletions

View File

@ -1,4 +1,4 @@
import type { HassEntity } from "home-assistant-js-websocket"; import type { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
import { import {
BINARY_STATE_OFF, BINARY_STATE_OFF,
BINARY_STATE_ON, BINARY_STATE_ON,
@ -119,7 +119,7 @@ export const subscribeLogbook = (
endDate: string, endDate: string,
entityIds?: string[], entityIds?: string[],
deviceIds?: string[] deviceIds?: string[]
): Promise<() => Promise<void>> => { ): Promise<UnsubscribeFunc> => {
// If all specified filters are empty lists, we can return an empty list. // If all specified filters are empty lists, we can return an empty list.
if ( if (
(entityIds || deviceIds) && (entityIds || deviceIds) &&

View File

@ -1,6 +1,7 @@
import type { PropertyValues } from "lit"; import type { PropertyValues } from "lit";
import { css, html, LitElement, nothing } from "lit"; import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
import { isComponentLoaded } from "../../common/config/is_component_loaded"; import { isComponentLoaded } from "../../common/config/is_component_loaded";
import { computeStateDomain } from "../../common/entity/compute_state_domain"; import { computeStateDomain } from "../../common/entity/compute_state_domain";
import { throttle } from "../../common/util/throttle"; import { throttle } from "../../common/util/throttle";
@ -76,7 +77,7 @@ export class HaLogbook extends LitElement {
@state() private _error?: string; @state() private _error?: string;
private _subscribed?: (() => Promise<void>) | undefined; private _unsubLogbook?: Promise<UnsubscribeFunc>;
private _liveUpdatesEnabled = true; private _liveUpdatesEnabled = true;
@ -132,14 +133,14 @@ export class HaLogbook extends LitElement {
} }
public async refresh(force = false) { public async refresh(force = false) {
if (!force && (this._subscribed || this._logbookEntries === undefined)) { if (!force && (this._unsubLogbook || this._logbookEntries === undefined)) {
return; return;
} }
this._throttleGetLogbookEntries.cancel(); this._throttleGetLogbookEntries.cancel();
this._updateTraceContexts.cancel(); this._updateTraceContexts.cancel();
this._updateUsers.cancel(); this._updateUsers.cancel();
await this._unsubscribeSetLoading(); this._unsubscribe(true);
this._liveUpdatesEnabled = true; this._liveUpdatesEnabled = true;
@ -208,16 +209,25 @@ export class HaLogbook extends LitElement {
); );
} }
private async _unsubscribe(): Promise<void> { /**
if (this._subscribed) { * Unsubscribe from a logbook stream since
try { * - we are unloading the page
await this._subscribed(); * - we are about to resubscribe
this._subscribed = undefined; * - the entity is not being tracked in the logbook
this._pendingStreamMessages = []; * and will not return results ever
} catch (err: any) { * - the requested start time is in the future
// eslint-disable-next-line *
console.error("Error unsubscribing:", err); * In cases where no events are expected, we set this._logbookEntries
} * to an empty list to show a no results message.
*
* @param loading Indicates if the page should be put in a loading state again.
*/
private _unsubscribe(loading: boolean): void {
if (this._unsubLogbook) {
this._unsubLogbook.then((unsub) => unsub());
this._unsubLogbook = undefined;
this._logbookEntries = loading ? undefined : [];
this._pendingStreamMessages = [];
} }
} }
@ -231,28 +241,7 @@ export class HaLogbook extends LitElement {
public disconnectedCallback() { public disconnectedCallback() {
super.disconnectedCallback(); super.disconnectedCallback();
this._unsubscribeSetLoading(); this._unsubscribe(true);
}
/** Unsubscribe because we are unloading
* or about to resubscribe.
* Setting this._logbookEntries to undefined
* will put the page in a loading state.
*/
private async _unsubscribeSetLoading() {
await this._unsubscribe();
this._logbookEntries = undefined;
this._pendingStreamMessages = [];
}
/** Unsubscribe because there are no results.
* Setting this._logbookEntries to an empty
* list will show a no results message.
*/
private async _unsubscribeNoResults() {
await this._unsubscribe();
this._logbookEntries = [];
this._pendingStreamMessages = [];
} }
private _calculateLogbookPeriod() { private _calculateLogbookPeriod() {
@ -284,20 +273,14 @@ export class HaLogbook extends LitElement {
private async _subscribeLogbookPeriod( private async _subscribeLogbookPeriod(
logbookPeriod: LogbookTimePeriod logbookPeriod: LogbookTimePeriod
): Promise<void> { ): Promise<void> {
if (this._subscribed) { if (this._unsubLogbook) {
return; return;
} }
try { try {
this._subscribed = await subscribeLogbook( this._unsubLogbook = subscribeLogbook(
this.hass, this.hass,
(streamMessage) => { (streamMessage) => {
// "recent" means start time is a sliding window
// so we need to calculate an expireTime to
// purge old events
if (!this._subscribed) {
// Message came in before we had a chance to unload
return;
}
this._processOrQueueStreamMessage(streamMessage); this._processOrQueueStreamMessage(streamMessage);
}, },
logbookPeriod.startTime.toISOString(), logbookPeriod.startTime.toISOString(),
@ -305,8 +288,9 @@ export class HaLogbook extends LitElement {
this.entityIds, this.entityIds,
this.deviceIds this.deviceIds
); );
await this._unsubLogbook;
} catch (err: any) { } catch (err: any) {
this._subscribed = undefined; this._unsubLogbook = undefined;
this._error = err; this._error = err;
} }
} }
@ -315,7 +299,7 @@ export class HaLogbook extends LitElement {
this._error = undefined; this._error = undefined;
if (this._filterAlwaysEmptyResults) { if (this._filterAlwaysEmptyResults) {
await this._unsubscribeNoResults(); this._unsubscribe(false);
return; return;
} }
@ -323,7 +307,7 @@ export class HaLogbook extends LitElement {
if (logbookPeriod.startTime > logbookPeriod.now) { if (logbookPeriod.startTime > logbookPeriod.now) {
// Time Travel not yet invented // Time Travel not yet invented
await this._unsubscribeNoResults(); this._unsubscribe(false);
return; return;
} }