From e8086b6a6f0f74ab945e0851622c316d493877f2 Mon Sep 17 00:00:00 2001 From: Zack Barett Date: Thu, 7 Jul 2022 07:27:28 -0500 Subject: [PATCH] Refactor History Panel Code a bit (#13129) Co-authored-by: D3v01dZA --- src/data/area_registry.ts | 42 ++++++ src/data/device_registry.ts | 16 +++ src/panels/history/ha-panel-history.ts | 172 +++++++------------------ 3 files changed, 108 insertions(+), 122 deletions(-) diff --git a/src/data/area_registry.ts b/src/data/area_registry.ts index ffb3d4c153..c316785cfc 100644 --- a/src/data/area_registry.ts +++ b/src/data/area_registry.ts @@ -3,6 +3,8 @@ import { Store } from "home-assistant-js-websocket/dist/store"; import { stringCompare } from "../common/string/compare"; import { debounce } from "../common/util/debounce"; import { HomeAssistant } from "../types"; +import { DeviceRegistryEntry } from "./device_registry"; +import { EntityRegistryEntry } from "./entity_registry"; export interface AreaRegistryEntry { area_id: string; @@ -10,6 +12,14 @@ export interface AreaRegistryEntry { picture: string | null; } +export interface AreaEntityLookup { + [areaId: string]: EntityRegistryEntry[]; +} + +export interface AreaDeviceLookup { + [areaId: string]: DeviceRegistryEntry[]; +} + export interface AreaRegistryEntryMutableParams { name: string; picture?: string | null; @@ -79,3 +89,35 @@ export const subscribeAreaRegistry = ( conn, onChange ); + +export const getAreaEntityLookup = ( + entities: EntityRegistryEntry[] +): AreaEntityLookup => { + const areaEntityLookup: AreaEntityLookup = {}; + for (const entity of entities) { + if (!entity.area_id) { + continue; + } + if (!(entity.area_id in areaEntityLookup)) { + areaEntityLookup[entity.area_id] = []; + } + areaEntityLookup[entity.area_id].push(entity); + } + return areaEntityLookup; +}; + +export const getAreaDeviceLookup = ( + devices: DeviceRegistryEntry[] +): AreaDeviceLookup => { + const areaDeviceLookup: AreaDeviceLookup = {}; + for (const device of devices) { + if (!device.area_id) { + continue; + } + if (!(device.area_id in areaDeviceLookup)) { + areaDeviceLookup[device.area_id] = []; + } + areaDeviceLookup[device.area_id].push(device); + } + return areaDeviceLookup; +}; diff --git a/src/data/device_registry.ts b/src/data/device_registry.ts index 6fb72404aa..63b050c856 100644 --- a/src/data/device_registry.ts +++ b/src/data/device_registry.ts @@ -126,3 +126,19 @@ export const sortDeviceRegistryByName = (entries: DeviceRegistryEntry[]) => entries.sort((entry1, entry2) => caseInsensitiveStringCompare(entry1.name || "", entry2.name || "") ); + +export const getDeviceEntityLookup = ( + entities: EntityRegistryEntry[] +): DeviceEntityLookup => { + const deviceEntityLookup: DeviceEntityLookup = {}; + for (const entity of entities) { + if (!entity.device_id) { + continue; + } + if (!(entity.device_id in deviceEntityLookup)) { + deviceEntityLookup[entity.device_id] = []; + } + deviceEntityLookup[entity.device_id].push(entity); + } + return deviceEntityLookup; +}; diff --git a/src/panels/history/ha-panel-history.ts b/src/panels/history/ha-panel-history.ts index ec643ea537..135620f5ed 100644 --- a/src/panels/history/ha-panel-history.ts +++ b/src/panels/history/ha-panel-history.ts @@ -18,8 +18,6 @@ import { css, html, LitElement, PropertyValues } from "lit"; import { property, state } from "lit/decorators"; import { LocalStorage } from "../../common/decorators/local-storage"; import { ensureArray } from "../../common/ensure-array"; -import { computeDomain } from "../../common/entity/compute_domain"; -import { computeStateName } from "../../common/entity/compute_state_name"; import { navigate } from "../../common/navigate"; import { createSearchParam, @@ -34,13 +32,17 @@ import "../../components/ha-icon-button"; import "../../components/ha-menu-button"; import "../../components/ha-target-picker"; import { - DeviceRegistryEntry, + AreaDeviceLookup, + AreaEntityLookup, + getAreaDeviceLookup, + getAreaEntityLookup, +} from "../../data/area_registry"; +import { + DeviceEntityLookup, + getDeviceEntityLookup, subscribeDeviceRegistry, } from "../../data/device_registry"; -import { - EntityRegistryEntry, - subscribeEntityRegistry, -} from "../../data/entity_registry"; +import { subscribeEntityRegistry } from "../../data/entity_registry"; import { computeHistory, fetchDateWS } from "../../data/history"; import "../../layouts/ha-app-layout"; import { SubscribeMixin } from "../../mixins/subscribe-mixin"; @@ -67,23 +69,11 @@ class HaPanelHistory extends SubscribeMixin(LitElement) { @state() private _ranges?: DateRangePickerRanges; - @state() private _devices?: { [deviceId: string]: DeviceRegistryEntry }; + @state() private _deviceEntityLookup?: DeviceEntityLookup; - @state() private _entities?: { [entityId: string]: EntityRegistryEntry }; + @state() private _areaEntityLookup?: AreaEntityLookup; - @state() private _stateEntities?: { [entityId: string]: EntityRegistryEntry }; - - @state() private _deviceIdToEntities?: { - [deviceId: string]: EntityRegistryEntry[]; - }; - - @state() private _areaIdToEntities?: { - [areaId: string]: EntityRegistryEntry[]; - }; - - @state() private _areaIdToDevices?: { - [areaId: string]: DeviceRegistryEntry[]; - }; + @state() private _areaDeviceLookup?: AreaDeviceLookup; public constructor() { super(); @@ -100,52 +90,11 @@ class HaPanelHistory extends SubscribeMixin(LitElement) { public hassSubscribe(): UnsubscribeFunc[] { return [ subscribeEntityRegistry(this.hass.connection!, (entities) => { - this._entities = entities.reduce((accumulator, current) => { - accumulator[current.entity_id] = current; - return accumulator; - }, {}); - this._deviceIdToEntities = entities.reduce((accumulator, current) => { - if (!current.device_id) { - return accumulator; - } - let found = accumulator[current.device_id]; - if (found === undefined) { - found = []; - accumulator[current.device_id] = found; - } - found.push(current); - return accumulator; - }, {}); - this._areaIdToEntities = entities.reduce((accumulator, current) => { - if (!current.area_id) { - return accumulator; - } - let found = accumulator[current.area_id]; - if (found === undefined) { - found = []; - accumulator[current.area_id] = found; - } - found.push(current); - return accumulator; - }, {}); + this._deviceEntityLookup = getDeviceEntityLookup(entities); + this._areaEntityLookup = getAreaEntityLookup(entities); }), subscribeDeviceRegistry(this.hass.connection!, (devices) => { - this._devices = devices.reduce((accumulator, current) => { - accumulator[current.id] = current; - return accumulator; - }, {}); - this._areaIdToDevices = devices.reduce((accumulator, current) => { - if (!current.area_id) { - return accumulator; - } - let found = accumulator[current.area_id]; - if (found === undefined) { - found = []; - accumulator[current.area_id] = found; - } - found.push(current); - return accumulator; - }, {}); + this._areaDeviceLookup = getAreaDeviceLookup(devices); }), ]; } @@ -282,12 +231,9 @@ class HaPanelHistory extends SubscribeMixin(LitElement) { changedProps.has("_endDate") || changedProps.has("_targetPickerValue") || (!this._stateHistory && - (changedProps.has("_entities") || - changedProps.has("_devices") || - changedProps.has("_stateEntities") || - changedProps.has("_deviceIdToEntities") || - changedProps.has("_areaIdToEntities") || - changedProps.has("_areaIdToDevices")))) + (changedProps.has("_deviceEntityLookup") || + changedProps.has("_areaEntityLookup") || + changedProps.has("_areaDeviceLookup")))) ) { this._getHistory(); } @@ -300,29 +246,6 @@ class HaPanelHistory extends SubscribeMixin(LitElement) { if (!oldHass || oldHass.language !== this.hass.language) { this.rtl = computeRTL(this.hass); } - - if (this._entities) { - const stateEntities: { [entityId: string]: EntityRegistryEntry } = {}; - const regEntityIds = new Set(Object.keys(this._entities)); - for (const entityId of Object.keys(this.hass.states)) { - if (regEntityIds.has(entityId)) { - continue; - } - stateEntities[entityId] = { - name: computeStateName(this.hass.states[entityId]), - entity_id: entityId, - platform: computeDomain(entityId), - disabled_by: null, - hidden_by: null, - area_id: null, - config_entry_id: null, - device_id: null, - icon: null, - entity_category: null, - }; - } - this._stateEntities = stateEntities; - } } private _removeAll() { @@ -363,15 +286,13 @@ class HaPanelHistory extends SubscribeMixin(LitElement) { private _getEntityIds(): string[] | undefined { if ( !this._targetPickerValue || - this._entities === undefined || - this._stateEntities === undefined || - this._devices === undefined || - this._deviceIdToEntities === undefined || - this._areaIdToEntities === undefined || - this._areaIdToDevices === undefined + this._deviceEntityLookup === undefined || + this._areaEntityLookup === undefined || + this._areaDeviceLookup === undefined ) { return undefined; } + const entityIds = new Set(); let { area_id: searchingAreaId, @@ -382,7 +303,7 @@ class HaPanelHistory extends SubscribeMixin(LitElement) { if (searchingAreaId) { searchingAreaId = ensureArray(searchingAreaId); for (const singleSearchingAreaId of searchingAreaId) { - const foundEntities = this._areaIdToEntities[singleSearchingAreaId]; + const foundEntities = this._areaEntityLookup[singleSearchingAreaId]; if (foundEntities?.length) { for (const foundEntity of foundEntities) { if (foundEntity.entity_category === null) { @@ -391,19 +312,24 @@ class HaPanelHistory extends SubscribeMixin(LitElement) { } } - const foundDevices = this._areaIdToDevices[singleSearchingAreaId]; - if (foundDevices) { - for (const foundDevice of foundDevices) { - const foundDeviceEntities = - this._deviceIdToEntities[foundDevice.id]; - for (const foundDeviceEntity of foundDeviceEntities) { - if ( - (!foundDeviceEntity.area_id || - foundDeviceEntity.area_id === singleSearchingAreaId) && - foundDeviceEntity.entity_category === null - ) { - entityIds.add(foundDeviceEntity.entity_id); - } + const foundDevices = this._areaDeviceLookup[singleSearchingAreaId]; + if (!foundDevices?.length) { + continue; + } + + for (const foundDevice of foundDevices) { + const foundDeviceEntities = this._deviceEntityLookup[foundDevice.id]; + if (!foundDeviceEntities?.length) { + continue; + } + + for (const foundDeviceEntity of foundDeviceEntities) { + if ( + (!foundDeviceEntity.area_id || + foundDeviceEntity.area_id === singleSearchingAreaId) && + foundDeviceEntity.entity_category === null + ) { + entityIds.add(foundDeviceEntity.entity_id); } } } @@ -413,18 +339,20 @@ class HaPanelHistory extends SubscribeMixin(LitElement) { if (searchingDeviceId) { searchingDeviceId = ensureArray(searchingDeviceId); for (const singleSearchingDeviceId of searchingDeviceId) { - const foundEntities = this._deviceIdToEntities[singleSearchingDeviceId]; - if (foundEntities?.length) { - for (const foundEntity of foundEntities) { - if (foundEntity.entity_category === null) { - entityIds.add(foundEntity.entity_id); - } + const foundEntities = this._deviceEntityLookup[singleSearchingDeviceId]; + if (!foundEntities?.length) { + continue; + } + + for (const foundEntity of foundEntities) { + if (foundEntity.entity_category === null) { + entityIds.add(foundEntity.entity_id); } } } } - if (searchingEntityId !== undefined) { + if (searchingEntityId) { searchingEntityId = ensureArray(searchingEntityId); for (const singleSearchingEntityId of searchingEntityId) { entityIds.add(singleSearchingEntityId);