Include device_on in set_brightness, set_color_temp, and set_hsv - #1680
Include device_on in set_brightness, set_color_temp, and set_hsv#1680fluffyspace wants to merge 5 commits into
Conversation
Some Tapo devices (confirmed on L900-5 LED strip) treat power state and brightness/color as independent parameters. When set_device_info is called with only brightness or color parameters (without device_on), the device accepts the command, updates its internal state, and reports success — but the LEDs do not physically turn on. This causes a particularly bad failure mode: the device enters a "zombie state" where it reports on/brightness=100 to all queries while the LEDs remain off. The device stays in this state until power cycled, and python-kasa has no way to detect the discrepancy since every protocol response indicates success. Adding device_on: True to set_brightness(), set_color_temp(), and set_hsv() ensures the device always receives an explicit power state with light property changes. This matches the behavior of set_state() which already includes device_on, and is consistent with how the official Tapo app sends commands. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update test_light_effect_brightness assertions in both test_light_effect.py and test_light_strip_effect.py to match the new set_brightness payload that includes device_on: True. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1680 +/- ##
==========================================
+ Coverage 93.22% 93.24% +0.02%
==========================================
Files 157 157
Lines 9815 9822 +7
Branches 1003 1006 +3
==========================================
+ Hits 9150 9159 +9
Misses 472 472
+ Partials 193 191 -2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Forcing device_on: True unconditionally in set_brightness, set_color_temp, and set_hsv fixed the L900-5 zombie state but reintroduced the python-kasa#1532 regression: users who want to change brightness on an off device without turning it on as a side-effect. Now device_on: True is injected only when self._device.is_on is already true. That still re-asserts the power state for devices in the zombie state (they report on, so the flag is still sent and the LEDs physically come up), while leaving a deliberately-off device alone. Tests parametrize all three setters over is_on=[True, False] to lock in both branches.
|
Updated in 85d8d38 to address the regression risk against #1532 / #1066. Original approach forced New approach: PR description updated with the full matrix; new parametrized tests in |
Fixes mypy: `dev` is typed as `Device` (the abstract base) which has no `_info` attribute. Patching the public `is_on` property has the same effect on the brightness module's logic and is type-clean.
|
There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days. |
Summary
device_on: Truein theset_device_infopayload fromset_brightness(),set_color_temp(), andset_hsv()— only whenself._device.is_onis already true.Problem
Some Tapo devices (confirmed on the L900-5 LED light strip) do not implicitly turn on when receiving brightness or color commands via
set_device_info. The device:error_code: 0)device_on: true,brightness: 100when queried)This creates a "zombie state" where the device reports it's on but the LEDs are off. The state persists until the device is power-cycled. Since every protocol response indicates success, python-kasa (and Home Assistant) have no way to detect the failure.
Root cause
Brightness.set_brightness()sent{"brightness": N}— nodevice_onColorTemperature.set_color_temp()sent{"color_temp": N}— nodevice_onColor.set_hsv()sent{"hue": N, "saturation": N}— nodevice_onMeanwhile,
Light.set_state()always includesdevice_onin the payload, and works correctly.Fix
Include
"device_on": Truein all three methods'set_device_infopayloads, only when the device is currently on. This re-asserts the power state for the zombie-state case (the device thinks it's on, so the flag is still sent and the LEDs physically come up) while leaving a deliberately-off device alone.is_ondevice_onsent?TrueTrueFalseThis matches the spirit of
set_state()(which sendsdevice_onexplicitly) without contradicting the "set brightness without turning on" use case from #1532 / #1066.Testing
Tested on a Tapo L900-5 (firmware current, KLAP v2 transport) controlled via Home Assistant's tplink integration:
light.turn_onwithbrightness_pct=100→ device reports on, LEDs stay offlight.turn_onwithbrightness_pct=100→ device reports on, LEDs turn onUnit tests
New
tests/smart/modules/test_light_device_on_payload.pyparametrizesset_brightness,set_color_temp, andset_hsvoveris_on=[True, False]and locks in:is_on=True→ payload includesdevice_on: Trueis_on=False→ payload omitsdevice_on(no regression for Regression? Latest kasa cli turns light on when setting brightness. #1532)Updated existing
test_light_effect_brightnesscases to forcedev._info["device_on"] = Trueso the asserted payload is deterministic across fixtures (some havedevice_on: falsebaked in).Closes the regression risk for #1532 / #1066.
🤖 Generated with Claude Code