Just a heads up to anyone using this, PurpleAir has retired the /json url and I have reached out to them on how we should proceed moving forward. They use api.purpleair.com now but it appears you need an API key but I wasn’t able to find a way to generate one on their site. I’m awaiting a response via email and will share the information I receive.
Update:
Received an email back from [email protected] with my new read/write API keys. Just email that address with your first and last name and request an API key. I had to update the sensors and templates as the returned data format has changed a little.
- platform: rest
name: 'PurpleAir'
#Change the 72291 to whatever station you use
resource: https://api.purpleair.com/v1/sensors/72291
headers:
X-API-Key: ********-****-****-****-************
scan_interval: 180
device_class: timestamp
value_template: >
{{ state_attr('sensor.purpleair', 'sensor')['last_seen']|timestamp_local(0) }}
json_attributes:
- sensor
purpleair_aqi:
friendly_name: 'PurpleAir AQI'
unique_id: purpleair_aqi
# Set this sensor to be the AQI value.
#
# Code translated from JavaScript found at:
# https://docs.google.com/document/d/15ijz94dXJ-YAZLi9iZ_RaBwrZ4KtYeCy08goGBwnbCU/edit#
value_template: >
{% macro calcAQI(Cp, Ih, Il, BPh, BPl) -%}
{{ (((Ih - Il)/(BPh - BPl)) * (Cp - BPl) + Il)|round }}
{%- endmacro %}
{% set pm25 = state_attr('sensor.purpleair', 'sensor')['pm2.5']|float(0) %}
{% if pm25 > 1000 %}
invalid
{% elif pm25 > 350.5 %}
{{ calcAQI(pm25, 500.0, 401.0, 500.0, 350.5) }}
{% elif pm25 > 250.5 %}
{{ calcAQI(pm25, 400.0, 301.0, 350.4, 250.5) }}
{% elif pm25 > 150.5 %}
{{ calcAQI(pm25, 300.0, 201.0, 250.4, 150.5) }}
{% elif pm25 > 55.5 %}
{{ calcAQI(pm25, 200.0, 151.0, 150.4, 55.5) }}
{% elif pm25 > 35.5 %}
{{ calcAQI(pm25, 150.0, 101.0, 55.4, 35.5) }}
{% elif pm25 > 12.1 %}
{{ calcAQI(pm25, 100.0, 51.0, 35.4, 12.1) }}
{% elif pm25 >= 0.0 %}
{{ calcAQI(pm25, 50.0, 0.0, 12.0, 0.0) }}
{% else %}
invalid
{% endif %}
unit_of_measurement: "AQI"
purpleair_pm25:
friendly_name: 'PurpleAir PM 2.5'
unique_id: purpleair_pm25
value_template: "{{ state_attr('sensor.purpleair', 'sensor')['pm2.5'] }}"
# value_template: "{{ state_attr('sensor.purpleair','results')[0]['PM2_5Value'] }}"
unit_of_measurement: "μg/m3"
I don’t use the other template sensors provided by OP, but they will need to be updated if you use them. I left the previous line in the above sensor as a reference but here’s a quick overview:
- “results” needs to be changed to “sensor”
- drop the [0]
- “PM2_5Value” needs to be changed to “pm2.5”
Here’s a sample of the json output using the new API for reference as well:
{
"api_version" : "V1.0.10-0.0.17",
"time_stamp" : 1653674398,
"data_time_stamp" : 1653674353,
"sensor" : {
"sensor_index" : 72291,
"last_modified" : 1614368627,
"date_created" : 1601050452,
"last_seen" : 1653674266,
"private" : 0,
"is_owner" : 0,
"name" : "Clean Air Carolina & ECU - EB Aycock Middle School",
"icon" : 0,
"location_type" : 0,
"model" : "PA-II",
"hardware" : "2.0+BME280+PMSX003-B+PMSX003-A",
"led_brightness" : 35,
"firmware_version" : "7.00",
"rssi" : -73,
"uptime" : 15804,
"pa_latency" : 343,
"memory" : 16080,
"position_rating" : 5,
"latitude" : 35.586803,
"longitude" : -77.35311,
"altitude" : 70,
"channel_state" : 3,
"channel_flags" : 0,
"channel_flags_manual" : 0,
"channel_flags_auto" : 0,
"confidence" : 100,
"confidence_auto" : 100,
"confidence_manual" : 100,
"humidity" : 69,
"humidity_a" : 69,
"temperature" : 80,
"temperature_a" : 80,
"pressure" : 1011.6,
"pressure_a" : 1011.62,
"analog_input" : 0.01,
"pm1.0" : 4.7,
"pm1.0_a" : 5.3,
"pm1.0_b" : 4.2,
"pm1.0_atm" : 4.7,
"pm1.0_cf_1" : 4.7,
"pm2.5" : 7.4,
"pm2.5_a" : 8.3,
"pm2.5_b" : 6.5,
"pm2.5_atm" : 7.4,
"pm2.5_cf_1" : 7.4,
"pm2.5_alt" : 4.9,
"pm2.5_alt_a" : 5.5,
"pm2.5_alt_b" : 4.3,
"pm10.0" : 8.9,
"pm10.0_a" : 9.7,
"pm10.0_b" : 8.0,
"pm10.0_atm" : 8.9,
"pm10.0_cf_1" : 8.9,
"scattering_coefficient" : 14.4,
"scattering_coefficient_a" : 15.1,
"scattering_coefficient_b" : 13.7,
"deciviews" : 10.0,
"deciviews_a" : 10.3,
"deciviews_b" : 9.7,
"visual_range" : 143.1,
"visual_range_a" : 138.6,
"visual_range_b" : 147.5,
"0.3_um_count" : 960,
"0.3_um_count_a" : 1008,
"0.3_um_count_b" : 913,
"0.5_um_count" : 283,
"0.5_um_count_a" : 299,
"0.5_um_count_b" : 268,
"1.0_um_count" : 53,
"1.0_um_count_a" : 62,
"1.0_um_count_b" : 44,
"2.5_um_count" : 5,
"2.5_um_count_a" : 5,
"2.5_um_count_b" : 5,
"5.0_um_count" : 1,
"5.0_um_count_a" : 1,
"5.0_um_count_b" : 1,
"10.0_um_count" : 1,
"10.0_um_count_a" : 1,
"10.0_um_count_b" : 1,
"pm1.0_atm_a" : 5.3,
"pm2.5_atm_a" : 8.32,
"pm10.0_atm_a" : 9.68,
"pm1.0_cf_1_a" : 5.3,
"pm2.5_cf_1_a" : 8.32,
"pm10.0_cf_1_a" : 9.68,
"pm1.0_atm_b" : 4.15,
"pm2.5_atm_b" : 6.46,
"pm10.0_atm_b" : 8.04,
"pm1.0_cf_1_b" : 4.15,
"pm2.5_cf_1_b" : 6.46,
"pm10.0_cf_1_b" : 8.04,
"primary_id_a" : 1158951,
"primary_key_a" : "BPVYP48L8OQGWGFQ",
"primary_id_b" : 1158953,
"primary_key_b" : "CO5OUXLQXW2MV6F2",
"secondary_id_a" : 1158952,
"secondary_key_a" : "KL54YM2SSVF5B4BL",
"secondary_id_b" : 1158954,
"secondary_key_b" : "LZFBH47P4EXH9GT4",
"stats" : {"pm2.5" : 7.4, "pm2.5_10minute" : 7.2, "pm2.5_30minute" : 6.8, "pm2.5_60minute" : 6.8, "pm2.5_6hour" : 7.5, "pm2.5_24hour" : 7.6, "pm2.5_1week" : 8.9, "time_stamp" : 1653674266},
"stats_a" : {"pm2.5" : 8.3, "pm2.5_10minute" : 7.5, "pm2.5_30minute" : 7.1, "pm2.5_60minute" : 7.0, "pm2.5_6hour" : 7.9, "pm2.5_24hour" : 8.0, "pm2.5_1week" : 9.5, "time_stamp" : 1653674266},
"stats_b" : {"pm2.5" : 6.5, "pm2.5_10minute" : 6.8, "pm2.5_30minute" : 6.6, "pm2.5_60minute" : 6.5, "pm2.5_6hour" : 7.1, "pm2.5_24hour" : 7.1, "pm2.5_1week" : 8.3, "time_stamp" : 1653674266}
}
}%
Should be back in business after getting your API key and making the above updates.