mirror of
https://github.com/home-assistant/frontend.git
synced 2026-09-10 05:41:44 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0050b6cf88 | ||
|
|
f36f542395 |
@@ -1,7 +1,7 @@
|
||||
import type { Connection } from "home-assistant-js-websocket";
|
||||
import type { Connection, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { getCollection } from "home-assistant-js-websocket";
|
||||
import type { Store } from "home-assistant-js-websocket/dist/store";
|
||||
import type { HassioAddonsInfo } from "../hassio/addon";
|
||||
import type { AddonState, HassioAddonsInfo } from "../hassio/addon";
|
||||
import type { HassioHassOSInfo, HassioHostInfo } from "../hassio/host";
|
||||
import type { NetworkInfo } from "../hassio/network";
|
||||
import type { HassioResolution } from "../hassio/resolution";
|
||||
@@ -56,6 +56,12 @@ export interface SupervisorEvent {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface SupervisorAppEvent {
|
||||
event: "app" | "addon";
|
||||
slug: string;
|
||||
state: AddonState;
|
||||
}
|
||||
|
||||
export interface Supervisor {
|
||||
host: HassioHostInfo;
|
||||
supervisor: HassioSupervisorInfo;
|
||||
@@ -100,16 +106,35 @@ async function processEvent(
|
||||
store.setState(event.data);
|
||||
}
|
||||
|
||||
const subscribeSupervisorEvents = (
|
||||
conn: Connection,
|
||||
callback: (event: SupervisorEvent) => void
|
||||
): Promise<UnsubscribeFunc> =>
|
||||
conn.subscribeMessage<SupervisorEvent>(callback, {
|
||||
type: "supervisor/subscribe",
|
||||
});
|
||||
|
||||
/**
|
||||
* Subscribe to app state transitions. Supervisor names the event "addon" until
|
||||
* its websocket v2 API is enabled, so both names are accepted.
|
||||
*/
|
||||
export const subscribeSupervisorAppEvents = (
|
||||
conn: Connection,
|
||||
callback: (event: SupervisorAppEvent) => void
|
||||
): Promise<UnsubscribeFunc> =>
|
||||
subscribeSupervisorEvents(conn, (event) => {
|
||||
if (event.event === "app" || event.event === "addon") {
|
||||
callback(event as SupervisorAppEvent);
|
||||
}
|
||||
});
|
||||
|
||||
const subscribeSupervisorEventUpdates = (
|
||||
conn: Connection,
|
||||
store: Store<unknown>,
|
||||
key: string
|
||||
) =>
|
||||
conn.subscribeMessage(
|
||||
(event) => processEvent(conn, store, event as SupervisorEvent, key),
|
||||
{
|
||||
type: "supervisor/subscribe",
|
||||
}
|
||||
subscribeSupervisorEvents(conn, (event) =>
|
||||
processEvent(conn, store, event, key)
|
||||
);
|
||||
|
||||
export const getSupervisorEventCollection = (
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
mdiShield,
|
||||
mdiStop,
|
||||
} from "@mdi/js";
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import type { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
@@ -60,6 +60,7 @@ import type { HaSwitch } from "../../../../../components/ha-switch";
|
||||
import "../../../../../components/item/ha-row-item";
|
||||
import {
|
||||
apiContext,
|
||||
connectionContext,
|
||||
internationalizationContext,
|
||||
registriesContext,
|
||||
} from "../../../../../data/context";
|
||||
@@ -89,6 +90,7 @@ import {
|
||||
supervisorUrl,
|
||||
} from "../../../../../data/hassio/common";
|
||||
import type { StoreAddonDetails } from "../../../../../data/supervisor/store";
|
||||
import { subscribeSupervisorAppEvents } from "../../../../../data/supervisor/supervisor";
|
||||
import {
|
||||
showAlertDialog,
|
||||
showConfirmationDialog,
|
||||
@@ -123,8 +125,6 @@ const RATING_ICON = {
|
||||
8: mdiNumeric8,
|
||||
};
|
||||
|
||||
const POLL_INTERVAL_SECONDS = 5;
|
||||
|
||||
@customElement("supervisor-app-info")
|
||||
class SupervisorAppInfo extends MobileAwareMixin(LitElement) {
|
||||
@property({ type: Boolean }) public narrow = false;
|
||||
@@ -147,6 +147,9 @@ class SupervisorAppInfo extends MobileAwareMixin(LitElement) {
|
||||
@consume({ context: apiContext, subscribe: true })
|
||||
private api!: ContextType<typeof apiContext>;
|
||||
|
||||
@consume({ context: connectionContext, subscribe: true })
|
||||
private connection!: ContextType<typeof connectionContext>;
|
||||
|
||||
@state() private _metrics?: HassioStats;
|
||||
|
||||
@state() private _error?: string;
|
||||
@@ -163,7 +166,7 @@ class SupervisorAppInfo extends MobileAwareMixin(LitElement) {
|
||||
})
|
||||
private _updateState?: HassEntity;
|
||||
|
||||
private _pollInterval?: number;
|
||||
private _unsubEvents?: Promise<UnsubscribeFunc>;
|
||||
|
||||
protected mobileSizeQuery =
|
||||
"all and (max-width: 1120px), all and (max-height: 500px)";
|
||||
@@ -174,7 +177,7 @@ class SupervisorAppInfo extends MobileAwareMixin(LitElement) {
|
||||
|
||||
public connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this._startPolling();
|
||||
this._subscribeStateChanges();
|
||||
}
|
||||
|
||||
protected willUpdate(changedProps: PropertyValues<this>) {
|
||||
@@ -190,7 +193,7 @@ class SupervisorAppInfo extends MobileAwareMixin(LitElement) {
|
||||
|
||||
public disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this._stopPolling();
|
||||
this._unsubscribeStateChanges();
|
||||
}
|
||||
|
||||
private _renderInfoCard() {
|
||||
@@ -1023,22 +1026,39 @@ class SupervisorAppInfo extends MobileAwareMixin(LitElement) {
|
||||
}
|
||||
}
|
||||
|
||||
private _startPolling() {
|
||||
if (this._pollInterval) {
|
||||
private _subscribeStateChanges() {
|
||||
if (this._unsubEvents) {
|
||||
return;
|
||||
}
|
||||
this._pollInterval = window.setInterval(() => {
|
||||
this._refreshAddonInfo();
|
||||
}, POLL_INTERVAL_SECONDS * 1000);
|
||||
this._unsubEvents = subscribeSupervisorAppEvents(
|
||||
this.connection.connection,
|
||||
(event) => {
|
||||
if (event.slug === this._currentAddon.slug) {
|
||||
this._refreshAddonInfo();
|
||||
}
|
||||
}
|
||||
);
|
||||
this.connection.connection.addEventListener(
|
||||
"ready",
|
||||
this._handleConnectionReady
|
||||
);
|
||||
}
|
||||
|
||||
private _stopPolling() {
|
||||
if (this._pollInterval) {
|
||||
clearInterval(this._pollInterval);
|
||||
this._pollInterval = undefined;
|
||||
}
|
||||
private _unsubscribeStateChanges() {
|
||||
this._unsubEvents?.then((unsub) => unsub());
|
||||
this._unsubEvents = undefined;
|
||||
this.connection.connection.removeEventListener(
|
||||
"ready",
|
||||
this._handleConnectionReady
|
||||
);
|
||||
}
|
||||
|
||||
// Transitions during a websocket outage are not replayed, so the state shown
|
||||
// can be stale once the subscription is restored.
|
||||
private _handleConnectionReady = () => {
|
||||
this._refreshAddonInfo();
|
||||
};
|
||||
|
||||
private async _refreshAddonInfo(): Promise<void> {
|
||||
const addon = this._currentAddon;
|
||||
if (!addon?.slug) {
|
||||
@@ -1431,7 +1451,6 @@ class SupervisorAppInfo extends MobileAwareMixin(LitElement) {
|
||||
|
||||
try {
|
||||
await startHassioAddon(this.api.callWS, addon.slug);
|
||||
this._addon = await fetchHassioAddonInfo(this.api.callWS, addon.slug);
|
||||
const eventdata = {
|
||||
success: true,
|
||||
response: undefined,
|
||||
|
||||
Reference in New Issue
Block a user