fix: cancel a running auto-reset timer when auto-reset is turned off

Setting autoreset_control_seconds to 0 dropped the stored delay but left
a timer that was already counting down. When it fired, it cleared the
light's manual control and re-adapted it, overriding the user's change.
Cancel that timer too, unless another profile for the light still uses
auto-reset.
This commit is contained in:
BrawnyBravo 2026-10-26 07:44:17 -07:00
commit 1770ec29c7
2 changed files with 29 additions and 0 deletions

View file

@ -1130,8 +1130,12 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
and switch._auto_reset_manual_control_time
):
still_reset.update(switch._resolve_lights())
timers = self.manager.auto_reset_manual_control_timers
for light in set(all_lights) - still_reset:
self.manager.auto_reset_manual_control_times.pop(light, None)
# A timer started under the old delay must not reset the light.
if timer := timers.pop(light, None):
timer.cancel()
async def _setup_listeners(self, _: Event[NoEventData] | None = None) -> None:
_LOGGER.debug("%s: Called '_setup_listeners'", self._name)

View file

@ -6414,6 +6414,31 @@ async def test_autoreset_control_seconds_zero_disables_existing_reset(hass):
assert ENTITY_LIGHT_1 not in manager.auto_reset_manual_control_timers
async def test_autoreset_zero_cancels_running_reset_timer(hass):
"""Disabling auto-reset must also stop a timer that is already running."""
switch, _ = await setup_lights_and_switch(hass, {CONF_AUTORESET_CONTROL: 0.2})
manager = switch.manager
manager.set_manual_control_attributes(ENTITY_LIGHT_1)
timer = manager.auto_reset_manual_control_timers[ENTITY_LIGHT_1]
assert timer.is_running()
await hass.services.async_call(
DOMAIN,
SERVICE_CHANGE_SWITCH_SETTINGS,
{ATTR_ENTITY_ID: switch.entity_id, CONF_AUTORESET_CONTROL: 0},
blocking=True,
)
await hass.async_block_till_done()
assert not timer.is_running()
assert ENTITY_LIGHT_1 not in manager.auto_reset_manual_control_timers
await asyncio.sleep(0.4) # longer than the old delay
await hass.async_block_till_done()
# The light stays manually controlled instead of being reset and re-adapted.
assert manager.get_manual_control_attributes(ENTITY_LIGHT_1)
assert switch.extra_state_attributes["autoreset_time_remaining"] == {}
async def test_autoreset_zero_keeps_other_profiles_reset(hass):
"""A profile without auto-reset must not clear another profile's delay."""
switch, _ = await setup_lights_and_switch(hass, {CONF_AUTORESET_CONTROL: 3600})