diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index 426ff3bed6f..287e8b065b9 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -1286,19 +1286,23 @@ def integration_entities(hass: HomeAssistant, entry_name: str) -> Iterable[str]: or provide a config entry title for filtering between instances of the same integration. """ - # first try if this is a config entry match - conf_entry = next( - ( - entry.entry_id - for entry in hass.config_entries.async_entries() - if entry.title == entry_name - ), - None, - ) - if conf_entry is not None: - ent_reg = entity_registry.async_get(hass) - entries = entity_registry.async_entries_for_config_entry(ent_reg, conf_entry) - return [entry.entity_id for entry in entries] + + # Don't allow searching for config entries without title + if not entry_name: + return [] + + # first try if there are any config entries with a matching title + entities: list[str] = [] + ent_reg = entity_registry.async_get(hass) + for entry in hass.config_entries.async_entries(): + if entry.title != entry_name: + continue + entries = entity_registry.async_entries_for_config_entry( + ent_reg, entry.entry_id + ) + entities.extend(entry.entity_id for entry in entries) + if entities: + return entities # fallback to just returning all entities for a domain # pylint: disable-next=import-outside-toplevel diff --git a/tests/helpers/test_template.py b/tests/helpers/test_template.py index 6279ea0089a..6ca93e79d5f 100644 --- a/tests/helpers/test_template.py +++ b/tests/helpers/test_template.py @@ -3280,6 +3280,16 @@ async def test_integration_entities( hass: HomeAssistant, entity_registry: er.EntityRegistry ) -> None: """Test integration_entities function.""" + # test entities for untitled config entry + config_entry = MockConfigEntry(domain="mock", title="") + config_entry.add_to_hass(hass) + entity_registry.async_get_or_create( + "sensor", "mock", "untitled", config_entry=config_entry + ) + info = render_to_info(hass, "{{ integration_entities('') }}") + assert_result_info(info, []) + assert info.rate_limit is None + # test entities for given config entry title config_entry = MockConfigEntry(domain="mock", title="Mock bridge 2") config_entry.add_to_hass(hass) @@ -3290,6 +3300,23 @@ async def test_integration_entities( assert_result_info(info, [entity_entry.entity_id]) assert info.rate_limit is None + # test entities for given non unique config entry title + config_entry = MockConfigEntry(domain="mock", title="Not unique") + config_entry.add_to_hass(hass) + entity_entry_not_unique_1 = entity_registry.async_get_or_create( + "sensor", "mock", "not_unique_1", config_entry=config_entry + ) + config_entry = MockConfigEntry(domain="mock", title="Not unique") + config_entry.add_to_hass(hass) + entity_entry_not_unique_2 = entity_registry.async_get_or_create( + "sensor", "mock", "not_unique_2", config_entry=config_entry + ) + info = render_to_info(hass, "{{ integration_entities('Not unique') }}") + assert_result_info( + info, [entity_entry_not_unique_1.entity_id, entity_entry_not_unique_2.entity_id] + ) + assert info.rate_limit is None + # test integration entities not in entity registry mock_entity = entity.Entity() mock_entity.hass = hass