Skip to content

Air Quality

air_quality

air_quality domain implementation (read-only).

SPEC module-attribute

SPEC: DomainSpec[AirQuality] = register_domain(DomainSpec(name='air_quality', entity_cls=AirQuality))

The DomainSpec registered with the shared DomainRegistry.

AirQuality

Bases: Entity

A read-only Home Assistant air quality entity.

Exposes typed properties for the pollutant metrics the underlying integration chooses to report. Every metric returns None when the sensor does not provide that reading, so unsupported metrics degrade silently rather than raising. The entity is read-only; the HA air_quality domain exposes no service actions.

The Home Assistant air_quality platform reports its overall Air Quality Index (AQI) as the entity state and individual pollutants as attributes. air_quality_index therefore prefers an explicit air_quality_index attribute when present and falls back to the state string. All other metrics are read directly from attributes.

Source code in src/haclient/domains/air_quality.py
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
class AirQuality(Entity):
    """A read-only Home Assistant air quality entity.

    Exposes typed properties for the pollutant metrics the underlying
    integration chooses to report. Every metric returns ``None`` when
    the sensor does not provide that reading, so unsupported metrics
    degrade silently rather than raising. The entity is read-only; the
    HA ``air_quality`` domain exposes no service actions.

    The Home Assistant ``air_quality`` platform reports its overall Air
    Quality Index (AQI) as the entity *state* and individual pollutants
    as attributes. `air_quality_index` therefore prefers an explicit
    ``air_quality_index`` attribute when present and falls back to the
    state string. All other metrics are read directly from attributes.
    """

    domain = "air_quality"

    # -- Listener decorators ------------------------------------------

    def on_aqi_change(self, func: ValueChangeHandler) -> ValueChangeHandler:
        """Register a listener for Air Quality Index changes.

        Fires whenever the entity *state* string changes, which mirrors
        the HA convention of reporting the AQI as the entity state.

        Parameters
        ----------
        func : callable
            Sync or async callable receiving ``(old_state, new_state)``.

        Returns
        -------
        callable
            The same *func*, returned for decorator use.
        """
        return self._register_state_value_listener(func)

    def on_pm25_change(self, func: ValueChangeHandler) -> ValueChangeHandler:
        """Register a listener for PM2.5 attribute changes.

        Parameters
        ----------
        func : callable
            Callable receiving ``(old_value, new_value)`` for the
            ``particulate_matter_2_5`` attribute.

        Returns
        -------
        callable
            The same *func*, returned for decorator use.
        """
        return self._register_attr_listener("particulate_matter_2_5", func)

    def on_co2_change(self, func: ValueChangeHandler) -> ValueChangeHandler:
        """Register a listener for CO2 attribute changes.

        Parameters
        ----------
        func : callable
            Callable receiving ``(old_value, new_value)`` for the
            ``carbon_dioxide`` attribute.

        Returns
        -------
        callable
            The same *func*, returned for decorator use.
        """
        return self._register_attr_listener("carbon_dioxide", func)

    # -- State properties ---------------------------------------------

    @property
    def air_quality_index(self) -> float | int | None:
        """Overall Air Quality Index, if reported.

        Returns
        -------
        float, int, or None
            The explicit ``air_quality_index`` attribute when present,
            otherwise the numeric coercion of the entity state, or
            ``None`` when neither yields a number.
        """
        explicit = _coerce_numeric(self.attributes.get("air_quality_index"))
        if explicit is not None:
            return explicit
        return _coerce_numeric(self.state)

    @property
    def particulate_matter_2_5(self) -> float | int | None:
        """PM2.5 reading, typically in µg/m³."""
        return _coerce_numeric(self.attributes.get("particulate_matter_2_5"))

    @property
    def particulate_matter_10(self) -> float | int | None:
        """PM10 reading, typically in µg/m³."""
        return _coerce_numeric(self.attributes.get("particulate_matter_10"))

    @property
    def carbon_dioxide(self) -> float | int | None:
        """CO2 concentration, typically in ppm."""
        return _coerce_numeric(self.attributes.get("carbon_dioxide"))

    @property
    def carbon_monoxide(self) -> float | int | None:
        """CO concentration, typically in ppm."""
        return _coerce_numeric(self.attributes.get("carbon_monoxide"))

    @property
    def volatile_organic_compounds(self) -> float | int | None:
        """Volatile organic compound concentration, if reported."""
        return _coerce_numeric(self.attributes.get("volatile_organic_compounds"))

    @property
    def nitrogen_dioxide(self) -> float | int | None:
        """NO2 concentration, if reported."""
        return _coerce_numeric(self.attributes.get("nitrogen_dioxide"))

    @property
    def ozone(self) -> float | int | None:
        """Ozone concentration, if reported."""
        return _coerce_numeric(self.attributes.get("ozone"))

air_quality_index property

air_quality_index: float | int | None

Overall Air Quality Index, if reported.

Returns:

Type Description
float, int, or None

The explicit air_quality_index attribute when present, otherwise the numeric coercion of the entity state, or None when neither yields a number.

particulate_matter_2_5 property

particulate_matter_2_5: float | int | None

PM2.5 reading, typically in µg/m³.

particulate_matter_10 property

particulate_matter_10: float | int | None

PM10 reading, typically in µg/m³.

carbon_dioxide property

carbon_dioxide: float | int | None

CO2 concentration, typically in ppm.

carbon_monoxide property

carbon_monoxide: float | int | None

CO concentration, typically in ppm.

volatile_organic_compounds property

volatile_organic_compounds: float | int | None

Volatile organic compound concentration, if reported.

nitrogen_dioxide property

nitrogen_dioxide: float | int | None

NO2 concentration, if reported.

ozone property

ozone: float | int | None

Ozone concentration, if reported.

on_aqi_change

on_aqi_change(func: ValueChangeHandler) -> ValueChangeHandler

Register a listener for Air Quality Index changes.

Fires whenever the entity state string changes, which mirrors the HA convention of reporting the AQI as the entity state.

Parameters:

Name Type Description Default
func callable

Sync or async callable receiving (old_state, new_state).

required

Returns:

Type Description
callable

The same func, returned for decorator use.

Source code in src/haclient/domains/air_quality.py
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
def on_aqi_change(self, func: ValueChangeHandler) -> ValueChangeHandler:
    """Register a listener for Air Quality Index changes.

    Fires whenever the entity *state* string changes, which mirrors
    the HA convention of reporting the AQI as the entity state.

    Parameters
    ----------
    func : callable
        Sync or async callable receiving ``(old_state, new_state)``.

    Returns
    -------
    callable
        The same *func*, returned for decorator use.
    """
    return self._register_state_value_listener(func)

on_pm25_change

on_pm25_change(func: ValueChangeHandler) -> ValueChangeHandler

Register a listener for PM2.5 attribute changes.

Parameters:

Name Type Description Default
func callable

Callable receiving (old_value, new_value) for the particulate_matter_2_5 attribute.

required

Returns:

Type Description
callable

The same func, returned for decorator use.

Source code in src/haclient/domains/air_quality.py
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
def on_pm25_change(self, func: ValueChangeHandler) -> ValueChangeHandler:
    """Register a listener for PM2.5 attribute changes.

    Parameters
    ----------
    func : callable
        Callable receiving ``(old_value, new_value)`` for the
        ``particulate_matter_2_5`` attribute.

    Returns
    -------
    callable
        The same *func*, returned for decorator use.
    """
    return self._register_attr_listener("particulate_matter_2_5", func)

on_co2_change

on_co2_change(func: ValueChangeHandler) -> ValueChangeHandler

Register a listener for CO2 attribute changes.

Parameters:

Name Type Description Default
func callable

Callable receiving (old_value, new_value) for the carbon_dioxide attribute.

required

Returns:

Type Description
callable

The same func, returned for decorator use.

Source code in src/haclient/domains/air_quality.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
def on_co2_change(self, func: ValueChangeHandler) -> ValueChangeHandler:
    """Register a listener for CO2 attribute changes.

    Parameters
    ----------
    func : callable
        Callable receiving ``(old_value, new_value)`` for the
        ``carbon_dioxide`` attribute.

    Returns
    -------
    callable
        The same *func*, returned for decorator use.
    """
    return self._register_attr_listener("carbon_dioxide", func)