1 """Support for Xiaomi Mi Air Quality Monitor (PM2.5)."""
3 from collections.abc
import Callable
6 from miio
import AirQualityMonitor, AirQualityMonitorCGDN1, DeviceException
16 MODEL_AIRQUALITYMONITOR_B1,
17 MODEL_AIRQUALITYMONITOR_CGDN1,
18 MODEL_AIRQUALITYMONITOR_S1,
19 MODEL_AIRQUALITYMONITOR_V1,
21 from .entity
import XiaomiMiioEntity
23 _LOGGER = logging.getLogger(__name__)
25 DEFAULT_NAME =
"Xiaomi Miio Air Quality Monitor"
27 ATTR_CO2E =
"carbon_dioxide_equivalent"
28 ATTR_TVOC =
"total_volatile_organic_compounds"
29 ATTR_TEMP =
"temperature"
33 "carbon_dioxide_equivalent": ATTR_CO2E,
34 "total_volatile_organic_compounds": ATTR_TVOC,
35 "temperature": ATTR_TEMP,
41 """Air Quality class for Xiaomi cgllc.airmonitor.b1 device."""
43 def __init__(self, name, device, entry, unique_id):
44 """Initialize the entity."""
45 super().
__init__(name, device, entry, unique_id)
58 """Fetch state from the miio device."""
60 state = await self.
hasshass.async_add_executor_job(self.
_device_device.status)
61 _LOGGER.debug(
"Got new state: %s", state)
65 self.
_temperature_temperature = round(state.temperature, 2)
66 self.
_humidity_humidity = round(state.humidity, 2)
68 except DeviceException
as ex:
70 _LOGGER.error(
"Got exception while fetching the state: %s", ex)
74 """Return the icon to use for device if any."""
75 return self.
_icon_icon
79 """Return true when state is known."""
84 """Return the Air Quality Index (AQI)."""
89 """Return the CO2 (carbon dioxide) level."""
94 """Return the CO2e (carbon dioxide equivalent) level."""
99 """Return the particulate matter 2.5 level."""
104 """Return the total volatile organic compounds."""
109 """Return the current temperature."""
114 """Return the current humidity."""
119 """Return the state attributes."""
122 for prop, attr
in PROP_TO_ATTR.items():
123 if (value := getattr(self, prop))
is not None:
130 """Air Quality class for Xiaomi cgllc.airmonitor.s1 device."""
133 """Fetch state from the miio device."""
135 state = await self.
hasshass.async_add_executor_job(self.
_device_device.status)
136 _LOGGER.debug(
"Got new state: %s", state)
143 except DeviceException
as ex:
146 _LOGGER.error(
"Got exception while fetching the state: %s", ex)
150 """Air Quality class for Xiaomi cgllc.airmonitor.s1 device."""
153 """Fetch state from the miio device."""
155 state = await self.
hasshass.async_add_executor_job(self.
_device_device.status)
156 _LOGGER.debug(
"Got new state: %s", state)
159 except DeviceException
as ex:
162 _LOGGER.error(
"Got exception while fetching the state: %s", ex)
166 """Return the unit of measurement."""
171 """Air Quality class for cgllc.airm.cgdn1 device."""
173 def __init__(self, name, device, entry, unique_id):
174 """Initialize the entity."""
175 super().
__init__(name, device, entry, unique_id)
184 """Fetch state from the miio device."""
186 state = await self.
hasshass.async_add_executor_job(self.
_device_device.status)
187 _LOGGER.debug(
"Got new state: %s", state)
192 except DeviceException
as ex:
194 _LOGGER.error(
"Got exception while fetching the state: %s", ex)
198 """Return the icon to use for device if any."""
199 return self.
_icon_icon
203 """Return true when state is known."""
208 """Return the CO2 (carbon dioxide) level."""
213 """Return the particulate matter 2.5 level."""
218 """Return the particulate matter 10 level."""
222 DEVICE_MAP: dict[str, dict[str, Callable]] = {
223 MODEL_AIRQUALITYMONITOR_S1: {
224 "device_class": AirQualityMonitor,
225 "entity_class": AirMonitorS1,
227 MODEL_AIRQUALITYMONITOR_B1: {
228 "device_class": AirQualityMonitor,
229 "entity_class": AirMonitorB1,
231 MODEL_AIRQUALITYMONITOR_V1: {
232 "device_class": AirQualityMonitor,
233 "entity_class": AirMonitorV1,
235 MODEL_AIRQUALITYMONITOR_CGDN1: {
236 "device_class":
lambda host, token, model: AirQualityMonitorCGDN1(host, token),
237 "entity_class": AirMonitorCGDN1,
244 config_entry: ConfigEntry,
245 async_add_entities: AddEntitiesCallback,
247 """Set up the Xiaomi Air Quality from a config entry."""
250 if config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE:
251 host = config_entry.data[CONF_HOST]
252 token = config_entry.data[CONF_TOKEN]
253 name = config_entry.title
254 model = config_entry.data[CONF_MODEL]
255 unique_id = config_entry.unique_id
257 _LOGGER.debug(
"Initializing with host %s (token %s...)", host, token[:5])
259 if model
in DEVICE_MAP:
260 device_entry = DEVICE_MAP[model]
262 device_entry[
"entity_class"](
264 device_entry[
"device_class"](host, token, model=model),
270 _LOGGER.warning(
"AirQualityMonitor model '%s' is not yet supported", model)
def extra_state_attributes(self)
def __init__(self, name, device, entry, unique_id)
def particulate_matter_2_5(self)
def carbon_dioxide_equivalent(self)
_carbon_dioxide_equivalent
def air_quality_index(self)
_total_volatile_organic_compounds
def total_volatile_organic_compounds(self)
def __init__(self, name, device, entry, unique_id)
def particulate_matter_2_5(self)
def particulate_matter_10(self)
_total_volatile_organic_compounds
def unit_of_measurement(self)
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)