Skip to content

Timer Events

Timer behavior is split between TimerHandler and TimerTask.

TimerHandler reacts to button events and state changes. TimerTask publishes display countdown messages and TIMER_COUNTDOWN events while a timer is running.

Event Summary

Event Payload Meaning
TIMER_STARTED none A full timer is considered started
TIMER_CLEARED none Timer was stopped/reset or returned idle
TIMER_EXPIRED none Timer or pause interval expired
TIMER_COUNTDOWN timer_event.seconds_remaining Current remaining seconds

Starting Timers

The timer handler listens for BUTTON_ACTION pressed events:

Button Behavior
TIMER_120 starts timer120Seconds
TIMER_60 starts timer60Seconds
TIMER_530 with no active quizzer starts timer530SingleSeconds and enters the special five-timer state
TIMER_530 with an active quizzer starts timer530DoubleSeconds
CONTEST starts contestSeconds with a pause at contestPauseSeconds
TIMER_RESET stops the timer, clears display when appropriate, publishes TIMER_CLEARED

Defaults:

Config field Default
timer_60_seconds 60
timer_120_seconds 120
timer_530_single_seconds 5
timer_530_double_seconds 30
contest_seconds 150
contest_pause_seconds 30
contest_gap_ms 4000

Countdown Events

When a timer starts, TimerTask immediately publishes:

EventMessage {
  type: TIMER_COUNTDOWN
  timer_event {
    seconds_remaining: <duration>
  }
}

Then it publishes a new countdown event approximately once per second. When stopped, it publishes seconds_remaining=0.

Expiration

When a timer reaches the end, TimerTask calls back into TimerHandler, which publishes TIMER_EXPIRED.

The root timer handler responds to TIMER_EXPIRED by:

  • publishing TIMER_STARTED
  • writing Expired to the display if no quizzer is displayed
  • starting the configured holdoff timer
  • playing the timer sound

The timerRunning state also has a TIMER_EXPIRED handler that plays the timer sound, resets the holdoff timer, and transitions idle. Because state handlers fall back through the parent state in the current state machine, clients should treat TIMER_EXPIRED, TIMER_STARTED, and TIMER_CLEARED as state notifications rather than a strict one-to-one request/response sequence.

Contest Timer

Contest mode starts a timer with a pause point. When the pause point is reached, the timer handler:

  • writes Contest? to the display
  • plays the contest timer sound
  • waits contest_gap_ms
  • resumes the timer automatically

Pressing CONTEST during the contest gap manually advances the gap handling by sending a local TIMER_EXPIRED event.

Display Interaction With Quizzers

Timer code tracks whether a quizzer has been displayed.

If a quizzer is displayed, timer reset and timer expiration paths avoid clearing or overwriting that display text in some cases. This is why QUIZZER_ACTIVE and QUIZZER_DISPLAYED are separate events.