feat: add Circulator Fan Pro (W1160) support#508
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests.
🚀 New features to boost your workflow:
|
|
Waiting for a PR for switchbot to add this |
|
@bdraco Hello, this account is being used by a developer from Switchbot. I don't quite understand what you mean by "Waiting for a PR for Switchbot to add this." I hope you can provide more information. Thanks! |
|
Opened the Home Assistant core PR that consumes this: home-assistant/core#173262 (adds the Circulator Fan Pro to the |
PR Review — feat: add Circulator Fan Pro (W1160) supportSolid, hardware-verified device addition. Merge-ready pending two minor cleanups. Strengths:
Needs attention (non-blocking):
🟢 Suggestions
1. Redundant `__init__` override adds no behavior
|
bluetoothbot
left a comment
There was a problem hiding this comment.
No blocking issues found.
There was a problem hiding this comment.
Pull request overview
Adds SwitchBot Circulator Fan Pro (W1160) support to the library by introducing a new encrypted fan device class and advertisement parsing so the device can be discovered and controlled over BLE.
Changes:
- Added Circulator Fan Pro model/exports/constants and API model mapping (
W1160000). - Added W1160 advertisement routing + parser for its modern fan broadcast layout.
- Added
SwitchbotCirculatorFanProdevice implementation plus dedicated unit tests for parsing and commands.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
tests/test_fan.py |
Adds unit tests and helpers for Circulator Fan Pro commands/state getters. |
tests/test_adv_parser.py |
Adds advertisement parsing tests and model routing verification for W1160. |
switchbot/devices/fan.py |
Introduces SwitchbotCirculatorFanPro and a fan_modes convenience property. |
switchbot/devices/device.py |
Maps SwitchBot API model string W1160000 to the new enum model. |
switchbot/const/fan.py |
Adds CirculatorFanProMode enum. |
switchbot/const/__init__.py |
Exports CirculatorFanProMode and adds CIRCULATOR_FAN_PRO to SwitchbotModel. |
switchbot/adv_parsers/fan.py |
Adds process_circulator_fan_pro advertisement parser. |
switchbot/adv_parser.py |
Adds W1160 service-data suffix signatures to route to the new parser. |
switchbot/__init__.py |
Exports SwitchbotCirculatorFanPro and CirculatorFanProMode. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| async def set_percentage(self, percentage: int) -> bool: | ||
| """ | ||
| Set the fan speed (1-100). | ||
|
|
||
| Speed lives in byte7 of the 0x11 power command and only applies in | ||
| direct mode, so this sends "on + direct mode + speed". | ||
| """ | ||
| result = await self._send_command(f"570f4111290101{percentage:02X}") | ||
| return self._check_command_result(result, 0, {1}) |
| The Pro uses extended commands (``57 0F <subcmd> …``) with a control-source | ||
| byte (0x29 = Home Assistant), wrapped in the encrypted command shell, so it | ||
| extends SwitchbotEncryptedDevice. Fan power uses subcommand 0x41 (open/close | ||
| sub-op 0x11); the night light uses subcommand 0x96. The night light command | ||
| is on/off only (the device exposes two read-only brightness levels in its | ||
| advertisement, but they are not separately settable here). |
| def create_circulator_fan_pro_for_testing(init_data: dict | None = None): | ||
| """Create an encrypted SwitchbotCirculatorFanPro instance for testing.""" | ||
| ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any") | ||
| fan_device = SwitchbotCirculatorFanPro( | ||
| ble_device, | ||
| "ff", | ||
| "ffffffffffffffffffffffffffffffff", | ||
| model=SwitchbotModel.CIRCULATOR_FAN_PRO, | ||
| ) | ||
| fan_device.update_from_advertisement(make_advertisement_data(ble_device, init_data)) | ||
| fan_device._send_command = AsyncMock() | ||
| fan_device._check_command_result = MagicMock() | ||
| fan_device.update = AsyncMock() | ||
| return fan_device |
Add the SwitchBot Circulator Fan Pro (W1160) as an encrypted BLE device: fan power/speed/preset-mode (direct/natural/sleep/hurricane), horizontal and vertical oscillation, and a two-level night light. State is parsed from the W1071-style advertisement (battery/fan-state swapped vs the legacy fan). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
e8b4508 to
fd84950
Compare
Summary
Adds support for the SwitchBot Circulator Fan Pro (W1160) as an encrypted BLE device.
The Pro shares the W1071 Modern Ceiling Fan advertisement layout (which differs from the legacy Circulator Fan — battery and the fan-state byte are swapped), and uses extended commands (
57 0F …) with a control-source byte for control.Features
Implementation
SwitchbotModel.CIRCULATOR_FAN_PRO(W1160000) + adv signaturesb"\x00\x11\xb3@"/b"\x01\x11\xb3@"process_circulator_fan_proadvertisement parserSwitchbotCirculatorFanProdevice (SwitchbotEncryptedDevice+SwitchbotFan)CirculatorFanProModeenum (mode 0x04 is hurricane, not the legacy baby)All command frames and advertisement parsing were verified against real W1160 hardware.
🤖 Generated with Claude Code
Note from SwitchBot team
This change is developed by the official SwitchBot team. The implementation has been verified with real hardware testing on physical devices.
If you have any questions or need clarification, please reach out: