예제 #1
0
async def test_get_clientsession_with_ssl(opp):
    """Test init clientsession with ssl."""
    client.async_get_clientsession(opp)

    assert isinstance(opp.data[client.DATA_CLIENTSESSION],
                      aiohttp.ClientSession)
    assert isinstance(opp.data[client.DATA_CONNECTOR], aiohttp.TCPConnector)
예제 #2
0
async def test_get_clientsession_without_ssl(opp):
    """Test init clientsession without ssl."""
    client.async_get_clientsession(opp, verify_ssl=False)

    assert isinstance(opp.data[client.DATA_CLIENTSESSION_NOTVERIFY],
                      aiohttp.ClientSession)
    assert isinstance(opp.data[client.DATA_CONNECTOR_NOTVERIFY],
                      aiohttp.TCPConnector)
예제 #3
0
async def test_get_clientsession_cleanup(opp):
    """Test init clientsession with ssl."""
    client.async_get_clientsession(opp)

    assert isinstance(opp.data[client.DATA_CLIENTSESSION],
                      aiohttp.ClientSession)
    assert isinstance(opp.data[client.DATA_CONNECTOR], aiohttp.TCPConnector)

    opp.bus.async_fire(EVENT_OPENPEERPOWER_CLOSE)
    await opp.async_block_till_done()

    assert opp.data[client.DATA_CLIENTSESSION].closed
    assert opp.data[client.DATA_CONNECTOR].closed
예제 #4
0
async def async_configure_sabnzbd(opp,
                                  config,
                                  use_ssl,
                                  name=DEFAULT_NAME,
                                  api_key=None):
    """Try to configure Sabnzbd and request api key if configuration fails."""

    host = config[CONF_HOST]
    port = config[CONF_PORT]
    web_root = config.get(CONF_PATH)
    uri_scheme = "https" if use_ssl else "http"
    base_url = BASE_URL_FORMAT.format(uri_scheme, host, port)
    if api_key is None:
        conf = await opp.async_add_executor_job(load_json,
                                                opp.config.path(CONFIG_FILE))
        api_key = conf.get(base_url, {}).get(CONF_API_KEY, "")

    sab_api = SabnzbdApi(base_url,
                         api_key,
                         web_root=web_root,
                         session=async_get_clientsession(opp))
    if await async_check_sabnzbd(sab_api):
        async_setup_sabnzbd(opp, sab_api, config, name)
    else:
        async_request_configuration(opp, config, base_url, web_root)
예제 #5
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry):
    """Set up BleBox devices from a config entry."""

    websession = async_get_clientsession(opp)

    host = entry.data[CONF_HOST]
    port = entry.data[CONF_PORT]
    timeout = DEFAULT_SETUP_TIMEOUT

    api_host = ApiHost(host, port, timeout, websession, opp.loop)

    try:
        product = await Products.async_from_host(api_host)
    except Error as ex:
        _LOGGER.error("Identify failed at %s:%d (%s)", api_host.host,
                      api_host.port, ex)
        raise ConfigEntryNotReady from ex

    domain = opp.data.setdefault(DOMAIN, {})
    domain_entry = domain.setdefault(entry.entry_id, {})
    product = domain_entry.setdefault(PRODUCT, product)

    opp.config_entries.async_setup_platforms(entry, PLATFORMS)

    return True
예제 #6
0
    async def validate_login_creds(self, data):
        """Validate the user input allows us to connect.

        data: contains values provided by the user.
        """
        websession = aiohttp_client.async_get_clientsession(self.opp)
        now = datetime.now()
        if not data.get(CONF_DEVICE_ID):
            data[CONF_DEVICE_ID] = int(now.timestamp())
        date = now.strftime("%Y-%m-%d")
        device_name = "Open Peer Power: Added " + date

        self.controller = SubaruAPI(
            websession,
            username=data[CONF_USERNAME],
            password=data[CONF_PASSWORD],
            device_id=data[CONF_DEVICE_ID],
            pin=None,
            device_name=device_name,
            country=data[CONF_COUNTRY],
        )
        _LOGGER.debug(
            "Setting up first time connection to Subaru API.  This may take up to 20 seconds"
        )
        if await self.controller.connect():
            _LOGGER.debug("Successfully authenticated and authorized with Subaru API")
            self.config_data.update(data)
예제 #7
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry):
    """Set up AirNow from a config entry."""
    api_key = entry.data[CONF_API_KEY]
    latitude = entry.data[CONF_LATITUDE]
    longitude = entry.data[CONF_LONGITUDE]
    distance = entry.data[CONF_RADIUS]

    # Reports are published hourly but update twice per hour
    update_interval = datetime.timedelta(minutes=30)

    # Setup the Coordinator
    session = async_get_clientsession(opp)
    coordinator = AirNowDataUpdateCoordinator(opp, session, api_key, latitude,
                                              longitude, distance,
                                              update_interval)

    # Sync with Coordinator
    await coordinator.async_config_entry_first_refresh()

    # Store Entity and Initialize Platforms
    opp.data.setdefault(DOMAIN, {})
    opp.data[DOMAIN][entry.entry_id] = coordinator

    opp.config_entries.async_setup_platforms(entry, PLATFORMS)

    return True
예제 #8
0
    async def async_step_user(self, user_input: dict = None) -> dict:
        """Handle configuration via the UI."""
        if user_input is None:
            return self.async_show_form(step_id="user",
                                        data_schema=DATA_SCHEMA,
                                        errors={})

        unique_id = f"{user_input[CONF_PLACE_ID]}, {user_input[CONF_SERVICE_ID]}"

        await self.async_set_unique_id(unique_id)
        self._abort_if_unique_id_configured()

        session = aiohttp_client.async_get_clientsession(self.opp)
        client = Client(user_input[CONF_PLACE_ID],
                        user_input[CONF_SERVICE_ID],
                        session=session)

        try:
            await client.async_get_next_pickup_event()
        except RecollectError as err:
            LOGGER.error("Error during setup of integration: %s", err)
            return self.async_show_form(
                step_id="user",
                data_schema=DATA_SCHEMA,
                errors={"base": "invalid_place_or_service_id"},
            )

        return self.async_create_entry(
            title=unique_id,
            data={
                CONF_PLACE_ID: user_input[CONF_PLACE_ID],
                CONF_SERVICE_ID: user_input[CONF_SERVICE_ID],
            },
        )
예제 #9
0
    async def _validate_input(self, data):
        """
        Validate the user input allows us to connect.

        Retrieve unique id and abort if already configured.
        """
        server = Server(
            async_get_clientsession(self.opp),
            data[CONF_HOST],
            data[CONF_PORT],
            data.get(CONF_USERNAME),
            data.get(CONF_PASSWORD),
        )

        try:
            status = await server.async_query("serverstatus")
            if not status:
                if server.http_status == HTTP_UNAUTHORIZED:
                    return "invalid_auth"
                return "cannot_connect"
        except Exception:  # pylint: disable=broad-except
            return "unknown"

        if "uuid" in status:
            await self.async_set_unique_id(status["uuid"])
            self._abort_if_unique_id_configured()
예제 #10
0
    def __init__(
        self,
        opp: OpenPeerPower,
        *,
        host: str,
        port: int,
        base_path: str,
        tls: bool,
        verify_ssl: bool,
    ) -> None:
        """Initialize global IPP data updater."""
        self.ipp = IPP(
            host=host,
            port=port,
            base_path=base_path,
            tls=tls,
            verify_ssl=verify_ssl,
            session=async_get_clientsession(opp, verify_ssl),
        )

        super().__init__(
            opp,
            _LOGGER,
            name=DOMAIN,
            update_interval=SCAN_INTERVAL,
        )
예제 #11
0
파일: light.py 프로젝트: OpenPeerPower/core
async def async_setup_platform(opp,
                               config,
                               async_add_entities,
                               discovery_info=None):
    """Set up the EverLights lights from configuration.yaml."""
    lights = []

    for ipaddr in config[CONF_HOSTS]:
        api = pyeverlights.EverLights(ipaddr, async_get_clientsession(opp))

        try:
            status = await api.get_status()

            effects = await api.get_all_patterns()

        except pyeverlights.ConnectionError as err:
            raise PlatformNotReady from err

        else:
            lights.append(
                EverLightsLight(api, pyeverlights.ZONE_1, status, effects))
            lights.append(
                EverLightsLight(api, pyeverlights.ZONE_2, status, effects))

    async_add_entities(lights)
예제 #12
0
async def validate_ws(opp: core.OpenPeerPower, data):
    """Validate the user input allows us to connect over WS."""
    ws_port = data.get(CONF_WS_PORT)
    if not ws_port:
        return

    host = data[CONF_HOST]
    port = data[CONF_PORT]
    username = data.get(CONF_USERNAME)
    password = data.get(CONF_PASSWORD)
    ssl = data.get(CONF_SSL)

    session = async_get_clientsession(opp)

    _LOGGER.debug("Connecting to %s:%s over WebSocket", host, ws_port)
    kwc = get_kodi_connection(host,
                              port,
                              ws_port,
                              username,
                              password,
                              ssl,
                              session=session)
    try:
        await kwc.connect()
        if not kwc.connected:
            _LOGGER.warning("Cannot connect to %s:%s over WebSocket", host,
                            ws_port)
            raise WSCannotConnect()
        kodi = Kodi(kwc)
        await kodi.ping()
    except CannotConnectError as error:
        raise WSCannotConnect from error
예제 #13
0
async def validate_http(opp: core.OpenPeerPower, data):
    """Validate the user input allows us to connect over HTTP."""

    host = data[CONF_HOST]
    port = data[CONF_PORT]
    username = data.get(CONF_USERNAME)
    password = data.get(CONF_PASSWORD)
    ssl = data.get(CONF_SSL)
    session = async_get_clientsession(opp)

    _LOGGER.debug("Connecting to %s:%s over HTTP", host, port)
    khc = get_kodi_connection(host,
                              port,
                              None,
                              username,
                              password,
                              ssl,
                              session=session)
    kodi = Kodi(khc)
    try:
        await kodi.ping()
    except CannotConnectError as error:
        raise CannotConnect from error
    except InvalidAuthError as error:
        raise InvalidAuth from error
예제 #14
0
async def validate_gw_input(opp: core.OpenPeerPower, data):
    """
    Validate whether the user input allows us to connect to the gateray.

    Data has the keys from _base_gw_schema() with values provided by the user.
    """
    websession = async_get_clientsession(opp, verify_ssl=False)

    api = Smile(
        host=data[CONF_HOST],
        password=data[CONF_PASSWORD],
        port=data[CONF_PORT],
        username=data[CONF_USERNAME],
        timeout=30,
        websession=websession,
    )

    try:
        await api.connect()
    except InvalidAuthentication as err:
        raise InvalidAuth from err
    except PlugwiseException as err:
        raise CannotConnect from err

    return api
예제 #15
0
def get_api(opp, entry):
    """Return the api from glances_api."""
    params = entry.copy()
    params.pop(CONF_NAME)
    verify_ssl = params.pop(CONF_VERIFY_SSL)
    session = async_get_clientsession(opp, verify_ssl)
    return Glances(opp.loop, session, **params)
예제 #16
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry):
    """Set up Atag integration from a config entry."""
    async def _async_update_data():
        """Update data via library."""
        with async_timeout.timeout(20):
            try:
                await atag.update()
            except AtagException as err:
                raise UpdateFailed(err) from err
        return atag

    atag = AtagOne(session=async_get_clientsession(opp),
                   **entry.data,
                   device=entry.unique_id)
    coordinator = DataUpdateCoordinator(
        opp,
        _LOGGER,
        name=DOMAIN.title(),
        update_method=_async_update_data,
        update_interval=timedelta(seconds=60),
    )

    await coordinator.async_config_entry_first_refresh()

    opp.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
    if entry.unique_id is None:
        opp.config_entries.async_update_entry(entry, unique_id=atag.id)

    opp.config_entries.async_setup_platforms(entry, PLATFORMS)

    return True
예제 #17
0
async def async_setup_platform(opp,
                               config,
                               async_add_entities,
                               discovery_info=None):
    """Set up the requested World Air Quality Index locations."""

    token = config.get(CONF_TOKEN)
    station_filter = config.get(CONF_STATIONS)
    locations = config.get(CONF_LOCATIONS)

    client = WaqiClient(token, async_get_clientsession(opp), timeout=TIMEOUT)
    dev = []
    try:
        for location_name in locations:
            stations = await client.search(location_name)
            _LOGGER.debug("The following stations were returned: %s", stations)
            for station in stations:
                waqi_sensor = WaqiSensor(client, station)
                if (not station_filter or {
                        waqi_sensor.uid,
                        waqi_sensor.url,
                        waqi_sensor.station_name,
                }
                        & set(station_filter)):
                    dev.append(waqi_sensor)
    except (
            aiohttp.client_exceptions.ClientConnectorError,
            asyncio.TimeoutError,
    ) as err:
        _LOGGER.exception("Failed to connect to WAQI servers")
        raise PlatformNotReady from err
    async_add_entities(dev, True)
예제 #18
0
async def async_setup_platform(opp,
                               config,
                               async_add_entities,
                               discovery_info=None):
    """Configure the platform and add the sensors."""

    session = aiohttp_client.async_get_clientsession(opp)

    client = SeventeenTrackClient(session=session)

    try:
        login_result = await client.profile.login(config[CONF_USERNAME],
                                                  config[CONF_PASSWORD])

        if not login_result:
            _LOGGER.error("Invalid username and password provided")
            return
    except SeventeenTrackError as err:
        _LOGGER.error("There was an error while logging in: %s", err)
        return

    scan_interval = config.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)

    data = SeventeenTrackData(
        client,
        async_add_entities,
        scan_interval,
        config[CONF_SHOW_ARCHIVED],
        config[CONF_SHOW_DELIVERED],
        str(opp.config.time_zone),
    )
    await data.async_update()
예제 #19
0
    def __init__(self, opp, host, port=None, name=None, init_callback=None):
        """Initialize the media player."""
        self.host = host
        self._opp = opp
        self.port = port
        self._polling_session = async_get_clientsession(opp)
        self._polling_task = None  # The actual polling task.
        self._name = name
        self._icon = None
        self._capture_items = []
        self._services_items = []
        self._preset_items = []
        self._sync_status = {}
        self._status = None
        self._last_status_update = None
        self._is_online = False
        self._retry_remove = None
        self._muted = False
        self._master = None
        self._is_master = False
        self._group_name = None
        self._group_list = []
        self._bluesound_device_name = None

        self._init_callback = init_callback
        if self.port is None:
            self.port = DEFAULT_PORT
예제 #20
0
    async def async_step_user(self, user_input=None):
        """Get configuration from the user."""
        errors = {}
        if user_input:
            ip_address = user_input[CONF_IP_ADDRESS]
            port = user_input[CONF_PORT]

            try:
                data = await advantage_air(
                    ip_address,
                    port=port,
                    session=async_get_clientsession(self.opp),
                    retry=ADVANTAGE_AIR_RETRY,
                ).async_get(1)
            except ApiError:
                errors["base"] = "cannot_connect"
            else:
                await self.async_set_unique_id(data["system"]["rid"])
                self._abort_if_unique_id_configured()

                return self.async_create_entry(
                    title=data["system"]["name"],
                    data=user_input,
                )

        return self.async_show_form(
            step_id="user",
            data_schema=ADVANTAGE_AIR_SCHEMA,
            errors=errors,
        )
예제 #21
0
파일: scene.py 프로젝트: OpenPeerPower/core
async def async_setup_platform(opp, config, async_add_entities, discovery_info=None):
    """Set up the scenes stored in the LIFX Cloud."""
    token = config.get(CONF_TOKEN)
    timeout = config.get(CONF_TIMEOUT)

    headers = {AUTHORIZATION: f"Bearer {token}"}

    url = "https://api.lifx.com/v1/scenes"

    try:
        httpsession = async_get_clientsession(opp)
        with async_timeout.timeout(timeout):
            scenes_resp = await httpsession.get(url, headers=headers)

    except (asyncio.TimeoutError, aiohttp.ClientError):
        _LOGGER.exception("Error on %s", url)
        return False

    status = scenes_resp.status
    if status == HTTP_OK:
        data = await scenes_resp.json()
        devices = [LifxCloudScene(opp, headers, timeout, scene) for scene in data]
        async_add_entities(devices)
        return True
    if status == HTTP_UNAUTHORIZED:
        _LOGGER.error("Unauthorized (bad token?) on %s", url)
        return False

    _LOGGER.error("HTTP error %d on %s", scenes_resp.status, url)
    return False
예제 #22
0
async def async_setup(opp, config):
    """Set up the Kaiterra integration."""

    conf = config[DOMAIN]
    scan_interval = conf[CONF_SCAN_INTERVAL]
    devices = conf[CONF_DEVICES]
    session = async_get_clientsession(opp)
    api = opp.data[DOMAIN] = KaiterraApiData(opp, conf, session)

    await api.async_update()

    async def _update(now=None):
        """Periodic update."""
        await api.async_update()

    async_track_time_interval(opp, _update, scan_interval)

    # Load platforms for each device
    for device in devices:
        device_name, device_id = (
            device.get(CONF_NAME) or device[CONF_TYPE],
            device[CONF_DEVICE_ID],
        )
        for platform in PLATFORMS:
            opp.async_create_task(
                async_load_platform(
                    opp,
                    platform,
                    DOMAIN,
                    {CONF_NAME: device_name, CONF_DEVICE_ID: device_id},
                    config,
                )
            )

    return True
예제 #23
0
파일: tts.py 프로젝트: OpenPeerPower/core
    async def async_get_tts_audio(self, message, language, options=None):
        """Load TTS from yandex."""
        websession = async_get_clientsession(self.opp)
        actual_language = language
        options = options or {}

        try:
            with async_timeout.timeout(10):
                url_param = {
                    "text": message,
                    "lang": actual_language,
                    "key": self._key,
                    "speaker": options.get(CONF_VOICE, self._speaker),
                    "format": options.get(CONF_CODEC, self._codec),
                    "emotion": options.get(CONF_EMOTION, self._emotion),
                    "speed": options.get(CONF_SPEED, self._speed),
                }

                request = await websession.get(YANDEX_API_URL,
                                               params=url_param)

                if request.status != HTTP_OK:
                    _LOGGER.error("Error %d on load URL %s", request.status,
                                  request.url)
                    return (None, None)
                data = await request.read()

        except (asyncio.TimeoutError, aiohttp.ClientError):
            _LOGGER.error("Timeout for yandex speech kit API")
            return (None, None)

        return (self._codec, data)
예제 #24
0
    async def fetching_data(self, *_):
        """Get the latest data from yr.no."""
        def try_again(err: str):
            """Retry in 15 to 20 minutes."""
            minutes = 15 + randrange(6)
            _LOGGER.error("Retrying in %i minutes: %s", minutes, err)
            async_call_later(self.opp, minutes * 60, self.fetching_data)

        try:
            websession = async_get_clientsession(self.opp)
            with async_timeout.timeout(10):
                resp = await websession.get(self._url, params=self._urlparams)
            if resp.status != 200:
                try_again(f"{resp.url} returned {resp.status}")
                return
            text = await resp.text()

        except (asyncio.TimeoutError, aiohttp.ClientError) as err:
            try_again(err)
            return

        try:
            self.data = xmltodict.parse(text)["weatherdata"]
        except (ExpatError, IndexError) as err:
            try_again(err)
            return

        await self.updating_devices()
        async_call_later(self.opp, 60 * 60, self.fetching_data)
예제 #25
0
async def async_setup(opp: OpenPeerPower, config: ConfigType) -> bool:
    """Create a Genius Hub system."""
    opp.data[DOMAIN] = {}

    kwargs = dict(config[DOMAIN])
    if CONF_HOST in kwargs:
        args = (kwargs.pop(CONF_HOST),)
    else:
        args = (kwargs.pop(CONF_TOKEN),)
    hub_uid = kwargs.pop(CONF_MAC, None)

    client = GeniusHub(*args, **kwargs, session=async_get_clientsession(opp))

    broker = opp.data[DOMAIN]["broker"] = GeniusBroker(opp, client, hub_uid)

    try:
        await client.update()
    except aiohttp.ClientResponseError as err:
        _LOGGER.error("Setup failed, check your configuration, %s", err)
        return False
    broker.make_debug_log_entries()

    async_track_time_interval(opp, broker.async_update, SCAN_INTERVAL)

    for platform in ["climate", "water_heater", "sensor", "binary_sensor", "switch"]:
        opp.async_create_task(async_load_platform(opp, platform, DOMAIN, {}, config))

    setup_service_functions(opp, broker)

    return True
예제 #26
0
async def _validate_input(opp: OpenPeerPower,
                          data: dict[str, Any]) -> tuple[str, str]:
    """Validate the user input allows us to connect."""

    bond = Bond(data[CONF_HOST],
                data[CONF_ACCESS_TOKEN],
                session=async_get_clientsession(opp))
    try:
        hub = BondHub(bond)
        await hub.setup(max_devices=1)
    except ClientConnectionError as error:
        raise InputValidationError("cannot_connect") from error
    except ClientResponseError as error:
        if error.status == HTTP_UNAUTHORIZED:
            raise InputValidationError("invalid_auth") from error
        raise InputValidationError("unknown") from error
    except Exception as error:
        _LOGGER.exception("Unexpected exception")
        raise InputValidationError("unknown") from error

    # Return unique ID from the hub to be stored in the config entry.
    if not hub.bond_id:
        raise InputValidationError("old_firmware")

    return hub.bond_id, hub.name
예제 #27
0
async def async_setup_entry(opp, entry, async_add_entities):
    """Set up the Mill climate."""
    mill_data_connection = Mill(
        entry.data[CONF_USERNAME],
        entry.data[CONF_PASSWORD],
        websession=async_get_clientsession(opp),
    )
    if not await mill_data_connection.connect():
        raise ConfigEntryNotReady

    await mill_data_connection.find_all_heaters()

    dev = []
    for heater in mill_data_connection.heaters.values():
        dev.append(MillHeater(heater, mill_data_connection))
    async_add_entities(dev)

    async def set_room_temp(service):
        """Set room temp."""
        room_name = service.data.get(ATTR_ROOM_NAME)
        sleep_temp = service.data.get(ATTR_SLEEP_TEMP)
        comfort_temp = service.data.get(ATTR_COMFORT_TEMP)
        away_temp = service.data.get(ATTR_AWAY_TEMP)
        await mill_data_connection.set_room_temperatures_by_name(
            room_name, sleep_temp, comfort_temp, away_temp
        )

    opp.services.async_register(
        DOMAIN, SERVICE_SET_ROOM_TEMP, set_room_temp, schema=SET_ROOM_TEMP_SCHEMA
    )
예제 #28
0
    async def async_update(self):
        """Get the current state from The Things Network Data Storage."""
        try:
            session = async_get_clientsession(self._opp)
            with async_timeout.timeout(DEFAULT_TIMEOUT):
                response = await session.get(self._url, headers=self._headers)

        except (asyncio.TimeoutError, aiohttp.ClientError):
            _LOGGER.error("Error while accessing: %s", self._url)
            return None

        status = response.status

        if status == 204:
            _LOGGER.error("The device is not available: %s", self._device_id)
            return None

        if status == HTTP_UNAUTHORIZED:
            _LOGGER.error("Not authorized for Application ID: %s",
                          self._app_id)
            return None

        if status == HTTP_NOT_FOUND:
            _LOGGER.error("Application ID is not available: %s", self._app_id)
            return None

        data = await response.json()
        self.data = data[-1]

        for value in self._values.items():
            if value[0] not in self.data:
                _LOGGER.warning("Value not available: %s", value[0])

        return response
예제 #29
0
async def async_setup_scanner(opp, config, async_see, discovery_info=None):
    """Validate the configuration and return a Traccar scanner."""

    session = async_get_clientsession(opp, config[CONF_VERIFY_SSL])

    api = API(
        opp.loop,
        session,
        config[CONF_USERNAME],
        config[CONF_PASSWORD],
        config[CONF_HOST],
        config[CONF_PORT],
        config[CONF_SSL],
    )

    scanner = TraccarScanner(
        api,
        opp,
        async_see,
        config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL),
        config[CONF_MAX_ACCURACY],
        config[CONF_SKIP_ACCURACY_ON],
        config[CONF_MONITORED_CONDITIONS],
        config[CONF_EVENT],
    )

    return await scanner.async_init()
예제 #30
0
async def async_setup(opp, opp_config):
    """Create an Intergas InComfort/Intouch system."""
    incomfort_data = opp.data[DOMAIN] = {}

    credentials = dict(opp_config[DOMAIN])
    hostname = credentials.pop(CONF_HOST)

    client = incomfort_data["client"] = InComfortGateway(
        hostname, **credentials, session=async_get_clientsession(opp)
    )

    try:
        heaters = incomfort_data["heaters"] = list(await client.heaters)
    except ClientResponseError as err:
        _LOGGER.warning("Setup failed, check your configuration, message is: %s", err)
        return False

    for heater in heaters:
        await heater.update()

    for platform in ["water_heater", "binary_sensor", "sensor", "climate"]:
        opp.async_create_task(
            async_load_platform(opp, platform, DOMAIN, {}, opp_config)
        )

    return True