Skip to content

Home Assistant Timer Dashboard

This example demonstrates how to create a comprehensive Home Assistant dashboard for monitoring and controlling voice assistant timers. The dashboard displays device status, timer progress, and provides quick controls for all timer-enabled areas.

Overview

Dashboard Overview

Prerequisites

Required HACS Components

This dashboard uses several custom cards from HACS (Home Assistant Community Store):

Install these via HACS before using this dashboard.

Required Entities

The dashboard expects these entities from the Voice Assistant Persistent Timers setup:

Entity Description
sensor.{area}_voice_assistant_state Voice assistant phase (idle, listening, etc.)
timer.{area} Home Assistant timer entity
switch.{area}_voice_assistant_mute Microphone mute control
input_number.{area}_timer_duration_minutes Quick-start timer duration

Configuration

Dashboard Header

# file: home-assistant/dashboards/timer-dashboard.yaml
# section: header
title: Voice Assistant Dashboard
views:
  - title: Timers
    path: timers
    icon: mdi:timer
    type: sections
    max_columns: 3

Section: Device Status Title

# file: home-assistant/dashboards/timer-dashboard.yaml
# section: status_title
sections:
  - type: grid
    column_span: 2
    cards:
      - type: custom:mushroom-title-card
        title: Device Status
        subtitle: Voice assistant monitoring across all areas

Section: Device Status Cards

Each device status card consists of two parts:

  1. A picture-entity card showing state-based images
  2. A mushroom-template-card showing status text and mute toggle
# file: home-assistant/dashboards/timer-dashboard.yaml
# section: device_status_cards
- type: horizontal-stack
  cards:
    # Kitchen Device Status
    - type: vertical-stack
      cards:
        - type: picture-entity
          entity: sensor.kitchen_voice_assistant_state
          name: Kitchen
          show_name: false
          show_state: false
          state_image:
            idle: /local/voice-assistant/idle.png
            listening: /local/voice-assistant/listening.png
            thinking: /local/voice-assistant/thinking.png
            replying: /local/voice-assistant/replying.png
            error: /local/voice-assistant/error.png
            not_ready: /local/voice-assistant/loading.png
            muted: /local/voice-assistant/muted.png
            timer_finished: /local/voice-assistant/timer-finished.png
            unavailable: /local/voice-assistant/loading.png
            unknown: /local/voice-assistant/loading.png
          image: /local/voice-assistant/idle.png
          tap_action:
            action: more-info
          card_mod:
            style: |
              ha-card {
                background: transparent;
                box-shadow: none;
                border-radius: 12px;
                overflow: hidden;
              }

        - type: custom:mushroom-template-card
          primary: Kitchen
          secondary: >-
            {% set state = states('sensor.kitchen_voice_assistant_state') %}
            {% if state == 'muted' %} MUTED
            {% elif state == 'idle' %} Online · Ready
            {% elif state == 'listening' %} Listening...
            {% elif state == 'thinking' %} Processing...
            {% elif state == 'replying' %} Speaking...
            {% elif state == 'timer_finished' %} Timer Complete!
            {% elif state == 'error' %} Error
            {% elif state == 'not_ready' %} Connecting...
            {% else %} {{ state | title }}
            {% endif %}
          icon: >-
            {% if is_state('switch.kitchen_voice_assistant_mute', 'on') %}
            mdi:microphone-off
            {% else %}
            mdi:microphone
            {% endif %}
          icon_color: >-
            {% if is_state('switch.kitchen_voice_assistant_mute', 'on') %}
            red
            {% else %}
            green
            {% endif %}
          entity: switch.kitchen_voice_assistant_mute
          tap_action:
            action: toggle
          hold_action:
            action: more-info
          card_mod:
            style: |
              ha-card {
                background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
                border-bottom: 3px solid var(--primary-color);
                margin-top: -8px;
              }

    # Bedroom Device Status
    - type: vertical-stack
      cards:
        - type: picture-entity
          entity: sensor.bedroom_voice_assistant_state
          name: Bedroom
          show_name: false
          show_state: false
          state_image:
            idle: /local/voice-assistant/idle.png
            listening: /local/voice-assistant/listening.png
            thinking: /local/voice-assistant/thinking.png
            replying: /local/voice-assistant/replying.png
            error: /local/voice-assistant/error.png
            not_ready: /local/voice-assistant/loading.png
            muted: /local/voice-assistant/muted.png
            timer_finished: /local/voice-assistant/timer-finished.png
            unavailable: /local/voice-assistant/loading.png
            unknown: /local/voice-assistant/loading.png
          image: /local/voice-assistant/idle.png
          tap_action:
            action: more-info
          card_mod:
            style: |
              ha-card {
                background: transparent;
                box-shadow: none;
                border-radius: 12px;
                overflow: hidden;
              }

        - type: custom:mushroom-template-card
          primary: Bedroom
          secondary: >-
            {% set state = states('sensor.bedroom_voice_assistant_state') %}
            {% if state == 'muted' %} MUTED
            {% elif state == 'idle' %} Online · Ready
            {% elif state == 'listening' %} Listening...
            {% elif state == 'thinking' %} Processing...
            {% elif state == 'replying' %} Speaking...
            {% elif state == 'timer_finished' %} Timer Complete!
            {% elif state == 'error' %} Error
            {% elif state == 'not_ready' %} Connecting...
            {% else %} {{ state | title }}
            {% endif %}
          icon: >-
            {% if is_state('switch.bedroom_voice_assistant_mute', 'on') %}
            mdi:microphone-off
            {% else %}
            mdi:microphone
            {% endif %}
          icon_color: >-
            {% if is_state('switch.bedroom_voice_assistant_mute', 'on') %}
            red
            {% else %}
            green
            {% endif %}
          entity: switch.bedroom_voice_assistant_mute
          tap_action:
            action: toggle
          hold_action:
            action: more-info
          card_mod:
            style: |
              ha-card {
                background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
                border-bottom: 3px solid #FF8000;
                margin-top: -8px;
              }

    # Playroom Device Status
    - type: vertical-stack
      cards:
        - type: picture-entity
          entity: sensor.playroom_voice_assistant_state
          name: Playroom
          show_name: false
          show_state: false
          state_image:
            idle: /local/voice-assistant/idle.png
            listening: /local/voice-assistant/listening.png
            thinking: /local/voice-assistant/thinking.png
            replying: /local/voice-assistant/replying.png
            error: /local/voice-assistant/error.png
            not_ready: /local/voice-assistant/loading.png
            muted: /local/voice-assistant/muted.png
            timer_finished: /local/voice-assistant/timer-finished.png
            unavailable: /local/voice-assistant/loading.png
            unknown: /local/voice-assistant/loading.png
          image: /local/voice-assistant/idle.png
          tap_action:
            action: more-info
          card_mod:
            style: |
              ha-card {
                background: transparent;
                box-shadow: none;
                border-radius: 12px;
                overflow: hidden;
              }

        - type: custom:mushroom-template-card
          primary: Playroom
          secondary: >-
            {% set state = states('sensor.playroom_voice_assistant_state') %}
            {% if state == 'muted' %} MUTED
            {% elif state == 'idle' %} Online · Ready
            {% elif state == 'listening' %} Listening...
            {% elif state == 'thinking' %} Processing...
            {% elif state == 'replying' %} Speaking...
            {% elif state == 'timer_finished' %} Timer Complete!
            {% elif state == 'error' %} Error
            {% elif state == 'not_ready' %} Connecting...
            {% else %} {{ state | title }}
            {% endif %}
          icon: >-
            {% if is_state('switch.playroom_voice_assistant_mute', 'on') %}
            mdi:microphone-off
            {% else %}
            mdi:microphone
            {% endif %}
          icon_color: >-
            {% if is_state('switch.playroom_voice_assistant_mute', 'on') %}
            red
            {% else %}
            green
            {% endif %}
          entity: switch.playroom_voice_assistant_mute
          tap_action:
            action: toggle
          hold_action:
            action: more-info
          card_mod:
            style: |
              ha-card {
                background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
                border-bottom: 3px solid #0080FF;
                margin-top: -8px;
              }

Section: Timer Status with Progress Bars

The timer status section uses timer-bar-card for visual countdown representation with play/pause/stop controls:

# file: home-assistant/dashboards/timer-dashboard.yaml
# section: timer_status
- type: grid
  column_span: 3
  cards:
    - type: custom:mushroom-title-card
      title: Timer Status
      subtitle: Active timer monitoring across all areas

    - type: horizontal-stack
      cards:
        # Kitchen Timer
        - type: vertical-stack
          cards:
            - type: custom:timer-bar-card
              entity: timer.kitchen
              name: Kitchen
              icon: mdi:chef-hat
              bar_height: 8px
              bar_background: "#333333"
              bar_foreground: var(--primary-color)
              text_width: 6em
              layout: hide_name
              invert: true
              card_mod:
                style: |
                  ha-card {
                    background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
                    border-left: 4px solid var(--primary-color);
                  }

            - type: horizontal-stack
              cards:
                # Play button
                - type: custom:mushroom-template-card
                  icon: mdi:play
                  icon_color: green
                  tap_action:
                    action: call-service
                    service: script.kitchen_start_timer
                  card_mod:
                    style: |
                      ha-card {
                        background: #1a1a1a;
                        --icon-size: 32px;
                      }
                      mushroom-shape-icon {
                        --shape-color: rgba(76, 175, 80, 0.2) !important;
                      }

                # Pause button
                - type: custom:mushroom-template-card
                  icon: mdi:pause
                  icon_color: orange
                  tap_action:
                    action: call-service
                    service: timer.pause
                    service_data:
                      entity_id: timer.kitchen
                  card_mod:
                    style: |
                      ha-card {
                        background: #1a1a1a;
                        --icon-size: 32px;
                      }
                      mushroom-shape-icon {
                        --shape-color: rgba(255, 152, 0, 0.2) !important;
                      }

                # Stop button
                - type: custom:mushroom-template-card
                  icon: mdi:stop
                  icon_color: red
                  tap_action:
                    action: call-service
                    service: timer.cancel
                    service_data:
                      entity_id: timer.kitchen
                  card_mod:
                    style: |
                      ha-card {
                        background: #1a1a1a;
                        --icon-size: 32px;
                      }
                      mushroom-shape-icon {
                        --shape-color: rgba(244, 67, 54, 0.2) !important;
                      }

        # Bedroom Timer
        - type: vertical-stack
          cards:
            - type: custom:timer-bar-card
              entity: timer.bedroom
              name: Bedroom
              icon: mdi:bed
              bar_height: 8px
              bar_background: "#333333"
              bar_foreground: "#FF8000"
              text_width: 6em
              layout: hide_name
              invert: true
              card_mod:
                style: |
                  ha-card {
                    background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
                    border-left: 4px solid #FF8000;
                  }

            - type: horizontal-stack
              cards:
                - type: custom:mushroom-template-card
                  icon: mdi:play
                  icon_color: green
                  tap_action:
                    action: call-service
                    service: script.bedroom_start_timer
                  card_mod:
                    style: |
                      ha-card {
                        background: #1a1a1a;
                        --icon-size: 32px;
                      }
                      mushroom-shape-icon {
                        --shape-color: rgba(76, 175, 80, 0.2) !important;
                      }

                - type: custom:mushroom-template-card
                  icon: mdi:pause
                  icon_color: orange
                  tap_action:
                    action: call-service
                    service: timer.pause
                    service_data:
                      entity_id: timer.bedroom
                  card_mod:
                    style: |
                      ha-card {
                        background: #1a1a1a;
                        --icon-size: 32px;
                      }
                      mushroom-shape-icon {
                        --shape-color: rgba(255, 152, 0, 0.2) !important;
                      }

                - type: custom:mushroom-template-card
                  icon: mdi:stop
                  icon_color: red
                  tap_action:
                    action: call-service
                    service: timer.cancel
                    service_data:
                      entity_id: timer.bedroom
                  card_mod:
                    style: |
                      ha-card {
                        background: #1a1a1a;
                        --icon-size: 32px;
                      }
                      mushroom-shape-icon {
                        --shape-color: rgba(244, 67, 54, 0.2) !important;
                      }

        # Playroom Timer
        - type: vertical-stack
          cards:
            - type: custom:timer-bar-card
              entity: timer.playroom
              name: Playroom
              icon: mdi:gamepad-variant
              bar_height: 8px
              bar_background: "#333333"
              bar_foreground: "#0080FF"
              text_width: 6em
              layout: hide_name
              invert: true
              card_mod:
                style: |
                  ha-card {
                    background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
                    border-left: 4px solid #0080FF;
                  }

            - type: horizontal-stack
              cards:
                - type: custom:mushroom-template-card
                  icon: mdi:play
                  icon_color: green
                  tap_action:
                    action: call-service
                    service: script.playroom_start_timer
                  card_mod:
                    style: |
                      ha-card {
                        background: #1a1a1a;
                        --icon-size: 32px;
                      }
                      mushroom-shape-icon {
                        --shape-color: rgba(76, 175, 80, 0.2) !important;
                      }

                - type: custom:mushroom-template-card
                  icon: mdi:pause
                  icon_color: orange
                  tap_action:
                    action: call-service
                    service: timer.pause
                    service_data:
                      entity_id: timer.playroom
                  card_mod:
                    style: |
                      ha-card {
                        background: #1a1a1a;
                        --icon-size: 32px;
                      }
                      mushroom-shape-icon {
                        --shape-color: rgba(255, 152, 0, 0.2) !important;
                      }

                - type: custom:mushroom-template-card
                  icon: mdi:stop
                  icon_color: red
                  tap_action:
                    action: call-service
                    service: timer.cancel
                    service_data:
                      entity_id: timer.playroom
                  card_mod:
                    style: |
                      ha-card {
                        background: #1a1a1a;
                        --icon-size: 32px;
                      }
                      mushroom-shape-icon {
                        --shape-color: rgba(244, 67, 54, 0.2) !important;
                      }

Section: Quick Controls

Quick controls allow setting timer duration and toggling microphone mute:

# file: home-assistant/dashboards/timer-dashboard.yaml
# section: quick_controls
      - type: grid
        column_span: 3
        cards:
          - type: custom:mushroom-title-card
            title: Quick Controls
            subtitle: Timer duration and microphone management

          - type: horizontal-stack
            cards:
              # Kitchen Quick Controls
              - type: vertical-stack
                cards:
                  - type: custom:mushroom-title-card
                    title: Kitchen
                    card_mod:
                      style: |
                        ha-card {
                          --primary-text-color: var(--primary-color);
                          --title-font-size: 16px;
                        }

                  - type: custom:mushroom-number-card
                    entity: input_number.kitchen_timer_duration_minutes
                    name: Duration
                    icon: mdi:timer-outline
                    display_mode: buttons
                    card_mod:
                      style: |
                        ha-card {
                          background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
                          border-left: 3px solid var(--primary-color);
                        }

                  - type: custom:mushroom-template-card
                    entity: switch.kitchen_voice_assistant_mute
                    primary: Microphone
                    secondary: >-
                      {% if is_state('switch.kitchen_voice_assistant_mute', 'on') %}
                      Muted
                      {% else %}
                      Active
                      {% endif %}
                    icon: >-
                      {% if is_state('switch.kitchen_voice_assistant_mute', 'on') %}
                      mdi:microphone-off
                      {% else %}
                      mdi:microphone
                      {% endif %}
                    icon_color: >-
                      {% if is_state('switch.kitchen_voice_assistant_mute', 'on') %}
                      red
                      {% else %}
                      green
                      {% endif %}
                    tap_action:
                      action: toggle
                    card_mod:
                      style: |
                        ha-card {
                          background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
                          border-left: 3px solid var(--primary-color);
                        }

              # Bedroom Quick Controls
              - type: vertical-stack
                cards:
                  - type: custom:mushroom-title-card
                    title: Bedroom
                    card_mod:
                      style: |
                        ha-card {
                          --primary-text-color: #FF8000;
                          --title-font-size: 16px;
                        }

                  - type: custom:mushroom-number-card
                    entity: input_number.bedroom_timer_duration_minutes
                    name: Duration
                    icon: mdi:timer-outline
                    display_mode: buttons
                    card_mod:
                      style: |
                        ha-card {
                          background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
                          border-left: 3px solid #FF8000;
                        }

                  - type: custom:mushroom-template-card
                    entity: switch.bedroom_voice_assistant_mute
                    primary: Microphone
                    secondary: >-
                      {% if is_state('switch.bedroom_voice_assistant_mute', 'on') %}
                      Muted
                      {% else %}
                      Active
                      {% endif %}
                    icon: >-
                      {% if is_state('switch.bedroom_voice_assistant_mute', 'on') %}
                      mdi:microphone-off
                      {% else %}
                      mdi:microphone
                      {% endif %}
                    icon_color: >-
                      {% if is_state('switch.bedroom_voice_assistant_mute', 'on') %}
                      red
                      {% else %}
                      green
                      {% endif %}
                    tap_action:
                      action: toggle
                    card_mod:
                      style: |
                        ha-card {
                          background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
                          border-left: 3px solid #FF8000;
                        }

              # Playroom Quick Controls
              - type: vertical-stack
                cards:
                  - type: custom:mushroom-title-card
                    title: Playroom
                    card_mod:
                      style: |
                        ha-card {
                          --primary-text-color: #0080FF;
                          --title-font-size: 16px;
                        }

                  - type: custom:mushroom-number-card
                    entity: input_number.playroom_timer_duration_minutes
                    name: Duration
                    icon: mdi:timer-outline
                    display_mode: buttons
                    card_mod:
                      style: |
                        ha-card {
                          background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
                          border-left: 3px solid #0080FF;
                        }

                  - type: custom:mushroom-template-card
                    entity: switch.playroom_voice_assistant_mute
                    primary: Microphone
                    secondary: >-
                      {% if is_state('switch.playroom_voice_assistant_mute', 'on') %}
                      Muted
                      {% else %}
                      Active
                      {% endif %}
                    icon: >-
                      {% if is_state('switch.playroom_voice_assistant_mute', 'on') %}
                      mdi:microphone-off
                      {% else %}
                      mdi:microphone
                      {% endif %}
                    icon_color: >-
                      {% if is_state('switch.playroom_voice_assistant_mute', 'on') %}
                      red
                      {% else %}
                      green
                      {% endif %}
                    tap_action:
                      action: toggle
                    card_mod:
                      style: |
                        ha-card {
                          background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
                          border-left: 3px solid #0080FF;
                        }

    cards: []

Supporting Configuration

Input Number Helpers

Create input_number entities for quick-start timer durations:

# file: home-assistant/configuration.yaml
# section: input_number
input_number:
  kitchen_timer_duration_minutes:
    name: Kitchen Timer Duration
    min: 1
    max: 60
    step: 1
    unit_of_measurement: min
    icon: mdi:timer

  bedroom_timer_duration_minutes:
    name: Bedroom Timer Duration
    min: 1
    max: 60
    step: 1
    unit_of_measurement: min
    icon: mdi:timer

  playroom_timer_duration_minutes:
    name: Playroom Timer Duration
    min: 1
    max: 60
    step: 1
    unit_of_measurement: min
    icon: mdi:timer

Quick Start Scripts

Create scripts to start timers with the configured duration:

# file: home-assistant/scripts/timer_quick_start.yaml
# section: quick_start_scripts
script:
  kitchen_start_timer:
    alias: "Kitchen: Start Timer"
    sequence:
      - service: timer.start
        target:
          entity_id: timer.kitchen
        data:
          duration: >-
            {{ states('input_number.kitchen_timer_duration_minutes') | int * 60 }}

  bedroom_start_timer:
    alias: "Bedroom: Start Timer"
    sequence:
      - service: timer.start
        target:
          entity_id: timer.bedroom
        data:
          duration: >-
            {{ states('input_number.bedroom_timer_duration_minutes') | int * 60 }}

  playroom_start_timer:
    alias: "Playroom: Start Timer"
    sequence:
      - service: timer.start
        target:
          entity_id: timer.playroom
        data:
          duration: >-
            {{ states('input_number.playroom_timer_duration_minutes') | int * 60 }}

Status Images

Place voice assistant state images in your Home Assistant www directory:

config/
└── www/
    └── voice-assistant/
        ├── idle.png
        ├── listening.png
        ├── thinking.png
        ├── replying.png
        ├── error.png
        ├── loading.png
        ├── muted.png
        └── timer-finished.png

You can download the default ESPHome casita images from:

Customization

Area Colors

Each area uses a distinct accent color:

  • Kitchen: Primary theme color (var(--primary-color))
  • Bedroom: Orange (#FF8000)
  • Playroom: Blue (#0080FF)

Change these by editing the border-left and bar_foreground values.

Adding More Areas

To add a new area (e.g., office):

  1. Create the timer entity: timer.office
  2. Add the ESPHome device with timer_area: "office"
  3. Create input_number.office_timer_duration_minutes
  4. Create script.office_start_timer
  5. Duplicate one of the device status cards and timer cards
  6. Replace all entity references with office

Dark/Light Theme Support

The dashboard uses hardcoded dark theme colors. For automatic theme support, replace:

  • #1a1a1a with var(--card-background-color)
  • #2d2d2d with var(--secondary-background-color)
  • #333333 with var(--divider-color)

Installation

  1. Install required HACS components (Mushroom, Timer Bar Card, card-mod)
  2. Create the input_number helpers (via UI or YAML)
  3. Create the quick-start scripts
  4. Add the dashboard YAML to your Lovelace configuration
  5. Place status images in www/voice-assistant/
  6. Reload Lovelace

Troubleshooting

Issue Solution
Cards show "Custom element doesn't exist" Install the required HACS components
Timer bar not updating Ensure timer.{area} entity exists and is properly configured
Images not loading Check that images are in www/ and referenced as /local/
Styles not applying Ensure card-mod is installed and reload the browser