RESTful Parse JSON Help

Hey all, I’m by no means an expert at home assistant but so far have seemed to struggle my way through most things but this one is stumping me.

I’m trying to learn more about how to parse a JSON API response using the RESTful api integration. I currently have something working with the below configuration but I’d like to be able to parse not based on the array position but filter by specific attributes so that if the endpoint response changes it doesn’t break my sensor.

- platform: rest
  resource: https://seagull-api.glos.org/api/v2/obs-latest
  method: GET
  value_template: '{{ (value_json[25]["parameters"][11]["observations"][0].value | float * 2.23694) | round(1) }}'
  name: "Green Bay Entrance Wind Speed" #Platform 155, Parameter 2570
  device_class: "wind_speed"
  state_class: "measurement"
  unit_of_measurement: "mph"
  scan_interval: 600

Attached is a sample response from the API call. I’d like to filter down by obs_dataset_id and parameter_id.

I can filter down using JSONPath syntax pefectly using the below but I can’t figure out a way of doing this same thing using value templates

$[?(@.obs_dataset_id==155)].parameters[?(@.parameter_id==2570)].observations[0].value

Here is a link to the output JSON

Can you share the data? Perhaps use a public gist.

Here is my example using Template Editor in Developer Tools. Once you get it right you just need to change (value_json | from_json).value_json to value_json before using in RESTful. This assumes that there will only ever be one dataset entry of 154 in json and one parameter_id of 2570 in parameters of that dataset as the template is using | first for both.

When developing a template like this, if I am not sure what a jinja interator (like selectattr) is outputting I just use | list to have a look, then adjust my next filter.

{% set value_json = '{
    "value_json": [
        { 
            "obs_dataset_id": 154,
            "parameters": [
                {   
                    "parameter_id": 2570,
                    "observations": [
                        { "value": 2.570 }
                    ]
                },
                {   
                    "parameter_id": 2571,
                    "observations": [
                        { "value": 2.571 }
                    ]
                }
            ]
        },
        { 
            "obs_dataset_id": 155,
            "parameters": [
                {   
                    "parameter_id": 3571,
                    "observations": [
                        { "value": 3.571 }
                    ]
                },
                {   
                    "parameter_id": 3572,
                    "observations": [
                        { "value": 3.572 }
                    ]
                }
            ]
        }
    ]
}' %}
{{ ((((value_json | from_json).value_json | selectattr("obs_dataset_id", "eq", 154) | first)["parameters"] | selectattr("parameter_id", "eq", 2570) | first)["observations"] | first)["value"] }}

You could have just used:

{% set value_json =  [
        { 
            "obs_dataset_id": 154,

…made sure you closed it off correctly:

        }
    ]
%}

…then used value_json directly in the template as you would in the Rest sensor:

{{ (((value_json|selectattr("obs_dataset_id", "eq", 154)|first)["parameters"]
      |selectattr("parameter_id", "eq", 2570)|first)["observations"]|first)["value"] }}

@chrisolson91 — you might find you have problems with a 438kB response. Might need to use a Command Line sensor with curl and jq to cut it down a bit first.

1 Like