NSW Air Quality - formatting JSON

My local Environment Department publishes a range of air quality stats via an API at https://www.dpie.nsw.gov.au/air-quality/air-quality-data-services/air-quality-api. I’m trying to setup a REST sensor to collect the data from this API. However, I’m having trouble getting it to work and hope that someone that better understand JSON formatting can help please?

An example of the data coming back from the API is formatted as follows:

[
  {
    "Site_Id": 190,
    "Parameter": {
      "ParameterCode": "NEPH",
      "ParameterDescription": "Nephelometer ",
      "Units": "10^-4 m^-1",
      "UnitsDescription": "10^-4 m^-1",
      "Category": "Averages",
      "SubCategory": "Hourly",
      "Frequency": "Hourly average"
    },
    "Date": "2021-09-20",
    "Hour": 18,
    "HourDescription": "5 pm - 6 pm",
    "Value": 0.09,
    "AirQualityCategory": null,
    "DeterminingPollutant": null
  },
  {
    "Site_Id": 190,
    "Parameter": {
      "ParameterCode": "PM10",
      "ParameterDescription": "PM10",
      "Units": "µg/m³",
      "UnitsDescription": "microgram per cubic meter",
      "Category": "Averages",
      "SubCategory": "Hourly",
      "Frequency": "Hourly average"
    },
    "Date": "2021-09-20",
    "Hour": 18,
    "HourDescription": "5 pm - 6 pm",
    "Value": 19.302,
    "AirQualityCategory": "GOOD",
    "DeterminingPollutant": null
  }
]

I have been trying to use a REST Sensor, but am confused as to the difference between this and the REST integration? In any event, it seems messy because the value is always in a ‘Value’ subfield and the field name (NEPH or PM10 in the example above) is a sub-sub field under ‘Parameter’.

Thus far I have the following in my sensors.yaml file:

- platform: rest
  name: 'Chullora Air Quality'
  json_attributes:
    - PM10
  resource: https://data.airquality.nsw.gov.au/api/Data/get_Observations
  method: POST
  payload: '{ "Parameters": [ "PM10","NEPH" ], "Sites": [190], "StartDate": "2021-09-20T17:00:00", "EndDate": "2021-09-20T18:00:00", "Categories": ["Averages", "Site AQC", "Regional AQC"], "Frequency": ["Hourly average"] }'
  timeout: 150
  json_attributes_path: "[0].response"
  json_attributes: 
    - Site_Id
    - Hour
    - Value
    - Date

I’ve spent hours reading and re-reading the Documentation without success. Any solutions or pointers to what I’m doing wrong would be gratefully received.

2 Likes

I believe in rest: will be most efficient.

Looking at below and dropping it in https://jsonpathfinder.com/ I believe the path you’re after is

 json_attributes_path: "$[0]"

and not

 json_attributes_path: "[0].response"
[
    {
        "Site_Id": 190,
        "Parameter": {
            "ParameterCode": "NEPH",
            "ParameterDescription": "Nephelometer ",
            "Units": "10^-4 m^-1",
            "UnitsDescription": "10^-4 m^-1",
            "Category": "Averages",
            "SubCategory": "Hourly",
            "Frequency": "Hourly average"
        },
        "Date": "2021-09-20",
        "Hour": 18,
        "HourDescription": "5 pm - 6 pm",
        "Value": 0.09,
        "AirQualityCategory": null,
        "DeterminingPollutant": null
    },
    {
        "Site_Id": 190,
        "Parameter": {
            "ParameterCode": "PM10",
            "ParameterDescription": "PM10",
            "Units": "µg/m³",
            "UnitsDescription": "microgram per cubic meter",
            "Category": "Averages",
            "SubCategory": "Hourly",
            "Frequency": "Hourly average"
        },
        "Date": "2021-09-20",
        "Hour": 18,
        "HourDescription": "5 pm - 6 pm",
        "Value": 19.302,
        "AirQualityCategory": "GOOD",
        "DeterminingPollutant": null
    }
]

See here for inspiration on rest: - this one gives an example of a dynamic json path to handle multiple objects in the array response. e.g. the sample above has two array objects in the response [0] and [1]

See https://jsonpath.curiousconcept.com/ to test a JSONpath expression to total the numbers in each array item.

and here on sensor:

1 Like

Thanks

Based on this, I thought I should have it working with the following, but no luck yet.

rest:
  - resource: https://data.airquality.nsw.gov.au/api/Data/get_Observations
    method: POST
    payload: '{ "Parameters": [ "PM10" ], "Sites": [190], "StartDate": "2021-09-20T17:00:00", "EndDate": "2021-09-20T18:00:00", "Categories": ["Averages", "Site AQC", "Regional AQC"], "Frequency": ["Hourly average"] }'
    timeout: 150
    scan_interval: 300
    sensor: 
      - name: "Chullora Air Quality"
        json_attributes_path: "$[0]"
        json_attributes:
          - "Site_Id"
          - "Parameter"
          - "Date"
          - "Hour"
          - "HourDescription"
          - "Value"
          - "AirQualityCategory"
          - "DeterminingPollutant"

Can anyone spot what I’m still doing wrong?

This seems to work

  - resource: https://data.airquality.nsw.gov.au/api/Data/get_Observations
    method: POST
    payload: '{ "Parameters": [ "NEPH", "PM10" ], "Sites": [190], "StartDate": "2021-09-20T17:00:00", "EndDate": "2021-09-20T18:00:00", "Categories": ["Averages", "Site AQC", "Regional AQC"], "Frequency": ["Hourly average"] }'
    timeout: 180
    scan_interval: 300
    headers:
      User-Agent: Home Assistant
      Content-Type: application/json
    sensor: 
      - name: "Chullora Air Quality NEPH"
        value_template: "OK"
        json_attributes_path: "$[0]"
        json_attributes:
          - Site_Id
          - Parameter
          - Date
          - Hour
          - HourDescription
          - Value
          - AirQualityCategory
          - DeterminingPollutant
      - name: "Chullora Air Quality PM10"
        value_template: "OK"
        json_attributes_path: "$[1]"
        json_attributes:
          - Site_Id
          - Parameter
          - Date
          - Hour
          - HourDescription
          - Value
          - AirQualityCategory
          - DeterminingPollutant

Parameter is nested. There might be another way to do this but i’ve created a separate sensor to handle the attributes under it

  - resource: https://data.airquality.nsw.gov.au/api/Data/get_Observations
    method: POST
    payload: '{ "Parameters": [ "NEPH", "PM10" ], "Sites": [190], "StartDate": "2021-09-20T17:00:00", "EndDate": "2021-09-20T18:00:00", "Categories": ["Averages", "Site AQC", "Regional AQC"], "Frequency": ["Hourly average"] }'
    timeout: 180
    scan_interval: 300
    headers:
      User-Agent: Home Assistant
      Content-Type: application/json
    sensor: 
      - name: "Chullora Air Quality NEPH"
        value_template: "OK"
        json_attributes_path: "$[0]"
        json_attributes:
          - Site_Id
          - Date
          - Hour
          - HourDescription
          - Value
          - AirQualityCategory
          - DeterminingPollutant
      - name: "Chullora Air Quality NEPH Parameter"
        value_template: "OK"
        json_attributes_path: "$[0].Parameter"
        json_attributes:
           - ParameterCode
           - Frequency
           - ParameterDescription
           - Units
           - UnitsDescription
           - Category
           - SubCategory
      - name: "Chullora Air Quality PM10"
        value_template: "OK"
        json_attributes_path: "$[1]"
        json_attributes:
          - Site_Id
          - Date
          - Hour
          - HourDescription
          - Value
          - AirQualityCategory
          - DeterminingPollutant
      - name: "Chullora Air Quality PM10 Parameter"
        value_template: "OK"
        json_attributes_path: "$[1].Parameter"
        json_attributes:
           - ParameterCode
           - Frequency
           - ParameterDescription
           - Units
           - UnitsDescription
           - Category
           - SubCategory

Anticipating you’ll want the starttime and endtime to change, slightly updated version

  - resource: https://data.airquality.nsw.gov.au/api/Data/get_Observations
    method: POST
    payload: '{ "Parameters": [ "NEPH", "PM10" ], "Sites": [190], "StartDate": "{{ ((now() - timedelta( hours = 1 ))).strftime("%Y-%m-%dT%H:00:00") }}", "EndDate": "{{ now().strftime("%Y-%m-%dT%H:00:00") }}", "Categories": ["Averages", "Site AQC", "Regional AQC"], "Frequency": ["Hourly average"] }'
    timeout: 180
    scan_interval: 300
    headers:
      User-Agent: Home Assistant
      Content-Type: application/json
    sensor: 
      - name: "Chullora Air Quality NEPH"
        value_template: "OK"
        json_attributes_path: "$[0]"
        json_attributes:
          - Site_Id
          - Date
          - Hour
          - HourDescription
          - Value
          - AirQualityCategory
          - DeterminingPollutant
      - name: "Chullora Air Quality NEPH Parameter"
        value_template: "OK"
        json_attributes_path: "$[0].Parameter"
        json_attributes:
           - ParameterCode
           - Frequency
           - ParameterDescription
           - Units
           - UnitsDescription
           - Category
           - SubCategory
      - name: "Chullora Air Quality PM10"
        value_template: "OK"
        json_attributes_path: "$[1]"
        json_attributes:
          - Site_Id
          - Date
          - Hour
          - HourDescription
          - Value
          - AirQualityCategory
          - DeterminingPollutant
      - name: "Chullora Air Quality PM10 Parameter"
        value_template: "OK"
        json_attributes_path: "$[1].Parameter"
        json_attributes:
           - ParameterCode
           - Frequency
           - ParameterDescription
           - Units
           - UnitsDescription
           - Category
           - SubCategory
1 Like

maybe we can make an integration out of this. :slight_smile:

There is already a world AQI integration.

or this:

yeah, I know. I have those but localy data is better and I mostly want pollen data.