Get difference from now() to last changed in minutes

Hi all,

I assume that I am overseeing something but I simple cannot get my head around how to accomplish this: I want that show the difference between now() and last_changed of a sensor only in minutes.

Now, this

{{ (as_timestamp(now()) - as_timestamp(states.binary_sensor.zugaengeeg.last_changed)) }}

results in a number that is neither minutes nor seconds nor milliseconds, so I have no clue what to do with it.

Can someone point me in the right direction, pls.
thx,
Zavjah

The result of that template should be the number of seconds since the sensor last changed. Try it in the template editor: here’s mine with a sensor on my system:

It’s now 11:00 BST = 10:00 UTC, sensor changed at about 03:30 UTC, so 6½ hours = 390 minutes.

What does yours show?

Hello @Troon,

this is what I see in my template editor:

here is the code:

now: {{now()}}
as timestamp: {{as_timestamp(now())}}

last ch.: {{ states.binary_sensor.zugaengeeg.last_changed }}
last ch. as timestamp:{{ (as_timestamp(states.binary_sensor.zugaengeeg.last_changed)) }}

difference: {{ (as_timestamp(now()) - as_timestamp(states.binary_sensor.zugaengeeg.last_changed)) | timestamp_custom ('%H:%M:%S')  }}
diff as timestamp: {{ (as_timestamp(now()) - as_timestamp(states.binary_sensor.zugaengeeg.last_changed))}}
diff in minutes: {{ (as_timestamp(now()) - as_timestamp(states.binary_sensor.zugaengeeg.last_changed)) / 60 | int}}

From what I see, last changed of my device was app. 2h and 8 minutes ago, but the difference is calculated a hour less. Is this due to time zones? how do I compensate this?

thx,
Zavjah

By avoiding as_timestamp and using the datetime objects.

{{ (now() - states.binary_sensor.zugaengeeg.last_changed).total_seconds() // 60 }}
1 Like

It was actually 8 minutes 40 seconds ago once you allow for the timezones: 12:12:20 UTC versus 14:21:00 UTC+2. The calculation is correct.

The only issue there is your timestamp_custom, which should include local=False after the format as you’re using it for an absolute time difference (docs). That would then read 00:08:40.

Alternatively, follow Petro’s advice.

Hello @petro ,

I’ve done as suggested but the result is now only 21 minutes:

Single states show correct times but the difference seams to ignore what ever seeting and removes 2 hours from the result.

I have no clue what I am doing wrong.

@Troon: It seems time zones are messing up the result. Did I set up something wrong? Why is UTC only considered in the calculation but not in the date object of now() itself?

That result will be correct. I have a feeling you don’t understand timezones in the timestamps.

Your time for now is 15:51 in the +02:00 timezone.

last updated is 13:28 in the +00:00 timezone.

13:28 in the +00:00 timezone in the +02:00 timezone is 15.28.

15:51 - 15:28 is ~23 minutes.

Nothing is being messed up. now() is reporting time in your local timezone of UTC+2, and the sensor last_changed is reporting in UTC.

Because both of these times are “timezone-aware” — that is, they refer to their timezone — you can do calculations with them. From that screenshot, the difference is indeed about 23 minutes from 13:28 UTC to 15:51 UTC+2.

It’s all working fine as far as I can see. Have a look at the history chart for your binary sensor: how long ago does that say it last changed?

Hello @petro,
hello @Troon,

thanks for quick replies - I GOT IT :smiley:

1 Like

Hi @Troon

Thank you for signposting me here form another post.

You kindly provided me with this template to retrieve the time form my next alarm as ‘08:15 AM’ for use in a TTS message.

{{
    strptime(state_attr("sensor.matthew_new_p30_pro_next_alarm", "Local Time"),
    "%a %b %d %H:%M:%S %Z%z %Y").strftime("%I:%M %p") }}

I’m hoping to retrieve the amount of hours and minutes from ‘now’ to time of the next alarm to use them in the same TTS message, it shows the hours in this card but I can’t see where i can find the value to attempt to extract it.

2023-05-09_16h50_57

I’ve spent hours looking at it but really don’t know how I should be doing this. Please could you help?

Does this work in the template editor?

{% set s = (strptime(state_attr('sensor.matthew_new_p30_pro_next_alarm', 'Local Time'), "%a %b %d %H:%M:%S %Z%z %Y") - now()).total_seconds() %}
{{ "%dm %ds" % (s//60, s%60) }}
1 Like

Yes, almost, it shows the time left in minutes and seconds, ideally it would show days (if any) hours and minutes.

Replace the last line with:

{{ timedelta(seconds=s|int) }}
1 Like

That does this for my alarm set to 8:15 am tomorrow

and this for my alarm set to 8:15 am Friday

Show me:

{{ state_attr('sensor.matthew_new_p30_pro_next_alarm', 'Local Time') }}
{{ strptime(state_attr('sensor.matthew_new_p30_pro_next_alarm', 'Local Time'), "%a %b %d %H:%M:%S %Z%z %Y") }}

for your Friday alarm.