mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Load registries in core, wait them to be loaded before generating das… (#19356)
* load registries in core, wait them to be loaded before generating dashboard * import * improve * Split out subscribe functions
This commit is contained in:
parent
b9069b25ad
commit
03751d2581
@ -1,11 +1,10 @@
|
|||||||
import { Connection, createCollection } from "home-assistant-js-websocket";
|
|
||||||
import { Store } from "home-assistant-js-websocket/dist/store";
|
|
||||||
import { stringCompare } from "../common/string/compare";
|
import { stringCompare } from "../common/string/compare";
|
||||||
import { debounce } from "../common/util/debounce";
|
|
||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant } from "../types";
|
||||||
import { DeviceRegistryEntry } from "./device_registry";
|
import { DeviceRegistryEntry } from "./device_registry";
|
||||||
import { EntityRegistryEntry } from "./entity_registry";
|
import { EntityRegistryEntry } from "./entity_registry";
|
||||||
|
|
||||||
|
export { subscribeAreaRegistry } from "./ws-area_registry";
|
||||||
|
|
||||||
export interface AreaRegistryEntry {
|
export interface AreaRegistryEntry {
|
||||||
area_id: string;
|
area_id: string;
|
||||||
name: string;
|
name: string;
|
||||||
@ -53,45 +52,6 @@ export const deleteAreaRegistryEntry = (hass: HomeAssistant, areaId: string) =>
|
|||||||
area_id: areaId,
|
area_id: areaId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const fetchAreaRegistry = (conn: Connection) =>
|
|
||||||
conn
|
|
||||||
.sendMessagePromise({
|
|
||||||
type: "config/area_registry/list",
|
|
||||||
})
|
|
||||||
.then((areas) =>
|
|
||||||
(areas as AreaRegistryEntry[]).sort((ent1, ent2) =>
|
|
||||||
stringCompare(ent1.name, ent2.name)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const subscribeAreaRegistryUpdates = (
|
|
||||||
conn: Connection,
|
|
||||||
store: Store<AreaRegistryEntry[]>
|
|
||||||
) =>
|
|
||||||
conn.subscribeEvents(
|
|
||||||
debounce(
|
|
||||||
() =>
|
|
||||||
fetchAreaRegistry(conn).then((areas: AreaRegistryEntry[]) =>
|
|
||||||
store.setState(areas, true)
|
|
||||||
),
|
|
||||||
500,
|
|
||||||
true
|
|
||||||
),
|
|
||||||
"area_registry_updated"
|
|
||||||
);
|
|
||||||
|
|
||||||
export const subscribeAreaRegistry = (
|
|
||||||
conn: Connection,
|
|
||||||
onChange: (areas: AreaRegistryEntry[]) => void
|
|
||||||
) =>
|
|
||||||
createCollection<AreaRegistryEntry[]>(
|
|
||||||
"_areaRegistry",
|
|
||||||
fetchAreaRegistry,
|
|
||||||
subscribeAreaRegistryUpdates,
|
|
||||||
conn,
|
|
||||||
onChange
|
|
||||||
);
|
|
||||||
|
|
||||||
export const getAreaEntityLookup = (
|
export const getAreaEntityLookup = (
|
||||||
entities: EntityRegistryEntry[]
|
entities: EntityRegistryEntry[]
|
||||||
): AreaEntityLookup => {
|
): AreaEntityLookup => {
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import { Connection, createCollection } from "home-assistant-js-websocket";
|
|
||||||
import type { Store } from "home-assistant-js-websocket/dist/store";
|
|
||||||
import { computeStateName } from "../common/entity/compute_state_name";
|
import { computeStateName } from "../common/entity/compute_state_name";
|
||||||
import { caseInsensitiveStringCompare } from "../common/string/compare";
|
import { caseInsensitiveStringCompare } from "../common/string/compare";
|
||||||
import { debounce } from "../common/util/debounce";
|
|
||||||
import type { HomeAssistant } from "../types";
|
import type { HomeAssistant } from "../types";
|
||||||
import type {
|
import type {
|
||||||
EntityRegistryDisplayEntry,
|
EntityRegistryDisplayEntry,
|
||||||
@ -10,6 +7,11 @@ import type {
|
|||||||
} from "./entity_registry";
|
} from "./entity_registry";
|
||||||
import type { EntitySources } from "./entity_sources";
|
import type { EntitySources } from "./entity_sources";
|
||||||
|
|
||||||
|
export {
|
||||||
|
fetchDeviceRegistry,
|
||||||
|
subscribeDeviceRegistry,
|
||||||
|
} from "./ws-device_registry";
|
||||||
|
|
||||||
export interface DeviceRegistryEntry {
|
export interface DeviceRegistryEntry {
|
||||||
id: string;
|
id: string;
|
||||||
config_entries: string[];
|
config_entries: string[];
|
||||||
@ -96,39 +98,6 @@ export const removeConfigEntryFromDevice = (
|
|||||||
config_entry_id: configEntryId,
|
config_entry_id: configEntryId,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const fetchDeviceRegistry = (conn: Connection) =>
|
|
||||||
conn.sendMessagePromise<DeviceRegistryEntry[]>({
|
|
||||||
type: "config/device_registry/list",
|
|
||||||
});
|
|
||||||
|
|
||||||
const subscribeDeviceRegistryUpdates = (
|
|
||||||
conn: Connection,
|
|
||||||
store: Store<DeviceRegistryEntry[]>
|
|
||||||
) =>
|
|
||||||
conn.subscribeEvents(
|
|
||||||
debounce(
|
|
||||||
() =>
|
|
||||||
fetchDeviceRegistry(conn).then((devices) =>
|
|
||||||
store.setState(devices, true)
|
|
||||||
),
|
|
||||||
500,
|
|
||||||
true
|
|
||||||
),
|
|
||||||
"device_registry_updated"
|
|
||||||
);
|
|
||||||
|
|
||||||
export const subscribeDeviceRegistry = (
|
|
||||||
conn: Connection,
|
|
||||||
onChange: (devices: DeviceRegistryEntry[]) => void
|
|
||||||
) =>
|
|
||||||
createCollection<DeviceRegistryEntry[]>(
|
|
||||||
"_dr",
|
|
||||||
fetchDeviceRegistry,
|
|
||||||
subscribeDeviceRegistryUpdates,
|
|
||||||
conn,
|
|
||||||
onChange
|
|
||||||
);
|
|
||||||
|
|
||||||
export const sortDeviceRegistryByName = (
|
export const sortDeviceRegistryByName = (
|
||||||
entries: DeviceRegistryEntry[],
|
entries: DeviceRegistryEntry[],
|
||||||
language: string
|
language: string
|
||||||
|
@ -8,6 +8,8 @@ import { HomeAssistant } from "../types";
|
|||||||
import { LightColor } from "./light";
|
import { LightColor } from "./light";
|
||||||
import { computeDomain } from "../common/entity/compute_domain";
|
import { computeDomain } from "../common/entity/compute_domain";
|
||||||
|
|
||||||
|
export { subscribeEntityRegistryDisplay } from "./ws-entity_registry_display";
|
||||||
|
|
||||||
type entityCategory = "config" | "diagnostic";
|
type entityCategory = "config" | "diagnostic";
|
||||||
|
|
||||||
export interface EntityRegistryDisplayEntry {
|
export interface EntityRegistryDisplayEntry {
|
||||||
@ -22,7 +24,7 @@ export interface EntityRegistryDisplayEntry {
|
|||||||
display_precision?: number;
|
display_precision?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EntityRegistryDisplayEntryResponse {
|
export interface EntityRegistryDisplayEntryResponse {
|
||||||
entities: {
|
entities: {
|
||||||
ei: string;
|
ei: string;
|
||||||
di?: string;
|
di?: string;
|
||||||
@ -255,34 +257,6 @@ export const subscribeEntityRegistry = (
|
|||||||
onChange
|
onChange
|
||||||
);
|
);
|
||||||
|
|
||||||
const subscribeEntityRegistryDisplayUpdates = (
|
|
||||||
conn: Connection,
|
|
||||||
store: Store<EntityRegistryDisplayEntryResponse>
|
|
||||||
) =>
|
|
||||||
conn.subscribeEvents(
|
|
||||||
debounce(
|
|
||||||
() =>
|
|
||||||
fetchEntityRegistryDisplay(conn).then((entities) =>
|
|
||||||
store.setState(entities, true)
|
|
||||||
),
|
|
||||||
500,
|
|
||||||
true
|
|
||||||
),
|
|
||||||
"entity_registry_updated"
|
|
||||||
);
|
|
||||||
|
|
||||||
export const subscribeEntityRegistryDisplay = (
|
|
||||||
conn: Connection,
|
|
||||||
onChange: (entities: EntityRegistryDisplayEntryResponse) => void
|
|
||||||
) =>
|
|
||||||
createCollection<EntityRegistryDisplayEntryResponse>(
|
|
||||||
"_entityRegistryDisplay",
|
|
||||||
fetchEntityRegistryDisplay,
|
|
||||||
subscribeEntityRegistryDisplayUpdates,
|
|
||||||
conn,
|
|
||||||
onChange
|
|
||||||
);
|
|
||||||
|
|
||||||
export const sortEntityRegistryByName = (
|
export const sortEntityRegistryByName = (
|
||||||
entries: EntityRegistryEntry[],
|
entries: EntityRegistryEntry[],
|
||||||
language: string
|
language: string
|
||||||
|
44
src/data/ws-area_registry.ts
Normal file
44
src/data/ws-area_registry.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { Connection, createCollection } from "home-assistant-js-websocket";
|
||||||
|
import { Store } from "home-assistant-js-websocket/dist/store";
|
||||||
|
import { stringCompare } from "../common/string/compare";
|
||||||
|
import { AreaRegistryEntry } from "./area_registry";
|
||||||
|
import { debounce } from "../common/util/debounce";
|
||||||
|
|
||||||
|
const fetchAreaRegistry = (conn: Connection) =>
|
||||||
|
conn
|
||||||
|
.sendMessagePromise({
|
||||||
|
type: "config/area_registry/list",
|
||||||
|
})
|
||||||
|
.then((areas) =>
|
||||||
|
(areas as AreaRegistryEntry[]).sort((ent1, ent2) =>
|
||||||
|
stringCompare(ent1.name, ent2.name)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const subscribeAreaRegistryUpdates = (
|
||||||
|
conn: Connection,
|
||||||
|
store: Store<AreaRegistryEntry[]>
|
||||||
|
) =>
|
||||||
|
conn.subscribeEvents(
|
||||||
|
debounce(
|
||||||
|
() =>
|
||||||
|
fetchAreaRegistry(conn).then((areas: AreaRegistryEntry[]) =>
|
||||||
|
store.setState(areas, true)
|
||||||
|
),
|
||||||
|
500,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
"area_registry_updated"
|
||||||
|
);
|
||||||
|
|
||||||
|
export const subscribeAreaRegistry = (
|
||||||
|
conn: Connection,
|
||||||
|
onChange: (areas: AreaRegistryEntry[]) => void
|
||||||
|
) =>
|
||||||
|
createCollection<AreaRegistryEntry[]>(
|
||||||
|
"_areaRegistry",
|
||||||
|
fetchAreaRegistry,
|
||||||
|
subscribeAreaRegistryUpdates,
|
||||||
|
conn,
|
||||||
|
onChange
|
||||||
|
);
|
37
src/data/ws-device_registry.ts
Normal file
37
src/data/ws-device_registry.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { Connection, createCollection } from "home-assistant-js-websocket";
|
||||||
|
import { Store } from "home-assistant-js-websocket/dist/store";
|
||||||
|
import { DeviceRegistryEntry } from "./device_registry";
|
||||||
|
import { debounce } from "../common/util/debounce";
|
||||||
|
|
||||||
|
export const fetchDeviceRegistry = (conn: Connection) =>
|
||||||
|
conn.sendMessagePromise<DeviceRegistryEntry[]>({
|
||||||
|
type: "config/device_registry/list",
|
||||||
|
});
|
||||||
|
|
||||||
|
const subscribeDeviceRegistryUpdates = (
|
||||||
|
conn: Connection,
|
||||||
|
store: Store<DeviceRegistryEntry[]>
|
||||||
|
) =>
|
||||||
|
conn.subscribeEvents(
|
||||||
|
debounce(
|
||||||
|
() =>
|
||||||
|
fetchDeviceRegistry(conn).then((devices) =>
|
||||||
|
store.setState(devices, true)
|
||||||
|
),
|
||||||
|
500,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
"device_registry_updated"
|
||||||
|
);
|
||||||
|
|
||||||
|
export const subscribeDeviceRegistry = (
|
||||||
|
conn: Connection,
|
||||||
|
onChange: (devices: DeviceRegistryEntry[]) => void
|
||||||
|
) =>
|
||||||
|
createCollection<DeviceRegistryEntry[]>(
|
||||||
|
"_dr",
|
||||||
|
fetchDeviceRegistry,
|
||||||
|
subscribeDeviceRegistryUpdates,
|
||||||
|
conn,
|
||||||
|
onChange
|
||||||
|
);
|
35
src/data/ws-entity_registry_display.ts
Normal file
35
src/data/ws-entity_registry_display.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { Connection, createCollection } from "home-assistant-js-websocket";
|
||||||
|
import { Store } from "home-assistant-js-websocket/dist/store";
|
||||||
|
import {
|
||||||
|
EntityRegistryDisplayEntryResponse,
|
||||||
|
fetchEntityRegistryDisplay,
|
||||||
|
} from "./entity_registry";
|
||||||
|
import { debounce } from "../common/util/debounce";
|
||||||
|
|
||||||
|
const subscribeEntityRegistryDisplayUpdates = (
|
||||||
|
conn: Connection,
|
||||||
|
store: Store<EntityRegistryDisplayEntryResponse>
|
||||||
|
) =>
|
||||||
|
conn.subscribeEvents(
|
||||||
|
debounce(
|
||||||
|
() =>
|
||||||
|
fetchEntityRegistryDisplay(conn).then((entities) =>
|
||||||
|
store.setState(entities, true)
|
||||||
|
),
|
||||||
|
500,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
"entity_registry_updated"
|
||||||
|
);
|
||||||
|
|
||||||
|
export const subscribeEntityRegistryDisplay = (
|
||||||
|
conn: Connection,
|
||||||
|
onChange: (entities: EntityRegistryDisplayEntryResponse) => void
|
||||||
|
) =>
|
||||||
|
createCollection<EntityRegistryDisplayEntryResponse>(
|
||||||
|
"_entityRegistryDisplay",
|
||||||
|
fetchEntityRegistryDisplay,
|
||||||
|
subscribeEntityRegistryDisplayUpdates,
|
||||||
|
conn,
|
||||||
|
onChange
|
||||||
|
);
|
@ -11,19 +11,22 @@ import {
|
|||||||
import { loadTokens, saveTokens } from "../common/auth/token_storage";
|
import { loadTokens, saveTokens } from "../common/auth/token_storage";
|
||||||
import { hassUrl } from "../data/auth";
|
import { hassUrl } from "../data/auth";
|
||||||
import { isExternal } from "../data/external";
|
import { isExternal } from "../data/external";
|
||||||
import { getRecorderInfo } from "../data/recorder";
|
|
||||||
import { subscribeFrontendUserData } from "../data/frontend";
|
import { subscribeFrontendUserData } from "../data/frontend";
|
||||||
import { fetchConfig } from "../data/lovelace/config/types";
|
import { fetchConfig } from "../data/lovelace/config/types";
|
||||||
import { fetchResources } from "../data/lovelace/resource";
|
import { fetchResources } from "../data/lovelace/resource";
|
||||||
|
import { MAIN_WINDOW_NAME } from "../data/main_window";
|
||||||
|
import { WindowWithPreloads } from "../data/preloads";
|
||||||
|
import { getRecorderInfo } from "../data/recorder";
|
||||||
|
import { subscribeRepairsIssueRegistry } from "../data/repairs";
|
||||||
|
import { subscribeAreaRegistry } from "../data/ws-area_registry";
|
||||||
|
import { subscribeDeviceRegistry } from "../data/ws-device_registry";
|
||||||
|
import { subscribeEntityRegistryDisplay } from "../data/ws-entity_registry_display";
|
||||||
import { subscribePanels } from "../data/ws-panels";
|
import { subscribePanels } from "../data/ws-panels";
|
||||||
import { subscribeThemes } from "../data/ws-themes";
|
import { subscribeThemes } from "../data/ws-themes";
|
||||||
import { subscribeRepairsIssueRegistry } from "../data/repairs";
|
|
||||||
import { subscribeUser } from "../data/ws-user";
|
import { subscribeUser } from "../data/ws-user";
|
||||||
import type { ExternalAuth } from "../external_app/external_auth";
|
import type { ExternalAuth } from "../external_app/external_auth";
|
||||||
import "../resources/array.flat.polyfill";
|
import "../resources/array.flat.polyfill";
|
||||||
import "../resources/safari-14-attachshadow-patch";
|
import "../resources/safari-14-attachshadow-patch";
|
||||||
import { MAIN_WINDOW_NAME } from "../data/main_window";
|
|
||||||
import { WindowWithPreloads } from "../data/preloads";
|
|
||||||
|
|
||||||
window.name = MAIN_WINDOW_NAME;
|
window.name = MAIN_WINDOW_NAME;
|
||||||
(window as any).frontendVersion = __VERSION__;
|
(window as any).frontendVersion = __VERSION__;
|
||||||
@ -113,6 +116,9 @@ window.hassConnection.then(({ conn }) => {
|
|||||||
// do nothing
|
// do nothing
|
||||||
};
|
};
|
||||||
subscribeEntities(conn, noop);
|
subscribeEntities(conn, noop);
|
||||||
|
subscribeEntityRegistryDisplay(conn, noop);
|
||||||
|
subscribeDeviceRegistry(conn, noop);
|
||||||
|
subscribeAreaRegistry(conn, noop);
|
||||||
subscribeConfig(conn, noop);
|
subscribeConfig(conn, noop);
|
||||||
subscribeServices(conn, noop);
|
subscribeServices(conn, noop);
|
||||||
subscribePanels(conn, noop);
|
subscribePanels(conn, noop);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
import deepFreeze from "deep-freeze";
|
import deepFreeze from "deep-freeze";
|
||||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
import { html, LitElement, TemplateResult } from "lit";
|
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { constructUrlCurrentPath } from "../../common/url/construct-url";
|
import { constructUrlCurrentPath } from "../../common/url/construct-url";
|
||||||
import {
|
import {
|
||||||
@ -161,10 +161,15 @@ export class LovelacePanel extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated(changedProps) {
|
protected willUpdate(changedProps: PropertyValues) {
|
||||||
super.firstUpdated(changedProps);
|
super.willUpdate(changedProps);
|
||||||
|
if (!this.lovelace && this._panelState !== "error") {
|
||||||
|
this._fetchConfig(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this._fetchConfig(false);
|
protected firstUpdated(changedProps: PropertyValues): void {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
if (!this._unsubUpdates) {
|
if (!this._unsubUpdates) {
|
||||||
this._subscribeUpdates();
|
this._subscribeUpdates();
|
||||||
}
|
}
|
||||||
@ -267,6 +272,10 @@ export class LovelacePanel extends LitElement {
|
|||||||
|
|
||||||
// If strategy defined, apply it here.
|
// If strategy defined, apply it here.
|
||||||
if (isStrategyDashboard(rawConf)) {
|
if (isStrategyDashboard(rawConf)) {
|
||||||
|
if (!this.hass?.entities || !this.hass.devices || !this.hass.areas) {
|
||||||
|
// We need these to generate a dashboard, wait for them
|
||||||
|
return;
|
||||||
|
}
|
||||||
conf = await generateLovelaceDashboardStrategy(
|
conf = await generateLovelaceDashboardStrategy(
|
||||||
rawConf.strategy,
|
rawConf.strategy,
|
||||||
this.hass!
|
this.hass!
|
||||||
@ -282,6 +291,10 @@ export class LovelacePanel extends LitElement {
|
|||||||
this._errorMsg = err.message;
|
this._errorMsg = err.message;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!this.hass?.entities || !this.hass.devices || !this.hass.areas) {
|
||||||
|
// We need these to generate a dashboard, wait for them
|
||||||
|
return;
|
||||||
|
}
|
||||||
conf = await generateLovelaceDashboardStrategy(
|
conf = await generateLovelaceDashboardStrategy(
|
||||||
DEFAULT_CONFIG.strategy,
|
DEFAULT_CONFIG.strategy,
|
||||||
this.hass!
|
this.hass!
|
||||||
|
Loading…
x
Reference in New Issue
Block a user