Esempio n. 1
0
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)
Esempio n. 2
0
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)
Esempio n. 3
0
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)
Esempio n. 4
0
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)
Esempio n. 5
0
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)