From 6f846c26cab2666e296e2e5f617b9805ce8a251d Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Thu, 27 Nov 2025 09:27:13 -0800 Subject: [PATCH] Fix race condition where timer.start_time is None while is_running() is True (#1295) When start() creates a task with asyncio.create_task(), the task is scheduled but not immediately executed. This means is_running() returns True (task exists and not done), but start_time is still None because _run() hasn't executed yet. This causes a TypeError when comparing event.time_fired > timer.start_time. Fix by setting start_time in start() before creating the task. Fixes #1272 --- custom_components/adaptive_lighting/switch.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index fdeac7dd..6a22a41f 100644 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -2680,7 +2680,6 @@ class _AsyncSingleShotTimer: async def _run(self): """Run the timer. Don't call this directly, use start() instead.""" - self.start_time = dt_util.utcnow() await asyncio.sleep(self.delay) if self.callback: if asyncio.iscoroutinefunction(self.callback): @@ -2696,6 +2695,10 @@ class _AsyncSingleShotTimer: """Start the timer.""" if self.task is not None and not self.task.done(): self.task.cancel() + # Set start_time before creating task to avoid race condition + # where is_running() returns True but start_time is still None + # See: https://github.com/basnijholt/adaptive-lighting/issues/1272 + self.start_time = dt_util.utcnow() self.task = asyncio.create_task(self._run()) def cancel(self):