Create a template from a https request and json answer

Not sure if this can be done. I would like to query google and get time and distance. Today I am doing it with code running in AppDaemon. When a switch is flipped on, then an AppDaemon would hit the api, build a message that the notify platform would then text. I was seeing if I could move it into HA automation yaml. That is all I am using AppDaemon for now.

Here is my https call:

https://maps.googleapis.com/maps/api/distancematrix/json?origins=35.xxxxx,-97.xxxxx&destinations=35.xxxx,-97.xxxxx&mode=driving&language=en-EN&sensor=false&key=xxxx

It then responds with something like:

{
   "destination_addresses" : [ "xxx Antler Ridge, xxx, OK xxxxx, USA" ],
   "origin_addresses" : [ "xxx NE 63rd St, Oklahoma City, OK 73121, USA" ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "48.3 km",
                  "value" : 48317
               },
               "duration" : {
                  "text" : "36 mins",
                  "value" : 2133
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}

Is there a way to call a https and template the response?

Yes, with a RESTful Sensor. However, it depends on what you want to extract from the received message. A RESTful Sensor can extract one thing and use it to represent its state. It can’t extract other things and use them as attributes. If you wanted to do that (get attributes) then you’d need to use a Command Line Sensor.

@123 Thanks, that what I was looking for. If I get is just time, that fine.
According to the docs, the “Command Line Sensor” has a parameter to control how often the sensor updates. I only what it to update when forced. I only want to call the API when time to destination is needed.

You set scan_interval to a very large value (so that the polling interval is hours or days) and create an automation that calls service.homeassistant_update homeassistant.update_entity only when you need it.


EDIT
Fixed incorrect service name.

Maybe I am looking at the wrong docs https://www.home-assistant.io/integrations/rest/,
I did not see scan_interval. Is that in seconds? I wonder how large it can be? Once a day worth of seconds?

It’s not mentioned in the RESTful Sensor’s documentation. For some curious reason, scan_interval is documented separately from all sensors that use it. The value is expressed in seconds and the default is 30 seconds.

I know @123 really meant homeassistant.update_entity :slight_smile:

1 Like

Thanks, I felt that looked wrong when I wrote it but didn’t have the time to double-check.

While digging for information, I ran across the Waze sensor.
https://www.home-assistant.io/integrations/waze_travel_time/
For now, it does what I need …

But I still want to understand this sensor. I did get the sensor to work, my issue is in the template needed to get the data. Especially the dictionary.
So what would the template look like to get the duration?
From that example, I will see if I can deduce the others.


{
   "destination_addresses" : [ "xxx Antler Ridge, xxx, OK xxxxx, USA" ],
   "origin_addresses" : [ "xxx NE 63rd St, Oklahoma City, OK 73121, USA" ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "48.3 km",
                  "value" : 48317
               },
               "duration" : {
                  "text" : "36 mins",
                  "value" : 2133
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}

Paste this into the Template Editor and experiment with it:

{% set value_json = 
{
   "destination_addresses" : [ "xxx Antler Ridge, xxx, OK xxxxx, USA" ],
   "origin_addresses" : [ "xxx NE 63rd St, Oklahoma City, OK 73121, USA" ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "48.3 km",
                  "value" : 48317
               },
               "duration" : {
                  "text" : "36 mins",
                  "value" : 2133
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}
%}
{{ value_json.rows[0].elements[0].duration.value }}

The result of the above is 2133.

@SteveDinn Thanks pointing that out, I made the same assumption.
@123 Thanks for all that you did. You nudges got me in the right area.

One last note before I leave this subject. I add this note not only if anyone else runs into it, but also as a note if I revisit it. The google maps api is a per call charge. You get a $200 dollar credit every month. Currently the Waze if free. Not sure why it just responds with travel time and not the other info. Anyway, I am going to stick a pin in this path and just use the Waze. The last big hurdle that is left, is to expand “zone.home” and “person.paul” longitude and latitude. as part of the call. Also, expand the API from the secret file.

I did go look at the code to see what it would take to add attributes. I saw that it had that as part of the config.get(). Then I went back to the documentation with a different perspective and sure enough there it was. Someone added it. :slight_smile:

So here is my yaml with the resource chopped to protect the secrets.

sensor:
  - platform: rest
    name: Paul Travel Time to Home
    scan_interval: 84600
    json_attributes:
      - destination_addresses
      - origin_addresses
    resource: https://maps.googleapis.com/maps/api/distancematrix/json?origins=35
    value_template: '{{ value_json.rows[0].elements[0].duration.value }}'
  - platform: template
    sensors:
      destination_addresses:
        friendly_name: 'Destination Addresses'
        value_template: '{{ value_json.destination_addresses[0] }}'
      origin_addresses:
        friendly_name: 'Origin Addresses'
        value_template: '{{ value_json.origin_addresses[0] }}'

Here is the template to read the attribute
{{ state_attr('sensor.paul_travel_time_to_home', 'destination_addresses')[0] }}

Not sure why I had to add an array element, I thought I handle it in the value_template.

Thanks again everyone.