Display remaining seconds of timer in frontend

Please don’t randomly tag people to bring them into foreign threads.

The best way to get a ‘countdown’ is to create a timestamp sensor when the timer end will occur. The UI will naturally count down to that timestamp but it will be in a long winded format. There may be other ways to handle this now that the main event loop is sub-second based as well. But these are uncharted waters in that regards.

This sensor should get the job done.

sensor:
  - platform: template
    sensors:
      timer_end:
        friendly_name: "Timer End"
        device_class: timestamp
        entity_id: timer.xxxxxxxxxxxxxxxx # <--- Your timer (and first line of template)
        value_template: >-
          {%- set duration = state_attr('timer.xxxxxxxxxxxxxxxx ', 'duration') %}
          {%- if duration in ['none', 'idle'] %}
            unavailable
          {%- else %}
            {% set h, m, s = duration.split(':') %}
            {% set n = now().timestamp() | list | map('int') %}
            {{ (n + h * 60 * 60 + m * 60 + s) | timestamp_custom('%Y-%m-%dT%H:%M:%S-00:00', False) }}
          {%- endif -%}

This will create a sensor that looks weird in the template section, but when you place it into an entity or entities card, it will update live.

2 Likes

Is there something missing in the timer_end Template Sensor because, based on a test, it doesn’t update live.

Before it can be tested, the template needs this minor adjustment because h, m, and s are strings:

(n + h|int * 60 * 60 + m|int * 60 + s|int)

When the associated timer begins its countdown, the Template Sensor displays the timestamp. However, during the countdown, it doesn’t change because its entity_id (the associated timer) maintains a constant state of active and none of its attributes change.

You can sort of see that from this screenshot where timer.my_timer is active (therefore in a countdown) but sensor.my_timer maintains the same value (5 minutes and 15 seconds) throughout the countdown.
Screenshot from 2020-07-24 09-28-56

Yep fixed the template

This shouldn’t matter. Adding device_class: timestamp with a timestamp causes the UI to treat the datetime as a relative time. So it should count up or down without state changes when placed into UI elements that utilize the timestamp deviceclass.

EDIT: This is how ‘last_updated’, ‘last_changed’, and ‘last_triggered’ works in the UI by the way.

EDIT2: The states page will just have the timestamp like you see in your pic.

EDIT3: The only question is, (haven’t tested) Does relative time work for future timestamps? My memory says yes.

I have no luck getting it to work.

Screenshot from 2020-07-24 10-07-09

That’s a screenshot of this:

views:
  - title: Timer Test
    badges:
      - entity: timer.my_timer
      - entity: sensor.my_timer_end
    cards:
      - type: entities
        title: ''
        entities:
          - entity: timer.my_timer
          - entity: sensor.my_timer_end
  • timer.my_timer displayed as a badge or in an entities card, displays its countdown.
  • sensor.my_timer_end displays the full duration in a badge and Invalid date in an entities card but never shows a countdown.

Regardless of whether timer.my_timer is idle or active, the state of sensor.my_timer_end remains fixed at my_timer's duration (5 minutes in this example).

Screenshot from 2020-07-24 10-14-02

Screenshot from 2020-07-24 10-16-16

Hmm, I just noticed this:

image

Mistake in my template? It should just be the timestamp but it also has the duration?

Aaargh! That’s my mistake! I was experimenting with the template and that leading time is a leftover (from the Template Editor) that I copied into the sensor’s configuration.

It works now and looks like this:

Screenshot from 2020-07-24 10-32-19

:man_facepalming:

Nice, I would be interested to see what happens with the template under 1 minute. Also what happens if you pause

Hmm. Paused with 1:41 remaining.

Screenshot from 2020-07-24 10-35-50

Even though the timer remains paused, the sensor continues to report the time difference and proceeds to say:
In 4 minutes
In 3 minutes
In 2 minutes
In 1 minute
In 59 seconds
etc

Screenshot from 2020-07-24 10-39-47

It then proceeds to “wrap around” and tell you how long ago the timer allegedly finished (even though it is actually still paused).

Screenshot from 2020-07-24 10-40-34

Upon starting the paused timer, the sensor resets itself to the original duration.
Screenshot from 2020-07-24 10-43-00

Until v113 my timers in buttons updated (showed a countdown) in the frontend but now they have reverted to the ‘old’ behaviour - when the view loses focus it stops updating until the browser is refreshed.

I have no idea if this similar to or related to the old bug…

Is it happening with core buttons also?

I don’t use any core buttons :wink:
I’ll set one up and check…

After some testing I can say, no it is not happening in core buttons.

Alright, please file a bug on github, I’m going to have a look :slight_smile:

Done, thanks.

Hi,
i’ve tried to show countdown with the code above but it’s something wrong:

Thank you so much for any help.
Regards,

Alessandro

Good work! But I don’t see definition of sensor.timer_duration_aircon_run that comes in automation. It’s time that’s determined in UI?

Yeah looks like I missed that one, I’ve updated the original post. Its an MQTT sensor.

1 Like

I tried to adapt this template for two different timers. But I can’t get it to work.
I have this in configuration.yaml:

timer:
  rasen:
    duration: '02:23:00'
    icon: mdi:timer-outline
  beete:
    duration: '01:20:00'
    icon: mdi:timer-outline

sensor:
  - platform: time_date
    display_options:
      - 'time'
      - 'date'
      - 'date_time'
      - 'date_time_utc'
      - 'date_time_iso'
      - 'time_date'
      - 'time_utc'
      - 'beat'
  - platform: template
    sensors:
      rasen_timer_end:
        friendly_name: "Rasen Timer End"
        device_class: timestamp
        entity_id: timer.rasen # <--- Your timer (and first line of template)
        value_template: >-
          {%- set duration = state_attr('timer.rasen', 'duration') %}
          {%- if duration in ['none', 'idle'] %}
            unavailable
          {%- else %}
            {% set h, m, s = duration.split(':') %}
            {% set n = now().timestamp() | list | map('int') %}
            {{ (n + h|int * 60 * 60 + m|int * 60 + s|int) | timestamp_custom('%Y-%m-%dT%H:%M:%S-00:00', False) }}
          {%- endif -%}
      beete_timer_end:
        friendly_name: "Beete Timer End"
        device_class: timestamp
        entity_id: timer.beete # <--- Your timer (and first line of template)
        value_template: >-
          {%- set duration = state_attr('timer.beete', 'duration') %}
          {%- if duration in ['none', 'idle'] %}
            unavailable
          {%- else %}
            {% set h, m, s = duration.split(':') %}
            {% set n = now().timestamp() | list | map('int') %}
            {{ (n + h * 60 * 60 + m * 60 + s) | timestamp_custom('%Y-%m-%dT%H:%M:%S+02:00', False) }}
          {%- endif -%}

Both timers work correct. I can start them an they show me the timestamp when finished.

The sensors are created but their states are unavailable.

What do I wrong?

try this

          {%- set duration = state_attr('timer.rasen', 'duration') %}
          {%- if duration in ['none', 'idle'] %}
            unavailable
          {%- else %}
            {% set h, m, s = duration.split(':') | list | map('int') %}
            {% set n = now().timestamp()  %}
            {{ (n + h * 60 * 60 + m * 60 + s) | timestamp_custom('%Y-%m-%dT%H:%M:%S-00:00', False) }}
          {%- endif -%}

Thank you very much. It was a step to the right way. The sensor is now updating … but … strange behaviour … the update is every 30 seconds. :slight_smile:
For example: If I use a 5 min timer, the display says 5 min left. After 30 seconds the display says 4 min left … and … hold on to your seat … another 30 sec later it jups to … 5 min. It goes so again and again. From 5 to 4 to 5 to 4 … Even when the timer is stopped. :face_with_raised_eyebrow: