8000 Add 'for' to alarm device triggers by emontnemery · Pull Request #48503 · home-assistant/core · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add 'for' to alarm device triggers #48503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions homeassistant/components/alarm_control_panel/device_trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
CONF_DEVICE_ID,
CONF_DOMAIN,
CONF_ENTITY_ID,
CONF_FOR,
CONF_PLATFORM,
CONF_TYPE,
STATE_ALARM_ARMED_AWAY,
Expand Down Expand Up @@ -44,6 +45,7 @@
{
vol.Required(CONF_ENTITY_ID): cv.entity_id,
vol.Required(CONF_TYPE): vol.In(TRIGGER_TYPES),
vol.Optional(CONF_FOR): cv.positive_time_period_dict,
}
)

Expand Down Expand Up @@ -124,6 +126,15 @@ async def async_get_triggers(hass: HomeAssistant, device_id: str) -> list[dict]:
return triggers


async def async_get_trigger_capabilities(hass: HomeAssistant, config: dict) -> dict:
"""List trigger capabilities."""
return {
"extra_fields": vol.Schema(
{vol.Optional(CONF_FOR): cv.positive_time_period_dict}
)
}


async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
Expand All @@ -149,6 +160,8 @@ async def async_attach_trigger(
CONF_ENTITY_ID: config[CONF_ENTITY_ID],
state_trigger.CONF_TO: to_state,
}
if CONF_FOR in config:
state_config[CONF_FOR] = config[CONF_FOR]
state_config = state_trigger.TRIGGER_SCHEMA(state_config)
return await state_trigger.async_attach_trigger(
hass, state_config, action, automation_info, platform_type="device"
Expand Down
88 changes: 87 additions & 1 deletion tests/components/alarm_control_panel/test_device_trigger.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""The tests for Alarm control panel device triggers."""
from datetime import timedelta

import pytest

from homeassistant.components.alarm_control_panel import DOMAIN
Expand All @@ -13,10 +15,13 @@
)
from homeassistant.helpers import device_registry
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util

from tests.common import (
MockConfigEntry,
assert_lists_same,
async_fire_time_changed,
async_get_device_automation_capabilities,
async_get_device_automations,
async_mock_service,
mock_device_registry,
Expand Down Expand Up @@ -44,7 +49,7 @@ def calls(hass):


async def test_get_triggers(hass, device_reg, entity_reg):
"""Test we get the expected triggers from a alarm_control_panel."""
"""Test we get the expected triggers from an alarm_control_panel."""
config_entry = MockConfigEntry(domain="test", data={})
config_entry.add_to_hass(hass)
device_entry = device_reg.async_get_or_create(
Expand Down Expand Up @@ -103,6 +108,32 @@ async def test_get_triggers(hass, device_reg, entity_reg):
assert_lists_same(triggers, expected_triggers)


async def test_get_trigger_capabilities(hass, device_reg, entity_reg):
"""Test we get the expected capabilities from an alarm_control_panel."""
config_entry = MockConfigEntry(domain="test", data={})
config_entry.add_to_hass(hass)
device_entry = device_reg.async_get_or_create(
config_entry_id=config_entry.entry_id,
connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
)
entity_reg.async_get_or_create(DOMAIN, "test", "5678", device_id=device_entry.id)
hass.states.async_set(
"alarm_control_panel.test_5678", "attributes", {"supported_features": 15}
)

triggers = await async_get_device_automations(hass, "trigger", device_entry.id)
assert len(triggers) == 6
for trigger in triggers:
capabilities = await async_get_device_automation_capabilities(
hass, "trigger", trigger
)
assert capabilities == {
"extra_fields": [
{"name": "for", "optional": True, "type": "positive_time_period_dict"}
]
}


async def test_if_fires_on_state_change(hass, calls):
"""Test for turn_on and turn_off triggers firing."""
hass.states.async_set("alarm_control_panel.entity", STATE_ALARM_PENDING)
Expand Down Expand Up @@ -255,3 +286,58 @@ async def test_if_fires_on_state_change(hass, calls):
calls[4].data["some"]
== "armed_night - device - alarm_control_panel.entity - armed_away - armed_night - None"
)


async def test_if_fires_on_state_change_with_for(hass, calls):
"""Test for triggers firing with delay."""
entity_id = f"{DOMAIN}.entity"
hass.states.async_set(entity_id, STATE_ALARM_DISARMED)

assert await async_setup_component(
hass,
automation.DOMAIN,
{
automation.DOMAIN: [
{
"trigger": {
"platform": "device",
"domain": DOMAIN,
"device_id": "",
"entity_id": entity_id,
"type": "triggered",
"for": {"seconds": 5},
},
"action": {
"service": "test.automation",
"data_template": {
"some": "turn_off {{ trigger.%s }}"
% "}} - {{ trigger.".join(
(
"platform",
"entity_id",
"from_state.state",
"to_state.state",
"for",
)
)
},
},
}
]
},
)
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == STATE_ALARM_DISARMED
assert len(calls) == 0

hass.states.async_set(entity_id, STATE_ALARM_TRIGGERED)
await hass.async_block_till_done()
assert len(calls) == 0
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=10))
await hass.async_block_till_done()
assert len(calls) == 1
await hass.async_block_till_done()
assert (
calls[0].data["some"]
== f"turn_off device - {entity_id} - disarmed - triggered - 0:00:05"
)
0