Mushroom : how to display remaining time of a timer?

Where are you in the world? Like most datetime objects in HA, finishes_at value is stored as UTC timezone…

I copied your code with the change to my entity.
As an entity it works fine, but if I want to display it in the mushroom template card it tells me “unknown”.
What I’m doing wrong?

This is my template code I try to add the “Secondary”:

secondary: |-
  {% if is_state("timer.boiler_timer", "active") -%}
  {{ states('boiler_timer_countdown_remaining') }} 
  {%- else -%}
    
  {%- endif %}

This is how it looks:
boiler

Should be sensor.boiler_timer_countdown_remaining

After reading this thread I found a different solution to display and control timers using mushroom and a couple of other custom cards. This method updates the time remaining every second.

I mostly use timers to control devices, for example a space heater and an electric blanket. Here’s how it looks:

Idle:

Active (timer running)

Active (not timed)

The required cards are stack-in-card, numberbox-card and timer-bar-card. I use them with a script which activates the correct device/timer and a separate automation to switch the devices off.

Here’s the code for horizontal version (edit: now with card_mod to center the numberbox card, it’s not needed when you change the mode to vertical):

type: custom:stack-in-card
mode: horizontal
cards:
  - type: custom:mushroom-template-card
    entity: switch.smart_plug_2_switch
    icon: mdi:heat-wave
    tap_action:
      action: call-service
      service: script.bed_warmer
      data:
        bed_side: switch.smart_plug_2_switch
        timer: timer.heater
      target: {}
    icon_color: '{% if is_state(''switch.smart_plug_2_switch'',''on'')%}red{%else%}{%endif%}'
    hold_action:
      action: toggle
    primary: Heater
    secondary: '{{states(''switch.smart_plug_2_switch'')|title()}}'
  - type: conditional
    conditions:
      - entity: switch.smart_plug_2_switch
        state: 'off'
    card:
      type: custom:numberbox-card
      entity: timer.heater
      icon: false
      name: false
      service: timer.start
      param: duration
      state: duration
      border: true
      min: 0
      max: 1800
      step: 300
      unit: time
      card_mod:
        style: |
          ha-card {
          margin-top: 10px
          }
  - type: conditional
    conditions:
      - entity: switch.smart_plug_2_switch
        state: 'on'
      - entity: timer.heater
        state: active
    card:
      type: custom:timer-bar-card
      entities:
        - timer.heater
      sync_issues: ignore
      compressed: true
      bar_radius: 4px
      text_width: 40px
      layout: full_row
      bar_foreground: orange
      icon: mdi:stop-circle
      tap_action:
        action: none

I can share the script too if someone’s interested.

9 Likes

Oh right. What a stupid mistake I made :sweat_smile:
Thanks for noticing this! :slight_smile:

Yes please!

Glad you like it! :slight_smile:

The script:

alias: Bed warmer
sequence:
  - if:
      - condition: template
        value_template: |
          {{is_state(bed_side,'on')}}
    then:
      - service: switch.turn_off
        data: {}
        target:
          entity_id: "{{bed_side}}"
        enabled: true
      - service: timer.cancel
        data: {}
        target:
          entity_id: "{{timer}}"
    else:
      - service: switch.turn_on
        data: {}
        target:
          entity_id: "{{bed_side}}"
      - service: timer.start
        data: {}
        target:
          entity_id: "{{timer}}"
mode: parallel
icon: mdi:car-seat-heater
max: 5

Example script call:

action: call-service
      service: script.bed_warmer
      data:
        bed_side: switch.smart_plug_2_switch
        timer: timer.heater

And automation:

alias: Bed warmer - timer
description: ""
trigger:
  - platform: event
    event_type: timer.finished
    event_data:
      entity_id: timer.heater
    id: Heater
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id: Heater
        sequence:
          - repeat:
              until:
                - condition: state
                  state: "off"
                  entity_id: switch.smart_plug_2_switch
              sequence:
                - service: switch.turn_off
                  data: {}
                  target:
                    entity_id: switch.smart_plug_2_switch
                - delay:
                    hours: 0
                    minutes: 0
                    seconds: 5
                    milliseconds: 0
mode: parallel
max: 5

It’s separate to prevent reaching limit of parallel runs when handling multiple timers.
I use a while loop in the automation because I had some issues with zigbee plugs not reacting to a single command. If your devices are more reliable/less critical, you can do without it :wink:

6 Likes

I have updated the card code from my post with a small card_mod entry which will center the numberbox card :slight_smile:

3 Likes

Thanks @calisro and @Tsar for the above - Im an absolute beginner at this complexity of template and the above template has definistely got me into the ballpark of my use-case

I would like to ask though, if the timer is set to more than 24 hours this template only shows the hours remaining as timer-24 (eg: 36 hour timer shows 12:00:00)

How can this be alleviated to show the total hours (36:00:00)

This is awesome and exactly what I was looking for!! Thanks so much for sharing!
I hope this sort of functionality will be built in / simpler in Home Assistant someday… But for now this does it :smiley:

1 Like

Thanks so much for this code. I’m using it to display the time of my ‘rain delay’ timer for my irrigation system. It works great for that, but it would be just a little nicer if once it got to 0 I could then display a word like ‘idle’ or ‘off’ or something.

Is that possible?

{% set t = 'timer.kitchen_auto_off_timer' %}
{% set state = states(t) %}
{% set finish = state_attr(t, 'finishes_at') %}
{% set remain = state_attr(t, 'remaining') %}
{% set seconds = (as_timestamp(finish,0)-as_timestamp(now()))|int %}
{% set left = iif(finish == None,iif(remain == None,0,as_timedelta('0 ' ~remain).seconds),seconds) %}
{% if left == 0 %}
  Off
{% else %}
  {{ left| timestamp_custom('%H:%M:%S', 0) }}
{% endif %}
3 Likes

I am still not getting what am I missing to accomplish remaining time of timer to be shown in a for ex.: mushroom template card.
Current configuration:

  • Configuration.yaml:
automation: !include automations.yaml
timer:
  eldes:
    duration: "00:10:00"
  • automations.yaml:
- trigger:
    - platform: time_pattern
      seconds: "/1"    
  sensor:
    - name: timer_eldes_remaining
      state: >
        {% set t = 'timer.eldes' %}
        {% set state = states(t) %}
        {% set finish = state_attr(t, 'finishes_at') %}
        {% set remain = state_attr(t, 'remaining') %}
        {% set seconds = (as_timestamp(finish,0)-as_timestamp(now()))|int %}
        {% set left = iif(finish == None,iif(remain == None,0,as_timedelta('0 ' ~remain).seconds),seconds) %}
        {{ left| timestamp_custom('%H:%M:%S', 0) }}
  • lowelace:
type: custom:mushroom-template-card
primary: Remaining time
secondary: |-
  {% if is_state("timer.eldes", "active") -%}
  {{ states('sensor.timer_eldes_remaining', 'remaining') }} 
  {%- else -%}    
  {%- endif %}

Please help… Spent already 2 days on that… :frowning:

sensor.timer_eldes_remaining cannot even be found under entities.

Create the timer in the interface.
What you put in automations.yaml should actually be in template.yaml.
And this is how you get the info: {{ states(‘sensor.timer_eldes_remaining’) }}

I hope that makes sense.

Hi, I’m also a newbie to HA.
I’m lost where everything goes.

I create a template sensor using the helpers with this code:

{% set t = 'timer.stairs_timer' %}
{% set state = states(t) %}
{% set finish = state_attr(t, 'finishes_at') %}
{% set remain = state_attr(t, 'remaining') %}
{% set seconds = (as_timestamp(finish,0)-as_timestamp(now()))|int %}
{% set left = iif(finish == None,iif(remain == None,0,as_timedelta('0 ' ~remain).seconds),seconds) %}
{{ left| timestamp_custom('%H:%M:%S', 0) }}

At the dashboard:

type: custom:mushroom-chips-card
chips:
  - type: entity
    entity: person.junior
  - type: entity
    entity: sensor.lights_on_count
    icon: mdi:lightbulb-group
  - type: entity
    entity: binary_sensor.stairs_door_sensor_contact
    icon: mdi:door
    use_entity_picture: false
    name: Stairs Door
    content_info: name
  - type: template
    entity: timer.stairs_timer
    icon: "{{ 'mdi:timer' if states('switch.stairs') == 'on' else 'mdi:timer-off' }}"
    icon_color: "{{ 'green' if states('switch.stairs') == 'on' else 'white' }}"
    content: >-
      {{ state_attr('timer.stairs_timer', 'remaining') if
      states('switch.stairs') == 'on' else '' if states('switch.stairs') not in
      ['on', 'off'] else 'Idle' }}

But the time wont update at all.

I don’t know where the Time Trigger goes.

Did you get working?


On the bottom bar I want to display the timer remaining instead of Idle.

Home-Assistant-01-06-2025_03_27_PM
The 0:01:30 doesn’t update.

I just found this discussion and need some help. I posted my situation on a post bellow and appreciate any help.

Did you add the trigger ?

Here is an example :

- trigger:
    - platform: time_pattern
      seconds: "/1"
  sensor:
    - name: timer_countdown_streaming_camera_garagedeur_remaining
      state: >
        {% set t = 'timer.countdown_streaming_camera_garagedeur' %}
        {% set state = states(t) %}
        {% set finish = state_attr(t, 'finishes_at') %}
        {% set remain = state_attr(t, 'remaining') %}
        {% set seconds = (as_timestamp(finish,0)-as_timestamp(now()))|int(0) %}
        {% set left = iif(finish == None,iif(remain == None,0,as_timedelta('0 ' ~remain).seconds),seconds) %}
        {{ left| timestamp_custom('%H:%M:%S', 0) }}  

When I try to add the Trigger part of the code on the Helper Template Sensor I got an Error.

[quote=“Tsar, post:40, topic:433056”]

- trigger:
    - platform: time_pattern
      seconds: "/1"
  sensor:
    - name: timer_countdown_streaming_camera_garagedeur_remaining
      state: >

You must create a new file templates.yaml and put it in there.

In you configuration file you have to make this reference :

template: !include templates.yaml
1 Like

Thank you @Tsar, is working now.