WTH are timers so useless?

Things that are realy hard now:

  • Trigger an automation X minutes before a timer ends.
  • Have a condition that checks whether there are atleast/atmost X minutes to go for a timer.
  • Ensure there are atleast/atmost X minutes remaining on the timer.
  • Add/remove X minutes to a timer.

Trigger an automation X minutes before a timer ends.

Turn 3 lights off after an hour, but not all at the same time, so we’re not in the dark suddenly.
Now I have to start a timer which runs for 60 minutes, and another that runs for 65 and another that runs for 70 minutes; or have a timer for 60 minutes and two for 5 minutes, either way; you need 3 timers for a single timed event.

Have a condition that checks whether there are atleast/atmost X minutes to go for a timer.

User presses a button: thing happens, unless the timer is almost up, then we want another thing to happen.

Ensure there are atleast/atmost X minutes remaining on the timer.

Open a door: light turns on for 1 minute, press a button light turns on for 5 minutes. Open a door while the 5 minute timer is running: light shouldn’t go out after just 1 minute.

Add/remove X minutes to a timer.

Press a button: light goes on for 5 minutes, wait a minute (4 minutes to go), press the button again, light stays on for 9 minutes.

Edit:

Proposal

Add new services for timers:

timer.add / timer.subtract

action:
  - service: timer.add
    entity_id: timer.my_timer
    data:
      duration: "00:05:00"

Would add or subtract 5 minutes to/from the timer. Alternatively only add the timer.add service and have it support negative values.

timer.atleast / timer.atmost

action:
  - service: timer.atleast / timer.atmost
    entity_id: timer.my_timer
    data:
      duration: "00:05:00"

Would set the timer to atleast or at most the specified duration.

Add a timer condition, like the numeric_state conditions.

Condition passes if there is atleast 5 minutes remaining:

condition:
  - condition: timer
    entity_id: timer.my_timer
    atleast: "00:05:00"

Condition passes if there is atmost 5 minutes remaining:

condition:
  - condition: timer
    entity_id: timer.my_timer
    atmost: "00:05:00"

atleast and atmost would support the same values as for in the state platform, so a time-string, a number of seconds or a hours/minutes/seconds object.

For consistency we may want to shadow the state condition to the timer condition too:

condition:
 - condition: timer
   entity_id: timer.my_timer
   state: idle | active | paused

Make the timer into a proper trigger platform in stead of having to use the event platform:

trigger:
  platform: timer
  entity_id: timer.my_timer
  state: started | paused | finished | cancelled | restarted

Would be analogous to

trigger:
  platform: event
  event_type: timer.started
  event_data:
    entity_id: timer.my_timer

And this would add the new functionality:
This would trigger when the timer has 10 minutes remaining:

trigger:
  platform: timer
  entity_id: timer.my_timer
  remaining: "00:10:00"

This would trigger when the timer has been running for 10 minutes.

trigger:
  platform: timer
  entity_id: timer.my_timer
  elapsed: "00:10:00"

remaining and elapsed would support the same values as for in the state platform, so a time-string, a number of seconds or a hours/minutes/seconds object.

What is your proposal to make all of those things easy to achieve?

FWIW, many of the things you mentioned can be achieved using templates. However, I suspect templating is what you referred to as “really hard now”. So what do you propose should be modified/enhanced to support all of the things you mentioned, without employing templates? For example, do you propose that a timer entity should have more attributes? The Time Trigger should support a timer entity’s attributes?

There is nothing stopping anyone from canceling or pausing a timer so one minute from time ends of a timer is not defined.

I think a better and easier approach is to set a datetime of when the last action should be carried out then you can use offset (if I recall correctly) from the datetime backwards to -1 minute

I use timers extensively to control my lights. I implement a grace period for my lights where they go to 50% brightness for a period of time before turning off completely. I do this by having a delay in the automation that is called to turn off the lights when the timer expires.
Rather then making timers more complicated think of them as a building block for making a lights automation work exactly how you want.

Good questions! I’ve edited my post with a concrete proposal :slight_smile:

I agree that we need easy to use building blocks. I also believe that having better timers would greatly reduce complexity in some automations. Time is an integral part of our lives, so it makes sense to have good time-building blocks.

Let’s take your example:

The grace period as you described works fine, but if you want to stop your lights for going out completely as soon as you notice the 50% brightness “warning”, things get a lot more complicated. Now you need to check the state of the lights after the delay, which requires you to know the original brightness. All events that could cancel the lights going out would then need to increase the brightness to full to stop the lights from going out. All doable, but messy imho.

Having more timer functionality would streamline this a lot: dim the lights 5 minutes before the timer ends. All events that should cancel the lights from going out just cancel the timer. Add a cancelled trigger to the timer that restores the lights to full brigtness. To me atleast this feels way more accessible, less “computer programmy”.

I’m also not advocating we get rid of the delay it’s ok for there to be more than one way to do things.

Every room that is controlled by the light automation has a switch as well that enables the occupant to override what the light automation is doing.
That is an additional building block for me to refine how the automation works, rather than put all the intelligence in a timer. For large or communal rooms like a lounge I might have 2+ motions sensors and switches for convince.
I have 3 automations that deal with switches, motion detectors and expired timers. All parameters such as how long the grace period is or brightness/colour of the lights are controller by input_* helpers

Looking at your examples that would require multiple timers under the hood managed by HA which could significantly increase the load on the system.

Being able to edit the time on a timer would be great while it’s running. At the moment I use this to add time to a timer, it’s changed a bit over time but this adds 5 minutes, there is a bit of the maths that could be made cleaner! Essentially you need to pause the timer, and then use something like the below to add time to it as part of a follow-up start action (maybe there’s a better way):

service: timer.start
data_template:
  duration: >
    {% set t =
    as_timestamp(strptime(states.timer.my_timer.attributes.remaining,'%H:%M:%S'))
    %}

    {% set g = ((t--2208988800)-3600+300)|timestamp_custom ('%H:%M:%S') %}

    {{g}}
target:
  entity_id: timer.my_timer

1 Like

The timer.start service accepts a duration as an argument. So to my understanding you could just keep on (re)starting the timer by all kinds of triggers, without it ever emmitting the timer.finished event. :man_shrugging:

Edit: just realised that was just posted above. :sweat_smile:

Automation mode restart is great for motion sensor timers.
For motion sensor lights I use trigger, on, delay, off. With automation mode restart, the delay is restarted everytime the motion sensor is triggered. This is great as it keeps the light on while the area is occupied without having to have a very long delay, so it turns off relatively quickly when the area is empty.

1 Like

Glad I saw this post of yours. It was exactly what I was trying to do. I was just over thinking it.

So is this a service you created and you then call this service instead of the default or are you modifying an existing service? This is just on the edge of what I’ve played with so far.

Sorry for the late reply over the Christmas break.

So in my case, this is done as two scripts. We have an electric blanket which gets triggered in winter based on outside temperature when we are heading to bed! I have two buttons which trigger scripts to add or subtract 5 minutes from the timer which turns off the blanket when done. First, a call is made to pause the timer (otherwise the start command gets ignored), then a call to start the timer with the new duration using the code I posted above, here’s a screenshot of the script actions if its helpful.

1 Like

I’m fascinated how few people mind that the countdown timer doesn’t show a remaining countdown time in state, nor even atribute, but only if it’s active or not. It’s so illogical, that I would like to meet the guy who did it. :slight_smile: Imagine you get task to create timer and you do not think the remaining time is most relevant. I´m sorry, this was too much to me.

Before it was released it actually had that. But this part of the integration was rejected, as with every second the state changes, which would result in a lot of state changes being stored into the history. That’s inefficient for something, that often times is just doing its work in the background. Few people stare at their dashboards to see the remaining time of a timer that’s just used to turn off a light after some time.