Is there any way to see remaining time on a timer component?
I’ve got one tied to a motion sensor, each time the sensor detects motion it should restart the timer. I’ve had a few bugs / unexpected behaviour with it so being able to see the remaining time would help me to ensure the timer is getting extended correctly.
I was also hoping I could use timers to display countdowns in my UI until things happen, but since timers don’t expose the remaining time it would have to be done via an entirely separate mechanism.
I don’t know if we can get the timestamp of a service call? It would be possible then to use the “timer.start” to determine the start time and then display the remaining time.
Then just doing “(start time + duration) - current time” should give us the remaining time.
I did something similar like that in the PR of the component: https://github.com/home-assistant/home-assistant/pull/9889
It’s using the counter-component to display the elapsed seconds. This can also be done in reverse by setting the initial counter value to the total duration and then decrementing every second.
The key-thing to note about the timer is, that for performance reasons it doesn’t update itself every seconds. Instead it just schedules the end-time, and as soon as HASS reaches that, it fires the finished-event. That’s why you have to calculate the time yourself. Which is ok for most scenarios, since timers are something that happens in the background.
But I agree, that for debugging purposes it’s good to see the remaining time. I have planned to build an UI for the timer. I’m dodging that though since the frontend part of HASS is seeing some changes, and I haven’t yet figured out what’s the right way to develop anything for the UI.
Anyways, this is how I calculate the elapsed time:
If the timer just exposed the scheduled end time that would be sufficient and feels like it could be implemented without affecting performance (not having looked at the code at all ).
Those actually once were part of the attributes of the entity. They however got stripped out because essentially the timer is about durations with flexible start- and end-times. Lets say you have a timer with a duration of 2 minutes, and while it’s running it has been paused. At this time the end-time is uncertain, and the start time would indicate a certain amount of time has passed, which is not the case if the 2-minute timer has been paused for an hour.
Additionally, if you continue a paused timer, the end-time would be clear. But what would be the start-time? When it originally started or the time it has been continued? The first would make the total duration longer than it should be, the continuation-time would be less than the configured duration.
Essentially start and end only make sense for a running timer, which in most cases won’t be needed and adds unnecessary complexity. If it’s really needed, the start time could be calculated by looking at when the state changed from idle / paused to active. The end time would be the start-time plus the remaining time, which is available as an attribute of the entity.
I restart my timer each time my motion sensor detects motion, so as I understand it there is no way for me to actually calculate remaining time from the timer component. The start time could be an hour in the past for my 15 minute timer because there has been constant motion.
I could start looking at when my motion sensor was last triggered and calculate time remaining from that, but at that point I’m not sure why I’m using a timer component. It would be less moving parts to ditch the timer completely and just use automations that care about duration since state change like I used to.
Using automations is legitimate in a lot of cases. If you use your motion-timer to turn on lights and always want to extend (or rather reset actually) the duration by a static time, then the classic way is totally fine. The thing about the timer is, that it can have dynamic durations. So for example after 5 motion events leave the lights on for 10 instead of 5 minutes because apparently there is some static activity at that location. Dynamic timers, as far as I know, are not possible with regular automations and scripts.
Another key difference is, that timers have two different ways to end: timer.finished and timer.cancelled. That would be useful for a countdown of an alarm system. If the front door has been opened you could start a 60 second timer. Via some method you authenticate, and with that call the timer.cancel service and the timer fires the timer.cancelled event, which could start some TTS that welcomes you home. If instead the timer expires by itself, you can use the then fired timer.finished event to ring the siren.
Yes, that could be replicated with a ton of automations and scripts. But by using the timer this becomes very intuitive and does the same in a lot less code.
Of course I agree, that a visual representation of the remaining time can be useful in some cases (that’s why I will take care of that when I figure out how UI works). But I would say most of the timers people are using are just running in the background doing their thing. Like the motion driven lights. When I trigger those lights I don’t really care what’s the exact remaining time as long as the lights turn off after the configured amount of time.
PS: The start-time gets updated with every call of the timer.start service. Even if the timer was already running. So you won’t have a start-time that’s two hours ago.
Ah, I didn’t realise the start-time restarted. Cheers that should be enough to figure out what I need.
Edit: Ah I see, you mean using the automation you have above you track the start time?
I was using the timer instead of just a traditional automation because I check if the timer is already running when motion is detected to turn on the lights to a certain scene. It stops HA resetting the scene every time motion is detected.
With the automation above I simply count the seconds since the timer has started. That’s easy with a static timer. So lets say your timer is configured for a duration of 90 seconds. I then use a counter with a initial value of 0, which corresponds to the the idle state.
Then, in whatever way, the timer is started. We now use an automation that tracks the state of the timer. If it has become active, we use another automation (based on time, every second), that increments the counter. That way it will increment the counter as long as it is active. At the end we reset the counter to 0 as soon as the timer has finished. We could also include the timer.cancelled event here. It’s ust a demo.
And you could do the same thing in reverse. I once did that with an input_number. Whenever the timer has started, the value of the input_number would be decremented every second. And when it’s finished, the set_value service would be used to reset the entity to it’s initial starting time. That’s what I would to for something like a visual representation of a countdown-timer of an alarm system.
Besides that, you don’t have to do this with seconds. Instead you can have a minute based timer and just increment / decrement every minute. I just use seconds here because of the instant feedback.
Regarding the controlling of scenes:
Ideally you would have an automation based on the motion event, which would trigger the timer. Over and over again if needed. The last_update will change. What will NOT change is the state of the timer-entity. It will remain active as long as the timer is running. So all you would need to control a scen was an automation that checks if the timer becomes active. If yes, toggle the scene. If the timer gets restarted due to motion, it won’t toggle the scene again since the timer already is active. You could then have two further automations for timer.finished and timer.cancelled. So maybe cancel the timer if the phone rings (turn light back to normal), or let the timer finish and ease in the lighting more slowly to wake up. Not the best example, but that’s would could be done. And all without a gazillion scripts with delays and starting and stopping and what not.
The key here is, that, in my opinion, the timer ist just more natural and intuitive to use. I’m a HASS user for over a year. Still I always worked around using scripts with delays because it feels like re-inventing the wheel for something that should be super-easy. With the scripts you can build your own “clock” by adding every single gear in exactly the way you like. But most of the time you just want to say “do x for y minutes”. Which I couldn’t do out of my head with scripts because they are so complex. Beginners would struggle even more. Here the timer is an easy solution for a quite common task.
Hey Guys, i see the topic is nearly diminished but i got to the same struggle as you all and thought i share my solution with you. its not a perfect one, i wanted cooler stuff but hadn’t had the ability; My Solution can count down with every Minute you insert, but it doesn’t count as time running down - perhaps anyone has an idea how to integrate the time sensor here.
Aim of my approach was to build an timer that shuts down all lights and media every night and i wanted to have an visual feedback of the running timer, after a while using my first timer i got to that last point
First things first:
input_boolean:
timer:
name: timer
initial: off
input_number:
timer:
name: Timer
min: 1
max: 180
step: 1
mode: slider
script:
timeron:
sequence:
#### Turn on Timer based on input_number.timer
- delay: '00:{{ states.input_number.timer.state | int }}:00'
- service: homeassistant.turn_off
entity_id: "something to turn off"
#### Set timer in Normal Position
- service: input_number.set_value
data:
entity_id: input_number.timer
value: 45.0
- service: input_boolean.turn_off
entity_id: input_boolean.timer
timeroff:
sequence:
- service: script.turn_off
entity_id: script.timer
#### The Important Part taken from the first Post here in this Topic
automation:
- alias: timerstarted
trigger:
platform: time_pattern
minutes: '/1'
condition:
condition: state
entity_id: 'input_boolean.timer'
state: 'on'
action:
service: input_number.decrement
data:
entity_id: input_number.timer
- id: 'Timer'
alias: 'Timer'
hide_entity: False
trigger:
platform: state
entity_id: input_boolean.timer
to: 'on'
action:
- service: homeassistant.turn_on
entity_id: script.timer
- service: homeassistant.turn_on
entity_id: automation.timerstarted
- service: automation.trigger
entity_id: automation.timerstarted
- id: 'Timer Off'
alias: 'Timer Off'
hide_entity: False
trigger:
platform: state
entity_id: input_boolean.timer
to: 'off'
action:
- service: homeassistant.turn_on
entity_id: script.timeroff
- service: homeassistant.turn_off
entity_id: automation.timerstarted
I had an issue trying to find the custom button card and getting that to work so I just used an entities card.
I don’t like how scripts show up in an entities card with the word execute rather than having a button, but it works.