diff --git a/homeassistant/components/cover/device_action.py b/homeassistant/components/cover/device_action.py index dba4ff8be89..29dd97909e3 100644 --- a/homeassistant/components/cover/device_action.py +++ b/homeassistant/components/cover/device_action.py @@ -16,6 +16,7 @@ from homeassistant.const import ( SERVICE_OPEN_COVER_TILT, SERVICE_SET_COVER_POSITION, SERVICE_SET_COVER_TILT_POSITION, + SERVICE_STOP_COVER, ) from homeassistant.core import Context, HomeAssistant from homeassistant.helpers import entity_registry @@ -31,9 +32,10 @@ from . import ( SUPPORT_OPEN_TILT, SUPPORT_SET_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"} 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", } ) + 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: actions.append( @@ -160,6 +171,8 @@ async def async_call_action_from_config( service = SERVICE_OPEN_COVER elif config[CONF_TYPE] == "close": service = SERVICE_CLOSE_COVER + elif config[CONF_TYPE] == "stop": + service = SERVICE_STOP_COVER elif config[CONF_TYPE] == "open_tilt": service = SERVICE_OPEN_COVER_TILT elif config[CONF_TYPE] == "close_tilt": diff --git a/homeassistant/components/cover/strings.json b/homeassistant/components/cover/strings.json index de52614891f..cb98c542d43 100644 --- a/homeassistant/components/cover/strings.json +++ b/homeassistant/components/cover/strings.json @@ -4,6 +4,7 @@ "action_type": { "open": "Open {entity_name}", "close": "Close {entity_name}", + "stop": "Stop {entity_name}", "open_tilt": "Open {entity_name} tilt", "close_tilt": "Close {entity_name} tilt", "set_position": "Set {entity_name} position", diff --git a/homeassistant/components/cover/translations/en.json b/homeassistant/components/cover/translations/en.json index de2ad4e0b15..10551a82988 100644 --- a/homeassistant/components/cover/translations/en.json +++ b/homeassistant/components/cover/translations/en.json @@ -6,7 +6,8 @@ "open": "Open {entity_name}", "open_tilt": "Open {entity_name} tilt", "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": { "is_closed": "{entity_name} is closed", @@ -27,9 +28,9 @@ }, "state": { "_": { - "closed": "Closed", + "closed": "[%key:common::state::closed%]", "closing": "Closing", - "open": "Open", + "open": "[%key:common::state::open%]", "opening": "Opening", "stopped": "Stopped" } diff --git a/tests/components/cover/test_device_action.py b/tests/components/cover/test_device_action.py index e70c18621f4..b38521d4051 100644 --- a/tests/components/cover/test_device_action.py +++ b/tests/components/cover/test_device_action.py @@ -60,6 +60,12 @@ async def test_get_actions(hass, device_reg, entity_reg): "device_id": device_entry.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) 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, "entity_id": ent.entity_id, }, + { + "domain": DOMAIN, + "type": "stop", + "device_id": device_entry.id, + "entity_id": ent.entity_id, + }, { "domain": DOMAIN, "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, "entity_id": ent.entity_id, }, + { + "domain": DOMAIN, + "type": "stop", + "device_id": device_entry.id, + "entity_id": ent.entity_id, + }, { "domain": DOMAIN, "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"}}) 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: capabilities = await async_get_device_automation_capabilities( 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) - assert len(actions) == 3 # open, close, set_tilt_position + assert len(actions) == 4 # open, close, stop, set_tilt_position for action in actions: capabilities = await async_get_device_automation_capabilities( hass, "action", action @@ -322,27 +340,40 @@ async def test_action(hass): "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") 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") await hass.async_block_till_done() assert len(open_calls) == 1 assert len(close_calls) == 0 + assert len(stop_calls) == 0 hass.bus.async_fire("test_event_close") await hass.async_block_till_done() assert len(open_calls) == 1 assert len(close_calls) == 1 + assert len(stop_calls) == 0 hass.bus.async_fire("test_event_stop") await hass.async_block_till_done() assert len(open_calls) == 1 assert len(close_calls) == 1 + assert len(stop_calls) == 1 async def test_action_tilt(hass):