PurpleAir Air Quality Sensor

The formula to convert to the Canadian AQHI is included but that’s all I’ve done since I live in Canada and that’s all I care about. You would have to look up the AQI formula and just replace what I have as needed.

The API doc shows how to get multiple sensors at once and I plan to add that eventually but haven’t done that yet. Likely it would just be a matter adjusting the API call according to the doc and then pulling the results from the multiple sensors via an index, something like ‘value_json[0][‘sensor’][‘stats’]…’, ‘value_json[1][‘sensor’][‘stats’]…’, etc but don’t quote me. I’m on mobile and can’t look at the API doc right now. Then you’d just have to average that out or do whatever else you want with the individual readings.

Got it… Yes… Selecting multiple PurpleAir sites through the API is well documented… I am kind of a noob on YAML, and I was trying to sort how to instantiate two of the sensors you defined in my config.yaml.

@inkylatte - I had the integration working, and it stopped about 2 months ago… Downloaded and installed the github directory, and the get the error message I posted in my logs

The manifest.json needs a version field, as it is required by the newer versions of home assistant. See the last lines.

{
  "domain": "purpleair",
  "name": "PurpleAir",
  "config_flow": true,
  "documentation": "https://www.home-assistant.io/integrations/purpleair",
  "requirements": [],
  "ssdp": [],
  "zeroconf": [],
  "homekit": {},
  "dependencies": [],
  "codeowners": [
    "@gibwar"
  ],
  "version": "0.1.0"
}

Perfect. Thanks.

I was also able to clone gibwar’s updated code on gitlab, and that seemed to work.

-Bill

For those interested in pulling in the US EPA AQI conversion (particularly those in the US West affected by wildfire smoke), I forked gibwar’s Purple Air integration and added the EPA conversion formula. This adds the EPA AQI value as an attribute to the air quality sensor in addition to the default Purple Air AQI value provided. But for the AQI sensor, I now provide the EPA AQI converted value instead of the default Purple Air AQI value.

4 Likes

Here’s some code for anyone using the integration who wants to compute an average of multiple sensors (the trigger is to prevent it from updating for each individual sensor update):

  - trigger:
    - platform: time_pattern
      minutes: "/5"
    sensor:
    - name: "PurpleAir Outdoor AQI"
      # Average all AQI neighbor sensors so if one goes down I still have data:
      state: >-
        {% set ns = namespace(count=0, sum=0) %}
        {% for s in states.air_quality %}
          {% if state_attr(s.entity_id, 'attribution') == 'Data provided by PurpleAir' %}
            {% set ns.sum = ns.sum + state_attr(s.entity_id, 'air_quality_index') %}
            {% set ns.count = ns.count + 1 %}
          {% endif %}
        {% endfor %}
        {% if ns.count == 0 %}
           None
        {% else %}
           {{ (ns.sum / ns.count)| int }}
        {% endif %}
      unit_of_measurement: "AQI"
      attributes:
        total_sensors: >-
          {% set ns = namespace(count=0) %}
          {% for s in states.air_quality %}
            {% if state_attr(s.entity_id, 'attribution') == 'Data provided by PurpleAir' %}
              {% set ns.count = ns.count + 1 %}
            {% endif %}
          {% endfor %}
          {{ ns.count }}
1 Like

I was able to get two versions of this running, one for outdoor sensors through the cloud API, and one for my internal purpleair sensor. It works great, except for one small detail. In order for multiple history charts to show on the same axes, the units have to match. For the outdoor sensor (and my foobot sensor), I get “ug/m^3” with an actual exponent for meters cubed. For the indoor sensor, I get the literal text “ug/m3”. Since they aren’t quite the same, they display on separate charts.

I can’t quite figure out how to configure the local sensor to what appears to be a built-in units of mass concentration, so that I can get all 3 readings on chart. Does anyone know more about this?

In the custom components, it seems to use some defined python constant for the units, but for the rest/template sensor, it just takes a string. Is this even possible?

Am I missing something? I can’t find the json url anymore?
It just gives me a widget url. Which doesn’t work obviously.
Could someone direct me as to where exactly to fin the json link?
I did go to Purple Air web site and found a sensor on the map, clicked on it and only can see a widget link.

Thanks

EDIT: I found it… well I found it from the get widget url. key is in there and the show number is also further down

=PurpleAirWidget_34495_module_AQI

I’m trying to figure out what the final URL is that you put together? I did go through and dig up the prupleair config data from core.config_entries and replaced the key with something newer but that didn’t seem to fix my stale data. Thanks!

haha no worries. I found the json link by using parts of info in the widget links.

Are you looking for the local URL or the URL for a station on the map?

Public station down the street from my home.

See Post 60 Above with the format.

I know it is here somewhere but I couldn’t find it readily for finding the station number so…
Go to the PurpleAir map
Click on the station you want to get
Hover over “Get Widget”
Take note of the station id number

Use the number for the resource listed in post #60

1 Like

Ah thank you! I’m not sure why I was trying to get this setup as a private sensor.

The url string along with the station id you want to feed into the HA integration is:

https://www.purpleair.com/json?show=

1 Like

Because subconsciously you want one for yourself.

I’ve been following this thread for a long time and finally got a configuration working well for my local sensor. Some additions from others I’ve seen:

  • Everything in a YAML file so it is easy to tweak and edit.
  • All of the interesting sensors have unique_ids so that they are easy to use in the UI.
  • Nice Unicode strings for the units and friendly names (e.g. µg/m³)
  • US EPA Smoke conversion provided as a separate sensor.
  • Temperature and Humidity offsets applied as documented by Purple Air.
  • Temperature smoothing statistics sensor (because mine seems to be a bit wonky).
1 Like

I noticed that you get noise (your words); there are at least two different pages for json info for the purpleair. I will have to check when I get home (or look around on here) what it actually is but I think it is “\avg” which will give you the 10 min running average. I use the 10 min running average for all my sensors.

Edit Why are you using slightly different correction constants for you EPA correction?
From the EPA:

PM2.5 corrected= 0.534*[PA_cf1(avgAB)] - 0.0844*RH +5.604

Yours:

{{ 0.52 * ((state_attr('sensor.purpleair','pm2_5_cf_1') + state_attr('sensor.purpleair','pm2_5_cf_1_b')) / 2) - (0.085 * state_attr('sensor.purpleair','current_humidity')) + 5.71 }}

I also like the idea of averaging the two channels together, which I will probably work on updating mine.

Somewhere above I have some other sensors like dewpoint that is calculated from my PA.
I can repost everything here or in your repo if you would like.

@GlennHA this is what my raw temperature readings looked like. Noisy, but not really random, which is why I chose to take the trailing max vs a trailing average.

For the wild fire correction, I used the formula on slide 8 from PurpleAir PM2.5 U.S. Correction and Performance During Smoke Events 4/2020 | Science Inventory | US EPA. Do you know of a more up to date formula?

I went off the link you had in the yaml which is not the same as above. You linked to the 2018 version instead of the 2020 version in that section of the yaml on your repository (just update to the link above).

I read that paper and from my personal experiance with looking at Purple Air map and the EPA AirNow map when compared to just going outside and breathing that the purple air is more acurate than the AirNow map. Also recently for some non-credible reason, the AirNow map forbids itself being used in an iFrame. The paper says that PurpleAir reports correct 80% of the time and only over reports 20% of the time (and only by 1AQI); my experience is that the AirNow map drastically under-reports. There were days when there was no visibility due to smoke from wildfires over a hundred miles away and the AirNow map showed my area as green. I also live less than 20 miles from an EPA test site at an airport.

Do you see any real difference with the calculations for the PurpleAir AQI and the ‘corrected’ AQI?