Timer
The timer accessor returns Timer entities representing Home
Assistant timer helpers. HaClient adds a typed
TimerAccessor.create for runtime creation and forwards every
timer-finished event back to the right entity.
Lifecycle of a timer
Timers move through these states:
idle— created but not started, or finished/cancelled.active— counting down.paused— paused mid-countdown.
timer = ha.timer("tea")
print(timer.is_idle, timer.is_active, timer.is_paused)
print(timer.duration) # configured duration as HA string ("HH:MM:SS")
print(timer.remaining) # remaining as HA string
print(timer.time_remaining) # remaining as float seconds
print(timer.finishes_at) # ISO timestamp or None
print(timer.persistent)
Starting, pausing, cancelling
await timer.start() # use configured duration
await timer.start(duration="00:05:00") # override duration
await timer.pause()
await timer.cancel() # back to idle
await timer.finish() # mark finished immediately
await timer.change(duration="00:10:00") # change a running timer
change only works on timers that are currently running; HA itself
rejects calls otherwise.
Reacting to timer events
The decorator names match the lifecycle transitions:
@timer.on_start
def started(old, new): ...
@timer.on_pause
def paused(old, new): ...
@timer.on_idle
def idle(old, new): ...
@timer.on_finished
async def finished(old, new):
await notify("Tea is ready")
@timer.on_cancelled
def cancelled(old, new): ...
Two of those — on_finished and on_cancelled — are wired to the
HA events timer.finished and timer.cancelled (not just the state
transition), so they fire reliably even on timers that briefly skip
through idle between cycles.
Creating a runtime timer
new_timer = await ha.timer.create(duration="00:01:30")
await new_timer.start()
create auto-generates a name when you do not supply one. For a
named, persistent timer (one that survives restarts) you must
provide a name:
laundry = await ha.timer.create(
name="laundry_cycle",
duration="00:45:00",
persistent=True,
)
Creating a persistent=True timer without a name raises
ValueError.
Deleting
await timer.delete()
Deletes the helper from HA. Library-created timers should be deleted when you are done with them, otherwise they accumulate.
Common patterns
Wait for a timer to finish
import asyncio
done = asyncio.Event()
@timer.on_finished
def _(old, new) -> None:
done.set()
await timer.start(duration="00:00:30")
await done.wait()
Resettable countdown
async def reset() -> None:
await timer.cancel()
await timer.start(duration="00:10:00")
cancel followed by start is the standard way to reset; HA does
not expose a single-call "restart".