mirror of
https://github.com/esphome/esphome.git
synced 2026-07-10 17:05:36 +00:00
[light] Preserve brightness on turn-off. (#17103)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -213,17 +213,19 @@ LightColorValues LightCall::validate_() {
|
||||
// Flag whether an explicit turn off was requested, in which case we'll also stop the effect.
|
||||
bool explicit_turn_off_request = this->has_state() && !this->state_;
|
||||
|
||||
// Turn off when brightness is set to zero, and reset brightness (so that it has nonzero brightness when turned on).
|
||||
if (this->has_brightness() && this->brightness_ == 0.0f) {
|
||||
// Treat zero brightness as an implicit turn-off when no state was explicitly requested.
|
||||
if (this->has_brightness() && this->brightness_ == 0.0f && !this->has_state()) {
|
||||
this->state_ = false;
|
||||
this->set_flag_(FLAG_HAS_STATE);
|
||||
if (color_mode & ColorCapability::BRIGHTNESS) {
|
||||
// Reset brightness so the light has nonzero brightness when turned back on.
|
||||
}
|
||||
|
||||
// Make sure a turn-on makes the light visible: if the resulting brightness would be zero
|
||||
// (e.g. restored from a brightness=0 turn-off), reset it to full brightness.
|
||||
if (this->has_state() && this->state_ && (color_mode & ColorCapability::BRIGHTNESS)) {
|
||||
float brightness = this->has_brightness() ? this->brightness_ : this->parent_->remote_values.get_brightness();
|
||||
if (brightness == 0.0f) {
|
||||
this->brightness_ = 1.0f;
|
||||
} else {
|
||||
// Light doesn't support brightness; clear the flag to avoid a spurious
|
||||
// "brightness not supported" warning during capability validation.
|
||||
this->clear_flag_(FLAG_HAS_BRIGHTNESS);
|
||||
this->set_flag_(FLAG_HAS_BRIGHTNESS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -322,6 +322,49 @@ async def test_light_calls(
|
||||
assert state.state is True
|
||||
assert state.brightness == pytest.approx(0.75)
|
||||
|
||||
# Test 31: Setting brightness to 0 without an explicit state implicitly turns
|
||||
# the light off; turning it back on (without an explicit brightness) then
|
||||
# restores full brightness so the light is visible again.
|
||||
client.light_command(key=rgbcw_light.key, state=True, brightness=0.5)
|
||||
state = await wait_for_state_change(rgbcw_light.key)
|
||||
assert state.state is True
|
||||
assert state.brightness == pytest.approx(0.5)
|
||||
|
||||
# Brightness 0 with no explicit state -> implicit turn-off
|
||||
client.light_command(key=rgbcw_light.key, brightness=0.0)
|
||||
state = await wait_for_state_change(rgbcw_light.key)
|
||||
assert state.state is False
|
||||
assert state.brightness == pytest.approx(0.0)
|
||||
# Turning on without an explicit brightness restores it to full brightness
|
||||
client.light_command(key=rgbcw_light.key, state=True)
|
||||
state = await wait_for_state_change(rgbcw_light.key)
|
||||
assert state.state is True
|
||||
assert state.brightness == pytest.approx(1.0)
|
||||
|
||||
# Test 31b: An explicit turn-on with brightness 0 still resets to full
|
||||
# brightness - a turn-on must never leave the light on-but-invisible. This
|
||||
# is the same path the restore logic exercises (set_state(true) +
|
||||
# set_brightness(0) from a persisted brightness=0 turn-off).
|
||||
client.light_command(key=rgbcw_light.key, state=True, brightness=0.0)
|
||||
state = await wait_for_state_change(rgbcw_light.key)
|
||||
assert state.state is True
|
||||
assert state.brightness == pytest.approx(1.0)
|
||||
|
||||
# Test 32: Turning a light on when it already has nonzero brightness leaves
|
||||
# the brightness unchanged (the reset only happens when brightness is 0).
|
||||
client.light_command(key=rgbcw_light.key, state=True, brightness=0.4)
|
||||
state = await wait_for_state_change(rgbcw_light.key)
|
||||
assert state.brightness == pytest.approx(0.4)
|
||||
|
||||
client.light_command(key=rgbcw_light.key, state=False)
|
||||
state = await wait_for_state_change(rgbcw_light.key)
|
||||
assert state.state is False
|
||||
|
||||
client.light_command(key=rgbcw_light.key, state=True)
|
||||
state = await wait_for_state_change(rgbcw_light.key)
|
||||
assert state.state is True
|
||||
assert state.brightness == pytest.approx(0.4)
|
||||
|
||||
# Final cleanup - turn all lights off
|
||||
for light in lights:
|
||||
client.light_command(
|
||||
|
||||
Reference in New Issue
Block a user