def mock_lj(opp):
    """Initialize components."""
    with mock.patch("openpeerpower.components.litejet.LiteJet") as mock_pylitejet:
        mock_lj = mock_pylitejet.return_value

        mock_lj.switch_pressed_callbacks = {}
        mock_lj.switch_released_callbacks = {}

        def on_switch_pressed(number, callback):
            mock_lj.switch_pressed_callbacks[number] = callback

        def on_switch_released(number, callback):
            mock_lj.switch_released_callbacks[number] = callback

        mock_lj.loads.return_value = range(0)
        mock_lj.button_switches.return_value = range(1, 3)
        mock_lj.all_switches.return_value = range(1, 6)
        mock_lj.scenes.return_value = range(0)
        mock_lj.get_switch_name.side_effect = get_switch_name
        mock_lj.on_switch_pressed.side_effect = on_switch_pressed
        mock_lj.on_switch_released.side_effect = on_switch_released

        config = {"litejet": {"port": "/dev/serial/by-id/mock-litejet"}}
        assert opp.loop.run_until_complete(
            setup.async_setup_component(opp, litejet.DOMAIN, config)
        )

        mock_lj.start_time = dt_util.utcnow()
        mock_lj.last_delta = timedelta(0)
        return mock_lj
def test_invalid_credentials(
    mock_open,
    mock_isfile,
    mock_makedirs,
    mock_json_dump,
    mock_json_load,
    mock_create_session,
    opp,
):
    """Test with invalid credentials."""
    opp.loop.run_until_complete(async_setup_component(opp, "http", {}))
    mock_json_load.return_value = {"refresh_token": "bad_token"}

    async def get_session(*args, **kwargs):
        """Return the test session."""
        raise aioautomatic.exceptions.BadRequestError("err_invalid_refresh_token")

    mock_create_session.side_effect = get_session

    config = {
        "platform": "automatic",
        "client_id": "client_id",
        "secret": "client_secret",
        "devices": None,
    }
    opp.loop.run_until_complete(async_setup_scanner(opp, config, None))
    assert mock_create_session.called
    assert len(mock_create_session.mock_calls) == 1
    assert mock_create_session.mock_calls[0][1][0] == "bad_token"
Exemple #3
0
def setup_comp(opp):
    """Initialize components."""
    mock_component(opp, "group")
    opp.config.set_time_zone(opp.config.time_zone)
    opp.loop.run_until_complete(
        async_setup_component(opp, sun.DOMAIN, {sun.DOMAIN: {sun.CONF_ELEVATION: 0}})
    )
def demo_camera(opp):
    """Initialize a demo camera platform."""
    opp.loop.run_until_complete(
        async_setup_component(opp, "camera",
                              {camera.DOMAIN: {
                                  "platform": "demo"
                              }}))
    return opp.data["camera"].get_entity("camera.demo_camera")
Exemple #5
0
def scanner(opp, enable_custom_integrations):
    """Initialize components."""
    scanner = getattr(opp.components,
                      "test.device_tracker").get_scanner(None, None)

    scanner.reset()
    scanner.come_home("DEV1")

    getattr(opp.components, "test.light").init()

    with patch(
            "openpeerpower.components.device_tracker.legacy.load_yaml_config_file",
            return_value={
                "device_1": {
                    "mac": "DEV1",
                    "name": "Unnamed Device",
                    "picture": "http://example.com/dev1.jpg",
                    "track": True,
                    "vendor": None,
                },
                "device_2": {
                    "mac": "DEV2",
                    "name": "Unnamed Device",
                    "picture": "http://example.com/dev2.jpg",
                    "track": True,
                    "vendor": None,
                },
            },
    ):
        assert opp.loop.run_until_complete(
            async_setup_component(
                opp,
                device_tracker.DOMAIN,
                {device_tracker.DOMAIN: {
                    CONF_PLATFORM: "test"
                }},
            ))

    assert opp.loop.run_until_complete(
        async_setup_component(opp, light.DOMAIN,
                              {light.DOMAIN: {
                                  CONF_PLATFORM: "test"
                              }}))

    return scanner
Exemple #6
0
    def setUp(self):
        """Set up things to be run when tests are started."""
        self.opp = get_test_open_peer_power()
        assert asyncio.run_coroutine_threadsafe(
            async_setup_component(self.opp, "openpeerpower", {}),
            self.opp.loop).result()

        self.opp.states.set("light.Bowl", STATE_ON)
        self.opp.states.set("light.Ceiling", STATE_OFF)
Exemple #7
0
async def async_from_config_dict(
        config: ConfigType,
        opp: core.OpenPeerPower) -> core.OpenPeerPower | None:
    """Try to configure Open Peer Power from a configuration dictionary.

    Dynamically loads required components and its dependencies.
    This method is a coroutine.
    """
    start = monotonic()

    opp.config_entries = config_entries.ConfigEntries(opp, config)
    await opp.config_entries.async_initialize()

    # Set up core.
    _LOGGER.debug("Setting up %s", CORE_INTEGRATIONS)

    if not all(await
               asyncio.gather(*(async_setup_component(opp, domain, config)
                                for domain in CORE_INTEGRATIONS))):
        _LOGGER.error("Open Peer Power core failed to initialize. ")
        return None

    _LOGGER.debug("Open Peer Power core initialized")

    core_config = config.get(core.DOMAIN, {})

    try:
        await conf_util.async_process_op_core_config(opp, core_config)
    except vol.Invalid as config_err:
        conf_util.async_log_exception(config_err, "openpeerpower", core_config,
                                      opp)
        return None
    except OpenPeerPowerError:
        _LOGGER.error("Open Peer Power core failed to initialize. "
                      "Further initialization aborted")
        return None

    await _async_set_up_integrations(opp, config)

    stop = monotonic()
    _LOGGER.info("Open Peer Power initialized in %.2fs", stop - start)

    if REQUIRED_NEXT_PYTHON_DATE and sys.version_info[:
                                                      3] < REQUIRED_NEXT_PYTHON_VER:
        msg = (
            "Support for the running Python version "
            f"{'.'.join(str(x) for x in sys.version_info[:3])} is deprecated and will "
            f"be removed in the first release after {REQUIRED_NEXT_PYTHON_DATE}. "
            "Please upgrade Python to "
            f"{'.'.join(str(x) for x in REQUIRED_NEXT_PYTHON_VER)} or "
            "higher.")
        _LOGGER.warning(msg)
        opp.components.persistent_notification.async_create(
            msg, "Python version", "python_version")

    return opp
Exemple #8
0
def mock_client(opp, aiohttp_client):
    """Start the Open Peer Power HTTP component."""
    mock_component(opp, "group")
    mock_component(opp, "zone")
    mock_component(opp, "device_tracker")

    MockConfigEntry(domain="owntracks",
                    data={
                        "webhook_id": "owntracks_test",
                        "secret": "abcd"
                    }).add_to_opp(opp)
    opp.loop.run_until_complete(async_setup_component(opp, "owntracks", {}))

    return opp.loop.run_until_complete(aiohttp_client(opp.http.app))
Exemple #9
0
def no_auth_websocket_client(opp, loop, aiohttp_client):
    """Websocket connection that requires authentication."""
    assert loop.run_until_complete(async_setup_component(opp, "websocket_api", {}))

    client = loop.run_until_complete(aiohttp_client(opp.http.app))
    ws = loop.run_until_complete(client.ws_connect(URL))

    auth_ok = loop.run_until_complete(ws.receive_json())
    assert auth_ok["type"] == TYPE_AUTH_REQUIRED

    yield ws

    if not ws.closed:
        loop.run_until_complete(ws.close())
Exemple #10
0
def setup_zone(opp):
    """Create test zone."""
    opp.loop.run_until_complete(
        async_setup_component(
            opp,
            zone.DOMAIN,
            {
                "zone": {
                    "name": "test",
                    "latitude": HOME_LATITUDE,
                    "longitude": HOME_LONGITUDE,
                    "radius": 250,
                }
            },
        ))
Exemple #11
0
def storage_setup(opp, opp_storage, opp_admin_user):
    """Storage setup."""
    opp_storage[DOMAIN] = {
        "key": DOMAIN,
        "version": 1,
        "data": {
            "persons": [{
                "id": "1234",
                "name": "tracked person",
                "user_id": opp_admin_user.id,
                "device_trackers": [DEVICE_TRACKER],
            }]
        },
    }
    assert opp.loop.run_until_complete(async_setup_component(opp, DOMAIN, {}))
def setup_comp(opp):
    """Initialize components."""
    mock_component(opp, "group")
    opp.loop.run_until_complete(
        async_setup_component(
            opp,
            zone.DOMAIN,
            {
                "zone": {
                    "name": "test",
                    "latitude": 32.880837,
                    "longitude": -117.237561,
                    "radius": 250,
                }
            },
        ))
Exemple #13
0
def setup_duckdns(opp, aioclient_mock):
    """Fixture that sets up DuckDNS."""
    aioclient_mock.get(duckdns.UPDATE_URL,
                       params={
                           "domains": DOMAIN,
                           "token": TOKEN
                       },
                       text="OK")

    opp.loop.run_until_complete(
        async_setup_component(
            opp, duckdns.DOMAIN,
            {"duckdns": {
                "domain": DOMAIN,
                "access_token": TOKEN
            }}))
Exemple #14
0
def mock_client(opp, opp_client):
    """Start the Open Peer Power HTTP component."""
    with patch("openpeerpower.components.spaceapi", return_value=mock_coro(True)):
        opp.loop.run_until_complete(async_setup_component(opp, "spaceapi", CONFIG))

    opp.states.async_set(
        "test.temp1", 25, attributes={ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}
    )
    opp.states.async_set(
        "test.temp2", 23, attributes={ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS}
    )
    opp.states.async_set(
        "test.hum1", 88, attributes={ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE}
    )

    return opp.loop.run_until_complete(opp_client())
Exemple #15
0
def oppio_stubs(oppio_env, opp, opp_client, aioclient_mock):
    """Create mock oppio http client."""
    with patch(
            "openpeerpower.components.oppio.OppIO.update_opp_api",
            return_value={"result": "ok"},
    ) as opp_api, patch(
            "openpeerpower.components.oppio.OppIO.update_opp_timezone",
            return_value={"result": "ok"},
    ), patch(
            "openpeerpower.components.oppio.OppIO.get_info",
            side_effect=OppioAPIError(),
    ):
        opp.state = CoreState.starting
        opp.loop.run_until_complete(async_setup_component(opp, "oppio", {}))

    return opp_api.call_args[0][1]
Exemple #16
0
def setup_no_ip(opp, aioclient_mock):
    """Fixture that sets up NO-IP."""
    aioclient_mock.get(UPDATE_URL, params={"hostname": DOMAIN}, text="good 0.0.0.0")

    opp.loop.run_until_complete(
        async_setup_component(
            opp,
            no_ip.DOMAIN,
            {
                no_ip.DOMAIN: {
                    "domain": DOMAIN,
                    "username": USERNAME,
                    "password": PASSWORD,
                }
            },
        )
    )
Exemple #17
0
def mock_google_setup(opp, test_calendar):
    """Mock the google set up functions."""
    opp.loop.run_until_complete(
        async_setup_component(opp, "group", {"group": {}}))
    calendar = get_calendar_info(test_calendar)
    calendars = {calendar[CONF_CAL_ID]: calendar}
    patch_google_auth = patch(
        "openpeerpower.components.google.do_authentication",
        side_effect=do_setup)
    patch_google_load = patch("openpeerpower.components.google.load_config",
                              return_value=calendars)
    patch_google_services = patch(
        "openpeerpower.components.google.setup_services")
    async_mock_service(opp, "google", SERVICE_SCAN_CALENDARS)

    with patch_google_auth, patch_google_load, patch_google_services:
        yield
def camera_client_fixture(opp, opp_client):
    """Fixture to fetch camera streams."""
    assert opp.loop.run_until_complete(
        async_setup_component(
            opp,
            "camera",
            {
                "camera": {
                    "name": "config_test",
                    "platform": "mjpeg",
                    "mjpeg_url": "http://example.com/mjpeg_stream",
                }
            },
        ))
    opp.loop.run_until_complete(opp.async_block_till_done())

    yield opp.loop.run_until_complete(opp_client())
Exemple #19
0
def setup_google_domains(opp, aioclient_mock):
    """Fixture that sets up NamecheapDNS."""
    aioclient_mock.get(UPDATE_URL,
                       params={"hostname": DOMAIN},
                       text="ok 0.0.0.0")

    opp.loop.run_until_complete(
        async_setup_component(
            opp,
            google_domains.DOMAIN,
            {
                "google_domains": {
                    "domain": DOMAIN,
                    "username": USERNAME,
                    "password": PASSWORD,
                }
            },
        ))
Exemple #20
0
def mock_http_client(loop, opp, opp_client):
    """Set up test fixture."""
    config = {
        "rss_feed_template": {
            "testfeed": {
                "title":
                "feed title is {{states.test.test1.state}}",
                "items": [{
                    "title": "item title is {{states.test.test2.state}}",
                    "description": "desc {{states.test.test3.state}}",
                }],
            }
        }
    }

    loop.run_until_complete(
        async_setup_component(opp, "rss_feed_template", config))
    return loop.run_until_complete(opp_client())
Exemple #21
0
def setup_freedns(opp, aioclient_mock):
    """Fixture that sets up FreeDNS."""
    params = {}
    params[ACCESS_TOKEN] = ""
    aioclient_mock.get(
        UPDATE_URL, params=params, text="Successfully updated 1 domains."
    )

    opp.loop.run_until_complete(
        async_setup_component(
            opp,
            freedns.DOMAIN,
            {
                freedns.DOMAIN: {
                    "access_token": ACCESS_TOKEN,
                    "scan_interval": UPDATE_INTERVAL,
                }
            },
        )
    )
Exemple #22
0
def assistant_client(loop, opp, aiohttp_client):
    """Create web client for the Google Assistant API."""
    loop.run_until_complete(
        setup.async_setup_component(
            opp,
            "google_assistant",
            {
                "google_assistant": {
                    "project_id": PROJECT_ID,
                    "entity_config": {
                        "light.ceiling_lights": {
                            "aliases": ["top lights", "ceiling lights"],
                            "name": "Roof Lights",
                        }
                    },
                }
            },
        ))

    return loop.run_until_complete(aiohttp_client(opp.http.app))
Exemple #23
0
    def test_all_work_done_before_start(self):
        """Test all init work done till start."""
        call_order = []

        async def component1_setup(opp, config):
            """Set up mock component."""
            await discovery.async_discover(opp, "test_component2", {},
                                           "test_component2", {})
            await discovery.async_discover(opp, "test_component3", {},
                                           "test_component3", {})
            return True

        def component_track_setup(opp, config):
            """Set up mock component."""
            call_order.append(1)
            return True

        mock_integration(
            self.opp,
            MockModule("test_component1", async_setup=component1_setup))

        mock_integration(
            self.opp, MockModule("test_component2",
                                 setup=component_track_setup))

        mock_integration(
            self.opp, MockModule("test_component3",
                                 setup=component_track_setup))

        @callback
        def track_start(event):
            """Track start event."""
            call_order.append(2)

        self.opp.bus.listen_once(EVENT_OPENPEERPOWER_START, track_start)

        self.opp.add_job(
            setup.async_setup_component(self.opp, "test_component1", {}))
        self.opp.block_till_done()
        self.opp.start()
        assert call_order == [1, 1, 2]
Exemple #24
0
def alexa_client(loop, opp, opp_client):
    """Initialize a Open Peer Power server for testing this module."""

    @callback
    def mock_service(call):
        calls.append(call)

    opp.services.async_register("test", "alexa", mock_service)

    assert loop.run_until_complete(
        async_setup_component(
            opp,
            alexa.DOMAIN,
            {
                # Key is here to verify we allow other keys in config too
                "openpeerpower": {},
                "alexa": {
                    "flash_briefings": {
                        "password": "******",
                        "weather": [
                            {
                                "title": "Weekly forecast",
                                "text": "This week it will be sunny.",
                            },
                            {
                                "title": "Current conditions",
                                "text": "Currently it is 80 degrees fahrenheit.",
                            },
                        ],
                        "news_audio": {
                            "title": "NPR",
                            "audio": NPR_NEWS_MP3_URL,
                            "display_url": "https://npr.org",
                            "uid": "uuid",
                        },
                    }
                },
            },
        )
    )
    return loop.run_until_complete(opp_client())
Exemple #25
0
async def async_setup_multi_components(
    opp: core.OpenPeerPower,
    domains: set[str],
    config: dict[str, Any],
) -> None:
    """Set up multiple domains. Log on failure."""
    futures = {
        domain:
        opp.async_create_task(async_setup_component(opp, domain, config))
        for domain in domains
    }
    await asyncio.wait(futures.values())
    errors = [domain for domain in domains if futures[domain].exception()]
    for domain in errors:
        exception = futures[domain].exception()
        assert exception is not None
        _LOGGER.error(
            "Error setting up integration %s - received exception",
            domain,
            exc_info=(type(exception), exception, exception.__traceback__),
        )
Exemple #26
0
def opp_fixture(loop, opp):
    """Set up a Open Peer Power instance for these tests."""
    # We need to do this to get access to openpeerpower/turn_(on,off)
    loop.run_until_complete(setup.async_setup_component(opp, core.DOMAIN, {}))

    loop.run_until_complete(
        setup.async_setup_component(opp, light.DOMAIN,
                                    {"light": [{
                                        "platform": "demo"
                                    }]}))
    loop.run_until_complete(
        setup.async_setup_component(opp, switch.DOMAIN,
                                    {"switch": [{
                                        "platform": "demo"
                                    }]}))
    loop.run_until_complete(
        setup.async_setup_component(opp, cover.DOMAIN,
                                    {"cover": [{
                                        "platform": "demo"
                                    }]}))

    loop.run_until_complete(
        setup.async_setup_component(opp, media_player.DOMAIN,
                                    {"media_player": [{
                                        "platform": "demo"
                                    }]}))

    loop.run_until_complete(
        setup.async_setup_component(opp, fan.DOMAIN,
                                    {"fan": [{
                                        "platform": "demo"
                                    }]}))

    loop.run_until_complete(
        setup.async_setup_component(opp, climate.DOMAIN,
                                    {"climate": [{
                                        "platform": "demo"
                                    }]}))

    loop.run_until_complete(
        setup.async_setup_component(opp, humidifier.DOMAIN,
                                    {"humidifier": [{
                                        "platform": "demo"
                                    }]}))

    loop.run_until_complete(
        setup.async_setup_component(opp, lock.DOMAIN,
                                    {"lock": [{
                                        "platform": "demo"
                                    }]}))

    loop.run_until_complete(
        setup.async_setup_component(
            opp,
            alarm_control_panel.DOMAIN,
            {"alarm_control_panel": [{
                "platform": "demo"
            }]},
        ))

    return opp
def setup_comp(opp):
    """Set up demo component."""
    opp.loop.run_until_complete(
        async_setup_component(opp, light.DOMAIN, {"light": {"platform": "demo"}})
    )
Exemple #28
0
def alexa_client(loop, opp, opp_client):
    """Initialize a Open Peer Power server for testing this module."""
    @callback
    def mock_service(call):
        calls.append(call)

    opp.services.async_register("test", "alexa", mock_service)

    assert loop.run_until_complete(
        async_setup_component(
            opp,
            alexa.DOMAIN,
            {
                # Key is here to verify we allow other keys in config too
                "openpeerpower": {},
                "alexa": {},
            },
        ))
    assert loop.run_until_complete(
        async_setup_component(
            opp,
            "intent_script",
            {
                "intent_script": {
                    "WhereAreWeIntent": {
                        "speech": {
                            "type":
                            "plain",
                            "text":
                            """
                            {%- if is_state("device_tracker.paulus", "home")
                                   and is_state("device_tracker.anne_therese",
                                                "home") -%}
                                You are both home, you silly
                            {%- else -%}
                                Anne Therese is at {{
                                    states("device_tracker.anne_therese")
                                }} and Paulus is at {{
                                    states("device_tracker.paulus")
                                }}
                            {% endif %}
                        """,
                        }
                    },
                    "GetZodiacHoroscopeIntent": {
                        "speech": {
                            "type": "plain",
                            "text":
                            "You told us your sign is {{ ZodiacSign }}.",
                        }
                    },
                    "AMAZON.PlaybackAction<object@MusicCreativeWork>": {
                        "speech": {
                            "type": "plain",
                            "text": "Playing {{ object_byArtist_name }}.",
                        }
                    },
                    "CallServiceIntent": {
                        "speech": {
                            "type": "plain",
                            "text": "Service called for {{ ZodiacSign }}",
                        },
                        "card": {
                            "type": "simple",
                            "title": "Card title for {{ ZodiacSign }}",
                            "content": "Card content: {{ ZodiacSign }}",
                        },
                        "action": {
                            "service": "test.alexa",
                            "data_template": {
                                "hello": "{{ ZodiacSign }}"
                            },
                            "entity_id": "switch.test",
                        },
                    },
                    APPLICATION_ID: {
                        "speech": {
                            "type": "plain",
                            "text": "LaunchRequest has been received.",
                        }
                    },
                }
            },
        ))
    return loop.run_until_complete(opp_client())
def test_valid_credentials(
    mock_open,
    mock_isfile,
    mock_makedirs,
    mock_json_dump,
    mock_json_load,
    mock_ws_connect,
    mock_create_session,
    opp,
):
    """Test with valid credentials."""
    opp.loop.run_until_complete(async_setup_component(opp, "http", {}))
    mock_json_load.return_value = {"refresh_token": "good_token"}

    session = MagicMock()
    vehicle = MagicMock()
    trip = MagicMock()
    mock_see = MagicMock()

    vehicle.id = "mock_id"
    vehicle.display_name = "mock_display_name"
    vehicle.fuel_level_percent = 45.6
    vehicle.latest_location = None
    vehicle.updated_at = datetime(2017, 8, 13, 1, 2, 3)

    trip.end_location.lat = 45.567
    trip.end_location.lon = 34.345
    trip.end_location.accuracy_m = 5.6
    trip.ended_at = datetime(2017, 8, 13, 1, 2, 4)

    async def get_session(*args, **kwargs):
        """Return the test session."""
        return session

    async def get_vehicles(*args, **kwargs):
        """Return list of test vehicles."""
        return [vehicle]

    async def get_trips(*args, **kwargs):
        """Return list of test trips."""
        return [trip]

    mock_create_session.side_effect = get_session
    session.ws_connect = MagicMock()
    session.get_vehicles.side_effect = get_vehicles
    session.get_trips.side_effect = get_trips
    session.refresh_token = "mock_refresh_token"

    config = {
        "platform": "automatic",
        "username": "******",
        "password": "******",
        "client_id": "client_id",
        "secret": "client_secret",
        "devices": None,
    }
    result = opp.loop.run_until_complete(async_setup_scanner(opp, config, mock_see))

    assert result

    assert mock_ws_connect.called
    assert len(mock_ws_connect.mock_calls) == 2

    assert mock_create_session.called
    assert len(mock_create_session.mock_calls) == 1
    assert mock_create_session.mock_calls[0][1][0] == "good_token"

    assert mock_see.called
    assert len(mock_see.mock_calls) == 2
    assert mock_see.mock_calls[0][2]["dev_id"] == "mock_id"
    assert mock_see.mock_calls[0][2]["mac"] == "mock_id"
    assert mock_see.mock_calls[0][2]["host_name"] == "mock_display_name"
    assert mock_see.mock_calls[0][2]["attributes"] == {"fuel_level": 45.6}
    assert mock_see.mock_calls[0][2]["gps"] == (45.567, 34.345)
    assert mock_see.mock_calls[0][2]["gps_accuracy"] == 5.6

    assert mock_json_dump.called
    assert len(mock_json_dump.mock_calls) == 1
    assert mock_json_dump.mock_calls[0][1][0] == {"refresh_token": "mock_refresh_token"}
async def _async_set_up_integrations(
    opp: core.OpenPeerPower, config: Dict[str, Any]
) -> None:
    """Set up all the integrations."""
    domains = _get_domains(opp, config)

    # Start up debuggers. Start these first in case they want to wait.
    debuggers = domains & DEBUGGER_INTEGRATIONS
    if debuggers:
        _LOGGER.debug("Starting up debuggers %s", debuggers)
        await asyncio.gather(
            *(async_setup_component(opp, domain, config) for domain in debuggers)
        )
        domains -= DEBUGGER_INTEGRATIONS

    # Resolve all dependencies of all components so we can find the logging
    # and integrations that need faster initialization.
    resolved_domains_task = asyncio.gather(
        *(loader.async_component_dependencies(opp, domain) for domain in domains),
        return_exceptions=True,
    )

    # Finish resolving domains
    for dep_domains in await resolved_domains_task:
        # Result is either a set or an exception. We ignore exceptions
        # It will be properly handled during setup of the domain.
        if isinstance(dep_domains, set):
            domains.update(dep_domains)

    # setup components
    logging_domains = domains & LOGGING_INTEGRATIONS
    stage_1_domains = domains & STAGE_1_INTEGRATIONS
    stage_2_domains = domains - logging_domains - stage_1_domains

    if logging_domains:
        _LOGGER.info("Setting up %s", logging_domains)

        await asyncio.gather(
            *(async_setup_component(opp, domain, config) for domain in logging_domains)
        )

    # Kick off loading the registries. They don't need to be awaited.
    asyncio.gather(
        opp.helpers.device_registry.async_get_registry(),
        opp.helpers.entity_registry.async_get_registry(),
        opp.helpers.area_registry.async_get_registry(),
    )

    if stage_1_domains:
        await asyncio.gather(
            *(async_setup_component(opp, domain, config) for domain in stage_1_domains)
        )

    # Load all integrations
    after_dependencies: Dict[str, Set[str]] = {}

    for int_or_exc in await asyncio.gather(
        *(loader.async_get_integration(opp, domain) for domain in stage_2_domains),
        return_exceptions=True,
    ):
        # Exceptions are handled in async_setup_component.
        if isinstance(int_or_exc, loader.Integration) and int_or_exc.after_dependencies:
            after_dependencies[int_or_exc.domain] = set(int_or_exc.after_dependencies)

    last_load = None
    while stage_2_domains:
        domains_to_load = set()

        for domain in stage_2_domains:
            after_deps = after_dependencies.get(domain)
            # Load if integration has no after_dependencies or they are
            # all loaded
            if not after_deps or not after_deps - opp.config.components:
                domains_to_load.add(domain)

        if not domains_to_load or domains_to_load == last_load:
            break

        _LOGGER.debug("Setting up %s", domains_to_load)

        await asyncio.gather(
            *(async_setup_component(opp, domain, config) for domain in domains_to_load)
        )

        last_load = domains_to_load
        stage_2_domains -= domains_to_load

    # These are stage 2 domains that never have their after_dependencies
    # satisfied.
    if stage_2_domains:
        _LOGGER.debug("Final set up: %s", stage_2_domains)

        await asyncio.gather(
            *(async_setup_component(opp, domain, config) for domain in stage_2_domains)
        )

    # Wrap up startup
    await opp.async_block_till_done()