Help with time helper calculations please

I was thinking that a simple calculation involving three time helpers would be straighforward, and I’m guessing with the correct knowledge it is!

I’m trying to achieve this start_time = end_time - offset, then use start_time to trigger an automation. The times don’t change during any one day so I’d like this calculation to be done around 00:20 to avoid any daylight savings issues as the earliest start time could be 00:30 GMT/UTC. Offset is limited to 7 hours in the dashboard.

I have three date_time helpers and they were setup as time. Currently input_datetime.heated_towel_rail_on_time is set to 05:00:00, input_datetime.economy_7_off_time_utc is 07:30:00 and input_datetime.heated_towel_rail_on_hours is 03:00:00 the last two helpers are set in dashboard.

For my use I don’t don’t think it matters if this a string calculation or a time calculation as long as it’s consistant but I’m not getting the type correct for the syntax I’ve used and not sure what to try, I’ve read many posts!

This is the code I have that doesn’t work, but I’ve been through many iterations and am about to turn to alcohol!!! in the afternoon!!!

alias: Reset Daily Actions
description: ''
trigger:
  - platform: time
    at: '0:20:00'
condition: []
action:
  - service: input_boolean.turn_off
    data: {}
    target:
      entity_id: input_boolean.morning_actions
  - service: input_datetime.set_datetime
    target:
      entity_id: input_datetime.heated_towel_rail_on_time
    data:
      time: >-
        {{ (input_datetime.economy_7_off_time_utc) -
        input_datetime.heated_towel_rail_on_hours }}
mode: single

This currently gives me a “Error: Error rendering data template: UndefinedError: ‘input_datetime’ is undefined” error but as I said I’ve tyied myself in knots with type mismatch and syntax already today

An enhancement is to set input_datetime.economy_7_off_time_utc to UTC and NOT local as this time does not change with DST but the basics need to be correct first!

Yours
Pained of Bristol

This is a way to add helper time to another helper time for todays date.

{{ today_at(states("input_datetime.<start_time>")) + as_timedelta(states("input_datetime.<offset>"))}}

One can also to the same with just the time of course

{{ as_timedelta(states("input_datetime.<start_time>")) + as_timedelta(states("input_datetime.<offset>")) }}

See also the Time section here:

Change time to timestamp and replace your template with the one shown in the following example:

  - service: input_datetime.set_datetime
    target:
      entity_id: input_datetime.heated_towel_rail_on_time
    data:
      timestamp: >
        {{ (today_at(states('input_datetime.economy_7_off_time_utc'))
           - as_timedelta(states('input_datetime.economy_7_off_time_utc'))).timestamp() }}

@123 Thank you! Don’t suppose you could do brief explanation of that formula/syntax? I did try using this syntax states.input_datetime.economy_7_off_time_utc but I continued to get errors. What I hadn’t tried (or found) is the today_at or as_timedelta or .timestamp(). I don’t like just doing stuff without some kind of idea of what’s going on!

Puting this into the Developer Tools, template I get a unix timestamp, which is the correct time of day. I’ve ammended the automation and lets see what happens!

That won’t report the input_datetime’s value.

This will:

states.input_datetime.economy_7_off_time_utc.state

but you can’t use it in a subtraction, like you did in your original example, because the value it reports is a string. You can’t subtract string values.


today_at returns a datetime object. If your input _datetime’s value is 07:30:00 then today_at returns a datetime object set to today at that time. You can do time/date arithmetic with datetime objects.

as_timedelta returns a timedelta object. If your input _datetime’s value is 03:00:00 then as_timedelta returns a timedelta object of 3 hours. It can be used to offset a datetime object (i.e. add/subtract it to/from a datetime object)

@123 Now that really helps! I was getting myself in knots, I was intending to use datetime but I was actually using strings.

That’s were I lack the knowledge, but I’m getting there!

Thank you for the explanation

1 Like

Finally with some further help, I set a time helper to when my cheap energy finishes, this time is in GMT/UTC, this will only change if my supplier changes and this time is changed. I set another helper that specifies how long I (the Mrs tells me) wants the rail to be on. This formula then work out the time, in local, taking into account daylight savings, BST for me. This template seems VERY complicated for what I thought was going to be a straightforward process.

Anyway, if anybody else encounters a similar issue here’s the solution I’ve arrived at with help and hopefully it will help others. OR, if someone has a simpler more eligant solution I’m (really) open to ideas!

service: input_datetime.set_datetime
target:
  entity_id: input_datetime.heated_towel_rail_on_time
data:
  timestamp: |-
    {{ (
      today_at(state_attr('input_datetime.economy_7_off_time_utc','timestamp') |
        timestamp_custom('%H:%M:%S', local=True)) -
      as_timedelta(states('input_datetime.heated_towel_rail_on_hours'))
    ).timestamp() }}

The complicating factor is your input_datetime contains a time in UTC. Home Assistant assumes a time-only input_datetime contains time in your local time zone. That’s a fair assumption because one normally uses a time-only input_datetime to specify a local time (for use by, for example, a Time Trigger).

In your case, it contains the time in UTC so, to accommodate the needs of today_at (which assumes the supplied time is local) it must first be converted from UTC to local.

You may wish to post a Feature Request to have today_at optionally support UTC time. For example, if 03:00 is in UTC and not local, then this would handle it correctly:

today_at('03:00', local=false)

The default for the local option would be true (meaning the supplied time is local) but if the local option is included and set to false the supplied time would be handled as UTC.

Whether the Feature Request gets implemented or not depends on how useful the author of today_at (petro) believes it to be. After all, using UTC time is an edge-case; local time is what is most frequently used.

What I’ve leaned so far on my HomeAssistant journey, is that what I anticipate are the easiest things turn out to be the most difficult and the what I assume to be hardest turn out to be the most straightforward.

I can remember the most difficult part of doing time calculations, when I was a mere whippersnapper, was finding out what each clock tick represented for the particular hardware in use!