Average travel time over multiple days

Hey folks. Here is my challenge.

I have an apex chart that I am using to show travel times from home to school. I have it showing current, yesterday, and day before, and yada yada. I can show multiple days on the graph with multiple line.

What I would like to do is show the current travel time with one graph line, and create a sensor to show the average travel time over the past week as another line.

I am no coding wizard by any stretch of imagination, so I spend much of time on Google. I am trying to create a new sensor with a template, but I just cannot figure out how to get ‘yesterday’s’ value.

What can I do to get the now() value for the duration for the yesterday variable? I then could expand on this to get 7-day average.

Sorry if I pasted the code incorrectly, trying to learn the etiquette here.

template: >
  - sensor:
      - name: "Average Travel Time to School"
        unit_of_measurement: "min"
        state: >
          {% set yesterday = state_attr('sensor.school','duration') | float %}
          {% set today = state_attr('sensor.school','duration') | float %}

          {{ ((yesterday + today) / 2) | round(1, default=0) }} min

Thank you very much!

You mean you need to get the sensors yesterday value?
I don’t think that is possible in yaml/template.
Perhaps you can save the values in a input text?

12;15;12;…

Should be fairly easy to just add one number at the end and pick the last 7 and place them in the input text.

Have you looked into the Statistics integration? Something like:

sensor:
  - platform: statistics
    name: "Average Travel Time to School"
    entity_id: sensor.school
    state_characteristic: mean
    precision: 1
    max_age:
      days: 7

Edit: Just noticed that you are using an attribute of the entity, not the state. I’m not aware of a way to directly use Statistics with attributes (but that doesn’t mean that it doesn’t exist), so you may have to throw that attribute into another sensor first, either with a Template Sensor or just an automation that updates a helper once a day.

1 Like

If the sensor is a travel time sensor then the statistics sensor won’t work.

The travel sensor will update as he moves closer to the school and thus skew the statistics.
I believe we need to capture a value just before leaving home or something like that.

Thanks for the responses. Really appreciate it.

I can use the state for the time instead of the attribute, since it is the same in this case. Was just trying some options.

The use case is in the morning to see if the travel time is trending worse or better compared to normal for two schools we have to take the kids to, which are not too close.

The statistics option is one that i looked at, but it has some restrictions from what I see with my use case. I will mess around with it some more and report back how I worked this out.

That said, what would the syntax be to subtract 24 hours from the current time value in a template?

I like where you’re going here. I can use the state itself instead of an attribute. What I want to do it get the average travel time at every point during the day. So at 10AM it might be 15 min, at 5PM it might be 30 minutes. When I added in this new sensor, it looks like it is pulling the average across all time periods. That is why I wanted to do something like:
((travel time now yesterday) + (travel time now 2 days ago) + (travel time now 3 days ago)) / 3 = average travel time at this current moment

I can then graph it. Right now, it shows the overall average time as a straight line.

I see, that is a bit more complicated than I originally understood it to be, and is going to lead to some complicated solutions. A couple ideas:

Hack It Together: Helpers

If you know that you’re going to be commuting around the same times every day, then you could just setup an automation to populate helpers at those times, one for each time (like 7am, 8am, 3pm, and 4pm). Then, use those to setup the statistics sensors. This feels a bit messy and relies on some consistency on your part, but would probably work just fine.

Dive in Deep

If you’re feeling like diving into the technical side of things, you could give History a read, and then the API documentation a read. Particularly, the history GET endpoint. I haven’t ever used this API myself, but it looks like it would be straightforward enough with something like:

{% for num in range(7) %}
  {% set time_period = (now() - timedelta(days=num)).isoformat() %}
  {% set url = "http://localhost:8123/api/history/period/" + ( time_period ) + "?end_time=" + ( time_period ) + "&filter_entity_id=sensor.school&no_attributes" %}
  {{ url }}
{% endfor %}

You’d then need to parse the JSON in the loop and do your averaging math, but, if the API calls are fast enough, that would let you get the average of the last however many days at the current time from, say, the push of a button.

I found a solution. I hope this helps someone else out in the future, as I hit my head on the desk many times trying to figure this out.

STEP 1: I used the SQL integration to query the database to get past values of the state. For the test, I just created three queries:

SQL Integration “P1”:
SELECT state FROM states WHERE entity_id = 'sensor.school' AND last_updated <= datetime('now','-1 day','-5 minute') AND last_updated >= datetime('now','-1 day','-10 minute')
SQL Integration “P2”:
SELECT state FROM states WHERE entity_id = 'sensor.school' AND last_updated <= datetime('now','-2 day','-5 minute') AND last_updated >= datetime('now','-2 day','-10 minute')
SQL Integration “P3”:
SELECT state FROM states WHERE entity_id = 'sensor.school' AND last_updated <= datetime('now','-3 day','-5 minute') AND last_updated >= datetime('now','-3 day','-10 minute')

STEP 2: I used a Template to create a new sensor:

template:
  - sensor:
      - name: "Average Travel Time School"
        unit_of_measurement: "min"
        state: >
          {% set today_1 = states('sensor.p1') | float %}
          {% set today_2 = states('sensor.p2') | float %}
          {% set today_3 = states('sensor.p3') | float %}

          {{ ((today_1 + today_2 + today_3) / 3) | round(1, default=0) }} min

I can now use the ‘sensor.average_travel_time_school’ to present a average trend line against current day drive times.

1 Like