PurpleAirMatterConverter module¶
Overview¶
The purpleair_api.PurpleAirMatterConverter module maps PurpleAir sensor readings to
Matter-compatible device type structures per the Matter 1.5.1 Core
Specification (Connectivity Standards Alliance, 2024).
This enables PurpleAir sensors to be exposed through any Matter-compatible bridge — including Apple Home, Google Home, Amazon Alexa, Samsung SmartThings, and Home Assistant — by providing data in the canonical format those platforms consume.
Note
This module generates Matter device data structures. It does not
implement the full Matter protocol stack. A Matter bridge (e.g.
python-matter-server or the Home Assistant Matter integration) is
required to actually commission and serve these devices on a Matter network.
References¶
Matter 1.5.1 Core Specification — Connectivity Standards Alliance, 2024.
Matter Air Quality Sensor Device Type — Section 11.3, Matter Device Library.
Air Quality Measurement Cluster (0x005D) — Matter.js implementation reference.
Temperature Measurement Cluster (0x0402) — Matter.js implementation reference.
Relative Humidity Measurement Cluster (0x0405) — Matter.js implementation reference.
Barometric Pressure Measurement Cluster (0x0403) — Matter.js implementation reference.
EPA AQI Technical Assistance Document (2012 revision) — AQI breakpoint table and formula.
python-matter-server — Reference Python Matter bridge server.
Installation¶
PurpleAirMatterConverter is included with the purpleair_api package.
No additional dependencies are required beyond requests.
pip install purpleair_api
Quick Start¶
from purpleair_api.PurpleAirReadAPI import PurpleAirReadAPI
from purpleair_api.PurpleAirMatterConverter import PurpleAirMatterConverter
# Fetch sensor data from PurpleAir
pa = PurpleAirReadAPI("YOUR_PURPLEAIR_READ_API_KEY")
raw = pa.request_sensor_data(282168)
# Convert to Matter Air Quality Sensor structure
matter_device = PurpleAirMatterConverter.to_air_quality_sensor(raw)
print(matter_device["device_type"]) # {'id': 45, 'label': 'Air Quality Sensor', ...}
print(matter_device["air_quality_summary"]) # {'epa_aqi': 68, 'epa_category': 'Moderate', ...}
Field Mapping¶
The following table shows how PurpleAir API fields map to Matter clusters and attributes.
PurpleAir Field |
Matter Cluster |
Matter Attribute |
Unit |
|---|---|---|---|
|
Air Quality Measurement (0x005D) |
|
µg/m³ |
|
Air Quality Measurement (0x005D) |
|
µg/m³ |
|
Air Quality Measurement (0x005D) |
|
µg/m³ |
|
Air Quality Measurement (0x005D) |
|
µg/m³ |
(computed) |
Air Quality Measurement (0x005D) |
|
category |
(computed) |
Air Quality Measurement (0x005D) |
|
rating |
|
Temperature Measurement (0x0402) |
|
°C |
|
Relative Humidity Measurement (0x0405) |
|
% |
|
Barometric Pressure Measurement (0x0403) |
|
kPa |
Matter Scaled-Integer Convention¶
Matter clusters store numeric values as scaled integers to avoid floating-point complexity in the protocol:
Temperature:
round(celsius × 100)— e.g., 23.45 °C → 2345Humidity:
round(percent × 100)— e.g., 45.6 % → 4560Pressure:
round(kPa × 10)— e.g., 101.3 kPa → 1013PM densities:
round(ug_m3 × 100)— e.g., 12.3 µg/m³ → 1230
The _raw fields in the output dictionary retain the original floating-point
values for debugging and display purposes.
EPA AQI Computation¶
PurpleAir provides raw PM2.5 readings but not the EPA Air Quality Index.
EpaAqiCalculator applies the EPA’s piecewise-linear formula:
AQI = ((I_high - I_low) / (C_high - C_low)) × (C - C_low) + I_low
Where:
C = PM2.5 24-hour average concentration (µg/m³)
C_low, C_high = concentration breakpoints from the EPA table
I_low, I_high = AQI breakpoints corresponding to
C_low, C_high
Matter Air Quality Rating is then derived from the computed AQI:
AQI Range |
EPA Category |
Matter |
|---|---|---|
0–50 |
Good |
1 (Excellent) |
51–100 |
Moderate |
2 (Good) |
101–150 |
Unhealthy for Sensitive Groups |
3 (Fair) |
151–200 |
Unhealthy |
4 (Poor) |
201–300 |
Very Unhealthy |
5 (Very Poor) |
301–500 |
Hazardous |
6 (Extremely Poor) |
< 0 / unknown |
— |
0 (Unknown) |
API Reference¶
Copyright 2024 carlkidcrypto, All rights reserved.
Matter Device Converter for PurpleAir Sensors.
Maps PurpleAir sensor readings to Matter device type structures per the Connectivity Standards Alliance Matter 1.5.1 Specification.
- References:
Matter 1.5.1 Core Specification (CSA, 2024) <https://csa-iot.org/developer-resource/specifications/>
Air Quality Sensor Device Type (Section 11.3, Device Library)
Air Quality Measurement Cluster (Cluster 0x005D / 93)
Temperature Measurement Cluster (Cluster 0x0402 / 1026)
Relative Humidity Measurement Cluster (Cluster 0x0405 / 1029)
Barometric Pressure Measurement Cluster (Cluster 0x0403 / 1027)
PM1.0, PM2.5, PM10.0 Matter Air Quality Measured Values <https://github.com/project-chip/matter.js>
EPA AQI Calculation <https://www.airnow.gov/sites/default/files/2022-05/AQI-Basics-Calculation.pdf>
Author: carlkidcrypto Repository: <https://github.com/carlkidcrypto/purpleair_api>
- class PurpleAirMatterConverter.EpaAqiCalculator¶
Bases:
objectConverts a PM2.5 concentration (µg/m³) to an EPA AQI value using the piecewise-linear table defined in the EPA’s AQI Technical Assistance document (revised 2012).
- Breakpoints are taken from the official EPA table:
<https://airnow.gov/sites/default/files/2021-03/AQI-Breakpoints.pdf>
AQI Category
PM2.5 (µg/m³)
AQI Range
Good
0.0 - 12.0
0 - 50
Moderate
12.1 - 35.4
51 - 100
Unhealthy for Sensitive Groups
35.5 - 55.4
101 - 150
Unhealthy
55.5 - 150.4
151 - 200
Very Unhealthy
150.5 - 250.4
201 - 300
Hazardous
250.5 - 500.4
301 - 500
- BREAKPOINTS: list[tuple[float, float, int, int]] = [(0.0, 12.0, 0, 50), (12.1, 35.4, 51, 100), (35.5, 55.4, 101, 150), (55.5, 150.4, 151, 200), (150.5, 250.4, 201, 300), (250.5, 500.4, 301, 500)]¶
- classmethod aqi_to_epa_category(aqi: float) str¶
Return the EPA AQI category name for a given AQI value.
- Parameters:
aqi – EPA AQI value.
- Returns:
Human-readable category string.
- classmethod pm25_to_aqi(pm25: float) float¶
Convert a 24-hour average PM2.5 concentration to an EPA AQI.
Uses the EPA formula:
AQI = ((I_high - I_low) / (C_high - C_low)) * (C - C_low) + I_low
- Parameters:
pm25 – 24-hour average PM2.5 concentration in µg/m³.
- Returns:
EPA AQI value rounded to the nearest integer (int).
- Raises:
ValueError – if
pm25is negative.
- PurpleAirMatterConverter.MATTER_CLUSTER_AIR_QUALITY_MEASUREMENT = 93¶
Matter 1.5.1 Air Quality Measurement cluster ID.
- PurpleAirMatterConverter.MATTER_CLUSTER_CO2_MEASUREMENT = 1037¶
Matter 1.5.1 Carbon Dioxide Measurement cluster ID.
- PurpleAirMatterConverter.MATTER_CLUSTER_HUMIDITY_MEASUREMENT = 1029¶
Matter 1.5.1 Relative Humidity Measurement cluster ID.
- PurpleAirMatterConverter.MATTER_CLUSTER_PRESSURE_MEASUREMENT = 1027¶
Matter 1.5.1 Barometric Pressure Measurement cluster ID.
- PurpleAirMatterConverter.MATTER_CLUSTER_TEMP_MEASUREMENT = 1026¶
Matter 1.5.1 Temperature Measurement cluster ID.
- PurpleAirMatterConverter.MATTER_DEVICE_TYPE_AIR_QUALITY_SENSOR = 45¶
Matter 1.5.1 Air Quality Sensor Device Type identifier (decimal 45).
- class PurpleAirMatterConverter.MatterAirQualityRating(*values)¶
Bases:
EnumMatter Air Quality Rating (attribute 0x0008 of Air Quality Measurement).
These match the Matter 1.5.1 specification values.
Label
Value
AQI Range
Unknown
0
sensor unavailable
Excellent
1
0-50
Good
2
51-100
Fair
3
101-150
Poor
4
151-200
Very Poor
5
201-300
Extremely Poor
6
301-500
- EXCELLENT = 1¶
- EXTREMELY_POOR = 6¶
- FAIR = 3¶
- GOOD = 2¶
- POOR = 4¶
- UNKNOWN = 0¶
- VERY_POOR = 5¶
- classmethod from_aqi(aqi: float) MatterAirQualityRating¶
Derive a Matter Air Quality Rating from an EPA AQI value.
- Parameters:
aqi – EPA AQI value.
- Returns:
Nearest
MatterAirQualityRatingenum member.
- class PurpleAirMatterConverter.PurpleAirMatterConverter(purpleair_sensor_data: dict[str, Any] | None = None)¶
Bases:
objectConverts raw PurpleAir API sensor data into Matter-compatible device structures per Matter Specification 1.5.1 (CSA, 2024).
Example — Air Quality Sensor:
from purpleair_api.PurpleAirReadAPI import PurpleAirReadAPI from purpleair_api.PurpleAirMatterConverter import PurpleAirMatterConverter pa = PurpleAirReadAPI("YOUR_READ_API_KEY") raw = pa.request_sensor_data(282168) matter_device = PurpleAirMatterConverter.to_air_quality_sensor(raw) print(matter_device)
- Attributes:
DEFAULT_SENSOR_INDEX (int): Default sensor index value. MATTER_VERSION (str): Supported Matter specification version.
- DEFAULT_SENSOR_INDEX: int = -1¶
- MATTER_VERSION: str = '1.5.1'¶
- static to_air_quality_sensor(purpleair_data: dict[str, Any], sensor_name: str | None = None) dict[str, Any]¶
Convert PurpleAir sensor data into a Matter Air Quality Sensor device type structure (Matter 1.5.1, Device Type 0x002D).
Maps the following PurpleAir fields to Matter clusters: ========================== =============================== =========== PurpleAir Field Matter Cluster / Attribute Unit ========================== =============================== =========== pm2.5 (primary) Air Quality / measuredValue µg/m³ × 100 pm1.0 Air Quality / pm1Density µg/m³ × 100 pm10.0 Air Quality / pm10Density µg/m³ × 100 voc Air Quality / vocDensity µg/m³ × 100 (calculated) Air Quality / airQuality enum (calculated) Air Quality / aqiRating enum temperature (°F → °C) Temperature / measuredValue °C × 100 humidity (%) Humidity / measuredValue % × 100 pressure (psi → kPa) Pressure / measuredValue kPa × 10 ========================== =============================== ===========
EPA AQI is computed from the PM2.5 concentration using
EpaAqiCalculator.- Parameters:
purpleair_data – Raw PurpleAir sensor data dict.
sensor_name – Optional display name override for the device.
- Returns:
Dictionary representing a Matter Air Quality Sensor endpoint.
- static to_environmental_sensor(purpleair_data: dict[str, Any], sensor_name: str | None = None) dict[str, Any]¶
Convert PurpleAir data into a Matter Humidity / Environmental Sensor device type (Matter 1.5.1, Device Type 0x0307).
Exposes temperature, humidity, and barometric pressure on a single endpoint.
- Parameters:
purpleair_data – Raw PurpleAir sensor data dict.
sensor_name – Optional display name override.
- Returns:
Matter Environmental Sensor endpoint structure.
- static to_temperature_sensor(purpleair_data: dict[str, Any], sensor_name: str | None = None) dict[str, Any]¶
Convert PurpleAir data into a Matter Temperature Sensor device type (Matter 1.5.1, Device Type 0x0302).
- Parameters:
purpleair_data – Raw PurpleAir sensor data dict.
sensor_name – Optional display name override.
- Returns:
Matter Temperature Sensor endpoint structure.
- with_data(data: dict[str, Any]) PurpleAirMatterConverter¶
Return a new converter instance populated with
data. Allows chaining without mutation.- Parameters:
data – Raw PurpleAir sensor data dictionary.
- Returns:
New
PurpleAirMatterConverterinstance.
- PurpleAirMatterConverter.fahrenheit_to_celsius(fahrenheit: float) float¶
Convert Fahrenheit temperature to Celsius.
Formula: °C = (°F − 32) × 5/9
- Parameters:
fahrenheit – Temperature in degrees Fahrenheit.
- Returns:
Temperature in degrees Celsius (unrounded; caller rounds as needed).
- PurpleAirMatterConverter.pressure_psi_to_kpa(psi: float) float¶
Convert pressure in PSI to kPa.
1 PSI = 6.89476 kPa.
- Parameters:
psi – Pressure in pounds per square inch.
- Returns:
Pressure in kilopascals, rounded to 3 decimal places.
Example — All Device Types¶
from purpleair_api.PurpleAirReadAPI import PurpleAirReadAPI
from purpleair_api.PurpleAirMatterConverter import PurpleAirMatterConverter
pa = PurpleAirReadAPI("YOUR_READ_API_KEY")
data = pa.request_sensor_data(282168)
# Air Quality Sensor (full)
aqs = PurpleAirMatterConverter.to_air_quality_sensor(data)
# Temperature-only sensor
tmp = PurpleAirMatterConverter.to_temperature_sensor(data)
# Environmental sensor (temp + humidity + pressure)
env = PurpleAirMatterConverter.to_environmental_sensor(data)
# EPA AQI directly
from purpleair_api.PurpleAirMatterConverter import EpaAqiCalculator
aqi = EpaAqiCalculator.pm25_to_aqi(data["sensor"]["pm2.5"])
print(f"AQI: {aqi} — {EpaAqiCalculator.aqi_to_epa_category(aqi)}")