fix: skip cached state override when bot ignores command (#213)#502
fix: skip cached state override when bot ignores command (#213)#502bluetoothbot wants to merge 2 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests.
... and 1 file with indirect coverage changes 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR fixes cached state handling for SwitchBot Bot (WoHand) commands by avoiding isOn cache overrides when the device replies that a command was ignored (e.g. 03ff00). This aligns the library’s cached state with the device’s actual acceptance/rejection semantics and prevents downstream consumers (e.g., Home Assistant) from reporting an incorrect state.
Changes:
- Gate
self._override_state({"isOn": ...})inturn_on/turn_offso it only runs when_check_command_result(...)indicates success. - Add a new
tests/test_bot.pysuite covering accepted vs rejected results forturn_on/turn_off, plus an inverse-mode regression check.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
switchbot/devices/bot.py |
Prevents cached isOn from being flipped when the device rejects/ignores the command. |
tests/test_bot.py |
Adds regression tests to ensure state overrides only occur on accepted command results (including inverse mode). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Extends the bot fix from sblibs#502 to SwitchbotPlugMini and SwitchbotHumidifier: both `turn_on`/`turn_off` (and humidifier's `set_level`) ran `_override_state` unconditionally, even when `_check_command_result` returned False. A rejected/garbled command response would still flip the cached state, making HA report a state the device never reached. Gate `_override_state` and `_fire_callbacks` on the result, matching the original intent of the existing `_check_command_result` calls. Tests added: tests/test_plug.py (4 cases), tests/test_humidifier.py (6 cases) covering accepted/rejected paths for turn_on, turn_off, and set_level. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR Review — fix: skip cached state override when bot ignores command (#213)Clean, minimal, well-tested fix — merge-ready. The two-line gate correctly addresses the latent half of #213. Verified against the codebase: Strengths:
No blocking issues found.
Checklist
Automated review by Kōan (Claude) |
When the bot replies with 0x03 0xff 0x00 ("command ignored", typically on
back-to-back presses), `Switchbot.turn_on`/`turn_off` still called
`_override_state` unconditionally, so Home Assistant's cached state
flipped even though the device never actuated. Gate the override on the
result of `_check_command_result` so a rejected command leaves the
cached state alone.
Adds tests covering accepted (`0x01`/`0x05`) and rejected return values
for both turn_on and turn_off, plus an inverse-mode regression check.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Simple rebaseBranch StatsActions performed
CI statusCI will be checked asynchronously. Automated by Kōan |
a02c6e0 to
9710999
Compare
What
When
Switchbot.turn_on/turn_offget a "command ignored" reply (0x03 0xff 0x00, typically on back-to-back presses), don't flip the cachedisOnstate. Only override the state when_check_command_resultreturnsTrue.Why
Closes the latent half of #213. The bot's own protocol distinguishes acceptance (
0x01 0x48 0x90) from rejection (0x03 0xff 0x00) and_check_command_result(result, 0, {1, 5})already returnsFalsefor the rejection case — but the next line ranself._override_state({"isOn": True})unconditionally, so HA's cached state flipped tooneven when the device never actuated.That makes the back-to-back press behaviour observable in the issue: log shows
Turn on result: 03ff00 -> {'isOn': True}for the second press, and HA happily reports the bot asondespite no physical actuation. The 8.5s disconnect timer + a brief delay between commands is still the user-side workaround; this PR just stops the library from lying about state when the command is rejected.How
Two-line gate in
bot.py:Behaviour for the success path (notification byte 0x01 or 0x05) is unchanged.
Testing
tests/test_bot.pycovers turn_on/turn_off for both accepted and rejected results, plus an inverse-mode regression. (No existing test file for theSwitchbotbot device class.)1218 passed.🤖 Generated with Claude Code
Quality Report
Changes: 2 files changed, 111 insertions(+), 2 deletions(-)
Code scan: clean
Tests: passed (1218 passed)
Branch hygiene: clean
Generated by Kōan post-mission quality pipeline