As a rule, device integrations can’t create sensors based on data that the device itself doesn’t provide—so, the integration won’t provide AQI directly.
That said, happy to share what I’m doing. I recently read this article, which advocates using raw values instead of AQI. A few quotes of interest:
[…] the more I start to ignore AQI and just pay attention to the direct measure -micrograms. Micrograms don’t have ever-changing conversion formulas, and they don’t depend on your government’s scale.
But wait, AQI is great because 100 is roughly “bad,” so it’s easy to understand. If we use micrograms, how do we know what’s good and what’s bad? I use the WHO guidelines:
Annual limit = 10 micrograms
24-hour limit = 25 micrograms
The WHO bases its limits on studies of the health effects of pollution.
I now follow the same strategy of looking at raw values to determine air quality. The challenge is that the EPA determines “healthiness level” by looking at values over time, like 24 hours (source). So, I first create statistics sensors that calculate the mean of both PM2.5 and PM10.0 over 24 hours:
sensor:
- platform: statistics
name: "Average Outdoor PM2.5 (24h)"
entity_id: sensor.sensor_pm2_5_mass_concentration
state_characteristic: mean
max_age:
hours: 24
- platform: statistics
name: "Average Outdoor PM10.0 (24h)"
entity_id: sensor.sensor_pm10_0_mass_concentration
state_characteristic: mean
max_age:
hours: 24
Then, I have this template sensor:
sensor:
- name: Local Outdoor Air Quality
state: >
{% set pm2_5_avg = states("sensor.average_outdoor_pm2_5_24h") | int %}
{% if 0 <= pm2_5_avg <= 12.0 %}
{% set pm2_5_rating = 0 %}
{% elif 12.0 < pm2_5_avg <= 35.4 %}
{% set pm2_5_rating = 1 %}
{% elif 35.4 < pm2_5_avg <= 55.4 %}
{% set pm2_5_rating = 2 %}
{% elif 55.4 < pm2_5_avg <= 150.4 %}
{% set pm2_5_rating = 3 %}
{% elif 150.4 < pm2_5_avg <= 250.4 %}
{% set pm2_5_rating = 4 %}
{% else %}
{% set pm2_5_rating = 5 %}
{% endif %}
{% set pm10_0_avg = states("sensor.average_outdoor_pm10_0_24h") | int %}
{% if 0 <= pm10_0_avg <= 54.0 %}
{% set pm10_0_rating = 0 %}
{% elif 54.0 < pm10_0_avg <= 154.0 %}
{% set pm10_0_rating = 1 %}
{% elif 154.0 < pm10_0_avg <= 254.0 %}
{% set pm10_0_rating = 2 %}
{% elif 254.0 < pm10_0_avg <= 354.0 %}
{% set pm10_0_rating = 3 %}
{% elif 354.0 < pm10_0_avg <= 424.0 %}
{% set pm10_0_rating = 4 %}
{% else %}
{% set pm10_0_rating = 5 %}
{% endif %}
{% set rating = [pm2_5_rating, pm10_0_rating] | max %}
{% if rating == 0 %}
Good
{% elif rating == 1 %}
Moderate
{% elif rating == 2 %}
Unhealthy for sensitive groups
{% elif rating == 3 %}
Unhealthy
{% elif rating == 4 %}
Very unhealthy
{% else %}
Hazardous
{% endif %}
unique_id: local_outdoor_air_quality
This is a more conservative approach, where the “worse” of the two sensors determines the overall value.