diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index 714a57336bd..cc619e25aed 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -1381,6 +1381,24 @@ def device_attr(hass: HomeAssistant, device_or_entity_id: str, attr_name: str) - return getattr(device, attr_name) +def config_entry_attr( + hass: HomeAssistant, config_entry_id_: str, attr_name: str +) -> Any: + """Get config entry specific attribute.""" + if not isinstance(config_entry_id_, str): + raise TemplateError("Must provide a config entry ID") + + if attr_name not in ("domain", "title", "state", "source", "disabled_by"): + raise TemplateError("Invalid config entry attribute") + + config_entry = hass.config_entries.async_get_entry(config_entry_id_) + + if config_entry is None: + return None + + return getattr(config_entry, attr_name) + + def is_device_attr( hass: HomeAssistant, device_or_entity_id: str, attr_name: str, attr_value: Any ) -> bool: @@ -2868,6 +2886,9 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment): self.globals["device_attr"] = hassfunction(device_attr) self.filters["device_attr"] = self.globals["device_attr"] + self.globals["config_entry_attr"] = hassfunction(config_entry_attr) + self.filters["config_entry_attr"] = self.globals["config_entry_attr"] + self.globals["is_device_attr"] = hassfunction(is_device_attr) self.tests["is_device_attr"] = hassfunction(is_device_attr, pass_eval_context) diff --git a/tests/helpers/test_template.py b/tests/helpers/test_template.py index 26e4f986592..3123c01f500 100644 --- a/tests/helpers/test_template.py +++ b/tests/helpers/test_template.py @@ -17,6 +17,7 @@ import orjson import pytest import voluptuous as vol +from homeassistant import config_entries from homeassistant.components import group from homeassistant.const import ( ATTR_UNIT_OF_MEASUREMENT, @@ -3990,6 +3991,48 @@ async def test_device_attr( assert info.rate_limit is None +async def test_config_entry_attr(hass: HomeAssistant) -> None: + """Test config entry attr.""" + info = { + "domain": "mock_light", + "title": "mock title", + "source": config_entries.SOURCE_BLUETOOTH, + "disabled_by": config_entries.ConfigEntryDisabler.USER, + } + config_entry = MockConfigEntry(**info) + config_entry.add_to_hass(hass) + + info["state"] = config_entries.ConfigEntryState.NOT_LOADED + + for key, value in info.items(): + tpl = template.Template( + "{{ config_entry_attr('" + config_entry.entry_id + "', '" + key + "') }}", + hass, + ) + assert tpl.async_render(parse_result=False) == str(value) + + for config_entry_id, key in ( + (config_entry.entry_id, "invalid_key"), + (56, "domain"), + ): + with pytest.raises(TemplateError): + template.Template( + "{{ config_entry_attr(" + + json.dumps(config_entry_id) + + ", '" + + key + + "') }}", + hass, + ).async_render() + + assert ( + template.Template( + "{{ config_entry_attr('invalid_id', 'domain') }}", hass + ).async_render(parse_result=False) + == "None" + ) + + async def test_issues(hass: HomeAssistant, issue_registry: ir.IssueRegistry) -> None: """Test issues function.""" # Test no issues