diff --git a/homeassistant/components/xiaomi_miio/air_quality.py b/homeassistant/components/xiaomi_miio/air_quality.py index 1a5aabcc141..4b56c60cd82 100644 --- a/homeassistant/components/xiaomi_miio/air_quality.py +++ b/homeassistant/components/xiaomi_miio/air_quality.py @@ -1,7 +1,7 @@ """Support for Xiaomi Mi Air Quality Monitor (PM2.5).""" import logging -from miio import AirQualityMonitor, DeviceException +from miio import AirQualityMonitor, AirQualityMonitorCGDN1, DeviceException import voluptuous as vol from homeassistant.components.air_quality import PLATFORM_SCHEMA, AirQualityEntity @@ -15,6 +15,7 @@ from .const import ( CONF_MODEL, DOMAIN, MODEL_AIRQUALITYMONITOR_B1, + MODEL_AIRQUALITYMONITOR_CGDN1, MODEL_AIRQUALITYMONITOR_S1, MODEL_AIRQUALITYMONITOR_V1, ) @@ -45,48 +46,6 @@ PROP_TO_ATTR = { } -async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): - """Import Miio configuration from YAML.""" - _LOGGER.warning( - "Loading Xiaomi Miio Air Quality via platform setup is deprecated. " - "Please remove it from your configuration" - ) - hass.async_create_task( - hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_IMPORT}, - data=config, - ) - ) - - -async def async_setup_entry(hass, config_entry, async_add_entities): - """Set up the Xiaomi Air Quality from a config entry.""" - entities = [] - - if config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE: - host = config_entry.data[CONF_HOST] - token = config_entry.data[CONF_TOKEN] - name = config_entry.title - model = config_entry.data[CONF_MODEL] - unique_id = config_entry.unique_id - - _LOGGER.debug("Initializing with host %s (token %s...)", host, token[:5]) - - device = AirQualityMonitor(host, token, model=model) - - if model == MODEL_AIRQUALITYMONITOR_S1: - entities.append(AirMonitorS1(name, device, config_entry, unique_id)) - elif model == MODEL_AIRQUALITYMONITOR_B1: - entities.append(AirMonitorB1(name, device, config_entry, unique_id)) - elif model == MODEL_AIRQUALITYMONITOR_V1: - entities.append(AirMonitorV1(name, device, config_entry, unique_id)) - else: - _LOGGER.warning("AirQualityMonitor model '%s' is not yet supported", model) - - async_add_entities(entities, update_before_add=True) - - class AirMonitorB1(XiaomiMiioEntity, AirQualityEntity): """Air Quality class for Xiaomi cgllc.airmonitor.b1 device.""" @@ -216,3 +175,119 @@ class AirMonitorV1(AirMonitorB1): def unit_of_measurement(self): """Return the unit of measurement.""" return None + + +class AirMonitorCGDN1(XiaomiMiioEntity, AirQualityEntity): + """Air Quality class for cgllc.airm.cgdn1 device.""" + + def __init__(self, name, device, entry, unique_id): + """Initialize the entity.""" + super().__init__(name, device, entry, unique_id) + + self._icon = "mdi:cloud" + self._available = None + self._carbon_dioxide = None + self._particulate_matter_2_5 = None + self._particulate_matter_10 = None + + async def async_update(self): + """Fetch state from the miio device.""" + try: + state = await self.hass.async_add_executor_job(self._device.status) + _LOGGER.debug("Got new state: %s", state) + self._carbon_dioxide = state.co2 + self._particulate_matter_2_5 = round(state.pm25, 1) + self._particulate_matter_10 = round(state.pm10, 1) + self._available = True + except DeviceException as ex: + self._available = False + _LOGGER.error("Got exception while fetching the state: %s", ex) + + @property + def icon(self): + """Return the icon to use for device if any.""" + return self._icon + + @property + def available(self): + """Return true when state is known.""" + return self._available + + @property + def carbon_dioxide(self): + """Return the CO2 (carbon dioxide) level.""" + return self._carbon_dioxide + + @property + def particulate_matter_2_5(self): + """Return the particulate matter 2.5 level.""" + return self._particulate_matter_2_5 + + @property + def particulate_matter_10(self): + """Return the particulate matter 10 level.""" + return self._particulate_matter_10 + + +DEVICE_MAP = { + MODEL_AIRQUALITYMONITOR_S1: { + "device_class": AirQualityMonitor, + "entity_class": AirMonitorS1, + }, + MODEL_AIRQUALITYMONITOR_B1: { + "device_class": AirQualityMonitor, + "entity_class": AirMonitorB1, + }, + MODEL_AIRQUALITYMONITOR_V1: { + "device_class": AirQualityMonitor, + "entity_class": AirMonitorV1, + }, + MODEL_AIRQUALITYMONITOR_CGDN1: { + "device_class": lambda host, token, model: AirQualityMonitorCGDN1(host, token), + "entity_class": AirMonitorCGDN1, + }, +} + + +async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): + """Import Miio configuration from YAML.""" + _LOGGER.warning( + "Loading Xiaomi Miio Air Quality via platform setup is deprecated. " + "Please remove it from your configuration" + ) + hass.async_create_task( + hass.config_entries.flow.async_init( + DOMAIN, + context={"source": SOURCE_IMPORT}, + data=config, + ) + ) + + +async def async_setup_entry(hass, config_entry, async_add_entities): + """Set up the Xiaomi Air Quality from a config entry.""" + entities = [] + + if config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE: + host = config_entry.data[CONF_HOST] + token = config_entry.data[CONF_TOKEN] + name = config_entry.title + model = config_entry.data[CONF_MODEL] + unique_id = config_entry.unique_id + + _LOGGER.debug("Initializing with host %s (token %s...)", host, token[:5]) + + if model in DEVICE_MAP: + device_entry = DEVICE_MAP[model] + entities.append( + device_entry["entity_class"]( + name, + device_entry["device_class"](host, token, model=model), + config_entry, + unique_id, + ) + ) + else: + _LOGGER.warning("AirQualityMonitor model '%s' is not yet supported", model) + + async_add_entities(entities, update_before_add=True) diff --git a/homeassistant/components/xiaomi_miio/const.py b/homeassistant/components/xiaomi_miio/const.py index e4084542e13..9b33bab08f7 100644 --- a/homeassistant/components/xiaomi_miio/const.py +++ b/homeassistant/components/xiaomi_miio/const.py @@ -66,6 +66,7 @@ MODELS_FAN_MIIO = [ MODEL_AIRQUALITYMONITOR_V1 = "zhimi.airmonitor.v1" MODEL_AIRQUALITYMONITOR_B1 = "cgllc.airmonitor.b1" MODEL_AIRQUALITYMONITOR_S1 = "cgllc.airmonitor.s1" +MODEL_AIRQUALITYMONITOR_CGDN1 = "cgllc.airm.cgdn1" # Light Models MODELS_LIGHT_EYECARE = ["philips.light.sread1"] @@ -106,6 +107,7 @@ MODELS_AIR_MONITOR = [ MODEL_AIRQUALITYMONITOR_V1, MODEL_AIRQUALITYMONITOR_B1, MODEL_AIRQUALITYMONITOR_S1, + MODEL_AIRQUALITYMONITOR_CGDN1, ] MODELS_ALL_DEVICES = (