-
-
Notifications
You must be signed in to change notification settings - Fork 37.5k
Extract triggers/conditions/services for non-primary entities #169319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
a19aebe
aad93fd
599fe25
e422c08
a53d3ea
8b2afb4
9369a5d
4d8acfa
9cf9540
056ff95
fcd6f78
7fad242
f84bf99
4f5d0a7
6fe1862
446d89a
0db50ac
ed560f0
39b690b
ca4d36d
838feef
245b9ed
19dd68b
4507f9a
9621307
458b5fe
f479b0a
ca70abe
1e0dc86
822b97d
2deb364
b5e66bb
99185bf
e7aa672
4625176
2278423
2eb9f69
e509c9b
54e3c3f
757deb3
6862b80
1978c97
77fd120
c3f66f9
5a79dd9
9e1c022
48b650c
db76773
b474a42
759ac2e
f225d81
19ebb1d
f06cd25
77df31f
c48502a
8e3070a
d1bdd6e
9ccc2e7
e9ca925
c1894ed
306fc52
e19d0e7
e7dae02
d832abc
1bf77e0
2c4f598
595f041
77c7225
e8e9914
8673694
f1fcca2
eed4acc
e78a79a
a506be4
aa0199b
fa9a336
cd98577
6384e6b
b5a1b59
d20d1df
9293797
f1bbe42
ed1aefc
2dd1632
f278711
040c960
5af3b36
392c46c
07c1448
70947c6
e684490
e3de695
5cedb0b
43fa4f2
4d4e458
45978f4
86af61d
605eea6
e9fc6b3
64c9a76
64f2fa4
6902504
a381a3a
cb62562
6ec4466
84a5ba2
12280db
0cc531e
3673a80
2053e61
3cc6cc9
ed371bc
54727a6
5d98f46
6422066
8a22e84
9321ff5
a5b6576
9390bf3
91d5c08
9cc9f24
ad836b4
0eb2045
d119bbe
663538c
080eb6a
21a3c5b
cc1eaa7
6c89ecb
370babf
6893d2b
45a6134
d590f4f
6a67c0f
53e4d6c
59711ba
f21ed90
4b9dd68
3e77a4b
2fb0de3
8ce1487
7594ead
d192218
1a25864
c048af2
d8a4b36
63d4f4d
308cb68
8d5f83e
f36799d
2f3a624
d3809dd
4eb000d
fa6c6ee
fa0cf37
73dcc2f
bf4b865
9656aaa
7f44fe0
7dacd00
7cb4d5c
33e5a96
6663717
eb85d7c
b2269b3
eb2217c
7e2a7b9
96bd991
c50676d
b47b7fa
ab08153
1fc0b62
955e836
0280d92
5ff1c15
ba8b1b2
3aea7f0
9b29b07
b90a074
eaf7210
de4e1c4
30f310f
6636e67
aa5e942
86e8b9d
d62f136
8fd3d0b
d19c250
d2fddf1
d3cf5d9
799bcb0
2f2413c
ea5b633
cd639b8
65a12b4
dfe4085
80c7e47
0ae5a19
4ea0e6b
e1c81c9
ea34fe4
d956af0
4c70fef
3683607
ef63ab5
c020008
fe0da5c
44e94a8
84d5085
cd5e21d
4b232be
c3f01b3
cd92cb1
a9c23ff
97be8f4
06a9671
aa74748
dc8abff
891efeb
62082bd
cdeb550
e975496
b56cdb9
b9bbe36
5e4f8f8
45121ed
326895f
05121b8
0224928
d531ce8
e4e4785
6552cf8
acd9dd2
3dd972c
2a5b95b
05bfb3a
a7baedc
8091f51
d41c9ae
71fc725
0dfbe3e
d41a3ae
a95c216
284242b
bb41a2d
39d3bc3
278f25e
b4bfe6b
f4637db
0190dc1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -10,7 +10,7 @@ | |||||||||||||||||
|
|
||||||||||||||||||
| from homeassistant.const import CONF_TARGET | ||||||||||||||||||
| from homeassistant.core import HomeAssistant | ||||||||||||||||||
| from homeassistant.helpers import target as target_helpers | ||||||||||||||||||
| from homeassistant.helpers import entity_registry as er, target as target_helpers | ||||||||||||||||||
| from homeassistant.helpers.condition import ( | ||||||||||||||||||
| async_get_all_descriptions as async_get_all_condition_descriptions, | ||||||||||||||||||
| ) | ||||||||||||||||||
|
|
@@ -92,12 +92,14 @@ class _AutomationComponentLookupData: | |||||||||||||||||
|
|
||||||||||||||||||
| component: str | ||||||||||||||||||
| filters: list[_EntityFilter] | ||||||||||||||||||
| primary_entities_only: bool = True | ||||||||||||||||||
|
|
||||||||||||||||||
| @classmethod | ||||||||||||||||||
| def create(cls, component: str, target_description: dict[str, Any]) -> Self: | ||||||||||||||||||
| """Build automation component lookup data from target description.""" | ||||||||||||||||||
| filters: list[_EntityFilter] = [] | ||||||||||||||||||
|
|
||||||||||||||||||
| primary_entities_only = target_description.get("primary_entities_only", True) | ||||||||||||||||||
| entity_filters_config = target_description.get("entity", []) | ||||||||||||||||||
| for entity_filter_config in entity_filters_config: | ||||||||||||||||||
| entity_filter = _EntityFilter( | ||||||||||||||||||
|
|
@@ -110,14 +112,28 @@ def create(cls, component: str, target_description: dict[str, Any]) -> Self: | |||||||||||||||||
| ) | ||||||||||||||||||
| filters.append(entity_filter) | ||||||||||||||||||
|
|
||||||||||||||||||
| return cls(component=component, filters=filters) | ||||||||||||||||||
| return cls( | ||||||||||||||||||
| component=component, | ||||||||||||||||||
| filters=filters, | ||||||||||||||||||
| primary_entities_only=primary_entities_only, | ||||||||||||||||||
| ) | ||||||||||||||||||
|
|
||||||||||||||||||
| def matches( | ||||||||||||||||||
| self, hass: HomeAssistant, entity_id: str, domain: str, integration: str | ||||||||||||||||||
| self, | ||||||||||||||||||
| hass: HomeAssistant, | ||||||||||||||||||
| entity_id: str, | ||||||||||||||||||
| domain: str, | ||||||||||||||||||
| integration: str, | ||||||||||||||||||
| check_entity_category: bool, | ||||||||||||||||||
| ) -> bool: | ||||||||||||||||||
| """Return if entity matches ANY of the filters.""" | ||||||||||||||||||
| if not self.filters: | ||||||||||||||||||
| return True | ||||||||||||||||||
|
|
||||||||||||||||||
| if check_entity_category and self.primary_entities_only: | ||||||||||||||||||
| entry = er.async_get(hass).async_get(entity_id) | ||||||||||||||||||
| if entry is None or entry.entity_category is not None: | ||||||||||||||||||
| return False | ||||||||||||||||||
|
Comment on lines
+133
to
+136
|
||||||||||||||||||
| return any( | ||||||||||||||||||
| f.matches(hass, entity_id, domain, integration) for f in self.filters | ||||||||||||||||||
| ) | ||||||||||||||||||
|
|
@@ -220,6 +236,7 @@ def _async_get_automation_components_for_target( | |||||||||||||||||
| hass, | ||||||||||||||||||
| target_helpers.TargetSelection(target_selection), | ||||||||||||||||||
| expand_group=expand_group, | ||||||||||||||||||
| primary_entities_only=False, | ||||||||||||||||||
| ) | ||||||||||||||||||
| _LOGGER.debug("Extracted entities for lookup: %s", extracted) | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -230,6 +247,7 @@ def _async_get_automation_components_for_target( | |||||||||||||||||
| "Automation components per domain: %s", lookup_table.domain_components | ||||||||||||||||||
| ) | ||||||||||||||||||
|
|
||||||||||||||||||
| check_entity_category = len(extracted.indirectly_referenced) > 0 | ||||||||||||||||||
| entity_infos = entity_sources(hass) | ||||||||||||||||||
| matched_components: set[str] = set() | ||||||||||||||||||
| for entity_id in extracted.referenced | extracted.indirectly_referenced: | ||||||||||||||||||
|
Comment on lines
+250
to
253
|
||||||||||||||||||
| check_entity_category = len(extracted.indirectly_referenced) > 0 | |
| entity_infos = entity_sources(hass) | |
| matched_components: set[str] = set() | |
| for entity_id in extracted.referenced | extracted.indirectly_referenced: | |
| entity_infos = entity_sources(hass) | |
| matched_components: set[str] = set() | |
| for entity_id in extracted.referenced | extracted.indirectly_referenced: | |
| check_entity_category = entity_id in extracted.indirectly_referenced |
Copilot
AI
Apr 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apply the entity_category filter only to indirectly expanded entities (e.g., when entity_id is in extracted.indirectly_referenced) instead of enabling it globally whenever any indirect entity exists, to avoid changing behavior for explicitly targeted entities in mixed targets (and to avoid excluding non-registry entities when combined with area/device/label targets).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Treat missing entity-registry entries as not providing an entity_category rather than as non-matching. As written,
entry is Nonereturns False, which will drop explicitly targeted entities that are not in the entity registry ifcheck_entity_categoryis enabled (e.g., a mixed target that includes an area/device plus an explicitly selected runtime-only entity); if you keep this check, consider only rejecting whenentry.entity_category is not Noneand otherwise allowing the match.