From 337b890abebbc0a6a515eb25331f746bf19bd86e Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Thu, 3 Jul 2025 18:06:44 +0200 Subject: [PATCH] Use entities and devices in compute entity name --- src/common/entity/compute_entity_name.ts | 17 ++++---- src/components/entity/ha-entity-picker.ts | 12 +++++- src/components/entity/ha-statistic-picker.ts | 12 +++++- src/data/selector/format_selector_value.ts | 6 ++- src/dialogs/more-info/ha-more-info-dialog.ts | 4 +- src/dialogs/quick-bar/ha-quick-bar.ts | 6 ++- .../device-detail/ha-device-entities-card.ts | 4 +- .../config/devices/ha-config-device-page.ts | 2 +- .../config/entities/ha-config-entities.ts | 3 +- .../card-editor/hui-entity-picker-table.ts | 6 ++- .../common/entity/compute_entity_name.test.ts | 40 +++++++++---------- 11 files changed, 72 insertions(+), 40 deletions(-) diff --git a/src/common/entity/compute_entity_name.ts b/src/common/entity/compute_entity_name.ts index 86dd0a096b..1ef6362520 100644 --- a/src/common/entity/compute_entity_name.ts +++ b/src/common/entity/compute_entity_name.ts @@ -10,9 +10,10 @@ import { stripPrefixFromEntityName } from "./strip_prefix_from_entity_name"; export const computeEntityName = ( stateObj: HassEntity, - hass: HomeAssistant + entities: HomeAssistant["entities"], + devices: HomeAssistant["devices"] ): string | undefined => { - const entry = hass.entities[stateObj.entity_id] as + const entry = entities[stateObj.entity_id] as | EntityRegistryDisplayEntry | undefined; @@ -20,25 +21,25 @@ export const computeEntityName = ( // Fall back to state name if not in the entity registry (friendly name) return computeStateName(stateObj); } - return computeEntityEntryName(entry, hass); + return computeEntityEntryName(entry, devices); }; export const computeEntityEntryName = ( entry: EntityRegistryDisplayEntry | EntityRegistryEntry, - hass: HomeAssistant + devices: HomeAssistant["devices"], + fallbackStateObj?: HassEntity ): string | undefined => { const name = entry.name || ("original_name" in entry ? entry.original_name : undefined); - const device = entry.device_id ? hass.devices[entry.device_id] : undefined; + const device = entry.device_id ? devices[entry.device_id] : undefined; if (!device) { if (name) { return name; } - const stateObj = hass.states[entry.entity_id] as HassEntity | undefined; - if (stateObj) { - return computeStateName(stateObj); + if (fallbackStateObj) { + return computeStateName(fallbackStateObj); } return undefined; } diff --git a/src/components/entity/ha-entity-picker.ts b/src/components/entity/ha-entity-picker.ts index ae7aa71088..b73acf6b47 100644 --- a/src/components/entity/ha-entity-picker.ts +++ b/src/components/entity/ha-entity-picker.ts @@ -150,7 +150,11 @@ export class HaEntityPicker extends LitElement { const { area, device } = getEntityContext(stateObj, this.hass); - const entityName = computeEntityName(stateObj, this.hass); + const entityName = computeEntityName( + stateObj, + this.hass.entities, + this.hass.devices + ); const deviceName = device ? computeDeviceName(device) : undefined; const areaName = area ? computeAreaName(area) : undefined; @@ -314,7 +318,11 @@ export class HaEntityPicker extends LitElement { const { area, device } = getEntityContext(stateObj, hass); const friendlyName = computeStateName(stateObj); // Keep this for search - const entityName = computeEntityName(stateObj, hass); + const entityName = computeEntityName( + stateObj, + hass.entities, + hass.devices + ); const deviceName = device ? computeDeviceName(device) : undefined; const areaName = area ? computeAreaName(area) : undefined; diff --git a/src/components/entity/ha-statistic-picker.ts b/src/components/entity/ha-statistic-picker.ts index 24f96b0eb2..a0b2ad04bb 100644 --- a/src/components/entity/ha-statistic-picker.ts +++ b/src/components/entity/ha-statistic-picker.ts @@ -262,7 +262,11 @@ export class HaStatisticPicker extends LitElement { const { area, device } = getEntityContext(stateObj, hass); const friendlyName = computeStateName(stateObj); // Keep this for search - const entityName = computeEntityName(stateObj, hass); + const entityName = computeEntityName( + stateObj, + this.hass.entities, + this.hass.devices + ); const deviceName = device ? computeDeviceName(device) : undefined; const areaName = area ? computeAreaName(area) : undefined; @@ -339,7 +343,11 @@ export class HaStatisticPicker extends LitElement { if (stateObj) { const { area, device } = getEntityContext(stateObj, this.hass); - const entityName = computeEntityName(stateObj, this.hass); + const entityName = computeEntityName( + stateObj, + this.hass.entities, + this.hass.devices + ); const deviceName = device ? computeDeviceName(device) : undefined; const areaName = area ? computeAreaName(area) : undefined; diff --git a/src/data/selector/format_selector_value.ts b/src/data/selector/format_selector_value.ts index 47950879d3..f616dd487f 100644 --- a/src/data/selector/format_selector_value.ts +++ b/src/data/selector/format_selector_value.ts @@ -81,7 +81,11 @@ export const formatSelectorValue = ( } const { device } = getEntityContext(stateObj, hass); const deviceName = device ? computeDeviceName(device) : undefined; - const entityName = computeEntityName(stateObj, hass); + const entityName = computeEntityName( + stateObj, + hass.entities, + hass.devices + ); return [deviceName, entityName].filter(Boolean).join(" ") || entityId; }) .join(", "); diff --git a/src/dialogs/more-info/ha-more-info-dialog.ts b/src/dialogs/more-info/ha-more-info-dialog.ts index 4ae42dd862..e54be9bde0 100644 --- a/src/dialogs/more-info/ha-more-info-dialog.ts +++ b/src/dialogs/more-info/ha-more-info-dialog.ts @@ -311,9 +311,9 @@ export class MoreInfoDialog extends LitElement { : undefined; const entityName = stateObj - ? computeEntityName(stateObj, this.hass) + ? computeEntityName(stateObj, this.hass.entities, this.hass.devices) : this._entry - ? computeEntityEntryName(this._entry, this.hass) + ? computeEntityEntryName(this._entry, this.hass.devices) : entityId; const deviceName = context?.device diff --git a/src/dialogs/quick-bar/ha-quick-bar.ts b/src/dialogs/quick-bar/ha-quick-bar.ts index 68b2fa2a5f..87590448b1 100644 --- a/src/dialogs/quick-bar/ha-quick-bar.ts +++ b/src/dialogs/quick-bar/ha-quick-bar.ts @@ -634,7 +634,11 @@ export class QuickBar extends LitElement { const { area, device } = getEntityContext(stateObj, this.hass); const friendlyName = computeStateName(stateObj); // Keep this for search - const entityName = computeEntityName(stateObj, this.hass); + const entityName = computeEntityName( + stateObj, + this.hass.entities, + this.hass.devices + ); const deviceName = device ? computeDeviceName(device) : undefined; const areaName = area ? computeAreaName(area) : undefined; diff --git a/src/panels/config/devices/device-detail/ha-device-entities-card.ts b/src/panels/config/devices/device-detail/ha-device-entities-card.ts index e16196b396..70e65c034d 100644 --- a/src/panels/config/devices/device-detail/ha-device-entities-card.ts +++ b/src/panels/config/devices/device-detail/ha-device-entities-card.ts @@ -171,7 +171,9 @@ export class HaDeviceEntitiesCard extends LitElement { element.hass = this.hass; const stateObj = this.hass.states[entry.entity_id]; - let name = computeEntityName(stateObj, this.hass) || this.deviceName; + let name = + computeEntityName(stateObj, this.hass.entities, this.hass.devices) || + this.deviceName; if (entry.hidden_by) { name += ` (${this.hass.localize( diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index c062dc699f..ddfe0ad1d2 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -1225,7 +1225,7 @@ export class HaConfigDevicePage extends LitElement { private _computeEntityName(entity: EntityRegistryEntry) { const device = this.hass.devices[this.deviceId]; return ( - computeEntityEntryName(entity, this.hass) || + computeEntityEntryName(entity, this.hass.devices) || computeDeviceNameDisplay(device, this.hass) ); } diff --git a/src/panels/config/entities/ha-config-entities.ts b/src/panels/config/entities/ha-config-entities.ts index 106a6fb8f3..9429a114a9 100644 --- a/src/panels/config/entities/ha-config-entities.ts +++ b/src/panels/config/entities/ha-config-entities.ts @@ -678,7 +678,8 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { const entityName = computeEntityEntryName( entry as EntityRegistryEntry, - this.hass + this.hass.devices, + entity ); const deviceName = device ? computeDeviceName(device) : undefined; diff --git a/src/panels/lovelace/editor/card-editor/hui-entity-picker-table.ts b/src/panels/lovelace/editor/card-editor/hui-entity-picker-table.ts index dd0c3a549c..d1dfe579fa 100644 --- a/src/panels/lovelace/editor/card-editor/hui-entity-picker-table.ts +++ b/src/panels/lovelace/editor/card-editor/hui-entity-picker-table.ts @@ -68,7 +68,11 @@ export class HuiEntityPickerTable extends LitElement { const { area, device } = getEntityContext(stateObj, this.hass); - const entityName = computeEntityName(stateObj, this.hass); + const entityName = computeEntityName( + stateObj, + this.hass.entities, + this.hass.devices + ); const deviceName = device ? computeDeviceName(device) : undefined; const areaName = area ? computeAreaName(area) : undefined; const name = [deviceName, entityName].filter(Boolean).join(" "); diff --git a/test/common/entity/compute_entity_name.test.ts b/test/common/entity/compute_entity_name.test.ts index 978e009dc3..82bc16fa44 100644 --- a/test/common/entity/compute_entity_name.test.ts +++ b/test/common/entity/compute_entity_name.test.ts @@ -20,13 +20,10 @@ describe("computeEntityName", () => { const hass = { entities: {}, devices: {}, - states: { - "light.kitchen": stateObj, - }, }; - expect(computeEntityName(stateObj as any, hass as any)).toBe( - "Kitchen Light" - ); + expect( + computeEntityName(stateObj as any, hass.entities, hass.devices) + ).toBe("Kitchen Light"); vi.restoreAllMocks(); }); @@ -41,6 +38,7 @@ describe("computeEntityName", () => { "light.kitchen": { entity_id: "light.kitchen", name: "Ceiling Light", + labels: [], }, }, devices: {}, @@ -48,9 +46,9 @@ describe("computeEntityName", () => { "light.kitchen": stateObj, }, }; - expect(computeEntityName(stateObj as any, hass as any)).toBe( - "Ceiling Light" - ); + expect( + computeEntityName(stateObj as any, hass.entities, hass.devices) + ).toBe("Ceiling Light"); }); }); @@ -58,7 +56,7 @@ describe("computeEntityEntryName", () => { it("returns entry.name if no device", () => { const entry = { entity_id: "light.kitchen", name: "Ceiling Light" }; const hass = { devices: {}, states: {} }; - expect(computeEntityEntryName(entry as any, hass as any)).toBe( + expect(computeEntityEntryName(entry as any, hass.devices)).toBe( "Ceiling Light" ); }); @@ -79,7 +77,9 @@ describe("computeEntityEntryName", () => { devices: { dev1: {} }, states: {}, }; - expect(computeEntityEntryName(entry as any, hass as any)).toBe("Light"); + expect(computeEntityEntryName(entry as any, hass.devices as any)).toBe( + "Light" + ); vi.restoreAllMocks(); }); @@ -96,7 +96,9 @@ describe("computeEntityEntryName", () => { devices: { dev1: {} }, states: {}, }; - expect(computeEntityEntryName(entry as any, hass as any)).toBeUndefined(); + expect( + computeEntityEntryName(entry as any, hass.devices as any) + ).toBeUndefined(); vi.restoreAllMocks(); }); @@ -107,13 +109,11 @@ describe("computeEntityEntryName", () => { const entry = { entity_id: "light.kitchen" }; const hass = { devices: {}, - states: { - "light.kitchen": { entity_id: "light.kitchen" }, - }, }; - expect(computeEntityEntryName(entry as any, hass as any)).toBe( - "Fallback Name" - ); + const stateObj = { entity_id: "light.kitchen" }; + expect( + computeEntityEntryName(entry as any, hass.devices, stateObj as any) + ).toBe("Fallback Name"); vi.restoreAllMocks(); }); @@ -123,7 +123,7 @@ describe("computeEntityEntryName", () => { devices: {}, states: {}, }; - expect(computeEntityEntryName(entry as any, hass as any)).toBe("Old Name"); + expect(computeEntityEntryName(entry as any, hass.devices)).toBe("Old Name"); }); it("returns undefined if no name, original_name, or device", () => { @@ -132,6 +132,6 @@ describe("computeEntityEntryName", () => { devices: {}, states: {}, }; - expect(computeEntityEntryName(entry as any, hass as any)).toBeUndefined(); + expect(computeEntityEntryName(entry as any, hass.devices)).toBeUndefined(); }); });