Skip to content

Commit

Permalink
Optimizations for context providers/consumers and entity configs (#23)
Browse files Browse the repository at this point in the history
* Fix context providers and consumers

* Add getter for extended configs
  • Loading branch information
alengwenus authored Oct 23, 2024
1 parent c0d2f7c commit 934a32a
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 57 deletions.
37 changes: 19 additions & 18 deletions src/lcn-devices-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type { HomeAssistant, Route } from "@ha/types";
import { lcnMainTabs } from "lcn-router";
import { showAlertDialog, showConfirmationDialog } from "@ha/dialogs/generic/show-dialog-box";
import "@ha/components/ha-svg-icon";
import memoizeOne from "memoize-one";
import memoize from "memoize-one";
import { LCN, scanDevices, deleteDevice, addDevice, LcnDeviceConfig } from "types/lcn";
import { addressToString, stringToAddress } from "helpers/address_conversion";
import type {
Expand All @@ -39,9 +39,7 @@ import {
import { loadProgressDialog, showProgressDialog } from "./dialogs/show-dialog-progress";

interface DeviceRowData extends LcnDeviceConfig {
segment_id: number;
address_id: number;
type: string;
unique_id: string;
}

@customElement("lcn-devices-page")
Expand Down Expand Up @@ -93,18 +91,17 @@ export class LCNConfigDashboard extends LitElement {
@queryAsync("hass-tabs-subpage-data-table")
private _dataTable!: Promise<HaTabsSubpageDataTable>;

private extDeviceConfigs = memoizeOne((devices: LcnDeviceConfig[]) => {
const deviceRowData: DeviceRowData[] = devices.map((device) => ({
...device,
unique_id: addressToString(device.address),
segment_id: device.address[0],
address_id: device.address[1],
type: device.address[2] ? this.lcn.localize("group") : this.lcn.localize("module"),
}));
return deviceRowData;
});

private _columns = memoizeOne(
private get _extDeviceConfigs(): DeviceRowData[] {
const extDeviceConfigs = memoize((deviceConfigs: LcnDeviceConfig[] = this._deviceConfigs) =>
deviceConfigs.map((deviceConfig) => ({
...deviceConfig,
unique_id: addressToString(deviceConfig.address),
})),
);
return extDeviceConfigs();
}

private _columns = memoize(
(): DataTableColumnContainer<DeviceRowData> => ({
icon: {
title: "",
Expand All @@ -129,16 +126,20 @@ export class LCNConfigDashboard extends LitElement {
title: this.lcn.localize("segment"),
sortable: true,
filterable: true,
template: (entry) => entry.address[0].toString(),
},
address_id: {
title: this.lcn.localize("id"),
sortable: true,
filterable: true,
template: (entry) => entry.address[1].toString(),
},
type: {
title: this.lcn.localize("type"),
sortable: true,
filterable: true,
template: (entry) =>
entry.address[2] ? this.lcn.localize("group") : this.lcn.localize("module"),
},
}),
);
Expand Down Expand Up @@ -168,7 +169,7 @@ export class LCNConfigDashboard extends LitElement {
.tabs=${lcnMainTabs}
.localizeFunc=${this.lcn.localize}
.columns=${this._columns()}
.data=${this.extDeviceConfigs(this._deviceConfigs)}
.data=${this._extDeviceConfigs}
selectable
.selected=${this._selected.length}
.initialSorting=${this._activeSorting}
Expand Down Expand Up @@ -307,7 +308,7 @@ export class LCNConfigDashboard extends LitElement {
for await (const device of devices) {
await deleteDevice(this.hass, this.lcn.config_entry, device);
}
this._clearSelection();
await this._clearSelection();
updateDeviceConfigs(this);
updateEntityConfigs(this);
}
Expand Down
59 changes: 29 additions & 30 deletions src/lcn-entities-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { consume } from "@lit-labs/context";
import { deviceConfigsContext, entityConfigsContext } from "components/context";
import { fullEntitiesContext } from "@ha/data/context";
import { haStyle } from "@ha/resources/styles";
import { EntityRegistryEntry, fetchEntityRegistry } from "@ha/data/entity_registry";
import { EntityRegistryEntry } from "@ha/data/entity_registry";
import { css, html, LitElement, CSSResultGroup, nothing, PropertyValues } from "lit";
import { ifDefined } from "lit/directives/if-defined";
import { customElement, property, state, queryAsync } from "lit/decorators";
Expand All @@ -21,7 +21,6 @@ import "@ha/components/ha-state-icon";
import "@ha/components/ha-domain-icon";
import "@ha/components/ha-fab";
import { mainWindow } from "@ha/common/dom/get_main_window";
import { debounce } from "@ha/common/util/debounce";
import {
LCN,
addEntity,
Expand Down Expand Up @@ -150,21 +149,26 @@ export class LCNEntitiesPage extends LitElement {
@queryAsync("hass-tabs-subpage-data-table")
private _dataTable!: Promise<HaTabsSubpageDataTable>;

private extEntityConfigs = memoize(
(entities: LcnEntityConfig[], entityRegistryEntries: EntityRegistryEntry[]) => {
const entityRowData: EntityRowData[] = entities.map((entity) => ({
...entity,
unique_id: createUniqueEntityId(entity),
address_str: addressToString(entity.address),
entityRegistryEntry: entityRegistryEntries.find(
(entry) =>
computeDomain(entry.entity_id) === entity.domain &&
createUniqueEntityId(entity, false) === entry.unique_id.split("-").slice(1).join("-"),
)!,
}));
return entityRowData;
},
);
private get _extEntityConfigs(): EntityRowData[] {
const extEntityConfigs = memoize(
(
entityConfigs: LcnEntityConfig[] = this._entityConfigs,
entityRegistryEntries: EntityRegistryEntry[] = this._entityRegistryEntries,
) =>
entityConfigs.map((entityConfig) => ({
...entityConfig,
unique_id: createUniqueEntityId(entityConfig),
address_str: addressToString(entityConfig.address),
entityRegistryEntry: entityRegistryEntries.find(
(entry) =>
computeDomain(entry.entity_id) === entityConfig.domain &&
createUniqueEntityId(entityConfig, false) ===
entry.unique_id.split("-").slice(1).join("-"),
)!,
})),
);
return extEntityConfigs();
}

private _columns = memoize(
(): DataTableColumnContainer<EntityRowData> => ({
Expand Down Expand Up @@ -201,6 +205,10 @@ export class LCNEntitiesPage extends LitElement {
filterable: true,
direction: "asc",
flex: 2,
template: (entry) =>
entry.entityRegistryEntry
? entry.entityRegistryEntry.name || entry.entityRegistryEntry.original_name!
: entry.name,
},
address_str: {
title: this.lcn.localize("address"),
Expand All @@ -225,9 +233,9 @@ export class LCNEntitiesPage extends LitElement {
(
filters: DataTableFiltersValues,
filteredItems: DataTableFiltersItems,
entities: LcnEntityConfig[],
entities: EntityRowData[],
) => {
let filteredEntityConfigs = this.extEntityConfigs(entities, this._entityRegistryEntries);
let filteredEntityConfigs = entities;

Object.entries(filters).forEach(([key, filter]) => {
if (key === "lcn-filter-address" && Array.isArray(filter) && filter.length) {
Expand Down Expand Up @@ -278,7 +286,7 @@ export class LCNEntitiesPage extends LitElement {
const filteredEntities = this._filteredEntities(
this._filters,
this._filteredItems,
this._entityConfigs,
this._extEntityConfigs,
);
if (filteredEntities.length === 0) {
this._deviceConfig = undefined;
Expand All @@ -294,25 +302,16 @@ export class LCNEntitiesPage extends LitElement {
);
}

protected async willUpdate(_changedProperties: PropertyValues): Promise<void> {
super.willUpdate(_changedProperties);
if (this._entityRegistryEntries.length === 0)
this._entityRegistryEntries = await fetchEntityRegistry(this.hass.connection);
}

protected async firstUpdated(changedProperties: PropertyValues): Promise<void> {
super.firstUpdated(changedProperties);
loadLCNCreateEntityDialog();
updateEntityConfigs(this);
this._setFiltersFromUrl();
}

private debouncedUpdateEntityConfig = debounce(() => updateEntityConfigs(this), 500, true);

protected async updated(changedProperties: PropertyValues): Promise<void> {
super.updated(changedProperties);
this._dataTable.then(renderBrandLogo);
if (changedProperties.has("hass")) this.debouncedUpdateEntityConfig();
}

private _setFiltersFromUrl() {
Expand All @@ -339,7 +338,7 @@ export class LCNEntitiesPage extends LitElement {
const filteredEntities = this._filteredEntities(
this._filters,
this._filteredItems,
this._entityConfigs,
this._extEntityConfigs,
);

const hasFab = this._deviceConfigs.length > 0;
Expand Down
26 changes: 17 additions & 9 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ContextProvider } from "@lit-labs/context";
import { deviceConfigsContext, entityConfigsContext } from "components/context";
import { LitElement, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";

import { debounce } from "@ha/common/util/debounce";
import { applyThemesOnElement } from "@ha/common/dom/apply_themes_on_element";
import { listenMediaQuery } from "@ha/common/dom/media_query";
import { navigate } from "@ha/common/navigate";
Expand All @@ -11,8 +11,7 @@ import "@ha/resources/ha-style";
import { getConfigEntry } from "@ha/data/config_entries";
import type { HomeAssistant, Route } from "@ha/types";
import { fullEntitiesContext } from "@ha/data/context";
import { subscribeEntityRegistry } from "@ha/data/entity_registry";

import { fetchEntityRegistry } from "@ha/data/entity_registry";
import "./lcn-router";
import { ProvideHassLitMixin } from "@ha/mixins/provide-hass-lit-mixin";
import { LCNLogger } from "./lcn-logger";
Expand Down Expand Up @@ -42,7 +41,7 @@ class LcnFrontend extends ProvideHassLitMixin(LitElement) {
initialValue: [],
});

private _entitiesContext = new ContextProvider(this, {
private _entityRegistryEntries = new ContextProvider(this, {
context: fullEntitiesContext,
initialValue: [],
});
Expand Down Expand Up @@ -100,14 +99,15 @@ class LcnFrontend extends ProvideHassLitMixin(LitElement) {
protected async _postLCNSetup(): Promise<void> {
await this._fetchDevices();
await this._fetchEntities();
this._fetchEntityRegistryEntries();

this.addEventListener("lcn-update-device-configs", (_e) => this._fetchDevices());
this.addEventListener("lcn-update-entity-configs", (_e) => this._fetchEntities());

subscribeEntityRegistry(this.hass.connection, (entities) => {
this._entitiesContext.setValue(
entities.filter((entry) => entry.config_entry_id === this.lcn.config_entry.entry_id),
);
});
this.hass.connection.subscribeEvents(
debounce(async () => this._fetchEntityRegistryEntries(), 500, false),
"entity_registry_updated",
);
}

private _setRoute(ev: LocationChangedEvent): void {
Expand Down Expand Up @@ -145,6 +145,14 @@ class LcnFrontend extends ProvideHassLitMixin(LitElement) {
const entityConfigs = await fetchEntities(this.hass, this.lcn.config_entry);
this._entityConfigs.setValue(entityConfigs);
}

private async _fetchEntityRegistryEntries() {
const entityRegistryEntries = await fetchEntityRegistry(this.hass.connection).then((entries) =>
entries.filter((entry) => entry.config_entry_id === this.lcn.config_entry.entry_id),
);
this._entityRegistryEntries.setValue(entityRegistryEntries);
this.lcn.log.debug("EntityRegistry:", entityRegistryEntries.length);
}
}

declare global {
Expand Down
5 changes: 5 additions & 0 deletions src/types/lcn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ export interface LcnDeviceConfig {
hardware_type: number;
}

export interface LcnConfig {
devices: LcnDeviceConfig[];
entities: LcnEntityConfig[];
}

export const fetchDevices = (
hass: HomeAssistant,
config_entry: ConfigEntry,
Expand Down

0 comments on commit 934a32a

Please sign in to comment.