1
0
mirror of https://github.com/home-assistant/core.git synced 2026-04-17 23:53:49 +01:00

Register trigger platform upon use (#166911)

This commit is contained in:
Artur Pragacz
2026-03-31 11:49:38 +02:00
committed by Bram Kragten
parent 92375078c0
commit d4d639dfa2
2 changed files with 66 additions and 9 deletions

View File

@@ -202,22 +202,28 @@ async def _register_trigger_platform(
from homeassistant.components import automation # noqa: PLC0415
new_triggers: set[str] = set()
triggers = hass.data[TRIGGERS]
if hasattr(platform, "async_get_triggers"):
for trigger_key in await platform.async_get_triggers(hass):
all_triggers = await platform.async_get_triggers(hass)
for trigger_key in all_triggers:
trigger_key = get_absolute_description_key(integration_domain, trigger_key)
hass.data[TRIGGERS][trigger_key] = integration_domain
new_triggers.add(trigger_key)
if trigger_key not in triggers:
triggers[trigger_key] = integration_domain
new_triggers.add(trigger_key)
if not new_triggers:
_LOGGER.debug(
"Integration %s returned no triggers in async_get_triggers",
integration_domain,
)
if not all_triggers:
_LOGGER.debug(
"Integration %s returned no triggers in async_get_triggers",
integration_domain,
)
return
elif hasattr(platform, "async_validate_trigger_config") or hasattr(
platform, "TRIGGER_SCHEMA"
):
hass.data[TRIGGERS][integration_domain] = integration_domain
if integration_domain in triggers:
return
triggers[integration_domain] = integration_domain
new_triggers.add(integration_domain)
else:
_LOGGER.debug(
@@ -1184,12 +1190,17 @@ async def _async_get_trigger_platform(
except IntegrationNotFound:
raise vol.Invalid(f"Invalid trigger '{trigger_key}' specified") from None
try:
return platform, await integration.async_get_platform("trigger")
platform_module = await integration.async_get_platform("trigger")
except ImportError:
raise vol.Invalid(
f"Integration '{platform}' does not provide trigger support"
) from None
# Ensure triggers are registered so descriptions can be loaded
await _register_trigger_platform(hass, platform, platform_module)
return platform, platform_module
async def async_validate_trigger_config(
hass: HomeAssistant, trigger_config: list[ConfigType]

View File

@@ -42,6 +42,7 @@ from homeassistant.helpers.automation import (
)
from homeassistant.helpers.trigger import (
DATA_PLUGGABLE_ACTIONS,
TRIGGERS,
EntityNumericalStateChangedTriggerWithUnitBase,
EntityNumericalStateCrossedThresholdTriggerWithUnitBase,
EntityTriggerBase,
@@ -669,6 +670,51 @@ async def test_platform_backwards_compatibility_for_new_style_configs(
assert result == config_old_style
async def test_get_trigger_platform_registers_triggers(
hass: HomeAssistant,
) -> None:
"""Test _async_get_trigger_platform registers triggers and notifies subscribers."""
class MockTrigger(Trigger):
"""Mock trigger."""
async def async_attach_runner(
self, run_action: TriggerActionRunner
) -> CALLBACK_TYPE:
return lambda: None
async def async_get_triggers(
hass: HomeAssistant,
) -> dict[str, type[Trigger]]:
return {"trig_a": MockTrigger, "trig_b": MockTrigger}
mock_integration(hass, MockModule("test"))
mock_platform(hass, "test.trigger", Mock(async_get_triggers=async_get_triggers))
subscriber_events: list[set[str]] = []
async def subscriber(new_triggers: set[str]) -> None:
subscriber_events.append(new_triggers)
trigger.async_subscribe_platform_events(hass, subscriber)
assert "test.trig_a" not in hass.data[TRIGGERS]
assert "test.trig_b" not in hass.data[TRIGGERS]
# First call registers all triggers from the platform and notifies subscribers
await _async_get_trigger_platform(hass, "test.trig_a")
assert hass.data[TRIGGERS]["test.trig_a"] == "test"
assert hass.data[TRIGGERS]["test.trig_b"] == "test"
assert len(subscriber_events) == 1
assert subscriber_events[0] == {"test.trig_a", "test.trig_b"}
# Subsequent calls are idempotent — no re-registration or re-notification
await _async_get_trigger_platform(hass, "test.trig_a")
await _async_get_trigger_platform(hass, "test.trig_b")
assert len(subscriber_events) == 1
@pytest.mark.parametrize(
"sun_trigger_descriptions",
[