diff --git a/homeassistant/components/zwave_js/cover.py b/homeassistant/components/zwave_js/cover.py index b7834e8e59c..5f473f80957 100644 --- a/homeassistant/components/zwave_js/cover.py +++ b/homeassistant/components/zwave_js/cover.py @@ -21,6 +21,8 @@ from .entity import ZWaveBaseEntity LOGGER = logging.getLogger(__name__) SUPPORT_GARAGE = SUPPORT_OPEN | SUPPORT_CLOSE +PRESS_BUTTON = True +RELEASE_BUTTON = False async def async_setup_entry( @@ -77,10 +79,17 @@ class ZWaveCover(ZWaveBaseEntity, CoverEntity): async def async_open_cover(self, **kwargs: Any) -> None: """Open the cover.""" - target_value = self.get_zwave_value("targetValue") - await self.info.node.async_set_value(target_value, 99) + target_value = self.get_zwave_value("Open") + await self.info.node.async_set_value(target_value, PRESS_BUTTON) async def async_close_cover(self, **kwargs: Any) -> None: """Close cover.""" - target_value = self.get_zwave_value("targetValue") - await self.info.node.async_set_value(target_value, 0) + target_value = self.get_zwave_value("Close") + await self.info.node.async_set_value(target_value, PRESS_BUTTON) + + async def async_stop_cover(self, **kwargs: Any) -> None: + """Stop cover.""" + target_value = self.get_zwave_value("Open") + await self.info.node.async_set_value(target_value, RELEASE_BUTTON) + target_value = self.get_zwave_value("Close") + await self.info.node.async_set_value(target_value, RELEASE_BUTTON) diff --git a/tests/components/zwave_js/test_cover.py b/tests/components/zwave_js/test_cover.py index c327034b61c..f014245a5f8 100644 --- a/tests/components/zwave_js/test_cover.py +++ b/tests/components/zwave_js/test_cover.py @@ -95,21 +95,65 @@ async def test_cover(hass, client, chain_actuator_zws12, integration): "commandClassName": "Multilevel Switch", "commandClass": 38, "endpoint": 0, - "property": "targetValue", - "propertyName": "targetValue", + "property": "Open", + "propertyName": "Open", "metadata": { - "label": "Target value", - "max": 99, - "min": 0, - "type": "number", + "type": "boolean", "readable": True, "writeable": True, - "label": "Target value", + "label": "Perform a level change (Open)", + "ccSpecific": {"switchType": 3}, }, } - assert args["value"] == 99 + assert args["value"] client.async_send_command.reset_mock() + # Test stop after opening + await hass.services.async_call( + "cover", + "stop_cover", + {"entity_id": WINDOW_COVER_ENTITY}, + blocking=True, + ) + + assert len(client.async_send_command.call_args_list) == 2 + open_args = client.async_send_command.call_args_list[0][0][0] + assert open_args["command"] == "node.set_value" + assert open_args["nodeId"] == 6 + assert open_args["valueId"] == { + "commandClassName": "Multilevel Switch", + "commandClass": 38, + "endpoint": 0, + "property": "Open", + "propertyName": "Open", + "metadata": { + "type": "boolean", + "readable": True, + "writeable": True, + "label": "Perform a level change (Open)", + "ccSpecific": {"switchType": 3}, + }, + } + assert not open_args["value"] + + close_args = client.async_send_command.call_args_list[1][0][0] + assert close_args["command"] == "node.set_value" + assert close_args["nodeId"] == 6 + assert close_args["valueId"] == { + "commandClassName": "Multilevel Switch", + "commandClass": 38, + "endpoint": 0, + "property": "Close", + "propertyName": "Close", + "metadata": { + "type": "boolean", + "readable": True, + "writeable": True, + "label": "Perform a level change (Close)", + "ccSpecific": {"switchType": 3}, + }, + } + assert not close_args["value"] # Test position update from value updated event event = Event( @@ -130,6 +174,7 @@ async def test_cover(hass, client, chain_actuator_zws12, integration): }, ) node.receive_event(event) + client.async_send_command.reset_mock() state = hass.states.get(WINDOW_COVER_ENTITY) assert state.state == "open" @@ -141,7 +186,6 @@ async def test_cover(hass, client, chain_actuator_zws12, integration): {"entity_id": WINDOW_COVER_ENTITY}, blocking=True, ) - assert len(client.async_send_command.call_args_list) == 1 args = client.async_send_command.call_args[0][0] assert args["command"] == "node.set_value" @@ -150,19 +194,66 @@ async def test_cover(hass, client, chain_actuator_zws12, integration): "commandClassName": "Multilevel Switch", "commandClass": 38, "endpoint": 0, - "property": "targetValue", - "propertyName": "targetValue", + "property": "Close", + "propertyName": "Close", "metadata": { - "label": "Target value", - "max": 99, - "min": 0, - "type": "number", + "type": "boolean", "readable": True, "writeable": True, - "label": "Target value", + "label": "Perform a level change (Close)", + "ccSpecific": {"switchType": 3}, }, } - assert args["value"] == 0 + assert args["value"] + + client.async_send_command.reset_mock() + + # Test stop after closing + await hass.services.async_call( + "cover", + "stop_cover", + {"entity_id": WINDOW_COVER_ENTITY}, + blocking=True, + ) + + assert len(client.async_send_command.call_args_list) == 2 + open_args = client.async_send_command.call_args_list[0][0][0] + assert open_args["command"] == "node.set_value" + assert open_args["nodeId"] == 6 + assert open_args["valueId"] == { + "commandClassName": "Multilevel Switch", + "commandClass": 38, + "endpoint": 0, + "property": "Open", + "propertyName": "Open", + "metadata": { + "type": "boolean", + "readable": True, + "writeable": True, + "label": "Perform a level change (Open)", + "ccSpecific": {"switchType": 3}, + }, + } + assert not open_args["value"] + + close_args = client.async_send_command.call_args_list[1][0][0] + assert close_args["command"] == "node.set_value" + assert close_args["nodeId"] == 6 + assert close_args["valueId"] == { + "commandClassName": "Multilevel Switch", + "commandClass": 38, + "endpoint": 0, + "property": "Close", + "propertyName": "Close", + "metadata": { + "type": "boolean", + "readable": True, + "writeable": True, + "label": "Perform a level change (Close)", + "ccSpecific": {"switchType": 3}, + }, + } + assert not close_args["value"] client.async_send_command.reset_mock()