A versatile and highly customizable timer card for Home Assistant Lovelace, offering multiple display styles and support for various timer sources.
Note This card provides a clean and intuitive interface for managing timers in Home Assistant. It supports both local storage and MQTT integration for persistent timers that survive browser reloads and stay synchronized across devices.
- Alexa Integration: Separate audio settings for Alexa devices, based on alexa_media_player. Supports both legacy and new attribute structures (v1.5.1+).
- Voice PE Integration: Full support for Voice PE timers with template sensors - see setup guide.
- Flexible Display Styles: Choose from five distinct timer display styles:
fill_horizontal,fill_vertical,bar_horizontal,bar_vertical, orcircle. - Progress Animation Modes: Circle and bar styles support
drain(shrinks/empties),fill(grows), andmilestones(segmented progress by time units) animations for visual preference. - Dual Layout Control: Separate
layout(for no-timers state) andstyle(for active timers) options allow any combination. - Timer Presets: Quick-access buttons for commonly used timer durations. Supports both minutes and seconds format (e.g.,
5,90s). - Timer Name Presets: Predefined timer names for quick selection when creating timers (e.g., "Break", "Exercise", "Cooking").
- Custom Timers: Set custom timer durations using minute/second buttons or manual input with flexible format support (
5m,90s,1h30m,2:30). Default duration can be customized viadefault_new_timer_duration_minsparameter. - Persistent Storage: Support for local browser storage or MQTT integration for timers that survive reloads and sync across devices. MQTT publishes both
startedandexpiredevents for automation triggers. - Audio Notifications: Play custom audio files when timers expire, with repeat counts and play-until-dismissed options.
- Timer Actions: Configurable actions when timers expire (keep, dismiss, or auto-dismiss).
- Snooze Functionality: Easily snooze expired timers for additional time.
- Active Timer Management: View and manage multiple active timers simultaneously.
- Customizable Time Display: Multiple time format options including HMS, HM, human-readable formats, and customizable time unit ordering.
- Smart Auto-Detection & Entity Integration: Automatic detection of timer sources with ISO date validation and entity type checking. Connect to Home Assistant entities including MQTT sensors, input helpers, and more.
- Customizable Appearance: Adjust colors, icons, and styling to match your Home Assistant theme.
- Native Theme Integration: Automatically uses Home Assistant theme colors and native UI elements.
- Visual Progress Indicators: Clear visual feedback showing timer progress and status.
- Language Support: Added support for multiple languages. Currently supports English (
en), German (de), and Spanish (es). - π Security Features: Built-in XSS protection, input validation, rate limiting, and secure audio URL handling.
Simple Timer Card v1.2.0+ includes comprehensive security features:
- XSS Protection: All timer labels are automatically sanitized to prevent script injection
- Input Validation: Duration limits (24h max), label length limits (100 chars), and type validation
- URL Security: Audio URLs are validated to only allow safe protocols and paths
- Rate Limiting: Actions are throttled to prevent spam and performance issues
- Data Integrity: localStorage and MQTT data validation with graceful error handling
For security guidelines and vulnerability reporting, see SECURITY.md.
- Home Assistant: Version 2023.4 or newer
- Optional: MQTT sensor for persistent timer storage
HACS
Simple Timer Card is available in HACS (Home Assistant Community Store).
Use this link to directly go to the repository in HACS:
- Download the
simple-timer-card.jsfile from the latest release - Copy it to your
config/wwwfolder - Add the following to your Lovelace resources:
resources:
- url: /local/simple-timer-card.js
type: module| Name | Type | Default | Description |
|---|---|---|---|
type |
string |
Required | custom:simple-timer-card |
layout |
string |
horizontal |
Card layout for no-timers state. Can be horizontal or vertical |
style |
string |
bar_horizontal |
Timer display style. Can be fill_vertical, fill_horizontal, bar_vertical, bar_horizontal (default), or circle |
title |
string |
null |
Optional title for the card |
language |
string |
en |
Language for UI text. Supports en (English), de (German), es (Spanish). |
entities |
array |
[] |
Array of timer entities to display |
progress_mode |
string |
drain |
Progress animation mode: drain (shrinks as time counts down), fill (grows as time elapses), or milestones (segmented progress by time units). Applies to circle, bar_horizontal, and bar_vertical styles. Note: circle_mode is deprecated in favor of progress_mode |
Each entity in the entities array can be either a simple string (entity ID) or an object with the following properties:
| Name | Type | Default | Description |
|---|---|---|---|
entity |
string |
Required | Home Assistant entity ID |
name |
string |
auto |
Override the entity name |
mode |
string |
auto |
Timer parsing mode: auto, alexa, timer, voice_pe, helper, timestamp, or minutes_attr |
icon |
string |
auto |
Override the entity icon |
color |
string |
auto |
Override the entity color |
minutes_attr |
string |
Minutes to arrival |
Attribute name for minutes_attr mode |
start_time_attr |
string |
start_time |
Attribute name for start time when using timestamp mode (enables duration calculation) |
start_time_entity |
string |
none | Entity ID for separate start time entity when using timestamp mode (alternative to start_time_attr) |
keep_timer_visible_when_idle |
boolean |
false |
Keep timer visible when idle (timer mode only) |
audio_enabled |
boolean |
false |
Enable per-entity audio notifications |
audio_file_url |
string |
"" |
Per-entity audio file URL |
audio_repeat_count |
number |
1 |
Per-entity audio repeat count |
audio_play_until_dismissed |
boolean |
false |
Per-entity play until dismissed setting |
hide_timer_actions |
boolean |
false |
Hide manual action buttons (start/pause/cancel/dismiss/snooze) for entities where mode: timer |
Supported Timer Sources:
- Auto: Automatically detects the timer source based on entity type and attributes
- Alexa: Amazon Alexa timers via alexa_media_player integration. Supports both
sorted_active/sorted_paused(legacy) andalarms_brief(v1.5.1+) attribute structures - Timer: Native Home Assistant timer entities (
timer.*) - Voice PE: Voice PE integration timers with
display_nameattribute support - Helper: Input text/text entities for manual timer management
- Timestamp: Sensor entities with timestamp device class. Supports optional
start_time_attrattribute or separatestart_time_entityfor duration calculation - Minutes Attr: Sensors with custom minutes-to-arrival attributes
π‘ Style Options: The
styleparameter supports five distinct visual presentations with direction control. Thelayoutparameter controls how the card appears when there are no active timers, whilestylecontrols the active timer display. Any layout/style combination is possible for maximum flexibility.
| Name | Type | Default | Description |
|---|---|---|---|
timer_presets |
array |
[5, 15, 30] |
Array of preset timer durations. Supports minutes (e.g., 5, 15) or seconds with 's' suffix (e.g., 30s, 90s) |
show_timer_presets |
boolean |
true |
Show or hide the timer preset buttons |
minute_buttons |
array |
[1, 5, 10] |
Array of minute increment buttons for custom timers. Supports minutes or seconds with 's' suffix (e.g., 30s) |
show_time_selector |
boolean |
false |
Show manual time input selector. Supports flexible formats like 5m, 90s, 1h30m, or 2:30 |
show_active_header |
boolean |
true |
Show "Active Timers" header section |
default_timer_icon |
string |
mdi:timer-outline |
Default icon for timer cards |
default_timer_color |
string |
var(--primary-color) |
Default color for timer elements |
timer_name_presets |
array |
[] |
Array of preset timer names for quick selection when creating timers (e.g., ['Break', 'Exercise']) |
default_new_timer_duration_mins |
number |
15 |
Default duration in minutes for custom timer picker |
Timer Name Presets: When configured, preset timer names appear as clickable buttons during timer creation, allowing users to quickly assign meaningful names like "Break", "Exercise", or "Cooking" to their timers. If no presets are configured, a simple text input field is shown instead.
| Name | Type | Default | Description |
|---|---|---|---|
time_format |
string |
hms |
Time display format: hms (HH:MM:SS), hm (HH:MM), ss (seconds only), dhms (DD:HH:MM:SS), human_compact (e.g., "5h 30m"), human_short (e.g., "5h 30m 15s"), or human_natural (e.g., "5 hours 30 minutes") |
time_format_units |
array |
['days','hours','minutes','seconds'] |
Ordered array of time units to display. Supports: years, months, weeks, days, hours, minutes, seconds. Can also be a comma-separated string |
When progress_mode is set to milestones, the progress bar is divided into segments based on time units. The following settings control milestone behavior:
| Name | Type | Default | Description |
|---|---|---|---|
milestone_unit |
string |
auto |
Unit for milestone segments: auto (automatically selects appropriate unit), none, years, months, weeks, days, hours, minutes, or seconds. Only applies when progress_mode: milestones |
milestone_pulse |
boolean |
true |
Enable pulsing animation on the active milestone segment. Only applies when progress_mode: milestones |
| Name | Type | Default | Description |
|---|---|---|---|
default_timer_entity |
string |
null |
Entity ID for timer storage. Supports input_text.*, text.* entities for helper-based storage, or sensor.* entities for MQTT-based storage. Required for persistent timers |
storage_namespace |
string |
"default" or entity ID |
Namespace for local storage isolation. Allows multiple card instances to maintain separate timer storage. If not specified, uses default_timer_entity value when available, otherwise defaults to "default" |
| Name | Type | Default | Description |
|---|---|---|---|
expire_action |
string |
keep |
Action when timer expires: keep, dismiss, or remove |
expire_keep_for |
number |
120 |
How long to keep expired timers (in seconds) before auto-dismissing |
auto_dismiss_writable |
boolean |
false |
Allow expired timers to be dismissed automatically |
snooze_duration |
number |
5 |
Default snooze duration in minutes |
expired_subtitle |
string |
Time's up! |
Message displayed when timer expires |
show_progress_when_unknown |
boolean |
false |
Show progress bar even when timer duration is unknown |
Expiry Action Behavior:
keep: Expired timers remain visible forexpire_keep_forseconds, then auto-dismiss. Works with all timer sources.dismiss: Expired timers are immediately hidden from view but remain in entity state (for read-only sources liketimestamp,voice_pe,alexa).remove: Expired timers are completely removed. For writable sources (helper,local,mqtt), this deletes the timer data. For read-only sources, behaves likedismiss.
| Name | Type | Default | Description |
|---|---|---|---|
audio_enabled |
boolean |
false |
Enable audio notifications when timers expire |
audio_file_url |
string |
"" |
URL or path to audio file to play |
audio_repeat_count |
number |
1 |
Number of times to repeat the audio (1-10) |
audio_play_until_dismissed |
boolean |
false |
Continue playing audio until timer is dismissed or snoozed |
audio_completion_delay |
number |
4 |
Delay in seconds before auto-dismissing timer after audio completes (when using expire_action: remove) |
| Name | Type | Default | Description |
|---|---|---|---|
alexa_audio_enabled |
boolean |
false |
Enable separate audio settings for Alexa devices |
alexa_audio_file_url |
string |
"" |
URL or path to audio file for Alexa devices |
alexa_audio_repeat_count |
number |
1 |
Number of times to repeat Alexa audio (1-10) |
alexa_audio_play_until_dismissed |
boolean |
false |
Continue playing Alexa audio until timer is dismissed or snoozed |
This card focuses on timer display and management. For notifications when timers expire, use Home Assistant automations.
If you use MQTT storage, Simple Timer Card publishes timer event messages to MQTT topics for external automation, notification, or cross-device sync. The following topics/events are published:
simple_timer_card/events/startedWhen a timer is created/startedsimple_timer_card/events/expiredWhen a timer finishes/expires (countdown hits zero)simple_timer_card/events/cancelledWhen a timer is cancelledsimple_timer_card/events/pausedWhen a timer is pausedsimple_timer_card/events/resumedWhen a timer is resumed
See examples/mqtt_timer_notifications.yaml for a mobile notification automation.
For helper entities, create a state trigger automation. See examples/helper_timer_monitor.yaml.
Use the built-in timer.finished event. Example:
trigger:
- platform: event
event_type: timer.finishedCheck the examples/ folder for ready-to-use automation templates.
For persistent timers that survive browser reloads and sync across devices, configure an MQTT sensor:
# configuration.yaml
mqtt:
sensor:
- name: Simple Timer Store
unique_id: simple_timer_store
state_topic: simple_timer_card/timers/state
value_template: "{{ value_json.version | default(1) }}"
json_attributes_topic: simple_timer_card/timers
β οΈ Important: Thestate_topicandjson_attributes_topicmust be exactly as shown above. It is also strongly recommended to keep thevalue_templateas is. Please follow the Hybrid Model setup guide to setup a failover.
The card offers flexible styling options with five distinct display styles:
- Progress Bar Horizontal (
bar_horizontal): Traditional horizontal progress bar with timer information - Progress Bar Vertical (
bar_vertical): Vertical progress bar layout with timer information - Background Fill Horizontal (
fill_horizontal): Full horizontal background color fill that progresses as timer counts down - Background Fill Vertical (
fill_vertical): Full vertical background color fill that progresses as timer counts down - Circle (
circle): Modern circular progress ring with centered timer display. Supports both clockwise (fill) and counter-clockwise (drain) progress modes
The layout parameter controls the card appearance when there are no active timers, while style controls active timer display. This separation allows any combination of layout and style for maximum flexibility.
When using circle, bar_horizontal, or bar_vertical styles, you can control the progress animation:
drain(default): Progress shrinks/empties as time counts down - circle empties, bars decreasefill: Progress grows as time elapses - circle fills up, bars increasemilestones: Progress bar is divided into segments based on time units (only works with bar styles:bar_horizontalandbar_vertical). Each segment represents a time unit (e.g., hours, minutes) and fills/empties as time progresses
type: custom:simple-timer-card
style: circle
progress_mode: drain # Counter-clockwise drain effect for circle, decreasing bar for barstype: custom:simple-timer-card
style: bar_horizontal
progress_mode: fill # Bar grows from left to right as time elapsestype: custom:simple-timer-card
style: bar_horizontal
progress_mode: milestones # Segmented progress bar with milestone units
milestone_unit: auto # Automatically select appropriate unit
milestone_pulse: true # Pulse the active segmentNote: The deprecated
circle_modeparameter is still supported for backward compatibility but will be removed in a future version. Please useprogress_modeinstead.
The milestones progress mode creates a segmented progress bar where each segment represents a unit of time. This provides a clear visual indication of progress through distinct time intervals.
How it works:
- The progress bar is divided into equal segments
- Each segment represents one unit of the selected time scale (hours, minutes, etc.)
- Segments fill or empty based on the
progress_modesetting (drain vs fill) - The currently active segment can pulse for visual feedback (controlled by
milestone_pulse) - The time unit is automatically selected based on timer duration when
milestone_unit: auto
Configuration options:
milestone_unit: Choose the time unit for segments (auto,hours,minutes,seconds, etc.)milestone_pulse: Enable/disable pulsing animation on the active segment (default:true)
Example:
A 30-minute timer with milestone_unit: minutes will show 30 segments, each representing 1 minute.
The card uses CSS custom properties that can be overridden:
type: custom:simple-timer-card
card_mod:
style: |
:host {
--stc-radius: 12px;
--stc-chip-radius: 6px;
}Timers not persisting after browser reload:
- Ensure you have configured a
default_timer_entitypointing to a valid MQTT sensor - Verify your MQTT sensor is using the exact state topic:
simple_timer_card/timers/state
Audio not playing:
- Check that the audio file URL is accessible
- Verify browser audio permissions
- Test with a simple audio file first
Notifications not working:
- Timer notifications are now handled by Home Assistant automations
- Check the
examples/folder for automation templates - For MQTT timers, ensure your automation listens to
simple_timer_card/events/expired - For helper timers, create state trigger automations
- For native timer entities, use the built-in
timer.finishedevent
Card not loading:
- Ensure the card is properly added to your Lovelace resources
- Check the browser console for JavaScript errors
This project is licensed under the MIT License. See the LICENSE file for details.
If you find this card useful and would like to show your support, you can buy me a coffee:
