(JSON) REST Sensor Help

I want to extract some data from a JSON file made available by A.R.P.A. and in which the air pollution data is contained.

https://www.arpae.it/qualita-aria/bollettino-qa/json

I can extract the data relating to the monitoring unit of my interest by creating two sensors that interrogate the ID 5.
Kindly someone explains to me how to create a single sensor with multiple attributes generated with a single query to the Json file.
I would like to extract the data of my interest later with templates and make it more linear.
They are low level

Thanks

These are the current sensors

- platform: rest
  resource: https://www.arpae.it/qualita-aria/bollettino-qa/json
  name: arpa_montecucco_pm10
  scan_interval: 3600
  value_template: '{{ value_json[5]["pm10"]}}'
  unit_of_measurement: "µg/m³"

- platform: rest
  resource: https://www.arpae.it/qualita-aria/bollettino-qa/json
  name: arpa_montecucco_pm25
  scan_interval: 3600
  value_template: '{{ value_json[5]["pm25"]}}'
  unit_of_measurement: "µg/m³"

The RESTful integration has an option called json_attributes. The documentation provides an example of how to extract multiple attributes from the received JSON data:

Fetch multiple JSON values and present them as attributes

The requirement is that the attributes are presented as a dictionary. In other words, it expects the data to look like this:

{ "name": "John", "age": 35, "hobby": "home automation" }

and then it can extract attributes like this:

    json_attributes:
      - name
      - age
      - hobby

If the attributes are not in a simple dictionary format then it becomes more challenging (possible even impossible) to extract them. There is another option available called json_attributes_path. It gives you additional flexibility to parse information using JSONPATH. However, whatever is parsed must still be in dictionary format (see the example in the documentation).

If we put the two options together, we get this:

- platform: rest
  resource: https://www.arpae.it/qualita-aria/bollettino-qa/json
  name: arpa_montecucco_pm10
  scan_interval: 3600
  value_template: '{{ value_json[5]["pm10"]}}'
  unit_of_measurement: "µg/m³"
  json_attributes_path: "$.[5]"
  json_attributes:
    - prov
    - idstazione
    - stazione
    - tipostazione
    - pm10
    - pm25
    - no2
    - o3mediaorariamax
    - o3media8oremax
    - benzene
    - co
    - so2
    - pm10supgiorni
    - no2supore
    - o3supore
    - o3supgiorni
    - giorno

Give that a try and let me know if it works the way you want.


Example:

2 Likes

very nice @123 taras, I think that will work well.

related question:
I’m also setting up some further sensors nested in one of the attributes, this works well but every now and then the response of the server is bad. Is there a way to check this before doing anything else?
So I get an invalid json or none at all back.

In the value_template you could test the payload’s length. If it is zero, or abnormally small, (you can’t validate the JSON structure) then you could discard it and simply report the sensor’s last-known value. However, I know of no way to do that for json_attributes so it will fail if the received data is invalid.

In comparison, the MQTT Sensor has a json_attributes_template option that provides the same flexibility as value_template.

Thanks @123 for a very quick reply.
will try checking the length tomorrow to at least catch the original response.
maybe set a binary sensor as well for good/bad and work the json_attributes only if valid.
will get back once some more results.

How do you plan on doing that? json_attributes does not accept a template.

Regardless of what value_template does with an invalid payload, json_attributes will always attempt to process it.

Thank you very much. It works!

1 Like

Hi @123… I’m trying something similar, attempting to paraphrase the yaml from Restful as:

sensor:
  - platform: rest
    name: "Deepwater Bend Tides"
    resource: https://api.willyweather.com.au/v2/Y***my-API-here***/locations/33389/weather.json?forecasts=tides&days=7&startDate={{ now().strftime("%Y-%m-%d") }}
    method: GET
    scan_interval: 86400
    sensor:
      - name: 'Deepwater Bend tides - 1'
        value_template: "OK"
        json_attribute_path: "$.forecasts.tides.days[0].entries[0]"
        json_attributes:
          - "dateTime"
          - "height"
          - "type"
      - name: 'Deepwater Bend tides - 2'
        value_template: "OK"
        json_attribute_path: "$.forecasts.tides.days[0].entries[1]"
        json_attributes:
          - "dateTime"
          - "height"
          - "type"
      - name: 'Deepwater Bend tides - 3'
        value_template: "OK"
        json_attribute_path: "$.forecasts.tides.days[0].entries[2]"
        json_attributes:
          - "dateTime"
          - "height"
          - "type"
      - name: 'Deepwater Bend tides - 4'
        value_template: "OK"
        json_attribute_path: "$.forecasts.tides.days[0].entries[3]"
        json_attributes:
          - "dateTime"
          - "height"
          - "type"
      - name: 'Deepwater Bend tides - 5'
        value_template: "OK"
        json_attribute_path: "$.forecasts.tides.days[1].entries[0]"
        json_attributes:
          - "dateTime"
          - "height"
          - "type"
      - name: 'Deepwater Bend tides - 6'
        value_template: "OK"
        json_attribute_path: "$.forecasts.tides.days[1].entries[1]"
        json_attributes:
          - "dateTime"
          - "height"
          - "type"
      - name: 'Deepwater Bend tides - 7'
        value_template: "OK"
        json_attribute_path: "$.forecasts.tides.days[1].entries[2]"
        json_attributes:
          - "dateTime"
          - "height"
          - "type"
      - name: 'Deepwater Bend tides - 8'
        value_template: "OK"
        json_attribute_path: "$.forecasts.tides.days[1].entries[3]"
        json_attributes:
          - "dateTime"
          - "height"
          - "type"
      - name: 'Deepwater Bend tides - 9'
        value_template: "OK"
        json_attribute_path: "$.forecasts.tides.days[2].entries[0]"
        json_attributes:
          - "dateTime"
          - "height"
          - "type"
      - name: 'Deepwater Bend tides - 10'
        value_template: "OK"
        json_attribute_path: "$.forecasts.tides.days[2].entries[1]"
        json_attributes:
          - "dateTime"
          - "height"
          - "type"
      - name: 'Deepwater Bend tides - 11'
        value_template: "OK"
        json_attribute_path: "$.forecasts.tides.days[2].entries[2]"
        json_attributes:
          - "dateTime"
          - "height"
          - "type"
      - name: 'Deepwater Bend tides - 12'
        value_template: "OK"
        json_attribute_path: "$.forecasts.tides.days[2].entries[3]"
        json_attributes:
          - "dateTime"
          - "height"
          - "type"

Sample JSON from the Rest GET is:

{
   "location":{
      "id":33389,
      "name":"Pine River - Deepwater Bend Boat Ramp",
      "region":"Sunshine Coast",
      "state":"QLD",
      "postcode":"",
      "timeZone":"Australia\/Brisbane",
      "lat":-27.299,
      "lng":153.0352,
      "typeId":14
   },
   "forecasts":{
      "tides":{
         "days":[
            {
               "dateTime":"2022-01-03 00:00:00",
               "entries":[
                  {
                     "dateTime":"2022-01-03 04:04:00",
                     "height":0.23,
                     "type":"low"
                  },
                  {
                     "dateTime":"2022-01-03 10:13:00",
                     "height":2.68,
                     "type":"high"
                  },
                  {
                     "dateTime":"2022-01-03 17:31:00",
                     "height":0.42,
                     "type":"low"
                  },
                  {
                     "dateTime":"2022-01-03 22:25:00",
                     "height":1.83,
                     "type":"high"
                  }
               ]
            },
            {
               "dateTime":"2022-01-04 00:00:00",
               "entries":[
                  {
                     "dateTime":"2022-01-04 04:52:00",
                     "height":0.24,
                     "type":"low"
                  },
                  {
                     "dateTime":"2022-01-04 11:02:00",
                     "height":2.69,
                     "type":"high"
                  },
                  {
                     "dateTime":"2022-01-04 18:22:00",
                     "height":0.42,
                     "type":"low"
                  },
                  {
                     "dateTime":"2022-01-04 23:16:00",
                     "height":1.83,
                     "type":"high"
                  }
               ]
            },
            {
               "dateTime":"2022-01-05 00:00:00",
               "entries":[
                  {
                     "dateTime":"2022-01-05 05:39:00",
                     "height":0.28,
                     "type":"low"
                  },
                  {
                     "dateTime":"2022-01-05 11:48:00",
                     "height":2.63,
                     "type":"high"
                  },
                  {
                     "dateTime":"2022-01-05 19:09:00",
                     "height":0.44,
                     "type":"low"
                  }
               ]
            },
            {
               "dateTime":"2022-01-06 00:00:00",
               "entries":[
                  {
                     "dateTime":"2022-01-06 00:05:00",
                     "height":1.82,
                     "type":"high"
                  },
                  {
                     "dateTime":"2022-01-06 06:25:00",
                     "height":0.37,
                     "type":"low"
                  },
                  {
                     "dateTime":"2022-01-06 12:33:00",
                     "height":2.53,
                     "type":"high"
                  },
                  {
                     "dateTime":"2022-01-06 19:53:00",
                     "height":0.49,
                     "type":"low"
                  }
               ]
            },
            {
               "dateTime":"2022-01-07 00:00:00",
               "entries":[
                  {
                     "dateTime":"2022-01-07 00:54:00",
                     "height":1.8,
                     "type":"high"
                  },
                  {
                     "dateTime":"2022-01-07 07:11:00",
                     "height":0.49,
                     "type":"low"
                  },
                  {
                     "dateTime":"2022-01-07 13:16:00",
                     "height":2.39,
                     "type":"high"
                  },
                  {
                     "dateTime":"2022-01-07 20:36:00",
                     "height":0.55,
                     "type":"low"
                  }
               ]
            },
            {
               "dateTime":"2022-01-08 00:00:00",
               "entries":[
                  {
                     "dateTime":"2022-01-08 01:44:00",
                     "height":1.78,
                     "type":"high"
                  },
                  {
                     "dateTime":"2022-01-08 08:00:00",
                     "height":0.64,
                     "type":"low"
                  },
                  {
                     "dateTime":"2022-01-08 14:00:00",
                     "height":2.22,
                     "type":"high"
                  },
                  {
                     "dateTime":"2022-01-08 21:18:00",
                     "height":0.59,
                     "type":"low"
                  }
               ]
            },
            {
               "dateTime":"2022-01-09 00:00:00",
               "entries":[
                  {
                     "dateTime":"2022-01-09 02:39:00",
                     "height":1.77,
                     "type":"high"
                  },
                  {
                     "dateTime":"2022-01-09 08:55:00",
                     "height":0.77,
                     "type":"low"
                  },
                  {
                     "dateTime":"2022-01-09 14:44:00",
                     "height":2.06,
                     "type":"high"
                  },
                  {
                     "dateTime":"2022-01-09 22:01:00",
                     "height":0.62,
                     "type":"low"
                  }
               ]
            }
         ],
         "units":{
            "height":"m"
         },
         "issueDateTime":"2021-10-10 10:09:16",
         "carousel":{
            "size":2191,
            "start":1829
         }
      }
   }
}

But when testing the config I keep getting a “Invalid config for [sensor.rest]: [sensor] is an invalid option for [sensor.rest]. Check: sensor.rest->sensor.” error.

Am I misreading the example? Any thoughts?

Your example’s syntax is a blend of the traditional way of configuring a REST sensor and the new way of doing it. Pick one or the other but don’t combine them.

I’m trying to do something similar to @AussieByrd - but I don’t understand which thing is “traditional way” and which is “the new way of doing it”. Can you explain?

It’s explained in the documentation for Template Sensor. The initial section explains the current (modern) way of configuring a Template Sensor followed by another section that explains the old (legacy) method.

It really works. Thank you so much.