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:
committed by
Bram Kragten
parent
92375078c0
commit
d4d639dfa2
@@ -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]
|
||||
|
||||
@@ -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",
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user