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

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

pm2.5

Air Quality Measurement (0x005D)

measuredValue (scaled ×100)

µg/m³

pm1.0

Air Quality Measurement (0x005D)

pm1Density (scaled ×100)

µg/m³

pm10.0

Air Quality Measurement (0x005D)

pm10Density (scaled ×100)

µg/m³

voc

Air Quality Measurement (0x005D)

vocDensity (scaled ×100)

µg/m³

(computed)

Air Quality Measurement (0x005D)

airQuality enum

category

(computed)

Air Quality Measurement (0x005D)

aqiRating enum

rating

temperature (°F)

Temperature Measurement (0x0402)

measuredValue (scaled ×100)

°C

humidity

Relative Humidity Measurement (0x0405)

measuredValue (scaled ×100)

%

pressure (PSI)

Barometric Pressure Measurement (0x0403)

measuredValue (scaled ×10)

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 → 2345

  • Humidity: round(percent  × 100) — e.g., 45.6 % → 4560

  • Pressure: round(kPa     × 10) — e.g., 101.3 kPa → 1013

  • PM 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 airQuality Value

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:

Author: carlkidcrypto Repository: <https://github.com/carlkidcrypto/purpleair_api>

class PurpleAirMatterConverter.EpaAqiCalculator

Bases: object

Converts 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 pm25 is 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: Enum

Matter 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 MatterAirQualityRating enum member.

class PurpleAirMatterConverter.PurpleAirMatterConverter(purpleair_sensor_data: dict[str, Any] | None = None)

Bases: object

Converts 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 PurpleAirMatterConverter instance.

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)}")