Improve automation reload (#81854)

* Improve automation reload

* Small tweak

* Improve
This commit is contained in:
Erik Montnemery 2022-11-10 14:44:55 +01:00 committed by GitHub
parent ee9231363f
commit 9bd676aff6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 3 deletions

View file

@ -817,9 +817,28 @@ async def _async_process_config(
"""
automation_matches: set[int] = set()
config_matches: set[int] = set()
automation_configs_with_id: dict[str, tuple[int, AutomationEntityConfig]] = {}
automation_configs_without_id: list[tuple[int, AutomationEntityConfig]] = []
for config_idx, config in enumerate(automation_configs):
if automation_id := config.config_block.get(CONF_ID):
automation_configs_with_id[automation_id] = (config_idx, config)
continue
automation_configs_without_id.append((config_idx, config))
for automation_idx, automation in enumerate(automations):
for config_idx, config in enumerate(automation_configs):
if automation.unique_id:
if automation.unique_id not in automation_configs_with_id:
continue
config_idx, config = automation_configs_with_id.pop(
automation.unique_id
)
if automation_matches_config(automation, config):
automation_matches.add(automation_idx)
config_matches.add(config_idx)
continue
for config_idx, config in automation_configs_without_id:
if config_idx in config_matches:
# Only allow an automation config to match at most once
continue

View file

@ -738,7 +738,8 @@ async def test_automation_stops(hass, calls, service):
assert len(calls) == (1 if service == "turn_off_no_stop" else 0)
async def test_reload_unchanged_does_not_stop(hass, calls):
@pytest.mark.parametrize("extra_config", ({}, {"id": "sun"}))
async def test_reload_unchanged_does_not_stop(hass, calls, extra_config):
"""Test that reloading stops any running actions as appropriate."""
test_entity = "test.entity"
@ -753,6 +754,7 @@ async def test_reload_unchanged_does_not_stop(hass, calls):
],
}
}
config[automation.DOMAIN].update(**extra_config)
assert await async_setup_component(hass, automation.DOMAIN, config)
running = asyncio.Event()
@ -970,6 +972,41 @@ async def test_reload_identical_automations_without_id(hass, calls):
},
}
},
{
"id": "sun",
"trigger": {"platform": "event", "event_type": "test_event"},
"action": [{"service": "test.automation"}],
},
# An automation using templates
{
"id": "sun",
"trigger": {"platform": "event", "event_type": "test_event"},
"action": [{"service": "{{ 'test.automation' }}"}],
},
# An automation using blueprint
{
"id": "sun",
"use_blueprint": {
"path": "test_event_service.yaml",
"input": {
"trigger_event": "test_event",
"service_to_call": "test.automation",
"a_number": 5,
},
},
},
# An automation using blueprint with templated input
{
"id": "sun",
"use_blueprint": {
"path": "test_event_service.yaml",
"input": {
"trigger_event": "{{ 'test_event' }}",
"service_to_call": "{{ 'test.automation' }}",
"a_number": 5,
},
},
},
),
)
async def test_reload_unchanged_automation(hass, calls, automation_config):
@ -1004,7 +1041,8 @@ async def test_reload_unchanged_automation(hass, calls, automation_config):
assert len(calls) == 2
async def test_reload_automation_when_blueprint_changes(hass, calls):
@pytest.mark.parametrize("extra_config", ({}, {"id": "sun"}))
async def test_reload_automation_when_blueprint_changes(hass, calls, extra_config):
"""Test an automation is updated at reload if the blueprint has changed."""
with patch(
"homeassistant.components.automation.AutomationEntity", wraps=AutomationEntity
@ -1023,6 +1061,7 @@ async def test_reload_automation_when_blueprint_changes(hass, calls):
}
]
}
config[automation.DOMAIN][0].update(**extra_config)
assert await async_setup_component(hass, automation.DOMAIN, config)
assert automation_entity_init.call_count == 1
automation_entity_init.reset_mock()