Support 'stop' action for covers in device automation (#38219)

This commit is contained in:
Eugene Prystupa 2020-07-31 08:45:03 -04:00 committed by GitHub
parent d02c432e4d
commit c795c68bc0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 6 deletions

View file

@ -16,6 +16,7 @@ from homeassistant.const import (
SERVICE_OPEN_COVER_TILT, SERVICE_OPEN_COVER_TILT,
SERVICE_SET_COVER_POSITION, SERVICE_SET_COVER_POSITION,
SERVICE_SET_COVER_TILT_POSITION, SERVICE_SET_COVER_TILT_POSITION,
SERVICE_STOP_COVER,
) )
from homeassistant.core import Context, HomeAssistant from homeassistant.core import Context, HomeAssistant
from homeassistant.helpers import entity_registry from homeassistant.helpers import entity_registry
@ -31,9 +32,10 @@ from . import (
SUPPORT_OPEN_TILT, SUPPORT_OPEN_TILT,
SUPPORT_SET_POSITION, SUPPORT_SET_POSITION,
SUPPORT_SET_TILT_POSITION, SUPPORT_SET_TILT_POSITION,
SUPPORT_STOP,
) )
CMD_ACTION_TYPES = {"open", "close", "open_tilt", "close_tilt"} CMD_ACTION_TYPES = {"open", "close", "stop", "open_tilt", "close_tilt"}
POSITION_ACTION_TYPES = {"set_position", "set_tilt_position"} POSITION_ACTION_TYPES = {"set_position", "set_tilt_position"}
CMD_ACTION_SCHEMA = cv.DEVICE_ACTION_BASE_SCHEMA.extend( CMD_ACTION_SCHEMA = cv.DEVICE_ACTION_BASE_SCHEMA.extend(
@ -99,6 +101,15 @@ async def async_get_actions(hass: HomeAssistant, device_id: str) -> List[dict]:
CONF_TYPE: "close", CONF_TYPE: "close",
} }
) )
if supported_features & SUPPORT_STOP:
actions.append(
{
CONF_DEVICE_ID: device_id,
CONF_DOMAIN: DOMAIN,
CONF_ENTITY_ID: entry.entity_id,
CONF_TYPE: "stop",
}
)
if supported_features & SUPPORT_SET_TILT_POSITION: if supported_features & SUPPORT_SET_TILT_POSITION:
actions.append( actions.append(
@ -160,6 +171,8 @@ async def async_call_action_from_config(
service = SERVICE_OPEN_COVER service = SERVICE_OPEN_COVER
elif config[CONF_TYPE] == "close": elif config[CONF_TYPE] == "close":
service = SERVICE_CLOSE_COVER service = SERVICE_CLOSE_COVER
elif config[CONF_TYPE] == "stop":
service = SERVICE_STOP_COVER
elif config[CONF_TYPE] == "open_tilt": elif config[CONF_TYPE] == "open_tilt":
service = SERVICE_OPEN_COVER_TILT service = SERVICE_OPEN_COVER_TILT
elif config[CONF_TYPE] == "close_tilt": elif config[CONF_TYPE] == "close_tilt":

View file

@ -4,6 +4,7 @@
"action_type": { "action_type": {
"open": "Open {entity_name}", "open": "Open {entity_name}",
"close": "Close {entity_name}", "close": "Close {entity_name}",
"stop": "Stop {entity_name}",
"open_tilt": "Open {entity_name} tilt", "open_tilt": "Open {entity_name} tilt",
"close_tilt": "Close {entity_name} tilt", "close_tilt": "Close {entity_name} tilt",
"set_position": "Set {entity_name} position", "set_position": "Set {entity_name} position",

View file

@ -6,7 +6,8 @@
"open": "Open {entity_name}", "open": "Open {entity_name}",
"open_tilt": "Open {entity_name} tilt", "open_tilt": "Open {entity_name} tilt",
"set_position": "Set {entity_name} position", "set_position": "Set {entity_name} position",
"set_tilt_position": "Set {entity_name} tilt position" "set_tilt_position": "Set {entity_name} tilt position",
"stop": "Stop {entity_name}"
}, },
"condition_type": { "condition_type": {
"is_closed": "{entity_name} is closed", "is_closed": "{entity_name} is closed",
@ -27,9 +28,9 @@
}, },
"state": { "state": {
"_": { "_": {
"closed": "Closed", "closed": "[%key:common::state::closed%]",
"closing": "Closing", "closing": "Closing",
"open": "Open", "open": "[%key:common::state::open%]",
"opening": "Opening", "opening": "Opening",
"stopped": "Stopped" "stopped": "Stopped"
} }

View file

@ -60,6 +60,12 @@ async def test_get_actions(hass, device_reg, entity_reg):
"device_id": device_entry.id, "device_id": device_entry.id,
"entity_id": ent.entity_id, "entity_id": ent.entity_id,
}, },
{
"domain": DOMAIN,
"type": "stop",
"device_id": device_entry.id,
"entity_id": ent.entity_id,
},
] ]
actions = await async_get_device_automations(hass, "action", device_entry.id) actions = await async_get_device_automations(hass, "action", device_entry.id)
assert_lists_same(actions, expected_actions) assert_lists_same(actions, expected_actions)
@ -95,6 +101,12 @@ async def test_get_actions_tilt(hass, device_reg, entity_reg):
"device_id": device_entry.id, "device_id": device_entry.id,
"entity_id": ent.entity_id, "entity_id": ent.entity_id,
}, },
{
"domain": DOMAIN,
"type": "stop",
"device_id": device_entry.id,
"entity_id": ent.entity_id,
},
{ {
"domain": DOMAIN, "domain": DOMAIN,
"type": "open_tilt", "type": "open_tilt",
@ -171,6 +183,12 @@ async def test_get_actions_set_tilt_pos(hass, device_reg, entity_reg):
"device_id": device_entry.id, "device_id": device_entry.id,
"entity_id": ent.entity_id, "entity_id": ent.entity_id,
}, },
{
"domain": DOMAIN,
"type": "stop",
"device_id": device_entry.id,
"entity_id": ent.entity_id,
},
{ {
"domain": DOMAIN, "domain": DOMAIN,
"type": "set_tilt_position", "type": "set_tilt_position",
@ -201,7 +219,7 @@ async def test_get_action_capabilities(hass, device_reg, entity_reg):
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "test"}}) assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "test"}})
actions = await async_get_device_automations(hass, "action", device_entry.id) actions = await async_get_device_automations(hass, "action", device_entry.id)
assert len(actions) == 2 # open, close assert len(actions) == 3 # open, close, stop
for action in actions: for action in actions:
capabilities = await async_get_device_automation_capabilities( capabilities = await async_get_device_automation_capabilities(
hass, "action", action hass, "action", action
@ -282,7 +300,7 @@ async def test_get_action_capabilities_set_tilt_pos(hass, device_reg, entity_reg
] ]
} }
actions = await async_get_device_automations(hass, "action", device_entry.id) actions = await async_get_device_automations(hass, "action", device_entry.id)
assert len(actions) == 3 # open, close, set_tilt_position assert len(actions) == 4 # open, close, stop, set_tilt_position
for action in actions: for action in actions:
capabilities = await async_get_device_automation_capabilities( capabilities = await async_get_device_automation_capabilities(
hass, "action", action hass, "action", action
@ -322,27 +340,40 @@ async def test_action(hass):
"type": "close", "type": "close",
}, },
}, },
{
"trigger": {"platform": "event", "event_type": "test_event_stop"},
"action": {
"domain": DOMAIN,
"device_id": "abcdefgh",
"entity_id": "cover.entity",
"type": "stop",
},
},
] ]
}, },
) )
open_calls = async_mock_service(hass, "cover", "open_cover") open_calls = async_mock_service(hass, "cover", "open_cover")
close_calls = async_mock_service(hass, "cover", "close_cover") close_calls = async_mock_service(hass, "cover", "close_cover")
stop_calls = async_mock_service(hass, "cover", "stop_cover")
hass.bus.async_fire("test_event_open") hass.bus.async_fire("test_event_open")
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(open_calls) == 1 assert len(open_calls) == 1
assert len(close_calls) == 0 assert len(close_calls) == 0
assert len(stop_calls) == 0
hass.bus.async_fire("test_event_close") hass.bus.async_fire("test_event_close")
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(open_calls) == 1 assert len(open_calls) == 1
assert len(close_calls) == 1 assert len(close_calls) == 1
assert len(stop_calls) == 0
hass.bus.async_fire("test_event_stop") hass.bus.async_fire("test_event_stop")
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(open_calls) == 1 assert len(open_calls) == 1
assert len(close_calls) == 1 assert len(close_calls) == 1
assert len(stop_calls) == 1
async def test_action_tilt(hass): async def test_action_tilt(hass):