Use entities and devices in compute entity name

This commit is contained in:
Paul Bottein 2025-07-03 18:06:44 +02:00
parent 6e7874c2c9
commit 337b890abe
No known key found for this signature in database
11 changed files with 72 additions and 40 deletions

View File

@ -10,9 +10,10 @@ import { stripPrefixFromEntityName } from "./strip_prefix_from_entity_name";
export const computeEntityName = ( export const computeEntityName = (
stateObj: HassEntity, stateObj: HassEntity,
hass: HomeAssistant entities: HomeAssistant["entities"],
devices: HomeAssistant["devices"]
): string | undefined => { ): string | undefined => {
const entry = hass.entities[stateObj.entity_id] as const entry = entities[stateObj.entity_id] as
| EntityRegistryDisplayEntry | EntityRegistryDisplayEntry
| undefined; | undefined;
@ -20,25 +21,25 @@ export const computeEntityName = (
// Fall back to state name if not in the entity registry (friendly name) // Fall back to state name if not in the entity registry (friendly name)
return computeStateName(stateObj); return computeStateName(stateObj);
} }
return computeEntityEntryName(entry, hass); return computeEntityEntryName(entry, devices);
}; };
export const computeEntityEntryName = ( export const computeEntityEntryName = (
entry: EntityRegistryDisplayEntry | EntityRegistryEntry, entry: EntityRegistryDisplayEntry | EntityRegistryEntry,
hass: HomeAssistant devices: HomeAssistant["devices"],
fallbackStateObj?: HassEntity
): string | undefined => { ): string | undefined => {
const name = const name =
entry.name || ("original_name" in entry ? entry.original_name : undefined); 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 (!device) {
if (name) { if (name) {
return name; return name;
} }
const stateObj = hass.states[entry.entity_id] as HassEntity | undefined; if (fallbackStateObj) {
if (stateObj) { return computeStateName(fallbackStateObj);
return computeStateName(stateObj);
} }
return undefined; return undefined;
} }

View File

@ -150,7 +150,11 @@ export class HaEntityPicker extends LitElement {
const { area, device } = getEntityContext(stateObj, this.hass); 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 deviceName = device ? computeDeviceName(device) : undefined;
const areaName = area ? computeAreaName(area) : undefined; const areaName = area ? computeAreaName(area) : undefined;
@ -314,7 +318,11 @@ export class HaEntityPicker extends LitElement {
const { area, device } = getEntityContext(stateObj, hass); const { area, device } = getEntityContext(stateObj, hass);
const friendlyName = computeStateName(stateObj); // Keep this for search 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 deviceName = device ? computeDeviceName(device) : undefined;
const areaName = area ? computeAreaName(area) : undefined; const areaName = area ? computeAreaName(area) : undefined;

View File

@ -262,7 +262,11 @@ export class HaStatisticPicker extends LitElement {
const { area, device } = getEntityContext(stateObj, hass); const { area, device } = getEntityContext(stateObj, hass);
const friendlyName = computeStateName(stateObj); // Keep this for search 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 deviceName = device ? computeDeviceName(device) : undefined;
const areaName = area ? computeAreaName(area) : undefined; const areaName = area ? computeAreaName(area) : undefined;
@ -339,7 +343,11 @@ export class HaStatisticPicker extends LitElement {
if (stateObj) { if (stateObj) {
const { area, device } = getEntityContext(stateObj, this.hass); 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 deviceName = device ? computeDeviceName(device) : undefined;
const areaName = area ? computeAreaName(area) : undefined; const areaName = area ? computeAreaName(area) : undefined;

View File

@ -81,7 +81,11 @@ export const formatSelectorValue = (
} }
const { device } = getEntityContext(stateObj, hass); const { device } = getEntityContext(stateObj, hass);
const deviceName = device ? computeDeviceName(device) : undefined; 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; return [deviceName, entityName].filter(Boolean).join(" ") || entityId;
}) })
.join(", "); .join(", ");

View File

@ -311,9 +311,9 @@ export class MoreInfoDialog extends LitElement {
: undefined; : undefined;
const entityName = stateObj const entityName = stateObj
? computeEntityName(stateObj, this.hass) ? computeEntityName(stateObj, this.hass.entities, this.hass.devices)
: this._entry : this._entry
? computeEntityEntryName(this._entry, this.hass) ? computeEntityEntryName(this._entry, this.hass.devices)
: entityId; : entityId;
const deviceName = context?.device const deviceName = context?.device

View File

@ -634,7 +634,11 @@ export class QuickBar extends LitElement {
const { area, device } = getEntityContext(stateObj, this.hass); const { area, device } = getEntityContext(stateObj, this.hass);
const friendlyName = computeStateName(stateObj); // Keep this for search 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 deviceName = device ? computeDeviceName(device) : undefined;
const areaName = area ? computeAreaName(area) : undefined; const areaName = area ? computeAreaName(area) : undefined;

View File

@ -171,7 +171,9 @@ export class HaDeviceEntitiesCard extends LitElement {
element.hass = this.hass; element.hass = this.hass;
const stateObj = this.hass.states[entry.entity_id]; 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) { if (entry.hidden_by) {
name += ` (${this.hass.localize( name += ` (${this.hass.localize(

View File

@ -1225,7 +1225,7 @@ export class HaConfigDevicePage extends LitElement {
private _computeEntityName(entity: EntityRegistryEntry) { private _computeEntityName(entity: EntityRegistryEntry) {
const device = this.hass.devices[this.deviceId]; const device = this.hass.devices[this.deviceId];
return ( return (
computeEntityEntryName(entity, this.hass) || computeEntityEntryName(entity, this.hass.devices) ||
computeDeviceNameDisplay(device, this.hass) computeDeviceNameDisplay(device, this.hass)
); );
} }

View File

@ -678,7 +678,8 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
const entityName = computeEntityEntryName( const entityName = computeEntityEntryName(
entry as EntityRegistryEntry, entry as EntityRegistryEntry,
this.hass this.hass.devices,
entity
); );
const deviceName = device ? computeDeviceName(device) : undefined; const deviceName = device ? computeDeviceName(device) : undefined;

View File

@ -68,7 +68,11 @@ export class HuiEntityPickerTable extends LitElement {
const { area, device } = getEntityContext(stateObj, this.hass); 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 deviceName = device ? computeDeviceName(device) : undefined;
const areaName = area ? computeAreaName(area) : undefined; const areaName = area ? computeAreaName(area) : undefined;
const name = [deviceName, entityName].filter(Boolean).join(" "); const name = [deviceName, entityName].filter(Boolean).join(" ");

View File

@ -20,13 +20,10 @@ describe("computeEntityName", () => {
const hass = { const hass = {
entities: {}, entities: {},
devices: {}, devices: {},
states: {
"light.kitchen": stateObj,
},
}; };
expect(computeEntityName(stateObj as any, hass as any)).toBe( expect(
"Kitchen Light" computeEntityName(stateObj as any, hass.entities, hass.devices)
); ).toBe("Kitchen Light");
vi.restoreAllMocks(); vi.restoreAllMocks();
}); });
@ -41,6 +38,7 @@ describe("computeEntityName", () => {
"light.kitchen": { "light.kitchen": {
entity_id: "light.kitchen", entity_id: "light.kitchen",
name: "Ceiling Light", name: "Ceiling Light",
labels: [],
}, },
}, },
devices: {}, devices: {},
@ -48,9 +46,9 @@ describe("computeEntityName", () => {
"light.kitchen": stateObj, "light.kitchen": stateObj,
}, },
}; };
expect(computeEntityName(stateObj as any, hass as any)).toBe( expect(
"Ceiling Light" computeEntityName(stateObj as any, hass.entities, hass.devices)
); ).toBe("Ceiling Light");
}); });
}); });
@ -58,7 +56,7 @@ describe("computeEntityEntryName", () => {
it("returns entry.name if no device", () => { it("returns entry.name if no device", () => {
const entry = { entity_id: "light.kitchen", name: "Ceiling Light" }; const entry = { entity_id: "light.kitchen", name: "Ceiling Light" };
const hass = { devices: {}, states: {} }; const hass = { devices: {}, states: {} };
expect(computeEntityEntryName(entry as any, hass as any)).toBe( expect(computeEntityEntryName(entry as any, hass.devices)).toBe(
"Ceiling Light" "Ceiling Light"
); );
}); });
@ -79,7 +77,9 @@ describe("computeEntityEntryName", () => {
devices: { dev1: {} }, devices: { dev1: {} },
states: {}, states: {},
}; };
expect(computeEntityEntryName(entry as any, hass as any)).toBe("Light"); expect(computeEntityEntryName(entry as any, hass.devices as any)).toBe(
"Light"
);
vi.restoreAllMocks(); vi.restoreAllMocks();
}); });
@ -96,7 +96,9 @@ describe("computeEntityEntryName", () => {
devices: { dev1: {} }, devices: { dev1: {} },
states: {}, states: {},
}; };
expect(computeEntityEntryName(entry as any, hass as any)).toBeUndefined(); expect(
computeEntityEntryName(entry as any, hass.devices as any)
).toBeUndefined();
vi.restoreAllMocks(); vi.restoreAllMocks();
}); });
@ -107,13 +109,11 @@ describe("computeEntityEntryName", () => {
const entry = { entity_id: "light.kitchen" }; const entry = { entity_id: "light.kitchen" };
const hass = { const hass = {
devices: {}, devices: {},
states: {
"light.kitchen": { entity_id: "light.kitchen" },
},
}; };
expect(computeEntityEntryName(entry as any, hass as any)).toBe( const stateObj = { entity_id: "light.kitchen" };
"Fallback Name" expect(
); computeEntityEntryName(entry as any, hass.devices, stateObj as any)
).toBe("Fallback Name");
vi.restoreAllMocks(); vi.restoreAllMocks();
}); });
@ -123,7 +123,7 @@ describe("computeEntityEntryName", () => {
devices: {}, devices: {},
states: {}, 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", () => { it("returns undefined if no name, original_name, or device", () => {
@ -132,6 +132,6 @@ describe("computeEntityEntryName", () => {
devices: {}, devices: {},
states: {}, states: {},
}; };
expect(computeEntityEntryName(entry as any, hass as any)).toBeUndefined(); expect(computeEntityEntryName(entry as any, hass.devices)).toBeUndefined();
}); });
}); });