Ensure automations do not execute from a trigger if they are disabled (#115305)
* Ensure automations are stopped as soon as the stop future is set * revert script changes and move them to #115325
This commit is contained in:
parent
f80894d56f
commit
63545ceaa4
2 changed files with 97 additions and 1 deletions
|
@ -795,6 +795,22 @@ class AutomationEntity(BaseAutomationEntity, RestoreEntity):
|
|||
"""Log helper callback."""
|
||||
self._logger.log(level, "%s %s", msg, self.name, **kwargs)
|
||||
|
||||
async def _async_trigger_if_enabled(
|
||||
self,
|
||||
run_variables: dict[str, Any],
|
||||
context: Context | None = None,
|
||||
skip_condition: bool = False,
|
||||
) -> ScriptRunResult | None:
|
||||
"""Trigger automation if enabled.
|
||||
|
||||
If the trigger starts but has a delay, the automation will be triggered
|
||||
when the delay has passed so we need to make sure its still enabled before
|
||||
executing the action.
|
||||
"""
|
||||
if not self._is_enabled:
|
||||
return None
|
||||
return await self.async_trigger(run_variables, context, skip_condition)
|
||||
|
||||
async def _async_attach_triggers(
|
||||
self, home_assistant_start: bool
|
||||
) -> Callable[[], None] | None:
|
||||
|
@ -818,7 +834,7 @@ class AutomationEntity(BaseAutomationEntity, RestoreEntity):
|
|||
return await async_initialize_triggers(
|
||||
self.hass,
|
||||
self._trigger_config,
|
||||
self.async_trigger,
|
||||
self._async_trigger_if_enabled,
|
||||
DOMAIN,
|
||||
str(self.name),
|
||||
self._log_callback,
|
||||
|
|
|
@ -2651,3 +2651,83 @@ def test_deprecated_constants(
|
|||
import_and_test_deprecated_constant(
|
||||
caplog, automation, constant_name, replacement.__name__, replacement, "2025.1"
|
||||
)
|
||||
|
||||
|
||||
async def test_automation_turns_off_other_automation(
|
||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""Test an automation that turns off another automation."""
|
||||
hass.set_state(CoreState.not_running)
|
||||
calls = async_mock_service(hass, "persistent_notification", "create")
|
||||
hass.states.async_set("binary_sensor.presence", "on")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "state",
|
||||
"entity_id": "binary_sensor.presence",
|
||||
"from": "on",
|
||||
},
|
||||
"action": {
|
||||
"service": "automation.turn_off",
|
||||
"target": {
|
||||
"entity_id": "automation.automation_1",
|
||||
},
|
||||
"data": {
|
||||
"stop_actions": True,
|
||||
},
|
||||
},
|
||||
"id": "automation_0",
|
||||
"mode": "single",
|
||||
},
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "state",
|
||||
"entity_id": "binary_sensor.presence",
|
||||
"from": "on",
|
||||
"for": {
|
||||
"hours": 0,
|
||||
"minutes": 0,
|
||||
"seconds": 5,
|
||||
},
|
||||
},
|
||||
"action": {
|
||||
"service": "persistent_notification.create",
|
||||
"metadata": {},
|
||||
"data": {
|
||||
"message": "Test race",
|
||||
},
|
||||
},
|
||||
"id": "automation_1",
|
||||
"mode": "single",
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
await hass.async_start()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
hass.states.async_set("binary_sensor.presence", "off")
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 0
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=5))
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 0
|
||||
|
||||
await hass.services.async_call(
|
||||
"automation",
|
||||
"turn_on",
|
||||
{"entity_id": "automation.automation_1"},
|
||||
blocking=True,
|
||||
)
|
||||
hass.states.async_set("binary_sensor.presence", "off")
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 0
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=5))
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 0
|
||||
|
|
Loading…
Add table
Reference in a new issue