Skip to content

Commit fe687c3

Browse files
den-mkobdraco
andauthored
Added QuietDrift support for Curtain 3 (#223)
Co-authored-by: J. Nick Koston <[email protected]>
1 parent 8ca063a commit fe687c3

File tree

3 files changed

+31
-15
lines changed

3 files changed

+31
-15
lines changed

switchbot/adv_parsers/curtain.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ def process_wocurtain(
66
data: bytes | None, mfr_data: bytes | None, reverse: bool = True
77
) -> dict[str, bool | int]:
88
"""Process woCurtain/Curtain services data."""
9-
if mfr_data and len(mfr_data) >= 13: # Curtain 3
9+
if mfr_data and len(mfr_data) >= 13: # Curtain 3
1010
device_data = mfr_data[8:11]
1111
battery_data = mfr_data[12]
1212
elif mfr_data and len(mfr_data) >= 11:

switchbot/devices/curtain.py

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,22 @@
88

99
# Curtain keys
1010
CURTAIN_COMMAND = "4501"
11+
12+
# For second element of open and close arrs we should add two bytes i.e. ff00
13+
# First byte [ff] stands for speed (00 or ff - normal, 01 - slow) *
14+
# * Only for curtains 3. For other models use ff
15+
# Second byte [00] is a command (00 - open, 64 - close)
1116
OPEN_KEYS = [
1217
f"{REQ_HEADER}{CURTAIN_COMMAND}010100",
13-
f"{REQ_HEADER}{CURTAIN_COMMAND}05ff00",
18+
f"{REQ_HEADER}{CURTAIN_COMMAND}05", # +speed + "00"
1419
]
1520
CLOSE_KEYS = [
1621
f"{REQ_HEADER}{CURTAIN_COMMAND}010164",
17-
f"{REQ_HEADER}{CURTAIN_COMMAND}05ff64",
22+
f"{REQ_HEADER}{CURTAIN_COMMAND}05", # +speed + "64"
1823
]
1924
POSITION_KEYS = [
2025
f"{REQ_HEADER}{CURTAIN_COMMAND}0101",
21-
f"{REQ_HEADER}{CURTAIN_COMMAND}05ff",
26+
f"{REQ_HEADER}{CURTAIN_COMMAND}05", # +speed
2227
] # +actual_position
2328
STOP_KEYS = [f"{REQ_HEADER}{CURTAIN_COMMAND}0001", f"{REQ_HEADER}{CURTAIN_COMMAND}00ff"]
2429

@@ -63,27 +68,33 @@ async def _send_multiple_commands(self, keys: list[str]) -> bool:
6368
return final_result
6469

6570
@update_after_operation
66-
async def open(self) -> bool:
67-
"""Send open command."""
68-
return await self._send_multiple_commands(OPEN_KEYS)
71+
async def open(self, speed: int = 255) -> bool:
72+
"""Send open command. Speed 255 - normal, 1 - slow"""
73+
return await self._send_multiple_commands(
74+
[OPEN_KEYS[0], f"{OPEN_KEYS[1]}{speed:02X}00"]
75+
)
6976

7077
@update_after_operation
71-
async def close(self) -> bool:
72-
"""Send close command."""
73-
return await self._send_multiple_commands(CLOSE_KEYS)
78+
async def close(self, speed: int = 255) -> bool:
79+
"""Send close command. Speed 255 - normal, 1 - slow"""
80+
return await self._send_multiple_commands(
81+
[CLOSE_KEYS[0], f"{CLOSE_KEYS[1]}{speed:02X}64"]
82+
)
7483

7584
@update_after_operation
7685
async def stop(self) -> bool:
7786
"""Send stop command to device."""
7887
return await self._send_multiple_commands(STOP_KEYS)
7988

8089
@update_after_operation
81-
async def set_position(self, position: int) -> bool:
82-
"""Send position command (0-100) to device."""
90+
async def set_position(self, position: int, speed: int = 255) -> bool:
91+
"""Send position command (0-100) to device. Speed 255 - normal, 1 - slow"""
8392
position = (100 - position) if self._reverse else position
84-
hex_position = "%0.2X" % position
8593
return await self._send_multiple_commands(
86-
[key + hex_position for key in POSITION_KEYS]
94+
[
95+
f"{POSITION_KEYS[0]}{position:02X}",
96+
f"{POSITION_KEYS[1]}{speed:02X}{position:02X}",
97+
]
8798
)
8899

89100
def get_position(self) -> Any:

switchbot/discovery.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,12 @@ async def get_curtains(self) -> dict[str, SwitchBotAdvertisement]:
9595
pairing_curtains = await self._get_devices_by_model("C")
9696
regular_curtains3 = await self._get_devices_by_model("{")
9797
pairing_curtains3 = await self._get_devices_by_model("[")
98-
return {**regular_curtains, **pairing_curtains, **regular_curtains3, **pairing_curtains3}
98+
return {
99+
**regular_curtains,
100+
**pairing_curtains,
101+
**regular_curtains3,
102+
**pairing_curtains3,
103+
}
99104

100105
async def get_bots(self) -> dict[str, SwitchBotAdvertisement]:
101106
"""Return all WoHand/Bot devices with services data."""

0 commit comments

Comments
 (0)