Register condition platform upon use (#166939)

This commit is contained in:
Artur Pragacz
2026-03-31 19:32:20 +02:00
committed by Bram Kragten
parent d432092296
commit 8be6f441dd
2 changed files with 70 additions and 8 deletions
+17 -8
View File
@@ -230,19 +230,23 @@ async def _register_condition_platform(
from homeassistant.components import automation # noqa: PLC0415
new_conditions: set[str] = set()
conditions = hass.data[CONDITIONS]
if hasattr(platform, "async_get_conditions"):
for condition_key in await platform.async_get_conditions(hass):
all_conditions = await platform.async_get_conditions(hass)
for condition_key in all_conditions:
condition_key = get_absolute_description_key(
integration_domain, condition_key
)
hass.data[CONDITIONS][condition_key] = integration_domain
new_conditions.add(condition_key)
if condition_key not in conditions:
conditions[condition_key] = integration_domain
new_conditions.add(condition_key)
if not new_conditions:
_LOGGER.debug(
"Integration %s returned no conditions in async_get_conditions",
integration_domain,
)
if not all_conditions:
_LOGGER.debug(
"Integration %s returned no conditions in async_get_conditions",
integration_domain,
)
return
else:
_LOGGER.debug(
@@ -821,12 +825,17 @@ async def _async_get_condition_platform(
f'Invalid condition "{condition_key}" specified'
) from None
try:
return platform, await integration.async_get_platform("condition")
platform_module = await integration.async_get_platform("condition")
except ImportError:
raise HomeAssistantError(
f"Integration '{platform}' does not provide condition support"
) from None
# Ensure conditions are registered so descriptions can be loaded
await _register_condition_platform(hass, platform, platform_module)
return platform, platform_module
async def _async_get_checker(condition: Condition) -> ConditionCheckerType:
new_checker = await condition.async_get_checker()
+53
View File
@@ -48,9 +48,11 @@ from homeassistant.helpers.condition import (
ATTR_BEHAVIOR,
BEHAVIOR_ALL,
BEHAVIOR_ANY,
CONDITIONS,
Condition,
ConditionChecker,
EntityNumericalConditionWithUnitBase,
_async_get_condition_platform,
async_validate_condition_config,
make_entity_numerical_condition,
make_entity_numerical_condition_with_unit,
@@ -2276,6 +2278,57 @@ async def test_platform_backwards_compatibility_for_new_style_configs(
assert result == config_old_style
async def test_get_condition_platform_registers_conditions(
hass: HomeAssistant,
) -> None:
"""Test _async_get_condition_platform registers conditions and notifies subscribers."""
class MockCondition(Condition):
"""Mock condition."""
@classmethod
async def async_validate_config(
cls, hass: HomeAssistant, config: ConfigType
) -> ConfigType:
return config
async def async_get_checker(self) -> ConditionChecker:
return lambda **kwargs: True
async def async_get_conditions(
hass: HomeAssistant,
) -> dict[str, type[Condition]]:
return {"cond_a": MockCondition, "cond_b": MockCondition}
mock_integration(hass, MockModule("test"))
mock_platform(
hass, "test.condition", Mock(async_get_conditions=async_get_conditions)
)
subscriber_events: list[set[str]] = []
async def subscriber(new_conditions: set[str]) -> None:
subscriber_events.append(new_conditions)
condition.async_subscribe_platform_events(hass, subscriber)
assert "test.cond_a" not in hass.data[CONDITIONS]
assert "test.cond_b" not in hass.data[CONDITIONS]
# First call registers all conditions from the platform and notifies subscribers
await _async_get_condition_platform(hass, "test.cond_a")
assert hass.data[CONDITIONS]["test.cond_a"] == "test"
assert hass.data[CONDITIONS]["test.cond_b"] == "test"
assert len(subscriber_events) == 1
assert subscriber_events[0] == {"test.cond_a", "test.cond_b"}
# Subsequent calls are idempotent — no re-registration or re-notification
await _async_get_condition_platform(hass, "test.cond_a")
await _async_get_condition_platform(hass, "test.cond_b")
assert len(subscriber_events) == 1
@pytest.mark.parametrize("enabled_value", [True, "{{ 1 == 1 }}"])
async def test_enabled_condition(
hass: HomeAssistant, enabled_value: bool | str