async def async_create_miio_device_and_coordinator( hass: core.HomeAssistant, entry: config_entries.ConfigEntry): """Set up a data coordinator and one miio device to service multiple entities.""" model = entry.data[CONF_MODEL] host = entry.data[CONF_HOST] token = entry.data[CONF_TOKEN] name = entry.title device = None migrate = False if model not in MODELS_HUMIDIFIER and model not in MODELS_FAN: return _LOGGER.debug("Initializing with host %s (token %s...)", host, token[:5]) # Humidifiers if model in MODELS_HUMIDIFIER_MIOT: device = AirHumidifierMiot(host, token) migrate = True elif model in MODELS_HUMIDIFIER_MJJSQ: device = AirHumidifierMjjsq(host, token, model=model) migrate = True elif model in MODELS_HUMIDIFIER_MIIO: device = AirHumidifier(host, token, model=model) migrate = True # Airpurifiers and Airfresh elif model in MODEL_AIRPURIFIER_3C: device = AirPurifierMB4(host, token) elif model in MODELS_PURIFIER_MIOT: device = AirPurifierMiot(host, token) elif model.startswith("zhimi.airpurifier."): device = AirPurifier(host, token) elif model.startswith("zhimi.airfresh."): device = AirFresh(host, token) # Pedestal fans elif model == MODEL_FAN_P5: device = FanP5(host, token) elif model in MODELS_FAN_MIIO: device = Fan(host, token, model=model) else: _LOGGER.error( "Unsupported device found! Please create an issue at " "https://github.com/syssi/xiaomi_airpurifier/issues " "and provide the following data: %s", model, ) return if migrate: # Removing fan platform entity for humidifiers and migrate the name to the config entry for migration entity_registry = er.async_get(hass) entity_id = entity_registry.async_get_entity_id( "fan", DOMAIN, entry.unique_id) if entity_id: # This check is entities that have a platform migration only and should be removed in the future if migrate_entity_name := entity_registry.async_get( entity_id).name: hass.config_entries.async_update_entry( entry, title=migrate_entity_name) entity_registry.async_remove(entity_id)
async def async_create_miio_device_and_coordinator( hass: core.HomeAssistant, entry: config_entries.ConfigEntry): """Set up a data coordinator and one miio device to service multiple entities.""" model = entry.data[CONF_MODEL] host = entry.data[CONF_HOST] token = entry.data[CONF_TOKEN] name = entry.title device = None if model not in MODELS_HUMIDIFIER: return _LOGGER.debug("Initializing with host %s (token %s...)", host, token[:5]) if model in MODELS_HUMIDIFIER_MIOT: device = AirHumidifierMiot(host, token) else: device = AirHumidifier(host, token, model=model) # Removing fan platform entity for humidifiers and migrate the name to the config entry for migration entity_registry = er.async_get(hass) entity_id = entity_registry.async_get_entity_id("fan", DOMAIN, entry.unique_id) if entity_id: # This check is entities that have a platform migration only and should be removed in the future if migrate_entity_name := entity_registry.async_get(entity_id).name: hass.config_entries.async_update_entry(entry, title=migrate_entity_name) entity_registry.async_remove(entity_id)
async def async_create_miio_device_and_coordinator( hass: HomeAssistant, entry: ConfigEntry ) -> None: """Set up a data coordinator and one miio device to service multiple entities.""" model: str = entry.data[CONF_MODEL] host = entry.data[CONF_HOST] token = entry.data[CONF_TOKEN] name = entry.title device: MiioDevice | None = None migrate = False update_method = _async_update_data_default coordinator_class: type[DataUpdateCoordinator] = DataUpdateCoordinator if ( model not in MODELS_HUMIDIFIER and model not in MODELS_FAN and model not in MODELS_VACUUM and not model.startswith(ROBOROCK_GENERIC) and not model.startswith(ROCKROBO_GENERIC) ): return _LOGGER.debug("Initializing with host %s (token %s...)", host, token[:5]) # Humidifiers if model in MODELS_HUMIDIFIER_MIOT: device = AirHumidifierMiot(host, token) migrate = True elif model in MODELS_HUMIDIFIER_MJJSQ: device = AirHumidifierMjjsq(host, token, model=model) migrate = True elif model in MODELS_HUMIDIFIER_MIIO: device = AirHumidifier(host, token, model=model) migrate = True # Airpurifiers and Airfresh elif model in MODELS_PURIFIER_MIOT: device = AirPurifierMiot(host, token) elif model.startswith("zhimi.airpurifier."): device = AirPurifier(host, token) elif model.startswith("zhimi.airfresh."): device = AirFresh(host, token) elif model == MODEL_AIRFRESH_A1: device = AirFreshA1(host, token) elif model == MODEL_AIRFRESH_T2017: device = AirFreshT2017(host, token) elif ( model in MODELS_VACUUM or model.startswith(ROBOROCK_GENERIC) or model.startswith(ROCKROBO_GENERIC) ): device = RoborockVacuum(host, token) update_method = _async_update_data_vacuum coordinator_class = DataUpdateCoordinator[VacuumCoordinatorData] # Pedestal fans elif model in MODEL_TO_CLASS_MAP: device = MODEL_TO_CLASS_MAP[model](host, token) elif model in MODELS_FAN_MIIO: device = Fan(host, token, model=model) else: _LOGGER.error( "Unsupported device found! Please create an issue at " "https://github.com/syssi/xiaomi_airpurifier/issues " "and provide the following data: %s", model, ) return if migrate: # Removing fan platform entity for humidifiers and migrate the name to the config entry for migration entity_registry = er.async_get(hass) assert entry.unique_id entity_id = entity_registry.async_get_entity_id("fan", DOMAIN, entry.unique_id) if entity_id: # This check is entities that have a platform migration only and should be removed in the future if (entity := entity_registry.async_get(entity_id)) and ( migrate_entity_name := entity.name ): hass.config_entries.async_update_entry(entry, title=migrate_entity_name)
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up the miio fan device from config.""" if DATA_KEY not in hass.data: hass.data[DATA_KEY] = {} host = config[CONF_HOST] token = config[CONF_TOKEN] name = config[CONF_NAME] model = config.get(CONF_MODEL) _LOGGER.info("Initializing with host %s (token %s...)", host, token[:5]) unique_id = None if model is None: try: miio_device = Device(host, token) device_info = await hass.async_add_executor_job(miio_device.info) model = device_info.model unique_id = f"{model}-{device_info.mac_address}" _LOGGER.info( "%s %s %s detected", model, device_info.firmware_version, device_info.hardware_version, ) except DeviceException as ex: raise PlatformNotReady from ex if model in PURIFIER_MIOT: air_purifier = AirPurifierMiot(host, token) device = XiaomiAirPurifierMiot(name, air_purifier, model, unique_id) elif model.startswith("zhimi.airpurifier."): air_purifier = AirPurifier(host, token) device = XiaomiAirPurifier(name, air_purifier, model, unique_id) elif model in HUMIDIFIER_MIOT: air_humidifier = AirHumidifierMiot(host, token) device = XiaomiAirHumidifierMiot(name, air_humidifier, model, unique_id) elif model.startswith("zhimi.humidifier."): air_humidifier = AirHumidifier(host, token, model=model) device = XiaomiAirHumidifier(name, air_humidifier, model, unique_id) elif model.startswith("zhimi.airfresh."): air_fresh = AirFresh(host, token) device = XiaomiAirFresh(name, air_fresh, model, unique_id) else: _LOGGER.error( "Unsupported device found! Please create an issue at " "https://github.com/syssi/xiaomi_airpurifier/issues " "and provide the following data: %s", model, ) return False hass.data[DATA_KEY][host] = device async_add_entities([device], update_before_add=True) async def async_service_handler(service): """Map services to methods on XiaomiAirPurifier.""" method = SERVICE_TO_METHOD.get(service.service) params = { key: value for key, value in service.data.items() if key != ATTR_ENTITY_ID } entity_ids = service.data.get(ATTR_ENTITY_ID) if entity_ids: devices = [ device for device in hass.data[DATA_KEY].values() if device.entity_id in entity_ids ] else: devices = hass.data[DATA_KEY].values() update_tasks = [] for device in devices: if not hasattr(device, method["method"]): continue await getattr(device, method["method"])(**params) update_tasks.append(device.async_update_ha_state(True)) if update_tasks: await asyncio.wait(update_tasks) for air_purifier_service in SERVICE_TO_METHOD: schema = SERVICE_TO_METHOD[air_purifier_service].get( "schema", AIRPURIFIER_SERVICE_SCHEMA) hass.services.async_register(DOMAIN, air_purifier_service, async_service_handler, schema=schema)
async def async_setup_entry(opp, config_entry, async_add_entities): """Set up the Fan from a config entry.""" entities = [] if config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE: if DATA_KEY not in opp.data: opp.data[DATA_KEY] = {} 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 MODELS_PURIFIER_MIOT: air_purifier = AirPurifierMiot(host, token) entity = XiaomiAirPurifierMiot(name, air_purifier, config_entry, unique_id, allowed_failures=2) elif model.startswith("zhimi.airpurifier."): air_purifier = AirPurifier(host, token) entity = XiaomiAirPurifier(name, air_purifier, config_entry, unique_id) elif model in MODELS_HUMIDIFIER_MIOT: air_humidifier = AirHumidifierMiot(host, token) entity = XiaomiAirHumidifierMiot(name, air_humidifier, config_entry, unique_id) elif model.startswith("zhimi.humidifier."): air_humidifier = AirHumidifier(host, token, model=model) entity = XiaomiAirHumidifier(name, air_humidifier, config_entry, unique_id) elif model.startswith("zhimi.airfresh."): air_fresh = AirFresh(host, token) entity = XiaomiAirFresh(name, air_fresh, config_entry, unique_id) else: _LOGGER.error( "Unsupported device found! Please create an issue at " "https://github.com/syssi/xiaomi_airpurifier/issues " "and provide the following data: %s", model, ) return opp.data[DATA_KEY][host] = entity entities.append(entity) async def async_service_handler(service): """Map services to methods on XiaomiAirPurifier.""" method = SERVICE_TO_METHOD[service.service] params = { key: value for key, value in service.data.items() if key != ATTR_ENTITY_ID } entity_ids = service.data.get(ATTR_ENTITY_ID) if entity_ids: entities = [ entity for entity in opp.data[DATA_KEY].values() if entity.entity_id in entity_ids ] else: entities = opp.data[DATA_KEY].values() update_tasks = [] for entity in entities: entity_method = getattr(entity, method["method"], None) if not entity_method: continue await entity_method(**params) update_tasks.append( opp.async_create_task(entity.async_update_op_state(True))) if update_tasks: await asyncio.wait(update_tasks) for air_purifier_service in SERVICE_TO_METHOD: schema = SERVICE_TO_METHOD[air_purifier_service].get( "schema", AIRPURIFIER_SERVICE_SCHEMA) opp.services.async_register(DOMAIN, air_purifier_service, async_service_handler, schema=schema) async_add_entities(entities, update_before_add=True)