Skip to content

Air Quality (AQ) Payload

Environment and air quality sensor for the Traffic Monitor

Overview

The air quality monitor enables collection of a variety of environmental measurements including gasses commonly associated with pollution, temperature, pressure, humidity, and much more.

Info

The AQ software is available at greendormer/enviroplus-monitor. It is based on the wonderful work from the roscoe81/enviro-monitor and pimoroni/enviroplus projects.

Hardware

The following hardware has been tested and incorporated into the Traffic Monitor.

Info

Although we strive to include high-quality equipment and data collection into our application, we make no warranty on the veracity or quality of the hardware or data. We welcome those with an environmental science background to contribute!

  • Enviro for Raspberry Pi – Enviro + Air Quality
  • Enviro for Raspberry Pi – Enviro + Air Quality
  • Air quality (pollutant gases and particulates*), temperature, pressure, humidity, light, and noise
  • Getting started
  • PMS5003 Particulate Matter Sensor for Enviro
  • Monitor air pollution cheaply and accurately with this matchbox-sized particulate matter (PM) sensor from Plantower!
  • It senses particulates of various sizes (PM1, PM2.5, PM10) from sources like smoke, dust, pollen, metal and organic particles, and more.

Software

The AQ software is available at greendormer/enviroplus-monitor as a Python service script that communicates with the Traffic Monitor Node-RED flow via MQTT messages. See the repository for installation and setup instructions.

config.json

See Config Readme for a detailed description of every available key.

The following are important keys for the recommended default Traffic Monitor -specific configuration:

  • "enable_send_data_to_homemanager": true in order to send MQTT payloads to specified broker
  • "mqtt_broker_name": "localhost" to send to Node-RED MQTT broker (assumes port 1883)
  • "indoor_outdoor_function": "Outdoor" to utilize outdoor_mqtt_topic
  • "enable_display": false since the AQ sensor will be in an enclosure
  • "outdoor_mqtt_topic": "aq/sensorname01/readings" for sending messages, must start with "aq" and the middle element, "sensorname01" must be defined in your TM config
  • "long_update_delay": 300 for time between sending MQTT messages (default 300-seconds)

Deployment-specific config settings

The following location-based settings need to be set per-deployment for your location. They are utilized by the astral package for calculating the times of various aspects of the sun and phases of the moon (lat/lon, time zone) and calibrating temperature, humidity, barometer, and gas (altitude) readings.

{
    "altitude": 49,
    "city_name": "Portland",
    "time_zone": "America/Los_Angeles",
    "custom_locations": [
        "Portland, United States of America, America/Los_Angeles, 45.52, -122.681944"
    ]
}

Air Quality MQTT Incoming Payload

The TM AQ application sends messages via MQTT integration on the aq/readings topic.

Warning

The sensor needs to stabilize (default 5-minutes) after the script initializes before it will send external updates (via MQTT). This is defined by startup_stabilisation_time in config.json.

{
    "gas_calibrated": false,
    "bar": [
        1009.44,
        "0"
    ],
    "hum": [
        28.7,
        "2"
    ],
    "p025": 0,
    "p10": 0,
    "p01": 0,
    "dew": 2.1,
    "temp": 21,
    "temp_min": 20.9,
    "temp_max": 21.1,
    "gas_red": 4.2,
    "gas_oxi": 0.15,
    "gas_nh3": 0.69,
    "lux": 1.2,
    "proximity": 255,
    "lux_raw": 1.16185,
    "temp_raw": 28.68982029794099,
    "bar_raw": 1003.7122773175154,
    "hum_raw": 18.31337919009301,
    "gas_red_raw": 140805,
    "gas_oxi_raw": 103585,
    "gas_nh3_raw": 227871,
    "current_time": 1738698665.077546
}

MQTT attribute details:

Key Valid Values Units Notes
gas_calibrated true/false gas_sensors_warmup_time = 6000 or startup_stabilisation_time when reset_gas_sensor_calibration = true
bar [REAL, TEXT] hPa, Comfort-level {"0": "Stable", "1": "Fair", "3": "Poorer/Windy/", "4": "Rain/Gale/Storm"} Air pressure, compensated for altitude and temp as Bar / comp_factor where comp_factor = math.pow(1 - (0.0065 * altitude/(temp + 0.0065 * alt + 273.15)), -5.257)
hum [REAL, TEXT] %, Comfort-level {"good": "1", "dry": "2", "wet": "3"} Adjusted for compensation factor set in config.json
Forecast {OBJECT} Valid: true/false, 3 Hour Change is millibars difference in barometer readings, Forecast is description calculated from barometer change Calculated forecast based on sensor barometer changes
pm01 REAL ug/m3 (microgram per meter cubed, µg/m³) Particulate Matter 1 micrometers / microns (PM1, PM1), Read directly using the pms5003.pm_ug_per_m3() method from the particulate matter sensor.
pm025 REAL ug/m3 (microgram per meter cubed, µg/m³) Particulate Matter 2.5 micrometers / microns (PM2.5, PM2.5), read directly using the pms5003.pm_ug_per_m3() method from the particulate matter sensor.
pm10 REAL ug/m3 (microgram per meter cubed, µg/m³) Particulate Matter 10 micrometers / microns (PM10, PM10), Read directly using the pms5003.pm_ug_per_m3() method from the particulate matter sensor.
dew REAL C Calculated from Temp and Hum as (237.7 * (math.log(dew_hum/100)+17.271*dew_temp/(237.7+dew_temp))/(17.271 - math.log(dew_hum/100) - 17.271*dew_temp/(237.7 + dew_temp)))
temp REAL C Adjusted for compensation factor set in config.json
temp_min REAL C Minimum temperature measured while sensor was running (only resets on restart)
temp_max REAL C Maximum temperature measured while sensor was running (only resets on restart)
gas_red REAL ppm Red PPM calculated as red_in_ppm = math.pow(10, -1.25 * math.log10(red_ratio) + 0.64). red_ratio is compensated gas value, see Software notes.
gas_oxi REAL ppm Oxi PPM calculated as oxi_in_ppm = math.pow(10, math.log10(oxi_ratio) - 0.8129). oxi_ratio is compensated gas value, see Software notes.
nh3 REAL ppm NH3 PPM calculated as nh3_in_ppm = math.pow(10, -1.8 * math.log10(nh3_ratio) - 0.163). nh3_ratio is compensated gas value, see Software notes.
lux REAL lux Read directly using the ltr559.get_lux() method from the light sensor.
temp_raw REAL C Read directly from sensor absent compensation.
bar_raw REAL C Read directly from sensor absent compensation.
hum_raw REAL % Read directly from sensor absent compensation.
gas_red_raw REAL Ohms Read directly from sensor using gas_data.reducing method absent compensation.
gas_oxi_raw REAL Ohms Read directly from sensor using gas_data.oxidising method absent compensation.
gas_nh3_raw REAL Ohms Read directly from sensor using gas_data.nh3 method absent compensation.
current_time REAL Unix time in Seconds Created by script upon reading values.

Air Quality Database

The following attributes are captured, by default, into tmdb.events.sqlite:

Attribute Description SQLite data type Valid values
entryDateTime Unix timestamp when data capture began on sensor REAL Unix timestamp in Seconds
gas_calibrated Indicates if gas sensors are fully "warmed up". Will be false until `gas_sensors_warmup_time` is met (default 10-minutes after sensor starts) REAL BOOLEAN, 1 = true / 0 = false
temp Temperature reading in degree Celsius measured directly from BME280 sensor with compensation factor set from device config. REAL
bar Barometer air pressure reading in bars (hPa) measured directly from BME280 sensor with compensation set for altitude from device config. REAL
hum Humidity reading in percent (%) measured directly from BME280 sensor with compensation factor set from device config. REAL
dew Calculated dew point in degree Celsius, based on temperature and humidity using the following calculation (Python) `(237.7 * (math.log(dew_hum/100)+17.271*dew_temp/(237.7+dew_temp))/(17.271 - math.log(dew_hum/100) - 17.271*dew_temp/(237.7 + dew_temp)))` REAL
temp_raw Temperature reading in degree Celsius measured directly from BME280 sensor absent of any compensation (raw values). REAL
bar_raw Barometer air pressure reading in bars (hPa) measured directly from BME280 sensor absent of any compensation (raw values). REAL
hum_raw Humidity reading in percent (%) measured directly from BME280 sensor absent of any compensation (raw values). REAL
pm01 Particulate Matter (PM) at 1 micrometers or greater in diameter in micrograms per cubic meter (ug/m3) measured directly from PM sensor. REAL 0-infinity
pm025 Particulate Matter (PM) at 2.5 micrometers or greater in diameter in micrograms per cubic meter (ug/m3) measured directly from PM sensor. REAL 0-infinity
pm10 Particulate Matter (PM) at 10 micrometers or greater in diameter in micrograms per cubic meter (ug/m3) measured directly from PM sensor. REAL 0-infinity
gas_red Reducing gases (RED) reading in Parts Per Million (PPM) measured directly from gas sensor with compensation factor set for drift. Eg hydrogen, carbon monoxide REAL 0-infinity
gas_oxi Oxidising gases (OX) reading in Parts Per Million (PPM) measured directly from gas sensor with compensation factor set for drift. Eg chlorine, nitrous oxide REAL 0-infinity
gas_nh3 Ammonia (NH3) reading in Parts Per Million (PPM) measured directly from gas sensor with compensation factor set for drift. Gas resistance for nh3/ammonia REAL 0-infinity
gas_red_raw Reducing gases (RED) reading in Ohms measured directly from gas sensor absent of any compensation (raw values). Eg hydrogen, carbon monoxide REAL 0-infinity
gas_oxi_raw Oxidising gases (OX) reading in Ohms measured directly from gas sensor absent of any compensation (raw values). Eg chlorine, nitrous oxide REAL 0-infinity
gas_nh3_raw Ammonia (NH3) reading in Ohms measured directly from gas sensor absent of any compensation (raw values). Gas resistance for nh3/ammonia REAL 0-infinity
lux Lux reading in Lux measured directly from optical sensor with proximity-adjusted minimum. REAL 0.01 to 64k lux
lux_raw Lux reading in Lux measured directly from optical sensor. REAL 0.01 to 64k lux
proximity Proximity reading measure directly from optical sensor. REAL 0-infinity
sensorName Air Quality sensor that captured the data. This field may be used to associate with other sensors. TEXT
deployment_id Each ID represents a unique deployment configuration and/or location for the device. This acts a foreign key link to the `deployment` table, `id` column. TEXT, FOREIGN KEY `deployment`.`id` foreign key, may be null

Notes on Air Quality readings

Gas sensor

The MICS6814 analog gas sensor: The MiCS-6814 is a robust MEMS sensor for the detection of pollution from automobile exhausts and for agricultural/industrial odors.

The sensor includes the ability to detect reductive (RED), oxidative (OXI), and ammonia (NH3) gases. The raw gas readings are measured as Ohms of resistance for their respective gasses, but the software compensates for temperature, humidity, altitude, and drift to provide PPM (parts per million) equivalents.*

*See Software notes and additional discussions on pimoroni/enviroplus-python #47 and pimoroni/enviroplus-python #67.

Software notes

  • Gas calibrates using Temp, Humidity, and Barometric Pressure readings.
  • Gas Sensors (Red, Oxi, NH3) take 100-minutes to warm-up and readings to become available
  • To compensate for gas sensor drift over time, the software calibrates gas sensors daily at time set by gas_daily_r0_calibration_hour, using average of daily readings over a week if not already done in the current day and if warm-up calibration is completed. This compensates for gas sensor drift over time
  • Raw gas readings will also have compensation factors applied, determined by regression analysis.

Temperature, pressure, and humidity

The BME280 temperature, pressure, humidity sensor with I2S digital output.

Info

The Raspberry Pi and AI co-processor generate a substantial amount of heat that may affect the temperature and humidity readings. The Traffic Monitor enclosure attempts to isolate the AQ sensors by physically separating the hardware, but further adjustments may need to be made.

Software notes

  • Temp (temperature) and Hum (humidity) have cubic polynomial compensation factors applied to raw readings
  • Min Tempand Max Tempare calculated over the entire time the script is running
  • Bar(Barometer) reading updates only every 20 minutes
  • Air pressure reading has an altitude compensation factor applied (defined in config.json)
  • Dew(Dew Point) is calculated from temperature and humidity using the following calculation:

    dewpoint = (237.7 * (math.log(dew_hum/100)+17.271*dew_temp/(237.7+dew_temp))/(17.271 - math.log(dew_hum/100) - 17.271*dew_temp/(237.7 + dew_temp)))
    

Optical (light, proximity)

The LTR-559 light and proximity sensor

Noise

MEMS microphone (datasheet).

Particulate matter (PM)

The Plantower PMS5003 Particulate Matter (PM) Sensor.