8000 Add 'for' to cover device triggers by emontnemery · Pull Request #48324 · 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 cover device triggers #48324

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
14 changes: 10 additions & 4 deletions homeassistant/components/cover/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,
CONF_VALUE_TEMPLATE,
Expand Down Expand Up @@ -59,6 +60,7 @@
{
vol.Required(CONF_ENTITY_ID): cv.entity_id,
vol.Required(CONF_TYPE): vol.In(STATE_TRIGGER_TYPES),
vol.Optional(CONF_FOR): cv.positive_time_period_dict,
}
)

Expand Down Expand Up @@ -146,8 +148,12 @@ async def async_get_triggers(hass: HomeAssistant, device_id: str) -> list[dict]:

async def async_get_trigger_capabilities(hass: HomeAssistant, config: dict) -> dict:
"""List trigger capabilities."""
if config[CONF_TYPE] not in ["position", "tilt_position"]:
return {}
if config[CONF_TYPE] not in POSITION_TRIGGER_TYPES:
return {
"extra_fields": vol.Schema(
{vol.Optional(CONF_FOR): cv.positive_time_period_dict}
)
}

return {
"extra_fields": vol.Schema(
Expand All @@ -170,8 +176,6 @@ async def async_attach_trigger(
automation_info: dict,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
config = TRIGGER_SCHEMA(config)

if config[CONF_TYPE] in STATE_TRIGGER_TYPES:
if config[CONF_TYPE] == "opened":
to_state = STATE_OPEN
Expand All @@ -187,6 +191,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
85 changes: 82 additions & 3 deletions tests/components/cover/test_device_trigger.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""The tests for Cover device triggers."""
from datetime import timedelta

import pytest

import homeassistant.components.automation as automation
Expand All @@ -12,10 +14,12 @@
)
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,
Expand Down Expand Up @@ -234,7 +238,11 @@ async def test_get_trigger_capabilities(hass, device_reg, entity_reg):
capabilities = await async_get_device_automation_capabilities(
hass, "trigger", trigger
)
assert capabilities == {"extra_fields": []}
assert capabilities == {
"extra_fields": [
{"name": "for", "optional": True, "type": "positive_time_period_dict"}
]
}


async def test_get_trigger_capabilities_set_pos(hass, device_reg, entity_reg):
Expand Down Expand Up @@ -284,7 +292,15 @@ async def test_get_trigger_capabilities_set_pos(hass, device_reg, entity_reg):
if trigger["type"] == "position":
assert capabilities == expected_capabilities
else:
assert capabilities == {"extra_fields": []}
assert capabilities == {
"extra_fields": [
{
"name": "for",
"optional": True,
"type": "positive_time_period_dict",
}
]
}


async def test_get_trigger_capabilities_set_tilt_pos(hass, device_reg, entity_reg):
Expand Down Expand Up @@ -334,7 +350,15 @@ async def test_get_trigger_capabilities_set_tilt_pos(hass, device_reg, entity_re
if trigger["type"] == "tilt_position":
assert capabilities == expected_capabilities
else:
assert capabilities == {"extra_fields": []}
assert capabilities == {
"extra_fields": [
{
"name": "for",
"optional": True,
"type": "positive_time_period_dict",
}
]
}


async def test_if_fires_on_state_change(hass, calls):
Expand Down Expand Up @@ -459,6 +483,61 @@ async def test_if_fires_on_state_change(hass, calls):
] == "closing - device - {} - opening - closing - None".format("cover.entity")


async def test_if_fires_on_state_change_with_for(hass, calls):
"""Test for triggers firing with delay."""
entity_id = "cover.entity"
hass.states.async_set(entity_id, STATE_CLOSED)

assert await async_setup_component(
hass,
automation.DOMAIN,
{
automation.DOMAIN: [
{
"trigger": {
"platform": "device",
"domain": DOMAIN,
"device_id": "",
"entity_id": entity_id,
"type": "opened",
"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_CLOSED
assert len(calls) == 0

hass.states.async_set(entity_id, STATE_OPEN)
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} - closed - open - 0:00:05"
)


async def test_if_fires_on_position(hass, calls):
"""Test for position triggers."""
platform = getattr(hass.components, f"test.{DOMAIN}")
Expand Down
0