From a607edca96e29c23da2bdf874b4fd8e4186321d0 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 29 Oct 2025 13:02:14 +0100 Subject: [PATCH] Default entity name to friendly name --- package.json | 5 ++++- .../entity/ha-entity-name-picker.ts | 2 +- .../entity/compute-lovelace-entity-name.ts | 21 ++++++++++--------- .../hui-alarm-panel-card-editor.ts | 5 +---- .../config-elements/hui-button-card-editor.ts | 3 +-- .../hui-entity-badge-editor.ts | 5 +---- .../config-elements/hui-entity-card-editor.ts | 5 +---- .../config-elements/hui-gauge-card-editor.ts | 5 +---- .../hui-humidifier-card-editor.ts | 5 +---- .../config-elements/hui-light-card-editor.ts | 7 ++----- .../hui-media-control-card-editor.ts | 5 +---- .../hui-picture-entity-card-editor.ts | 7 ++----- .../hui-plant-status-card-editor.ts | 5 +---- .../config-elements/hui-sensor-card-editor.ts | 11 ++++------ .../hui-thermostat-card-editor.ts | 7 ++----- .../config-elements/hui-tile-card-editor.ts | 5 +---- .../hui-weather-forecast-card-editor.ts | 5 +---- .../hui-entity-heading-badge-editor.ts | 5 +---- .../compute-lovelace-entity-name.test.ts | 20 ++++++++---------- 19 files changed, 46 insertions(+), 87 deletions(-) diff --git a/package.json b/package.json index 68b933fb82..56523a8601 100644 --- a/package.json +++ b/package.json @@ -235,5 +235,8 @@ "tslib": "2.8.1", "@material/mwc-list@^0.27.0": "patch:@material/mwc-list@npm%3A0.27.0#~/.yarn/patches/@material-mwc-list-npm-0.27.0-5344fc9de4.patch" }, - "packageManager": "yarn@4.10.3" + "packageManager": "yarn@4.10.3", + "volta": { + "node": "22.21.1" + } } diff --git a/src/components/entity/ha-entity-name-picker.ts b/src/components/entity/ha-entity-name-picker.ts index 43c8290d21..2c9430fda1 100644 --- a/src/components/entity/ha-entity-name-picker.ts +++ b/src/components/entity/ha-entity-name-picker.ts @@ -312,7 +312,7 @@ export class HaEntityNamePicker extends LitElement { private _toValue = memoizeOne( (items: EntityNameItem[]): typeof this.value => { if (items.length === 0) { - return ""; + return undefined; } if (items.length === 1) { const item = items[0]; diff --git a/src/panels/lovelace/common/entity/compute-lovelace-entity-name.ts b/src/panels/lovelace/common/entity/compute-lovelace-entity-name.ts index 53ebd2df05..1eaae90d01 100644 --- a/src/panels/lovelace/common/entity/compute-lovelace-entity-name.ts +++ b/src/panels/lovelace/common/entity/compute-lovelace-entity-name.ts @@ -1,28 +1,29 @@ import type { HassEntity } from "home-assistant-js-websocket"; -import { - DEFAULT_ENTITY_NAME, - type EntityNameItem, -} from "../../../../common/entity/compute_entity_name_display"; -import type { HomeAssistant } from "../../../../types"; import { ensureArray } from "../../../../common/array/ensure-array"; +import type { EntityNameItem } from "../../../../common/entity/compute_entity_name_display"; +import { computeStateName } from "../../../../common/entity/compute_state_name"; +import type { HomeAssistant } from "../../../../types"; /** * Computes the display name for an entity in Lovelace (cards and badges). * * @param hass - The Home Assistant instance * @param stateObj - The entity state object - * @param nameConfig - The name configuration (string for override, or EntityNameItem[] for structured naming) + * @param config - The name configuration (string for override, or EntityNameItem[] for structured naming) * @returns The computed entity name */ export const computeLovelaceEntityName = ( hass: HomeAssistant, stateObj: HassEntity | undefined, - nameConfig: string | EntityNameItem | EntityNameItem[] | undefined + config: string | EntityNameItem | EntityNameItem[] | undefined ): string => { - if (typeof nameConfig === "string") { - return nameConfig; + // If no config is provided, fall back to the default state name + if (!config) { + return stateObj ? computeStateName(stateObj) : ""; + } + if (typeof config === "string") { + return config; } - const config = nameConfig || DEFAULT_ENTITY_NAME; if (stateObj) { return hass.formatEntityName(stateObj, config); } diff --git a/src/panels/lovelace/editor/config-elements/hui-alarm-panel-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-alarm-panel-card-editor.ts index 1b33d32520..c5dcf551ec 100644 --- a/src/panels/lovelace/editor/config-elements/hui-alarm-panel-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-alarm-panel-card-editor.ts @@ -4,7 +4,6 @@ import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { array, assert, assign, object, optional, string } from "superstruct"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; import { supportsFeature } from "../../../../common/entity/supports-feature"; import type { LocalizeFunc } from "../../../../common/translations/localize"; import "../../../../components/ha-form/ha-form"; @@ -65,9 +64,7 @@ export class HuiAlarmPanelCardEditor { name: "name", selector: { - entity_name: { - default_name: DEFAULT_ENTITY_NAME, - }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts index 40b6a15797..e8aaea2ae0 100644 --- a/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-button-card-editor.ts @@ -5,7 +5,6 @@ import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { assert, assign, boolean, object, optional, string } from "superstruct"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; import "../../../../components/ha-form/ha-form"; import type { HaFormSchema, @@ -73,7 +72,7 @@ export class HuiButtonCardEditor { name: "name", selector: { - entity_name: { default_name: DEFAULT_ENTITY_NAME }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/src/panels/lovelace/editor/config-elements/hui-entity-badge-editor.ts b/src/panels/lovelace/editor/config-elements/hui-entity-badge-editor.ts index 532150d754..6c57c9177c 100644 --- a/src/panels/lovelace/editor/config-elements/hui-entity-badge-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-entity-badge-editor.ts @@ -13,7 +13,6 @@ import { string, union, } from "superstruct"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; import { fireEvent } from "../../../../common/dom/fire_event"; import type { LocalizeFunc } from "../../../../common/translations/localize"; import "../../../../components/ha-form/ha-form"; @@ -86,9 +85,7 @@ export class HuiEntityBadgeEditor { name: "name", selector: { - entity_name: { - default_name: DEFAULT_ENTITY_NAME, - }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/src/panels/lovelace/editor/config-elements/hui-entity-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-entity-card-editor.ts index 0c5f3730db..98a816ef4c 100644 --- a/src/panels/lovelace/editor/config-elements/hui-entity-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-entity-card-editor.ts @@ -1,5 +1,4 @@ import { assert, assign, boolean, object, optional, string } from "superstruct"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; import type { LocalizeFunc } from "../../../../common/translations/localize"; import type { HaFormSchema } from "../../../../components/ha-form/types"; import { headerFooterConfigStructs } from "../../header-footer/structs"; @@ -26,9 +25,7 @@ const SCHEMA = [ { name: "name", selector: { - entity_name: { - default_name: DEFAULT_ENTITY_NAME, - }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/src/panels/lovelace/editor/config-elements/hui-gauge-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-gauge-card-editor.ts index e5dc15db1b..0beec32e2f 100644 --- a/src/panels/lovelace/editor/config-elements/hui-gauge-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-gauge-card-editor.ts @@ -14,7 +14,6 @@ import { string, } from "superstruct"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; import "../../../../components/ha-form/ha-form"; import type { SchemaUnion } from "../../../../components/ha-form/types"; import { NON_NUMERIC_ATTRIBUTES } from "../../../../data/entity_attributes"; @@ -102,9 +101,7 @@ export class HuiGaugeCardEditor { name: "name", selector: { - entity_name: { - default_name: DEFAULT_ENTITY_NAME, - }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/src/panels/lovelace/editor/config-elements/hui-humidifier-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-humidifier-card-editor.ts index e519085a81..a02e013d21 100644 --- a/src/panels/lovelace/editor/config-elements/hui-humidifier-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-humidifier-card-editor.ts @@ -14,7 +14,6 @@ import { } from "superstruct"; import type { HASSDomEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; import "../../../../components/ha-expansion-panel"; import "../../../../components/ha-form/ha-form"; import type { @@ -61,9 +60,7 @@ const SCHEMA = [ { name: "name", selector: { - entity_name: { - default_name: DEFAULT_ENTITY_NAME, - }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/src/panels/lovelace/editor/config-elements/hui-light-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-light-card-editor.ts index 77a956509d..bc76578489 100644 --- a/src/panels/lovelace/editor/config-elements/hui-light-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-light-card-editor.ts @@ -1,10 +1,9 @@ +import { mdiGestureTap } from "@mdi/js"; import type { CSSResultGroup } from "lit"; import { html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { assert, assign, object, optional, string } from "superstruct"; -import { mdiGestureTap } from "@mdi/js"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; import "../../../../components/ha-form/ha-form"; import type { SchemaUnion } from "../../../../components/ha-form/types"; import type { HomeAssistant } from "../../../../types"; @@ -37,9 +36,7 @@ const SCHEMA = [ { name: "name", selector: { - entity_name: { - default_name: DEFAULT_ENTITY_NAME, - }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/src/panels/lovelace/editor/config-elements/hui-media-control-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-media-control-card-editor.ts index cd53badf47..5a204801af 100644 --- a/src/panels/lovelace/editor/config-elements/hui-media-control-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-media-control-card-editor.ts @@ -2,7 +2,6 @@ import { html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { assert, assign, object, optional, string } from "superstruct"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; import "../../../../components/ha-form/ha-form"; import type { HaFormSchema, @@ -33,9 +32,7 @@ const SCHEMA = [ { name: "name", selector: { - entity_name: { - default_name: DEFAULT_ENTITY_NAME, - }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/src/panels/lovelace/editor/config-elements/hui-picture-entity-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-picture-entity-card-editor.ts index 46786724b5..ecf2e94131 100644 --- a/src/panels/lovelace/editor/config-elements/hui-picture-entity-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-picture-entity-card-editor.ts @@ -1,8 +1,8 @@ -import memoizeOne from "memoize-one"; import { mdiGestureTap } from "@mdi/js"; import type { CSSResultGroup } from "lit"; import { html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; +import memoizeOne from "memoize-one"; import { assert, assign, @@ -15,7 +15,6 @@ import { } from "superstruct"; import { fireEvent } from "../../../../common/dom/fire_event"; import { computeDomain } from "../../../../common/entity/compute_domain"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; import type { LocalizeFunc } from "../../../../common/translations/localize"; import "../../../../components/ha-form/ha-form"; import type { @@ -71,9 +70,7 @@ export class HuiPictureEntityCardEditor { name: "name", selector: { - entity_name: { - default_name: DEFAULT_ENTITY_NAME, - }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/src/panels/lovelace/editor/config-elements/hui-plant-status-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-plant-status-card-editor.ts index 3c2a3a1a14..62e16e18f7 100644 --- a/src/panels/lovelace/editor/config-elements/hui-plant-status-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-plant-status-card-editor.ts @@ -2,7 +2,6 @@ import { html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { assert, assign, object, optional, string } from "superstruct"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; import "../../../../components/ha-form/ha-form"; import type { SchemaUnion } from "../../../../components/ha-form/types"; import type { HomeAssistant } from "../../../../types"; @@ -25,9 +24,7 @@ const SCHEMA = [ { name: "name", selector: { - entity_name: { - default_name: DEFAULT_ENTITY_NAME, - }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/src/panels/lovelace/editor/config-elements/hui-sensor-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-sensor-card-editor.ts index 524fa81dbc..d7dfd5fff8 100644 --- a/src/panels/lovelace/editor/config-elements/hui-sensor-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-sensor-card-editor.ts @@ -1,7 +1,7 @@ -import memoizeOne from "memoize-one"; import type { CSSResultGroup } from "lit"; import { html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; +import memoizeOne from "memoize-one"; import { assert, assign, @@ -12,18 +12,17 @@ import { string, union, } from "superstruct"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; -import type { LocalizeFunc } from "../../../../common/translations/localize"; import { fireEvent } from "../../../../common/dom/fire_event"; +import type { LocalizeFunc } from "../../../../common/translations/localize"; import "../../../../components/ha-form/ha-form"; import type { SchemaUnion } from "../../../../components/ha-form/types"; import type { HomeAssistant } from "../../../../types"; +import { DEFAULT_HOURS_TO_SHOW } from "../../cards/hui-sensor-card"; import type { SensorCardConfig } from "../../cards/types"; import type { LovelaceCardEditor } from "../../types"; import { baseLovelaceCardConfig } from "../structs/base-card-struct"; import { entityNameStruct } from "../structs/entity-name-struct"; import { configElementStyle } from "./config-elements-style"; -import { DEFAULT_HOURS_TO_SHOW } from "../../cards/hui-sensor-card"; const cardConfigStruct = assign( baseLovelaceCardConfig, @@ -71,9 +70,7 @@ export class HuiSensorCardEditor { name: "name", selector: { - entity_name: { - default_name: DEFAULT_ENTITY_NAME, - }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/src/panels/lovelace/editor/config-elements/hui-thermostat-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-thermostat-card-editor.ts index 8498771c24..dd10d3c04b 100644 --- a/src/panels/lovelace/editor/config-elements/hui-thermostat-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-thermostat-card-editor.ts @@ -14,7 +14,7 @@ import { } from "superstruct"; import type { HASSDomEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; +import { computeDomain } from "../../../../common/entity/compute_domain"; import "../../../../components/ha-expansion-panel"; import "../../../../components/ha-form/ha-form"; import type { @@ -35,7 +35,6 @@ import type { EditDetailElementEvent, EditSubElementEvent } from "../types"; import { configElementStyle } from "./config-elements-style"; import "./hui-card-features-editor"; import type { FeatureType } from "./hui-card-features-editor"; -import { computeDomain } from "../../../../common/entity/compute_domain"; const COMPATIBLE_FEATURES_TYPES: Record = { climate: [ @@ -89,9 +88,7 @@ export class HuiThermostatCardEditor { name: "name", selector: { - entity_name: { - default_name: DEFAULT_ENTITY_NAME, - }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts index 598059825c..dca3127c1a 100644 --- a/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts @@ -16,7 +16,6 @@ import { } from "superstruct"; import type { HASSDomEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; import type { LocalizeFunc } from "../../../../common/translations/localize"; import { orderProperties } from "../../../../common/util/order-properties"; import "../../../../components/ha-expansion-panel"; @@ -102,9 +101,7 @@ export class HuiTileCardEditor { name: "name", selector: { - entity_name: { - default_name: DEFAULT_ENTITY_NAME, - }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/src/panels/lovelace/editor/config-elements/hui-weather-forecast-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-weather-forecast-card-editor.ts index 8d498e96bd..9bbdb91541 100644 --- a/src/panels/lovelace/editor/config-elements/hui-weather-forecast-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-weather-forecast-card-editor.ts @@ -12,7 +12,6 @@ import { string, } from "superstruct"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; import { supportsFeature } from "../../../../common/entity/supports-feature"; import type { LocalizeFunc } from "../../../../common/translations/localize"; import "../../../../components/ha-form/ha-form"; @@ -153,9 +152,7 @@ export class HuiWeatherForecastCardEditor { name: "name", selector: { - entity_name: { - default_name: DEFAULT_ENTITY_NAME, - }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/src/panels/lovelace/editor/heading-badge-editor/hui-entity-heading-badge-editor.ts b/src/panels/lovelace/editor/heading-badge-editor/hui-entity-heading-badge-editor.ts index dfc733c588..211c26aff5 100644 --- a/src/panels/lovelace/editor/heading-badge-editor/hui-entity-heading-badge-editor.ts +++ b/src/panels/lovelace/editor/heading-badge-editor/hui-entity-heading-badge-editor.ts @@ -13,7 +13,6 @@ import { union, } from "superstruct"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { DEFAULT_ENTITY_NAME } from "../../../../common/entity/compute_entity_name_display"; import type { LocalizeFunc } from "../../../../common/translations/localize"; import "../../../../components/ha-expansion-panel"; import "../../../../components/ha-form/ha-form"; @@ -94,9 +93,7 @@ export class HuiHeadingEntityEditor { name: "name", selector: { - entity_name: { - default_name: DEFAULT_ENTITY_NAME, - }, + entity_name: {}, }, context: { entity: "entity" }, }, diff --git a/test/panels/lovelace/common/entity/compute-lovelace-entity-name.test.ts b/test/panels/lovelace/common/entity/compute-lovelace-entity-name.test.ts index 77e4291a8a..3d46f3fd36 100644 --- a/test/panels/lovelace/common/entity/compute-lovelace-entity-name.test.ts +++ b/test/panels/lovelace/common/entity/compute-lovelace-entity-name.test.ts @@ -1,5 +1,4 @@ import { describe, expect, it, vi } from "vitest"; -import { DEFAULT_ENTITY_NAME } from "../../../../../src/common/entity/compute_entity_name_display"; import { computeLovelaceEntityName } from "../../../../../src/panels/lovelace/common/entity/compute-lovelace-entity-name"; import type { HomeAssistant } from "../../../../../src/types"; import { mockStateObj } from "../../../../common/entity/context/context-mock"; @@ -23,30 +22,29 @@ describe("computeLovelaceEntityName", () => { expect(mockFormatEntityName).not.toHaveBeenCalled(); }); - it("returns empty string when nameConfig is empty string", () => { + it("return state name when nameConfig is empty string", () => { const mockFormatEntityName = vi.fn(); const hass = createMockHass(mockFormatEntityName); const stateObj = mockStateObj({ entity_id: "light.kitchen" }); const result = computeLovelaceEntityName(hass, stateObj, ""); - expect(result).toBe(""); + expect(result).toBe("Kitchen Light"); expect(mockFormatEntityName).not.toHaveBeenCalled(); }); - it("calls formatEntityName with DEFAULT_ENTITY_NAME when nameConfig is undefined", () => { + it("return state name when nameConfig is undefined", () => { const mockFormatEntityName = vi.fn(() => "Formatted Name"); const hass = createMockHass(mockFormatEntityName); - const stateObj = mockStateObj({ entity_id: "light.kitchen" }); + const stateObj = mockStateObj({ + entity_id: "light.kitchen", + attributes: { friendly_name: "Kitchen Light" }, + }); const result = computeLovelaceEntityName(hass, stateObj, undefined); - expect(result).toBe("Formatted Name"); - expect(mockFormatEntityName).toHaveBeenCalledTimes(1); - expect(mockFormatEntityName).toHaveBeenCalledWith( - stateObj, - DEFAULT_ENTITY_NAME - ); + expect(result).toBe("Kitchen Light"); + expect(mockFormatEntityName).not.toHaveBeenCalled(); }); it("calls formatEntityName with EntityNameItem config", () => {