From 3bbf0841cce08e17fbb63c20f54cf4b1f606a4af Mon Sep 17 00:00:00 2001 From: Graham Hosking <142685548+ITSpecialist111@users.noreply.github.com> Date: Tue, 28 Jul 2026 07:02:06 +0100 Subject: [PATCH 1/2] Ignore Jinja context paths in dependencies --- automation_inspector/app/references.py | 2 ++ tests/test_references.py | 35 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/automation_inspector/app/references.py b/automation_inspector/app/references.py index db7603c..4dfb435 100644 --- a/automation_inspector/app/references.py +++ b/automation_inspector/app/references.py @@ -197,6 +197,8 @@ def scan_string(value: str, key: str | None) -> None: template_matches = set(TEMPLATE_ENTITY_RE.findall(value)) for entity_id in template_matches: add(entity_id, "template") + if _is_template(value): + return explicit_key = key in ENTITY_VALUE_KEYS source = "template" if "{{" in value or "{%" in value else "configuration" for entity_id in ENTITY_ID_RE.findall(value): diff --git a/tests/test_references.py b/tests/test_references.py index 868c93e..629a4c8 100644 --- a/tests/test_references.py +++ b/tests/test_references.py @@ -103,3 +103,38 @@ def test_ignores_entity_like_values_in_description() -> None: references = collect_entity_references(config, set()) assert references == {"sensor.real_dependency": {"explicit"}} + + +def test_ignores_jinja_context_paths_but_keeps_literal_template_entities() -> None: + config = { + "conditions": [ + { + "condition": "template", + "value_template": "{{ is_state('sensor.real_temperature', '20') }}", + } + ], + "actions": [ + { + "repeat": { + "for_each": [{"boolean": "input_boolean.window_pause"}], + "sequence": [ + { + "action": "input_boolean.turn_off", + "target": {"entity_id": "{{ repeat.item.boolean }}"}, + }, + { + "action": "logbook.log", + "data": {"message": "Triggered by {{ trigger.entity_id }}"}, + }, + ], + } + } + ], + } + + references = collect_entity_references(config, set()) + + assert references == { + "input_boolean.window_pause": {"configuration"}, + "sensor.real_temperature": {"template"}, + } From 66b27bf154cc5f7d3fb78d774f309231f2b58d3d Mon Sep 17 00:00:00 2001 From: Graham Hosking <142685548+ITSpecialist111@users.noreply.github.com> Date: Tue, 28 Jul 2026 07:26:00 +0100 Subject: [PATCH 2/2] Keep real template entity references --- automation_inspector/app/references.py | 30 ++++++++++++++++++++++---- tests/test_references.py | 26 ++++++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/automation_inspector/app/references.py b/automation_inspector/app/references.py index 4dfb435..b355542 100644 --- a/automation_inspector/app/references.py +++ b/automation_inspector/app/references.py @@ -27,6 +27,25 @@ "humidity_entity_id", } +JINJA_CONTEXT_ROOTS = frozenset( + { + "config", + "context", + "item", + "loop", + "now", + "repeat", + "state", + "states", + "this", + "trigger", + "utcnow", + "value_json", + "variables", + "wait", + } +) + STANDARD_DOMAINS = frozenset( { "air_quality", @@ -197,12 +216,15 @@ def scan_string(value: str, key: str | None) -> None: template_matches = set(TEMPLATE_ENTITY_RE.findall(value)) for entity_id in template_matches: add(entity_id, "template") - if _is_template(value): - return - explicit_key = key in ENTITY_VALUE_KEYS - source = "template" if "{{" in value or "{%" in value else "configuration" + templated = _is_template(value) + # A templated value is resolved by Home Assistant at runtime, so an + # entity-shaped key cannot vouch for the dotted tokens it contains. + explicit_key = key in ENTITY_VALUE_KEYS and not templated + source = "template" if templated else "configuration" for entity_id in ENTITY_ID_RE.findall(value): domain = entity_id.split(".", 1)[0] + if templated and domain in JINJA_CONTEXT_ROOTS: + continue if explicit_key or entity_id in template_matches or domain in domains: add(entity_id, "explicit" if explicit_key else source) diff --git a/tests/test_references.py b/tests/test_references.py index 629a4c8..aaecab4 100644 --- a/tests/test_references.py +++ b/tests/test_references.py @@ -138,3 +138,29 @@ def test_ignores_jinja_context_paths_but_keeps_literal_template_entities() -> No "input_boolean.window_pause": {"configuration"}, "sensor.real_temperature": {"template"}, } + + +def test_keeps_template_entity_references_not_matched_by_helper_functions() -> None: + config = { + "conditions": [ + {"condition": "template", "value_template": "{{ has_value('sensor.alpha') }}"}, + {"condition": "template", "value_template": "{{ states.sensor.beta }}"}, + { + "condition": "template", + "value_template": ( + "{% if is_state('binary_sensor.door','on') " + "and has_value('sensor.temp') %}on{% endif %}" + ), + }, + ], + "actions": [], + } + + references = collect_entity_references(config, {"sensor", "binary_sensor"}) + + assert sorted(references) == [ + "binary_sensor.door", + "sensor.alpha", + "sensor.beta", + "sensor.temp", + ]