diff --git a/src/panels/config/devices/device-detail/ha-device-info-card.ts b/src/panels/config/devices/device-detail/ha-device-info-card.ts
index 0a7de52392..524e57534a 100644
--- a/src/panels/config/devices/device-detail/ha-device-info-card.ts
+++ b/src/panels/config/devices/device-detail/ha-device-info-card.ts
@@ -1,15 +1,13 @@
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
+import { titleCase } from "../../../../common/string/title-case";
import "../../../../components/ha-card";
-import { AreaRegistryEntry } from "../../../../data/area_registry";
import {
computeDeviceName,
DeviceRegistryEntry,
} from "../../../../data/device_registry";
import { haStyle } from "../../../../resources/styles";
import { HomeAssistant } from "../../../../types";
-import { loadDeviceRegistryDetailDialog } from "../device-registry-detail/show-dialog-device-registry-detail";
-import { titleCase } from "../../../../common/string/title-case";
@customElement("ha-device-info-card")
export class HaDeviceCard extends LitElement {
@@ -17,10 +15,6 @@ export class HaDeviceCard extends LitElement {
@property() public device!: DeviceRegistryEntry;
- @property() public devices!: DeviceRegistryEntry[];
-
- @property() public areas!: AreaRegistryEntry[];
-
@property() public narrow!: boolean;
protected render(): TemplateResult {
@@ -37,7 +31,7 @@ export class HaDeviceCard extends LitElement {
>
${this.device.model
- ? html`
${this.device.model}
`
+ ? html`
${this.device.model}
`
: ""}
${this.device.manufacturer
? html`
@@ -58,10 +52,7 @@ export class HaDeviceCard extends LitElement {
${this._computeDeviceName(
- this.devices,
- this.device.via_device_id
- )}${this._computeDeviceName(this.device.via_device_id)}
@@ -123,13 +114,8 @@ export class HaDeviceCard extends LitElement {
);
}
- protected firstUpdated(changedProps) {
- super.firstUpdated(changedProps);
- loadDeviceRegistryDetailDialog();
- }
-
- private _computeDeviceName(devices, deviceId) {
- const device = devices.find((dev) => dev.id === deviceId);
+ private _computeDeviceName(deviceId) {
+ const device = this.hass.devices[deviceId];
return device
? computeDeviceName(device, this.hass)
: `<${this.hass.localize(
@@ -151,9 +137,6 @@ export class HaDeviceCard extends LitElement {
.device {
width: 30%;
}
- .area {
- color: var(--primary-text-color);
- }
.extra-info {
margin-top: 8px;
word-wrap: break-word;
diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts
index 71fd2983b6..06bac5799d 100644
--- a/src/panels/config/devices/ha-config-device-page.ts
+++ b/src/panels/config/devices/ha-config-device-page.ts
@@ -35,7 +35,6 @@ import "../../../components/ha-button-menu";
import "../../../components/ha-icon-button";
import "../../../components/ha-icon-next";
import "../../../components/ha-svg-icon";
-import { AreaRegistryEntry } from "../../../data/area_registry";
import { getSignedPath } from "../../../data/auth";
import {
ConfigEntry,
@@ -109,14 +108,8 @@ export interface DeviceAlert {
export class HaConfigDevicePage extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
- @property({ attribute: false }) public devices!: DeviceRegistryEntry[];
-
@property({ attribute: false }) public entries!: ConfigEntry[];
- @property({ attribute: false }) public entities!: EntityRegistryEntry[];
-
- @property({ attribute: false }) public areas!: AreaRegistryEntry[];
-
@property({ attribute: false }) public manifests!: IntegrationManifest[];
@property() public deviceId!: string;
@@ -144,14 +137,6 @@ export class HaConfigDevicePage extends LitElement {
private _logbookTime = { recent: 86400 };
- private _device = memoizeOne(
- (
- deviceId: string,
- devices: DeviceRegistryEntry[]
- ): DeviceRegistryEntry | undefined =>
- devices ? devices.find((device) => device.id === deviceId) : undefined
- );
-
private _integrations = memoizeOne(
(
device: DeviceRegistryEntry,
@@ -234,15 +219,6 @@ export class HaConfigDevicePage extends LitElement {
}
);
- private _computeArea = memoizeOne(
- (areas, device): AreaRegistryEntry | undefined => {
- if (!areas || !device || !device.area_id) {
- return undefined;
- }
- return areas.find((area) => area.area_id === device.area_id);
- }
- );
-
private _batteryEntity = memoizeOne(
(entities: EntityRegistryEntry[]): EntityRegistryEntry | undefined =>
findBatteryEntity(this.hass, entities)
@@ -272,7 +248,6 @@ export class HaConfigDevicePage extends LitElement {
this._deleteButtons &&
this._deviceActions &&
this._deviceAlerts) ||
- !this.devices ||
!this.deviceId ||
!this.entries
) {
@@ -302,10 +277,10 @@ export class HaConfigDevicePage extends LitElement {
}
protected render() {
- if (!this.devices || !this.deviceId) {
+ if (!this.hass || !this.deviceId) {
return nothing;
}
- const device = this._device(this.deviceId, this.devices);
+ const device = this.hass.devices[this.deviceId];
if (!device) {
return html`
@@ -324,7 +299,7 @@ export class HaConfigDevicePage extends LitElement {
this.entries,
this.manifests
);
- const entities = this._entities(this.deviceId, this.entities);
+ const entities = this._entities(this.deviceId, this._entityReg);
const entitiesByCategory = this._entitiesByCategory(entities);
const batteryEntity = this._batteryEntity(entities);
const batteryChargingEntity = this._batteryChargingEntity(entities);
@@ -336,7 +311,7 @@ export class HaConfigDevicePage extends LitElement {
const batteryChargingState = batteryChargingEntity
? this.hass.states[batteryChargingEntity.entity_id]
: undefined;
- const area = this._computeArea(this.areas, device);
+ const area = device.area_id ? this.hass.areas[device.area_id] : undefined;
const deviceInfo: TemplateResult[] = integrations.map(
(integration) =>
@@ -636,7 +611,7 @@ export class HaConfigDevicePage extends LitElement {
${this._related.script.map((script) => {
const entityState = this.hass.states[script];
- const entry = this.entities.find(
+ const entry = this._entityReg.find(
(e) => e.entity_id === script
);
let url = `/config/script/show/${entityState.entity_id}`;
@@ -766,8 +741,6 @@ export class HaConfigDevicePage extends LitElement {
}
${deviceInfo}
@@ -940,7 +913,7 @@ export class HaConfigDevicePage extends LitElement {
return;
}
- const device = this._device(this.deviceId, this.devices);
+ const device = this.hass.devices[this.deviceId];
if (!device) {
return;
@@ -1003,7 +976,7 @@ export class HaConfigDevicePage extends LitElement {
}
private _getDeleteActions() {
- const device = this._device(this.deviceId, this.devices);
+ const device = this.hass.devices[this.deviceId];
if (!device) {
return;
@@ -1066,7 +1039,7 @@ export class HaConfigDevicePage extends LitElement {
}
private async _getDeviceActions() {
- const device = this._device(this.deviceId, this.devices);
+ const device = this.hass.devices[this.deviceId];
if (!device) {
return;
@@ -1129,7 +1102,7 @@ export class HaConfigDevicePage extends LitElement {
}
private async _getDeviceAlerts() {
- const device = this._device(this.deviceId, this.devices);
+ const device = this.hass.devices[this.deviceId];
if (!device) {
return;
@@ -1179,7 +1152,7 @@ export class HaConfigDevicePage extends LitElement {
private _createScene() {
const entities: SceneEntities = {};
- this._entities(this.deviceId, this.entities).forEach((entity) => {
+ this._entities(this.deviceId, this._entityReg).forEach((entity) => {
entities[entity.entity_id] = "";
});
showSceneEditor({
@@ -1189,7 +1162,7 @@ export class HaConfigDevicePage extends LitElement {
private _showScriptDialog() {
showDeviceAutomationDialog(this, {
- device: this._device(this.deviceId, this.devices)!,
+ device: this.hass.devices[this.deviceId],
entityReg: this._entityReg,
script: true,
});
@@ -1197,7 +1170,7 @@ export class HaConfigDevicePage extends LitElement {
private _showAutomationDialog() {
showDeviceAutomationDialog(this, {
- device: this._device(this.deviceId, this.devices)!,
+ device: this.hass.devices[this.deviceId],
entityReg: this._entityReg,
script: false,
});
@@ -1232,7 +1205,7 @@ export class HaConfigDevicePage extends LitElement {
}
private async _showSettings() {
- const device = this._device(this.deviceId, this.devices)!;
+ const device = this.hass.devices[this.deviceId];
showDeviceRegistryDetailDialog(this, {
device,
updateEntry: async (updates) => {
@@ -1244,7 +1217,7 @@ export class HaConfigDevicePage extends LitElement {
if (disabled) {
for (const cnfg_entry of device.config_entries) {
if (
- !this.devices.some(
+ !Object.values(this.hass.devices).some(
(dvc) =>
dvc.id !== device.id &&
dvc.config_entries.includes(cnfg_entry)
@@ -1315,7 +1288,7 @@ export class HaConfigDevicePage extends LitElement {
) {
return;
}
- const entities = this._entities(this.deviceId, this.entities);
+ const entities = this._entities(this.deviceId, this._entityReg);
const renameEntityid =
this.showAdvanced &&
diff --git a/src/panels/config/devices/ha-config-devices-dashboard.ts b/src/panels/config/devices/ha-config-devices-dashboard.ts
index 3ec2e99554..c586252c7d 100644
--- a/src/panels/config/devices/ha-config-devices-dashboard.ts
+++ b/src/panels/config/devices/ha-config-devices-dashboard.ts
@@ -1,3 +1,4 @@
+import { consume } from "@lit-labs/context";
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
import { mdiCancel, mdiFilterVariant, mdiPlus } from "@mdi/js";
@@ -29,8 +30,8 @@ import "../../../components/ha-button-menu";
import "../../../components/ha-check-list-item";
import "../../../components/ha-fab";
import "../../../components/ha-icon-button";
-import { AreaRegistryEntry } from "../../../data/area_registry";
import { ConfigEntry, sortConfigEntries } from "../../../data/config_entries";
+import { fullEntitiesContext } from "../../../data/context";
import {
DeviceEntityLookup,
DeviceRegistryEntry,
@@ -65,13 +66,11 @@ export class HaConfigDeviceDashboard extends LitElement {
@property() public isWide = false;
- @property() public devices!: DeviceRegistryEntry[];
-
@property() public entries!: ConfigEntry[];
- @property() public entities!: EntityRegistryEntry[];
-
- @property() public areas!: AreaRegistryEntry[];
+ @state()
+ @consume({ context: fullEntitiesContext, subscribe: true })
+ entities!: EntityRegistryEntry[];
@property() public manifests!: IntegrationManifest[];
@@ -87,28 +86,34 @@ export class HaConfigDeviceDashboard extends LitElement {
private _ignoreLocationChange = false;
- public constructor() {
- super();
- window.addEventListener("location-changed", () => {
- if (this._ignoreLocationChange) {
- this._ignoreLocationChange = false;
- return;
- }
- if (
- window.location.search.substring(1) !== this._searchParms.toString()
- ) {
- this._searchParms = new URLSearchParams(window.location.search);
- }
- });
- window.addEventListener("popstate", () => {
- if (
- window.location.search.substring(1) !== this._searchParms.toString()
- ) {
- this._searchParms = new URLSearchParams(window.location.search);
- }
- });
+ public connectedCallback() {
+ super.connectedCallback();
+ window.addEventListener("location-changed", this._locationChanged);
+ window.addEventListener("popstate", this._popState);
}
+ disconnectedCallback(): void {
+ super.disconnectedCallback();
+ window.removeEventListener("location-changed", this._locationChanged);
+ window.removeEventListener("popstate", this._popState);
+ }
+
+ private _locationChanged = () => {
+ if (this._ignoreLocationChange) {
+ this._ignoreLocationChange = false;
+ return;
+ }
+ if (window.location.search.substring(1) !== this._searchParms.toString()) {
+ this._searchParms = new URLSearchParams(window.location.search);
+ }
+ };
+
+ private _popState = () => {
+ if (window.location.search.substring(1) !== this._searchParms.toString()) {
+ this._searchParms = new URLSearchParams(window.location.search);
+ }
+ };
+
private _activeFilters = memoizeOne(
(
entries: ConfigEntry[],
@@ -152,10 +157,10 @@ export class HaConfigDeviceDashboard extends LitElement {
private _devicesAndFilterDomains = memoizeOne(
(
- devices: DeviceRegistryEntry[],
+ devices: HomeAssistant["devices"],
entries: ConfigEntry[],
entities: EntityRegistryEntry[],
- areas: AreaRegistryEntry[],
+ areas: HomeAssistant["areas"],
manifests: IntegrationManifest[],
filters: URLSearchParams,
showDisabled: boolean,
@@ -163,12 +168,7 @@ export class HaConfigDeviceDashboard extends LitElement {
) => {
// Some older installations might have devices pointing at invalid entryIDs
// So we guard for that.
- let outputDevices: DeviceRowData[] = devices;
-
- const deviceLookup: { [deviceId: string]: DeviceRegistryEntry } = {};
- for (const device of devices) {
- deviceLookup[device.id] = device;
- }
+ let outputDevices: DeviceRowData[] = Object.values(devices);
// If nothing gets filtered, this is our correct count of devices
let startLength = outputDevices.length;
@@ -189,11 +189,6 @@ export class HaConfigDeviceDashboard extends LitElement {
entryLookup[entry.entry_id] = entry;
}
- const areaLookup: { [areaId: string]: AreaRegistryEntry } = {};
- for (const area of areas) {
- areaLookup[area.area_id] = area;
- }
-
const manifestLookup: { [domain: string]: IntegrationManifest } = {};
for (const manifest of manifests) {
manifestLookup[manifest.domain] = manifest;
@@ -251,8 +246,8 @@ export class HaConfigDeviceDashboard extends LitElement {
device.manufacturer ||
`<${localize("ui.panel.config.devices.data_table.unknown")}>`,
area:
- device.area_id && areaLookup[device.area_id]
- ? areaLookup[device.area_id].name
+ device.area_id && areas[device.area_id]
+ ? areas[device.area_id].name
: "—",
integration: deviceEntries.length
? deviceEntries
@@ -438,10 +433,10 @@ export class HaConfigDeviceDashboard extends LitElement {
protected render(): TemplateResult {
const { devicesOutput } = this._devicesAndFilterDomains(
- this.devices,
+ this.hass.devices,
this.entries,
this.entities,
- this.areas,
+ this.hass.areas,
this.manifests,
this._searchParms,
this._showDisabled,
@@ -580,10 +575,10 @@ export class HaConfigDeviceDashboard extends LitElement {
private _addDevice() {
const { filteredConfigEntry, filteredDomains } =
this._devicesAndFilterDomains(
- this.devices,
+ this.hass.devices,
this.entries,
this.entities,
- this.areas,
+ this.hass.areas,
this.manifests,
this._searchParms,
this._showDisabled,
diff --git a/src/panels/config/devices/ha-config-devices.ts b/src/panels/config/devices/ha-config-devices.ts
index 08a5e0188d..8b3329cec1 100644
--- a/src/panels/config/devices/ha-config-devices.ts
+++ b/src/panels/config/devices/ha-config-devices.ts
@@ -1,19 +1,5 @@
-import { UnsubscribeFunc } from "home-assistant-js-websocket";
-import { PropertyValues } from "lit";
import { customElement, property, state } from "lit/decorators";
-import {
- AreaRegistryEntry,
- subscribeAreaRegistry,
-} from "../../../data/area_registry";
import { ConfigEntry, getConfigEntries } from "../../../data/config_entries";
-import {
- DeviceRegistryEntry,
- subscribeDeviceRegistry,
-} from "../../../data/device_registry";
-import {
- EntityRegistryEntry,
- subscribeEntityRegistry,
-} from "../../../data/entity_registry";
import {
IntegrationManifest,
fetchIntegrationManifests,
@@ -53,47 +39,9 @@ class HaConfigDevices extends HassRouterPage {
@state() private _manifests: IntegrationManifest[] = [];
- @state()
- private _entityRegistryEntries: EntityRegistryEntry[] = [];
-
- @state()
- private _deviceRegistryEntries: DeviceRegistryEntry[] = [];
-
- @state() private _areas: AreaRegistryEntry[] = [];
-
- private _unsubs?: UnsubscribeFunc[];
-
- public connectedCallback() {
- super.connectedCallback();
-
- if (!this.hass) {
- return;
- }
- this._loadData();
- }
-
- public disconnectedCallback() {
- super.disconnectedCallback();
- if (this._unsubs) {
- while (this._unsubs.length) {
- this._unsubs.pop()!();
- }
- this._unsubs = undefined;
- }
- }
-
protected firstUpdated(changedProps) {
super.firstUpdated(changedProps);
- this.addEventListener("hass-reload-entries", () => {
- this._loadData();
- });
- }
-
- protected updated(changedProps: PropertyValues) {
- super.updated(changedProps);
- if (!this._unsubs && changedProps.has("hass")) {
- this._loadData();
- }
+ this._loadData();
}
protected updatePageEl(pageEl) {
@@ -103,39 +51,17 @@ class HaConfigDevices extends HassRouterPage {
pageEl.deviceId = this.routeTail.path.substr(1);
}
- pageEl.entities = this._entityRegistryEntries;
pageEl.entries = this._configEntries;
pageEl.manifests = this._manifests;
- pageEl.devices = this._deviceRegistryEntries;
- pageEl.areas = this._areas;
pageEl.narrow = this.narrow;
pageEl.isWide = this.isWide;
pageEl.showAdvanced = this.showAdvanced;
pageEl.route = this.routeTail;
}
- private _loadData() {
- getConfigEntries(this.hass).then((configEntries) => {
- this._configEntries = configEntries;
- });
- fetchIntegrationManifests(this.hass).then((manifests) => {
- this._manifests = manifests;
- });
-
- if (this._unsubs) {
- return;
- }
- this._unsubs = [
- subscribeAreaRegistry(this.hass.connection, (areas) => {
- this._areas = areas;
- }),
- subscribeEntityRegistry(this.hass.connection, (entries) => {
- this._entityRegistryEntries = entries;
- }),
- subscribeDeviceRegistry(this.hass.connection, (entries) => {
- this._deviceRegistryEntries = entries;
- }),
- ];
+ private async _loadData() {
+ this._configEntries = await getConfigEntries(this.hass);
+ this._manifests = await fetchIntegrationManifests(this.hass);
}
}