Compare commits

...

4 Commits

Author SHA1 Message Date
Paul Bottein
aca48f10d2 Set right friendly name 2025-10-29 15:34:41 +01:00
Paul Bottein
90eaa2c60a Clean code 2025-10-29 15:34:41 +01:00
Paul Bottein
d91b6d85f8 Fix tests 2025-10-29 15:34:40 +01:00
Paul Bottein
bf24f87aba Let Home Assistant generate the entity id for esphome entities 2025-10-29 15:34:40 +01:00
2 changed files with 10 additions and 25 deletions

View File

@@ -90,7 +90,7 @@ def async_static_info_updated(
# Create new entity if it doesn't exist
if not old_info:
entity = entity_type(entry_data, platform.domain, info, state_type)
entity = entity_type(entry_data, info, state_type)
add_entities.append(entity)
continue
@@ -112,7 +112,7 @@ def async_static_info_updated(
old_info.device_id,
info.device_id,
)
entity = entity_type(entry_data, platform.domain, info, state_type)
entity = entity_type(entry_data, info, state_type)
add_entities.append(entity)
continue
@@ -162,7 +162,7 @@ def async_static_info_updated(
entry_data.async_signal_entity_removal(info_type, old_info.device_id, info.key)
# Create new entity with the new device_id
add_entities.append(entity_type(entry_data, platform.domain, info, state_type))
add_entities.append(entity_type(entry_data, info, state_type))
# Anything still in current_infos is now gone
if current_infos:
@@ -329,7 +329,6 @@ class EsphomeEntity(EsphomeBaseEntity, Generic[_InfoT, _StateT]):
def __init__(
self,
entry_data: RuntimeEntryData,
domain: str,
entity_info: EntityInfo,
state_type: type[_StateT],
) -> None:
@@ -343,7 +342,6 @@ class EsphomeEntity(EsphomeBaseEntity, Generic[_InfoT, _StateT]):
self._state_type = state_type
self._on_static_info_update(entity_info)
device_name = device_info.name
# Determine the device connection based on whether this entity belongs to a sub device
if entity_info.device_id:
# Entity belongs to a sub device
@@ -352,27 +350,12 @@ class EsphomeEntity(EsphomeBaseEntity, Generic[_InfoT, _StateT]):
(DOMAIN, f"{device_info.mac_address}_{entity_info.device_id}")
}
)
# Use the pre-computed device_id_to_name mapping for O(1) lookup
device_name = entry_data.device_id_to_name.get(
entity_info.device_id, device_info.name
)
else:
# Entity belongs to the main device
self._attr_device_info = DeviceInfo(
connections={(dr.CONNECTION_NETWORK_MAC, device_info.mac_address)}
)
if entity_info.name:
self.entity_id = f"{domain}.{device_name}_{entity_info.name}"
else:
# https://github.com/home-assistant/core/issues/132532
# If name is not set, ESPHome will use the sanitized friendly name
# as the name, however we want to use the original object_id
# as the entity_id before it is sanitized since the sanitizer
# is not utf-8 aware. In this case, its always going to be
# an empty string so we drop the object_id.
self.entity_id = f"{domain}.{device_name}"
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
entry_data = self._entry_data

View File

@@ -489,7 +489,7 @@ async def test_entity_without_name_device_with_friendly_name(
states=states,
device_info={"friendly_name": "The Best Mixer", "name": "mixer"},
)
state = hass.states.get("binary_sensor.mixer")
state = hass.states.get("binary_sensor.the_best_mixer")
assert state is not None
assert state.state == STATE_ON
# Make sure we have set the name to `None` as otherwise
@@ -601,7 +601,7 @@ async def test_entity_id_preserved_on_upgrade_when_in_storage(
states=states,
device_info={"friendly_name": "The Best Mixer", "name": "mixer"},
)
state = hass.states.get("binary_sensor.mixer_my")
state = hass.states.get("binary_sensor.the_best_mixer_my")
assert state is not None
# now rename the entity
ent_reg_entry = entity_registry.async_get_or_create(
@@ -874,8 +874,8 @@ async def test_entity_friendly_names_with_empty_device_names(
)
# Check entity friendly name on sub-device with empty name
# Since sub device has empty name, it falls back to main device name "test"
state_1 = hass.states.get("binary_sensor.test_motion_detected")
# Since sub device has empty name, it falls back to main device name "Main device"
state_1 = hass.states.get("binary_sensor.main_device_motion_detected")
assert state_1 is not None
# With has_entity_name, friendly name is "{device_name} {entity_name}"
# Since sub-device falls back to main device name: "Main Device Motion Detected"
@@ -894,7 +894,7 @@ async def test_entity_friendly_names_with_empty_device_names(
assert state_3.attributes[ATTR_FRIENDLY_NAME] == "Kitchen Light"
# Test entity on main device
state_4 = hass.states.get("binary_sensor.test_main_status")
state_4 = hass.states.get("binary_sensor.main_device_main_status")
assert state_4 is not None
assert state_4.attributes[ATTR_FRIENDLY_NAME] == "Main Device Main Status"
@@ -1050,6 +1050,7 @@ async def test_entity_id_uses_sub_device_name(
device_info = {
"devices": sub_devices,
"name": "main_device",
"friendly_name": "Main Device",
}
# Create entities that belong to different devices
@@ -1131,6 +1132,7 @@ async def test_entity_id_with_empty_sub_device_name(
device_info = {
"devices": sub_devices,
"name": "main_device",
"friendly_name": "Main Device",
}
# Create entity on sub device with empty name