diff --git a/switchbot/devices/roller_shade.py b/switchbot/devices/roller_shade.py index 879213cf..d356a593 100644 --- a/switchbot/devices/roller_shade.py +++ b/switchbot/devices/roller_shade.py @@ -14,11 +14,11 @@ OPEN_KEYS = [ f"{REQ_HEADER}{ROLLERSHADE_COMMAND}01{CONTROL_SOURCE}0100", - f"{REQ_HEADER}{ROLLERSHADE_COMMAND}05{CONTROL_SOURCE}0000", + f"{REQ_HEADER}{ROLLERSHADE_COMMAND}05{CONTROL_SOURCE}", # +mode + "00" ] CLOSE_KEYS = [ f"{REQ_HEADER}{ROLLERSHADE_COMMAND}01{CONTROL_SOURCE}0164", - f"{REQ_HEADER}{ROLLERSHADE_COMMAND}05{CONTROL_SOURCE}0064", + f"{REQ_HEADER}{ROLLERSHADE_COMMAND}05{CONTROL_SOURCE}", # +mode + "64" ] POSITION_KEYS = [ f"{REQ_HEADER}{ROLLERSHADE_COMMAND}01{CONTROL_SOURCE}01", @@ -50,17 +50,21 @@ def _set_parsed_data( @update_after_operation async def open(self, mode: int = 0) -> bool: - """Send open command. 0 - performance mode, 1 - unfelt mode.""" + """Send open command. 0 - performance mode, 1 - quiet mode.""" self._is_opening = True self._is_closing = False - return await self._send_multiple_commands(OPEN_KEYS) + return await self._send_multiple_commands( + [OPEN_KEYS[0], f"{OPEN_KEYS[1]}{mode:02X}00"] + ) @update_after_operation - async def close(self, speed: int = 0) -> bool: - """Send close command. 0 - performance mode, 1 - unfelt mode.""" + async def close(self, mode: int = 0) -> bool: + """Send close command. 0 - performance mode, 1 - quiet mode.""" self._is_closing = True self._is_opening = False - return await self._send_multiple_commands(CLOSE_KEYS) + return await self._send_multiple_commands( + [CLOSE_KEYS[0], f"{CLOSE_KEYS[1]}{mode:02X}64"] + ) @update_after_operation async def stop(self) -> bool: diff --git a/tests/test_roller_shade.py b/tests/test_roller_shade.py index 7aafb584..ef059118 100644 --- a/tests/test_roller_shade.py +++ b/tests/test_roller_shade.py @@ -58,7 +58,18 @@ async def test_open(): assert roller_shade_device.is_opening() is True assert roller_shade_device.is_closing() is False roller_shade_device._send_multiple_commands.assert_awaited_once_with( - roller_shade.OPEN_KEYS + [roller_shade.OPEN_KEYS[0], f"{roller_shade.OPEN_KEYS[1]}0000"] + ) + + +@pytest.mark.asyncio +async def test_open_quietdrift(): + roller_shade_device = create_device_for_command_testing() + await roller_shade_device.open(mode=1) + assert roller_shade_device.is_opening() is True + assert roller_shade_device.is_closing() is False + roller_shade_device._send_multiple_commands.assert_awaited_once_with( + [roller_shade.OPEN_KEYS[0], f"{roller_shade.OPEN_KEYS[1]}0100"] ) @@ -69,7 +80,18 @@ async def test_close(): assert roller_shade_device.is_opening() is False assert roller_shade_device.is_closing() is True roller_shade_device._send_multiple_commands.assert_awaited_once_with( - roller_shade.CLOSE_KEYS + [roller_shade.CLOSE_KEYS[0], f"{roller_shade.CLOSE_KEYS[1]}0064"] + ) + + +@pytest.mark.asyncio +async def test_close_quietdrift(): + roller_shade_device = create_device_for_command_testing() + await roller_shade_device.close(mode=1) + assert roller_shade_device.is_opening() is False + assert roller_shade_device.is_closing() is True + roller_shade_device._send_multiple_commands.assert_awaited_once_with( + [roller_shade.CLOSE_KEYS[0], f"{roller_shade.CLOSE_KEYS[1]}0164"] ) @@ -204,6 +226,18 @@ async def test_set_position_closing(): curtain_device._send_multiple_commands.assert_awaited_once() +@pytest.mark.asyncio +async def test_set_position_quietdrift(): + curtain_device = create_device_for_command_testing(reverse_mode=True) + await curtain_device.set_position(50, mode=1) + curtain_device._send_multiple_commands.assert_awaited_once_with( + [ + f"{roller_shade.POSITION_KEYS[0]}32", + f"{roller_shade.POSITION_KEYS[1]}0132", + ] + ) + + def test_get_position(): curtain_device = create_device_for_command_testing() assert curtain_device.get_position() == 50