Add SwitchbotKeypad device class for classic Keypad#488
Add SwitchbotKeypad device class for classic Keypad#488italo-lombardi wants to merge 14 commits into
Conversation
The classic Keypad (WoKeypad) is a passive BLE-only device paired with SwitchBot Lock. The adv parser already exposes battery and attempt_state from advertisement data. This adds the device class and exports it so integrations can reference it explicitly.
Codecov Report✅ All modified and coverable lines are covered by tests.
... and 1 file with indirect coverage changes 🚀 New features to boost your workflow:
|
|
@bluetoothbot review |
There was a problem hiding this comment.
Pull request overview
Adds a minimal SwitchbotKeypad device class that wraps the existing process_wokeypad advertisement parser, exposes it from the package's public API, and adds a fixture plus three tests verifying battery and attempt_state parsing.
Changes:
- New
switchbot/devices/keypad.pydefiningSwitchbotKeypad(subclass ofSwitchbotDevice, no commands). - Public export added in
switchbot/__init__.py(SwitchbotKeypad). - New
KEYPAD_INFOAdvTestCasefixture intests/__init__.pyand a newtests/test_keypad.pyexercising advertisement parsing.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| switchbot/devices/keypad.py | Adds the new passive SwitchbotKeypad device class. |
| switchbot/init.py | Imports and re-exports SwitchbotKeypad in the public API. |
| tests/init.py | Adds KEYPAD_INFO advertisement fixture used by the new tests. |
| tests/test_keypad.py | Adds tests verifying parsed battery and attempt_state values, including battery=None override. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
Tests previously injected pre-parsed values, bypassing the parser. Now exercises parse_advertisement_data end-to-end so byte-layout regressions in adv_parsers/keypad.py are caught. - Assert get_battery_percent() instead of raw dict access - None test exercises parser's own None branch (empty mfr_data) - Extract make_advertisement_data to tests/__init__.py; remove duplicate in test_keypad_vision.py - Expand SwitchbotKeypad docstring: passive-only, no commands
|
Addressed all suggestions from the automated review:
|
|
@bluetoothbot review |
|
❌ Permission denied. Only users with write access can trigger bot commands. |
File was not in scope for this PR. Revert changes to it and remove the shared make_advertisement_data helper from tests/__init__.py that was added only to support that refactor.
|
@bluetoothbot review |
Completes coverage of the None-handling branch in process_wokeypad: both battery and attempt_state are None when manufacturer data absent.
|
What's the status here? Would love to have this in the upcoming HA release. Seems like the bot did not fire again. |
bdraco
left a comment
There was a problem hiding this comment.
The code as-is doesn't do anything. There is nothing to review
|
This PR was AI-assisted. The goal is to expose battery % for the classic WoKeypad in Home Assistant. The pySwitchbot side should be complete: A companion HA PR is needed to wire it up ( I have the physical device but no experience testing pySwitchbot integrations. Any guidance on how to validate this locally (e.g. with a BLE sniffer or test harness against real hardware) would be appreciated. |
Exposes attempt_state via _get_adv_value, consistent with how get_battery_percent is implemented in the base class.
Replace raw parsed_data dict access with device.attempt_state property so the new property is exercised by the test suite.
|
Update: tested on real hardware. Ran the parser against a live WoKeypad using BLE scanning on macOS. Results from advertisement data:
Parser correctly extracts both values from All 3 unit tests pass locally. |
|
Really cool, would love to see this merged! :-) |
… from PR sblibs#488 Co-authored-by: Alastair D'Silva <alastair@d-silva.org> Co-authored-by: Antigravity <antigravity@google.com>
… Keypad This Pull Request adds complete local and cloud passcode management and clock synchronization capabilities for the non-vision SwitchBot Keypad (WoKeypad). It also integrates the passive `attempt_state` advertisement property and tests proposed in closed PR sblibs#488 (by @italo-lombardi). Why Cloud Sync is Needed: - Keypad passcodes are stored and validated locally (allowing the Keypad to directly command the Lock offline without requiring internet connectivity). - However, for security reasons, the Keypad's BLE protocol is write-only for passcodes. There is no command to read back or list saved codes over BLE. - Since the SwitchBot app cannot query the Keypad to build its UI passcode list, it relies entirely on the SwitchBot Cloud database to track which codes exist. - If a passcode is added locally over BLE but not synced to the cloud, it will successfully operate the Lock offline, but will be completely invisible in the official mobile app. Integrating the cloud sync option ensures the app UI stays in sync with the keypad's physical storage. What Was Implemented: 1. Passcode Management: - `add_password`: Sends passcode bytes over BLE to register a new PIN code on the keypad. Parses response to retrieve the device-assigned index. - `modify_password`: Modifies an existing passcode by index. Overwrites values and configures active duration ranges. - `delete_password`: Instantly deletes a passcode from device memory by index. - `get_password_count`: Queries counts of stored PINs, NFC tags, fingerprints, and duress credentials. 2. Clock Synchronization (RTC): - `sync_time`: Synchronizes the internal device clock with millisecond precision (sending 8-byte big-endian milliseconds timestamp). Automatically scales second-level timestamps for backwards compatibility. - Note: Clock querying (`get_time`) was tested but found to return error 05 (unsupported) by the keypad hardware, indicating it is a write-only clock, so it has been dropped from the implementation. 3. SwitchBot Cloud Sync Option: - Added keyword-only parameters to `add_password`: `session`, `token`, `region`, `name`, and `creator`. - If provided, automatically triggers an HTTP POST request to API function 4245 to register the passcode in the SwitchBot Cloud database so it appears correctly in the official smartphone app. 4. Passive Advertisement Property Integration (from sblibs#488): - Exposes `attempt_state` property via `_get_adv_value` in `SwitchbotKeypad`. - Adds the missing `KEYPAD_INFO` test fixture to `tests/__init__.py`. Testing Methodology: 1. Automated Tests (tests/test_keypad.py): - Created full coverage suite for add/modify/delete password, counts, and sync_time. - Implemented `test_add_password_with_cloud_sync` mocking `api_request` to verify payload structures, regional routing, and authorization headers. - Added advertisement parsing unit tests for battery percentage and attempt state. - Verified that all 14 unit tests pass cleanly. 2. Manual/Hardware Verification: - Tested using test_hardware.py on a physical WoKeypad and Lock. - Verified that syncing clock with millisecond timestamps sets the correct RTC, allowing time-limited (temporary) passcodes to evaluate successfully offline and unlock the lock. Co-authored-by: Alastair D'Silva <alastair@d-silva.org> Co-authored-by: Italo Lombardi <italo.lombardi@sap.com> Co-authored-by: Antigravity <antigravity@google.com>
… Keypad This Pull Request adds complete local and cloud passcode management and clock synchronization capabilities for the non-vision SwitchBot Keypad (WoKeypad). It also integrates the passive `attempt_state` advertisement property and tests proposed in closed PR sblibs#488 (by @italo-lombardi). Why Cloud Sync is Needed: - Keypad passcodes are stored and validated locally (allowing the Keypad to directly command the Lock offline without requiring internet connectivity). - However, for security reasons, the Keypad's BLE protocol is write-only for passcodes. There is no command to read back or list saved codes over BLE. - Since the SwitchBot app cannot query the Keypad to build its UI passcode list, it relies entirely on the SwitchBot Cloud database to track which codes exist. - If a passcode is added locally over BLE but not synced to the cloud, it will successfully operate the Lock offline, but will be completely invisible in the official mobile app. Integrating the cloud sync option ensures the app UI stays in sync with the keypad's physical storage. What Was Implemented: 1. Passcode Management: - `add_password`: Sends passcode bytes over BLE to register a new PIN code on the keypad. Parses response to retrieve the device-assigned index. - `modify_password`: Modifies an existing passcode by index. Overwrites values and configures active duration ranges. - `delete_password`: Instantly deletes a passcode from device memory by index. - `get_password_count`: Queries counts of stored PINs, NFC tags, fingerprints, and duress credentials. 2. Clock Synchronization (RTC): - `sync_time`: Synchronizes the internal device clock with millisecond precision (sending 8-byte big-endian milliseconds timestamp). Automatically scales second-level timestamps for backwards compatibility. - Note: Clock querying (`get_time`) was tested but found to return error 05 (unsupported) by the keypad hardware, indicating it is a write-only clock, so it has been dropped from the implementation. 3. SwitchBot Cloud Sync Option: - Added keyword-only parameters to `add_password`: `session`, `token`, `region`, `name`, and `creator`. - If provided, automatically triggers an HTTP POST request to API function 4245 to register the passcode in the SwitchBot Cloud database so it appears correctly in the official smartphone app. 4. Passive Advertisement Property Integration (from sblibs#488): - Exposes `attempt_state` property via `_get_adv_value` in `SwitchbotKeypad`. - Adds the missing `KEYPAD_INFO` test fixture to `tests/__init__.py`. Testing Methodology: 1. Automated Tests (tests/test_keypad.py): - Created full coverage suite for add/modify/delete password, counts, and sync_time. - Implemented `test_add_password_with_cloud_sync` mocking `api_request` to verify payload structures, regional routing, and authorization headers. - Added advertisement parsing unit tests for battery percentage and attempt state. - Verified that all 14 unit tests pass cleanly. 2. Manual/Hardware Verification: - Tested using test_hardware.py on a physical WoKeypad and Lock. - Verified that syncing clock with millisecond timestamps sets the correct RTC, allowing time-limited (temporary) passcodes to evaluate successfully offline and unlock the lock. Co-authored-by: Alastair D'Silva <alastair@d-silva.org> Co-authored-by: Italo Lombardi <italo.lombardi@sap.com> Co-authored-by: Antigravity <antigravity@google.com>
… Keypad This Pull Request adds complete local and cloud passcode management and clock synchronization capabilities for the non-vision SwitchBot Keypad (WoKeypad). It also integrates the passive `attempt_state` advertisement property and tests proposed in closed PR sblibs#488 (by @italo-lombardi). Why Cloud Sync is Needed: - Keypad passcodes are stored and validated locally (allowing the Keypad to directly command the Lock offline without requiring internet connectivity). - However, for security reasons, the Keypad's BLE protocol is write-only for passcodes. There is no command to read back or list saved codes over BLE. - Since the SwitchBot app cannot query the Keypad to build its UI passcode list, it relies entirely on the SwitchBot Cloud database to track which codes exist. - If a passcode is added locally over BLE but not synced to the cloud, it will successfully operate the Lock offline, but will be completely invisible in the official mobile app. Integrating the cloud sync option ensures the app UI stays in sync with the keypad's physical storage. What Was Implemented: 1. Passcode Management: - `add_password`: Sends passcode bytes over BLE to register a new PIN code on the keypad. Parses response to retrieve the device-assigned index. - `modify_password`: Modifies an existing passcode by index. Overwrites values and configures active duration ranges. - `delete_password`: Instantly deletes a passcode from device memory by index. - `get_password_count`: Queries counts of stored PINs, NFC tags, fingerprints, and duress credentials. 2. Clock Synchronization (RTC): - `sync_time`: Synchronizes the internal device clock with millisecond precision (sending 8-byte big-endian milliseconds timestamp). Automatically scales second-level timestamps for backwards compatibility. - Note: Clock querying (`get_time`) was tested but found to return error 05 (unsupported) by the keypad hardware, indicating it is a write-only clock, so it has been dropped from the implementation. 3. SwitchBot Cloud Sync Option: - Added keyword-only parameters to `add_password`: `session`, `token`, `region`, `name`, and `creator`. - If provided, automatically triggers an HTTP POST request to API function 4245 to register the passcode in the SwitchBot Cloud database so it appears correctly in the official smartphone app. 4. Passive Advertisement Property Integration (from sblibs#488): - Exposes `attempt_state` property via `_get_adv_value` in `SwitchbotKeypad`. - Adds the missing `KEYPAD_INFO` test fixture to `tests/__init__.py`. Testing Methodology: 1. Automated Tests (tests/test_keypad.py): - Created full coverage suite for add/modify/delete password, counts, and sync_time. - Implemented `test_add_password_with_cloud_sync` mocking `api_request` to verify payload structures, regional routing, and authorization headers. - Added advertisement parsing unit tests for battery percentage and attempt state. - Verified that all 14 unit tests pass cleanly. 2. Manual/Hardware Verification: - Tested using test_hardware.py on a physical WoKeypad and Lock. - Verified that syncing clock with millisecond timestamps sets the correct RTC, allowing time-limited (temporary) passcodes to evaluate successfully offline and unlock the lock. Co-authored-by: Alastair D'Silva <alastair@d-silva.org> Co-authored-by: Antigravity <antigravity@google.com>
… Keypad This patch adds complete local and cloud passcode management and clock synchronization capabilities for the non-vision SwitchBot Keypad (WoKeypad). What Was Implemented: 1. Passcode Management: - `add_password`: Sends passcode bytes over BLE to register a new PIN code on the keypad. Parses response to retrieve the device-assigned index. - `modify_password`: Modifies an existing passcode by index. Overwrites values and configures active duration ranges. - `delete_password`: Instantly deletes a passcode from device memory by index. - `get_password_count`: Queries counts of stored PINs, NFC tags, fingerprints, and duress credentials. 2. Clock Synchronization (RTC): - `sync_time`: Synchronizes the internal device clock with millisecond precision (sending 8-byte big-endian milliseconds timestamp). Automatically scales second-level timestamps for backwards compatibility. - Note: Clock querying (`get_time`) was tested but found to return error 05 (unsupported) by the keypad hardware, indicating it is a write-only clock, so it has been dropped from the implementation. 3. SwitchBot Cloud Sync Option: - Added keyword-only parameters to `add_password`: `session`, `token`, `region`, `name`, and `creator`. - If provided, automatically triggers an HTTP POST request to API function 4245 to register the passcode in the SwitchBot Cloud database so it appears correctly in the official smartphone app. 4. Passive Advertisement Property Integration (from sblibs#488): - Exposes `attempt_state` property via `_get_adv_value` in `SwitchbotKeypad`. - Adds the missing `KEYPAD_INFO` test fixture to `tests/__init__.py`. Testing Methodology: 1. Automated Tests (tests/test_keypad.py): - Created full coverage suite for add/modify/delete password, counts, and sync_time. - Implemented `test_add_password_with_cloud_sync` mocking `api_request` to verify payload structures, regional routing, and authorization headers. - Added advertisement parsing unit tests for battery percentage and attempt state. - Verified that all 14 unit tests pass cleanly. 2. Manual/Hardware Verification: - Tested using test_hardware.py on a physical WoKeypad and Lock. - Verified that syncing clock with millisecond timestamps sets the correct RTC, allowing time-limited (temporary) passcodes to evaluate successfully offline and unlock the lock. Why Cloud Sync is Needed: - Keypad passcodes are stored and validated locally (allowing the Keypad to directly command the Lock offline without requiring internet connectivity). - However, for security reasons, the Keypad's BLE protocol is write-only for passcodes. There is no command to read back or list saved codes over BLE. - Since the SwitchBot app cannot query the Keypad to build its UI passcode list, it relies entirely on the SwitchBot Cloud database to track which codes exist. - If a passcode is added locally over BLE but not synced to the cloud, it will successfully operate the Lock offline, but will be completely invisible in the official mobile app. Integrating the cloud sync option ensures the app UI stays in sync with the keypad's physical storage. Co-authored-by: Alastair D'Silva <alastair@d-silva.org> Co-authored-by: Antigravity <antigravity@google.com>
| class SwitchbotKeypad(SwitchbotDevice): | ||
| """ | ||
| Representation of a Switchbot Keypad (WoKeypad) device. | ||
|
|
||
| Passive BLE-only — no commands. Battery and attempt_state come from | ||
| advertisement parsing in adv_parsers/keypad.py. | ||
| """ |
| advertisement = parse_advertisement_data( | ||
| ble_device, adv_data, SwitchbotModel.KEYPAD | ||
| ) | ||
| device = SwitchbotKeypad(ble_device) | ||
| device.update_from_advertisement(advertisement) |
| advertisement = parse_advertisement_data( | ||
| ble_device, adv_data, SwitchbotModel.KEYPAD | ||
| ) | ||
| device = SwitchbotKeypad(ble_device) | ||
| device.update_from_advertisement(advertisement) |
| advertisement = parse_advertisement_data( | ||
| ble_device, adv_data, SwitchbotModel.KEYPAD | ||
| ) | ||
| device = SwitchbotKeypad(ble_device) | ||
| device.update_from_advertisement(advertisement) |
Checked the codebase. Contact/leak/motion have no device class. |
Status: blocked on maintainer |
PR Review — Add SwitchbotKeypad device class for classic KeypadRe-attempt of the previously-rejected passive Keypad class; the maintainer's structural objection still applies. What's solid:
What needs attention:
Recommendation: confirm whether HA actually needs a pySwitchbot class for a non-connectable model (the existing passive sensors say no) and put that justification in the PR body — otherwise this remains "nothing to review." 🟡 Important
1. Device class duplicates what advertisement dispatch already provides
|
bluetoothbot
left a comment
There was a problem hiding this comment.
Blocking issues found.
- Device class duplicates what advertisement dispatch already provides
- Inherited update()/get_basic_info() contradict the passive-only contract
… Keypad This patch adds complete local and cloud passcode management and clock synchronization capabilities for the non-vision SwitchBot Keypad (WoKeypad). What Was Implemented: 1. Passcode Management: - `add_password`: Sends passcode bytes over BLE to register a new PIN code on the keypad. Parses response to retrieve the device-assigned index. - `modify_password`: Modifies an existing passcode by index. Overwrites values and configures active duration ranges. - `delete_password`: Instantly deletes a passcode from device memory by index. - `get_password_count`: Queries counts of stored PINs, NFC tags, fingerprints, and duress credentials. 2. Clock Synchronization (RTC): - `sync_time`: Synchronizes the internal device clock with millisecond precision (sending 8-byte big-endian milliseconds timestamp). Automatically scales second-level timestamps for backwards compatibility. - Note: Clock querying (`get_time`) was tested but found to return error 05 (unsupported) by the keypad hardware, indicating it is a write-only clock, so it has been dropped from the implementation. 3. SwitchBot Cloud Sync Option: - Added keyword-only parameters to `add_password`: `session`, `token`, `region`, `name`, and `creator`. - If provided, automatically triggers an HTTP POST request to API function 4245 to register the passcode in the SwitchBot Cloud database so it appears correctly in the official smartphone app. 4. Passive Advertisement Property Integration (from sblibs#488): - Exposes `attempt_state` property via `_get_adv_value` in `SwitchbotKeypad`. - Adds the missing `KEYPAD_INFO` test fixture to `tests/__init__.py`. Testing Methodology: 1. Automated Tests (tests/test_keypad.py): - Created full coverage suite for add/modify/delete password, counts, and sync_time. - Implemented `test_add_password_with_cloud_sync` mocking `api_request` to verify payload structures, regional routing, and authorization headers. - Added advertisement parsing unit tests for battery percentage and attempt state. - Verified that all unit tests pass cleanly. 2. Manual/Hardware Verification: - Tested using test_hardware.py on a physical WoKeypad and Lock. - Verified that syncing clock with millisecond timestamps sets the correct RTC, allowing time-limited (temporary) passcodes to evaluate successfully offline and unlock the lock. Why Cloud Sync is Needed: - Keypad passcodes are stored and validated locally (allowing the Keypad to directly command the Lock offline without requiring internet connectivity). - However, for security reasons, the Keypad's BLE protocol is write-only for passcodes. There is no command to read back or list saved codes over BLE. - Since the SwitchBot app cannot query the Keypad to build its UI passcode list, it relies entirely on the SwitchBot Cloud database to track which codes exist. - If a passcode is added locally over BLE but not synced to the cloud, it will successfully operate the Lock offline, but will be completely invisible in the official mobile app. Integrating the cloud sync option ensures the app UI stays in sync with the keypad's physical storage. Co-authored-by: Alastair D'Silva <alastair@d-silva.org> Co-authored-by: Antigravity <antigravity@google.com>
… Keypad This patch adds complete local and cloud passcode management and clock synchronization capabilities for the non-vision SwitchBot Keypad (WoKeypad). What Was Implemented: 1. Passcode Management: - `add_password`: Sends passcode bytes over BLE to register a new PIN code on the keypad. Parses response to retrieve the device-assigned index. - `modify_password`: Modifies an existing passcode by index. Overwrites values and configures active duration ranges. - `delete_password`: Instantly deletes a passcode from device memory by index. - `get_password_count`: Queries counts of stored PINs, NFC tags, fingerprints, and duress credentials. 2. Clock Synchronization (RTC): - `sync_time`: Synchronizes the internal device clock with millisecond precision (sending 8-byte big-endian milliseconds timestamp). Automatically scales second-level timestamps for backwards compatibility. - Note: Clock querying (`get_time`) was tested but found to return error 05 (unsupported) by the keypad hardware, indicating it is a write-only clock, so it has been dropped from the implementation. 3. SwitchBot Cloud Sync Option: - Added keyword-only parameters to `add_password`: `session`, `token`, `region`, `name`, and `creator`. - If provided, automatically triggers an HTTP POST request to API function 4245 to register the passcode in the SwitchBot Cloud database so it appears correctly in the official smartphone app. 4. Passive Advertisement Property Integration (from sblibs#488): - Exposes `attempt_state` property via `_get_adv_value` in `SwitchbotKeypad`. - Adds the missing `KEYPAD_INFO` test fixture to `tests/__init__.py`. Testing Methodology: 1. Automated Tests (tests/test_keypad.py): - Created full coverage suite for add/modify/delete password, counts, and sync_time. - Implemented `test_add_password_with_cloud_sync` mocking `api_request` to verify payload structures, regional routing, and authorization headers. - Added advertisement parsing unit tests for battery percentage and attempt state. - Verified that all unit tests pass cleanly and achieve 100% test coverage. 2. Manual/Hardware Verification: - Tested using test_hardware.py on a physical WoKeypad and Lock. - Verified that syncing clock with millisecond timestamps sets the correct RTC, allowing time-limited (temporary) passcodes to evaluate successfully offline and unlock the lock. Why Cloud Sync is Needed: - Keypad passcodes are stored and validated locally (allowing the Keypad to directly command the Lock offline without requiring internet connectivity). - However, for security reasons, the Keypad's BLE protocol is write-only for passcodes. There is no command to read back or list saved codes over BLE. - Since the SwitchBot app cannot query the Keypad to build its UI passcode list, it relies entirely on the SwitchBot Cloud database to track which codes exist. - If a passcode is added locally over BLE but not synced to the cloud, it will successfully operate the Lock offline, but will be completely invisible in the official mobile app. Integrating the cloud sync option ensures the app UI stays in sync with the keypad's physical storage. Co-authored-by: Alastair D'Silva <alastair@d-silva.org> Co-authored-by: Antigravity <antigravity@google.com>
… Keypad This patch adds complete local and cloud passcode management and clock synchronization capabilities for the non-vision SwitchBot Keypad (WoKeypad). What Was Implemented: 1. Passcode Management: - `add_password`: Sends passcode bytes over BLE to register a new PIN code on the keypad. Parses response to retrieve the device-assigned index. - `modify_password`: Modifies an existing passcode by index. Overwrites values and configures active duration ranges. - `delete_password`: Instantly deletes a passcode from device memory by index. - `get_password_count`: Queries counts of stored PINs, NFC tags, fingerprints, and duress credentials. 2. Clock Synchronization (RTC): - `sync_time`: Synchronizes the internal device clock with millisecond precision (sending 8-byte big-endian milliseconds timestamp). Automatically scales second-level timestamps for backwards compatibility. - Note: Clock querying (`get_time`) was tested but found to return error 05 (unsupported) by the keypad hardware, indicating it is a write-only clock, so it has been dropped from the implementation. 3. SwitchBot Cloud Sync Option: - Added keyword-only parameters to `add_password`: `session`, `token`, `region`, `name`, and `creator`. - If provided, automatically triggers an HTTP POST request to API function 4245 to register the passcode in the SwitchBot Cloud database so it appears correctly in the official smartphone app. 4. Passive Advertisement Property Integration (from sblibs#488): - Exposes `attempt_state` property via `_get_adv_value` in `SwitchbotKeypad`. - Adds the missing `KEYPAD_INFO` test fixture to `tests/__init__.py`. Testing Methodology: 1. Automated Tests (tests/test_keypad.py): - Created full coverage suite for add/modify/delete password, counts, and sync_time. - Implemented `test_add_password_with_cloud_sync` mocking `api_request` to verify payload structures, regional routing, and authorization headers. - Added advertisement parsing unit tests for battery percentage and attempt state. - Verified that all unit tests pass cleanly and achieve 100% test coverage. 2. Manual/Hardware Verification: - Tested using test_hardware.py on a physical WoKeypad and Lock. - Verified that syncing clock with millisecond timestamps sets the correct RTC, allowing time-limited (temporary) passcodes to evaluate successfully offline and unlock the lock. Why Cloud Sync is Needed: - Keypad passcodes are stored and validated locally (allowing the Keypad to directly command the Lock offline without requiring internet connectivity). - However, for security reasons, the Keypad's BLE protocol is write-only for passcodes. There is no command to read back or list saved codes over BLE. - Since the SwitchBot app cannot query the Keypad to build its UI passcode list, it relies entirely on the SwitchBot Cloud database to track which codes exist. - If a passcode is added locally over BLE but not synced to the cloud, it will successfully operate the Lock offline, but will be completely invisible in the official mobile app. Integrating the cloud sync option ensures the app UI stays in sync with the keypad's physical storage. Co-authored-by: Alastair D'Silva <alastair@d-silva.org> Co-authored-by: Antigravity <antigravity@google.com>
Adds support for SwitchBot Keypad (WoKeypad) — exposes battery level and attempt_state from BLE advertisements.
https://eu.switch-bot.com/products/switchbot-keypad
Tested on a real device — scanner confirmed
battery: 100andattempt_stateparsed correctly from live BLE advertisement data.Summary
The classic SwitchBot Keypad (WoKeypad) is a passive BLE-only device used to unlock doors paired with SwitchBot Lock. The advertisement parser (
adv_parsers/keypad.py) already parsesbatteryandattempt_statefrom BLE advertisements, andSwitchbotModel.KEYPADis already defined, but no device class existed.Changes
SwitchbotKeypaddevice class indevices/keypad.py, extendingSwitchbotDevice(passive-only, no BLE commands)SwitchbotKeypadfromswitchbot/__init__.pyKEYPAD_INFOtest fixture intests/__init__.pytests/test_keypad.pyverifying battery and attempt_state are correctly parsed from advertisement dataTest results
All 3 unit tests pass. Verified against real WoKeypad hardware — advertisement data parsed correctly.