I need help with a trigger based on time minus a google commute sensor

I need to set a reminder action with google_say that gives me enough time to wrap up in the morning and leave for work. I have a commute sensor that has the dynamic time to work from my phone. I need to subtract that number from 8:20, my desired arrival time.

So something like this:

trigger:
  platform: template
  template_value: '{% if state( sensor.time ) > ( 8:20am - commute sensor ) %}true{% endif %}'
condtion:
  condition: state
  entity_id: group.jordan_devices
  state: 'home'
action:
yada yada

My problem is these values have a mix of numbers, strings and times, and I can’t simply subtract the sensor value from 30 since sometimes it’s more than 30 minutes, which would then make it 8:-03, not ideal. Any ideas?

1 Like

You could always use a template sensor like the one below. It will give you a sensor with the time as a decimal (ie 12:30pm = 12.50, or 7:45pm = 19.75).

- platform: template
  sensors:
    time:
      value_template: '{{(now().strftime("%H") | int) + (now().strftime("%M")|int / 60) | round(2)}}'

Then you can set your template_valute to:

'{% if states.sensor.time.state > ( 8.33 - ((states.sensor.drive_time_to_work.state) | int /60)) %}true{% endif %}'
1 Like

That is perfect! Thanks!

Did you get this to work?

I’m curious because when I try I run into a an issue trying to evaluate the math. The error returned indicates that it is trying to subtract a “int” from a “float”.

What I’m thinking about trying is to convert that into a string, but I don’t know if that will work or not. If you could show a working bit of code, I would greatly appreciate it!

This trigger works for me.

trigger: 
  platform: template
  value_template: "{{ ((now().strftime('%H') | int) + (now().strftime('%M')|int / 60) | round(2)) > ( 8.33 - ((states.sensor.commute.state) | int / 60)) }}"

You could separate out the ((now().strftime('%H') | int) + (now().strftime('%M')|int / 60) | round(2)) into its own template sensor, but I don’t typically add sensors like that unless I need the code used more than once.

1 Like

Nice!

I tried converting mine to be a string and it was failing. This seems to be spot on so thanks for providing that.

This is where mine was failing:

'{% if states.sensor.time.state > ( 15.3 - ((states.sensor.dad_work_to_kids.state) | int /60)) | string %}true{%endif%}'

It would evaluate correctly, but kept firing needlessly and it only worked correctly once.

Thanks again!

I don’t quite understand this. Almost…but not quite.

So I think I get this part

trigger: 
  platform: template
  value_template: "{{ ((now().strftime('%H') | int) + (now().strftime('%M')|int / 60) | round(2)) > ( 8.33 - ((states.sensor.time_to_work.state) | int / 60)) }}"

is the 8.33 basically 8:20am?

So the trigger will fire if the current time is greater than 8:20am - the google commute time. So if the commute time was 20 minutes, it would fire at 8am or 8.00, is that basically the gist.

That’s what it looks like to me. He’s converting minutes into hours. The google travel time calculator returns minutes always. So he converts both values into hours and performs the check. 0.33*60 is 19.8. So to simplify the if check:

now() > ( 8:19:48 - travel time )

because .33 * 60 is 19.8 and .8*60 is 48, getting 8:19:48.

Thanks for the review as well

So I’m going to try this

- alias: "Notify me when its time to leave for work"
  trigger: 
    platform: template
    value_template: "{{ ((now().strftime('%H') | int) + (now().strftime('%M')|int / 60) | round(2)) > ( 8.33 - ((states.sensor.time_to_work.state) | int / 60)) }}"
  condition:
  - condition: state
    entity_id: binary_sensor.workday
    state: 'on'
  action:
  - service: notify.ios_my_iphone
    data:
      message: "Based on current traffic, you have 10 minutes to leave if you want to be to work by 8:30am"
      title: "Time to Leave for Work"

Added a workday binary sensor to my configuration.yaml so it only runs on workdays

binary_sensor:
  - platform: workday
    country: US
    workdays: [mon, tues, wed, thu, fri]

But this does leave me with a quick question about resources? How often is this “calculating” the times, every minute? Every time the google sensor changes? Both? Is this possibly a resource hog? If so, maybe have another automation to turn these off for most of the day, then turn them on about an hour or so before work?

I’ve always had that question myself and I cannot definitively answer that for you. The way I have understood template sensors to work is that it updates when an entity ID inside the value_template updates. This isn’t template sensors, this is triggering but I would assume it’s similar. Anyways, the only state device that is listed there is the sensor.time_to_work. So I believe it will evaluate the trigger only when that object updates. Don’t hold me to that though as this has always been a bit of a mystery.

1 Like

After running this for a few weeks, I can say with a pretty high level of confidence that you are correct in your assumption about only triggering when the sensor updates.

This automation was a fun project, so I have not come back to it to try to tweak it, but overall it’s not too reliable. For example my values seem so stay pretty stable most of the time, so … usually it does not trigger, so i dont get the “leave in the next 10 minutes message”. I actually forgot about this for a while. I think I’ve only had it trigger one or two times. haha.

Need to have some sort of other item to trigger on.

Still want to send a message when I have to leave within 10 minutes to get to work on time.

hmm, maybe run this every minute between certain times of the morning? I’ll play around and see what I come up with.

You could incorporate the date_time sensor into your value_template. This would force updates as the object is always updating.

sensor:
  - platform: time_date
    display_options:
      - 'time'

Thats a great idea. I actually already have the sensor set up, just not using it for anything.

Like this?

 value_template: "{{ (((states.sensor.time.state) | int / 60) | round(2)) > ( 8.33 - ((states.sensor.time_to_work.state) | int / 60)) }}"

Does this look like it should work to you? It has not worked yet, so I can only assume it’s not right, haha.

Here’s the full automation.

- alias: "Notify me when its time to leave for work"
  trigger: 
    platform: template
    value_template: "{{ (((states.sensor.time.state) | int ) | round(2)) > ( 8.33 - ((states.sensor.time_to_work.state) | int / 60)) }}"
  condition:
  - condition: numeric_state
    entity_id: sensor.ha_runtime_in_minutes
    above: 1    
  - condition: state
    entity_id: binary_sensor.workday
    state: 'on'
  action:
  - service: notify.pushbullet_notifications
    data:
      message: "Based on current traffic, you have 10 minutes to leave if you want to be to work by 8:30am"
      target:
      - email/[email protected]
      title: "Time to Leave for Work"

edit: nevermind, I think it was the/60 for states.sensor.time.state. That was left over from when I had minutes and hours

Leaving this here for someone in the future

does states.sensor.time.state return a datetime? I don’t use that platform so I can’t test it in my templates section to help! I can add it when i get home but that won’t be for a few hours.

sensor.time just returns a time
ie.
12:20

so I believe that converting to an INT but not dividing by 60 like I did should convert

12:20 to 12.33, and I believe that will get it working. :slight_smile:
Thanks again

Although I do need to make this only run once a day, since it would be true pretty much all day from 8am until midnight. haha

Maybe use the last triggered from the automation

automation.notify_me_when_its_time_to_leave_for_work

It returns a value like this
2018-05-23T00:43:30.827118+00:00

I’d just need it to be not to be today

EDIT:

OK, looks like a value template like this might work to keep it from running again

condition: template
value_template: '{{ as_timestamp(now()) - as_timestamp(states.automation.notify_me_when_its_time_to_leave_for_work.attributes.last_triggered) | int > 64800 }}'

64800 is 18 hours

If my logic is correct. lets say this ran successfully at 8am
current time - timestamp is 60 (after one minute, which is when the trigger would trigger the automation)
Definitely less than 64800, so does not run at all.
at midnight, timestamp now would be 0 but the value of the last_triggered should still be growing. Sometime a few hours later, the value should be over 64800, but the trigger would not be true, so it would not run until it’s supposed to.

At least I think that basiclly would work. The main thing I’m unsure of is how midnight would be handled for the last_triggered

Sorry for the delay! I think you could solve this with a simple check:

  trigger: 
    platform: template
    value_template: >
      {% if 5 <= strptime(states.sensor.time.state,'%I:%M').hour <= 8 %}
        {{ ( now().hour + now().minute / 60 ) > ( 8.33 - states.sensor.time_to_work.state | int / 60) }}
      {% else %}
        False
      {% endif %}

This will force the value template to update every time sensor.time changes, but will only execute between 5 am and 9 am