def setup(hass, config):
    'Set up the Xiaomi component.'
    gateways = []
    interface = 'any'
    discovery_retry = 3
    if (DOMAIN in config):
        gateways = config[DOMAIN][CONF_GATEWAYS]
        interface = config[DOMAIN][CONF_INTERFACE]
        discovery_retry = config[DOMAIN][CONF_DISCOVERY_RETRY]

    async def xiaomi_gw_discovered(service, discovery_info):
        'Perform action when Xiaomi Gateway device(s) has been found.'
    discovery.listen(hass, SERVICE_XIAOMI_GW, xiaomi_gw_discovered)
    from xiaomi_gateway import XiaomiGatewayDiscovery
    xiaomi = hass.data[PY_XIAOMI_GATEWAY] = XiaomiGatewayDiscovery(hass.add_job, gateways, interface)
    _LOGGER.debug('Expecting %s gateways', len(gateways))
    for k in range(discovery_retry):
        _LOGGER.info('Discovering Xiaomi Gateways (Try %s)', (k + 1))
        xiaomi.discover_gateways()
        if (len(xiaomi.gateways) >= len(gateways)):
            break
    if (not xiaomi.gateways):
        _LOGGER.error('No gateway discovered')
        return False
    xiaomi.listen()
    _LOGGER.debug('Gateways discovered. Listening for broadcasts')
    for component in ['binary_sensor', 'sensor', 'switch', 'light', 'cover', 'lock']:
        discovery.load_platform(hass, component, DOMAIN, {}, config)

    def stop_xiaomi(event):
        'Stop Xiaomi Socket.'
        _LOGGER.info('Shutting down Xiaomi Hub')
        xiaomi.stop_listen()
    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_xiaomi)

    def play_ringtone_service(call):
        'Service to play ringtone through Gateway.'
        ring_id = call.data.get(ATTR_RINGTONE_ID)
        gateway = call.data.get(ATTR_GW_MAC)
        kwargs = {'mid': ring_id}
        ring_vol = call.data.get(ATTR_RINGTONE_VOL)
        if (ring_vol is not None):
            kwargs['vol'] = ring_vol
        gateway.write_to_hub(gateway.sid, **kwargs)

    def stop_ringtone_service(call):
        'Service to stop playing ringtone on Gateway.'
        gateway = call.data.get(ATTR_GW_MAC)
        gateway.write_to_hub(gateway.sid, mid=10000)

    def add_device_service(call):
        'Service to add a new sub-device within the next 30 seconds.'
        gateway = call.data.get(ATTR_GW_MAC)
        gateway.write_to_hub(gateway.sid, join_permission='yes')
        hass.components.persistent_notification.async_create('Join permission enabled for 30 seconds! Please press the pairing button of the new device once.', title='Xiaomi Aqara Gateway')

    def remove_device_service(call):
        'Service to remove a sub-device from the gateway.'
        device_id = call.data.get(ATTR_DEVICE_ID)
        gateway = call.data.get(ATTR_GW_MAC)
        gateway.write_to_hub(gateway.sid, remove_device=device_id)
    gateway_only_schema = _add_gateway_to_schema(xiaomi, vol.Schema({}))
    hass.services.register(DOMAIN, SERVICE_PLAY_RINGTONE, play_ringtone_service, schema=_add_gateway_to_schema(xiaomi, SERVICE_SCHEMA_PLAY_RINGTONE))
    hass.services.register(DOMAIN, SERVICE_STOP_RINGTONE, stop_ringtone_service, schema=gateway_only_schema)
    hass.services.register(DOMAIN, SERVICE_ADD_DEVICE, add_device_service, schema=gateway_only_schema)
    hass.services.register(DOMAIN, SERVICE_REMOVE_DEVICE, remove_device_service, schema=_add_gateway_to_schema(xiaomi, SERVICE_SCHEMA_REMOVE_DEVICE))
    return True
Set up the Xiaomi component.
def setup(hass, config):
    
    gateways = []
    interface = 'any'
    discovery_retry = 3
    if (DOMAIN in config):
        gateways = config[DOMAIN][CONF_GATEWAYS]
        interface = config[DOMAIN][CONF_INTERFACE]
        discovery_retry = config[DOMAIN][CONF_DISCOVERY_RETRY]

    async def xiaomi_gw_discovered(service, discovery_info):
        'Perform action when Xiaomi Gateway device(s) has been found.'
    discovery.listen(hass, SERVICE_XIAOMI_GW, xiaomi_gw_discovered)
    from xiaomi_gateway import XiaomiGatewayDiscovery
    xiaomi = hass.data[PY_XIAOMI_GATEWAY] = XiaomiGatewayDiscovery(hass.add_job, gateways, interface)
    _LOGGER.debug('Expecting %s gateways', len(gateways))
    for k in range(discovery_retry):
        _LOGGER.info('Discovering Xiaomi Gateways (Try %s)', (k + 1))
        xiaomi.discover_gateways()
        if (len(xiaomi.gateways) >= len(gateways)):
            break
    if (not xiaomi.gateways):
        _LOGGER.error('No gateway discovered')
        return False
    xiaomi.listen()
    _LOGGER.debug('Gateways discovered. Listening for broadcasts')
    for component in ['binary_sensor', 'sensor', 'switch', 'light', 'cover', 'lock']:
        discovery.load_platform(hass, component, DOMAIN, {}, config)

    def stop_xiaomi(event):
        'Stop Xiaomi Socket.'
        _LOGGER.info('Shutting down Xiaomi Hub')
        xiaomi.stop_listen()
    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_xiaomi)

    def play_ringtone_service(call):
        'Service to play ringtone through Gateway.'
        ring_id = call.data.get(ATTR_RINGTONE_ID)
        gateway = call.data.get(ATTR_GW_MAC)
        kwargs = {'mid': ring_id}
        ring_vol = call.data.get(ATTR_RINGTONE_VOL)
        if (ring_vol is not None):
            kwargs['vol'] = ring_vol
        gateway.write_to_hub(gateway.sid, **kwargs)

    def stop_ringtone_service(call):
        'Service to stop playing ringtone on Gateway.'
        gateway = call.data.get(ATTR_GW_MAC)
        gateway.write_to_hub(gateway.sid, mid=10000)

    def add_device_service(call):
        'Service to add a new sub-device within the next 30 seconds.'
        gateway = call.data.get(ATTR_GW_MAC)
        gateway.write_to_hub(gateway.sid, join_permission='yes')
        hass.components.persistent_notification.async_create('Join permission enabled for 30 seconds! Please press the pairing button of the new device once.', title='Xiaomi Aqara Gateway')

    def remove_device_service(call):
        'Service to remove a sub-device from the gateway.'
        device_id = call.data.get(ATTR_DEVICE_ID)
        gateway = call.data.get(ATTR_GW_MAC)
        gateway.write_to_hub(gateway.sid, remove_device=device_id)
    gateway_only_schema = _add_gateway_to_schema(xiaomi, vol.Schema({}))
    hass.services.register(DOMAIN, SERVICE_PLAY_RINGTONE, play_ringtone_service, schema=_add_gateway_to_schema(xiaomi, SERVICE_SCHEMA_PLAY_RINGTONE))
    hass.services.register(DOMAIN, SERVICE_STOP_RINGTONE, stop_ringtone_service, schema=gateway_only_schema)
    hass.services.register(DOMAIN, SERVICE_ADD_DEVICE, add_device_service, schema=gateway_only_schema)
    hass.services.register(DOMAIN, SERVICE_REMOVE_DEVICE, remove_device_service, schema=_add_gateway_to_schema(xiaomi, SERVICE_SCHEMA_REMOVE_DEVICE))
    return True