Пример #1
0
    async def init_client(self) -> bool:
        """Initialse the evohome data broker.

        Return True if this is successful, otherwise return False.
        """
        refresh_token, access_token, access_token_expires = (
            await self._load_auth_tokens())

        # evohomeasync2 uses naive/local datetimes
        if access_token_expires is not None:
            access_token_expires = _dt_to_local_naive(access_token_expires)

        client = self.client = evohomeasync2.EvohomeClient(
            self.params[CONF_USERNAME],
            self.params[CONF_PASSWORD],
            refresh_token=refresh_token,
            access_token=access_token,
            access_token_expires=access_token_expires,
            session=async_get_clientsession(self.hass),
        )

        try:
            await client.login()
        except (aiohttp.ClientError, evohomeasync2.AuthenticationError) as err:
            if not _handle_exception(err):
                return False

        finally:
            self.params[CONF_PASSWORD] = "REDACTED"

        self.hass.add_job(self._save_auth_tokens())

        loc_idx = self.params[CONF_LOCATION_IDX]
        try:
            self.config = client.installation_info[loc_idx][GWS][0][TCS][0]

        except IndexError:
            _LOGGER.error(
                "Config error: '%s' = %s, but its valid range is 0-%s. "
                "Unable to continue. "
                "Fix any configuration errors and restart HA.",
                CONF_LOCATION_IDX,
                loc_idx,
                len(client.installation_info) - 1,
            )
            return False

        self.tcs = (
            client.locations[loc_idx]  # pylint: disable=protected-access
            ._gateways[0]._control_systems[0])

        _LOGGER.debug("Config = %s", self.config)
        if _LOGGER.isEnabledFor(
                logging.DEBUG):  # don't do an I/O unless required
            await self.update()  # includes: _LOGGER.debug("Status = %s"...

        return True
Пример #2
0
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
    """Create a (EMEA/EU-based) Honeywell TCC system."""
    async def load_auth_tokens(store) -> tuple[dict, dict | None]:
        app_storage = await store.async_load()
        tokens = dict(app_storage or {})

        if tokens.pop(CONF_USERNAME, None) != config[DOMAIN][CONF_USERNAME]:
            # any tokens won't be valid, and store might be be corrupt
            await store.async_save({})
            return ({}, None)

        # evohomeasync2 requires naive/local datetimes as strings
        if tokens.get(ACCESS_TOKEN_EXPIRES) is not None:
            tokens[ACCESS_TOKEN_EXPIRES] = _dt_aware_to_naive(
                dt_util.parse_datetime(tokens[ACCESS_TOKEN_EXPIRES]))

        user_data = tokens.pop(USER_DATA, None)
        return (tokens, user_data)

    store = hass.helpers.storage.Store(STORAGE_VER, STORAGE_KEY)
    tokens, user_data = await load_auth_tokens(store)

    client_v2 = evohomeasync2.EvohomeClient(
        config[DOMAIN][CONF_USERNAME],
        config[DOMAIN][CONF_PASSWORD],
        **tokens,
        session=async_get_clientsession(hass),
    )

    try:
        await client_v2.login()
    except (aiohttp.ClientError, evohomeasync2.AuthenticationError) as err:
        _handle_exception(err)
        return False
    finally:
        config[DOMAIN][CONF_PASSWORD] = "REDACTED"

    loc_idx = config[DOMAIN][CONF_LOCATION_IDX]
    try:
        loc_config = client_v2.installation_info[loc_idx]
    except IndexError:
        _LOGGER.error(
            "Config error: '%s' = %s, but the valid range is 0-%s. "
            "Unable to continue. Fix any configuration errors and restart HA",
            CONF_LOCATION_IDX,
            loc_idx,
            len(client_v2.installation_info) - 1,
        )
        return False

    if _LOGGER.isEnabledFor(logging.DEBUG):
        _config = {"locationInfo": {"timeZone": None}, GWS: [{TCS: None}]}
        _config["locationInfo"]["timeZone"] = loc_config["locationInfo"][
            "timeZone"]
        _config[GWS][0][TCS] = loc_config[GWS][0][TCS]
        _LOGGER.debug("Config = %s", _config)

    client_v1 = evohomeasync.EvohomeClient(
        client_v2.username,
        client_v2.password,
        user_data=user_data,
        session=async_get_clientsession(hass),
    )

    hass.data[DOMAIN] = {}
    hass.data[DOMAIN]["broker"] = broker = EvoBroker(hass, client_v2,
                                                     client_v1, store,
                                                     config[DOMAIN])

    await broker.save_auth_tokens()
    await broker.async_update()  # get initial state

    hass.async_create_task(
        async_load_platform(hass, "climate", DOMAIN, {}, config))
    if broker.tcs.hotwater:
        hass.async_create_task(
            async_load_platform(hass, "water_heater", DOMAIN, {}, config))

    hass.helpers.event.async_track_time_interval(
        broker.async_update, config[DOMAIN][CONF_SCAN_INTERVAL])

    setup_service_functions(hass, broker)

    return True
Пример #3
0
        # evohomeasync2 requires naive/local datetimes as strings
        if tokens.get(ACCESS_TOKEN_EXPIRES) is not None and (
                expires := dt_util.parse_datetime(
                    tokens[ACCESS_TOKEN_EXPIRES])):
            tokens[ACCESS_TOKEN_EXPIRES] = _dt_aware_to_naive(expires)

        user_data = tokens.pop(USER_DATA, None)
        return (tokens, user_data)

    store = Store[dict[str, Any]](hass, STORAGE_VER, STORAGE_KEY)
    tokens, user_data = await load_auth_tokens(store)

    client_v2 = evohomeasync2.EvohomeClient(
        config[DOMAIN][CONF_USERNAME],
        config[DOMAIN][CONF_PASSWORD],
        **tokens,
        session=async_get_clientsession(hass),
    )

    try:
        await client_v2.login()
    except (aiohttp.ClientError, evohomeasync2.AuthenticationError) as err:
        _handle_exception(err)
        return False
    finally:
        config[DOMAIN][CONF_PASSWORD] = "REDACTED"

    loc_idx = config[DOMAIN][CONF_LOCATION_IDX]
    try:
        loc_config = client_v2.installation_info[loc_idx]
    except IndexError: