Fix missing device & entity references in automations (#71103)

pull/71181/head
Franck Nijhof 2022-05-02 06:49:50 +02:00 committed by GitHub
parent 2a9f043039
commit 63679d3d29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 16 deletions

View File

@ -17,6 +17,7 @@ from homeassistant.const import (
CONF_CONDITION, CONF_CONDITION,
CONF_DEVICE_ID, CONF_DEVICE_ID,
CONF_ENTITY_ID, CONF_ENTITY_ID,
CONF_EVENT_DATA,
CONF_ID, CONF_ID,
CONF_MODE, CONF_MODE,
CONF_PLATFORM, CONF_PLATFORM,
@ -360,9 +361,7 @@ class AutomationEntity(ToggleEntity, RestoreEntity):
referenced |= condition.async_extract_devices(conf) referenced |= condition.async_extract_devices(conf)
for conf in self._trigger_config: for conf in self._trigger_config:
device = _trigger_extract_device(conf) referenced |= set(_trigger_extract_device(conf))
if device is not None:
referenced.add(device)
self._referenced_devices = referenced self._referenced_devices = referenced
return referenced return referenced
@ -764,13 +763,23 @@ async def _async_process_if(hass, name, config, p_config):
@callback @callback
def _trigger_extract_device(trigger_conf: dict) -> str | None: def _trigger_extract_device(trigger_conf: dict) -> list[str]:
"""Extract devices from a trigger config.""" """Extract devices from a trigger config."""
if trigger_conf[CONF_PLATFORM] != "device": if trigger_conf[CONF_PLATFORM] == "device":
return None return [trigger_conf[CONF_DEVICE_ID]]
if (
trigger_conf[CONF_PLATFORM] == "event"
and CONF_EVENT_DATA in trigger_conf
and CONF_DEVICE_ID in trigger_conf[CONF_EVENT_DATA]
):
return [trigger_conf[CONF_EVENT_DATA][CONF_DEVICE_ID]]
if trigger_conf[CONF_PLATFORM] == "tag" and CONF_DEVICE_ID in trigger_conf:
return trigger_conf[CONF_DEVICE_ID] return trigger_conf[CONF_DEVICE_ID]
return []
@callback @callback
def _trigger_extract_entities(trigger_conf: dict) -> list[str]: def _trigger_extract_entities(trigger_conf: dict) -> list[str]:
@ -778,6 +787,9 @@ def _trigger_extract_entities(trigger_conf: dict) -> list[str]:
if trigger_conf[CONF_PLATFORM] in ("state", "numeric_state"): if trigger_conf[CONF_PLATFORM] in ("state", "numeric_state"):
return trigger_conf[CONF_ENTITY_ID] return trigger_conf[CONF_ENTITY_ID]
if trigger_conf[CONF_PLATFORM] == "calendar":
return [trigger_conf[CONF_ENTITY_ID]]
if trigger_conf[CONF_PLATFORM] == "zone": if trigger_conf[CONF_PLATFORM] == "zone":
return trigger_conf[CONF_ENTITY_ID] + [trigger_conf[CONF_ZONE]] return trigger_conf[CONF_ENTITY_ID] + [trigger_conf[CONF_ZONE]]
@ -787,4 +799,11 @@ def _trigger_extract_entities(trigger_conf: dict) -> list[str]:
if trigger_conf[CONF_PLATFORM] == "sun": if trigger_conf[CONF_PLATFORM] == "sun":
return ["sun.sun"] return ["sun.sun"]
if (
trigger_conf[CONF_PLATFORM] == "event"
and CONF_EVENT_DATA in trigger_conf
and CONF_ENTITY_ID in trigger_conf[CONF_EVENT_DATA]
):
return [trigger_conf[CONF_EVENT_DATA][CONF_ENTITY_ID]]
return [] return []

View File

@ -1079,6 +1079,7 @@ async def test_automation_restore_last_triggered_with_initial_state(hass):
async def test_extraction_functions(hass): async def test_extraction_functions(hass):
"""Test extraction functions.""" """Test extraction functions."""
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
assert await async_setup_component( assert await async_setup_component(
hass, hass,
DOMAIN, DOMAIN,
@ -1086,7 +1087,24 @@ async def test_extraction_functions(hass):
DOMAIN: [ DOMAIN: [
{ {
"alias": "test1", "alias": "test1",
"trigger": {"platform": "state", "entity_id": "sensor.trigger_1"}, "trigger": [
{"platform": "state", "entity_id": "sensor.trigger_state"},
{
"platform": "numeric_state",
"entity_id": "sensor.trigger_numeric_state",
"above": 10,
},
{
"platform": "calendar",
"entity_id": "calendar.trigger_calendar",
"event": "start",
},
{
"platform": "event",
"event_type": "state_changed",
"event_data": {"entity_id": "sensor.trigger_event"},
},
],
"condition": { "condition": {
"condition": "state", "condition": "state",
"entity_id": "light.condition_state", "entity_id": "light.condition_state",
@ -1111,13 +1129,30 @@ async def test_extraction_functions(hass):
}, },
{ {
"alias": "test2", "alias": "test2",
"trigger": { "trigger": [
{
"platform": "device", "platform": "device",
"domain": "light", "domain": "light",
"type": "turned_on", "type": "turned_on",
"entity_id": "light.trigger_2", "entity_id": "light.trigger_2",
"device_id": "trigger-device-2", "device_id": "trigger-device-2",
}, },
{
"platform": "tag",
"tag_id": "1234",
"device_id": "device-trigger-tag1",
},
{
"platform": "tag",
"tag_id": "1234",
"device_id": ["device-trigger-tag2", "device-trigger-tag3"],
},
{
"platform": "event",
"event_type": "esphome.button_pressed",
"event_data": {"device_id": "device-trigger-event"},
},
],
"condition": { "condition": {
"condition": "device", "condition": "device",
"device_id": "condition-device", "device_id": "condition-device",
@ -1159,7 +1194,10 @@ async def test_extraction_functions(hass):
"automation.test2", "automation.test2",
} }
assert set(automation.entities_in_automation(hass, "automation.test1")) == { assert set(automation.entities_in_automation(hass, "automation.test1")) == {
"sensor.trigger_1", "calendar.trigger_calendar",
"sensor.trigger_state",
"sensor.trigger_numeric_state",
"sensor.trigger_event",
"light.condition_state", "light.condition_state",
"light.in_both", "light.in_both",
"light.in_first", "light.in_first",
@ -1173,6 +1211,10 @@ async def test_extraction_functions(hass):
"condition-device", "condition-device",
"device-in-both", "device-in-both",
"device-in-last", "device-in-last",
"device-trigger-event",
"device-trigger-tag1",
"device-trigger-tag2",
"device-trigger-tag3",
} }