1 """The Honeywell Lyric integration."""
3 from __future__
import annotations
6 from datetime
import timedelta
7 from http
import HTTPStatus
10 from aiohttp.client_exceptions
import ClientResponseError
11 from aiolyric
import Lyric
12 from aiolyric.exceptions
import LyricAuthenticationException, LyricException
20 config_entry_oauth2_flow,
21 config_validation
as cv,
26 ConfigEntryLyricClient,
27 LyricLocalOAuth2Implementation,
30 from .const
import DOMAIN
32 CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
34 _LOGGER = logging.getLogger(__name__)
36 PLATFORMS = [Platform.CLIMATE, Platform.SENSOR]
40 """Set up Honeywell Lyric from a config entry."""
42 await config_entry_oauth2_flow.async_get_config_entry_implementation(
46 if not isinstance(implementation, LyricLocalOAuth2Implementation):
47 raise TypeError(
"Unexpected auth implementation; can't find oauth client id")
49 session = aiohttp_client.async_get_clientsession(hass)
54 client_id = implementation.client_id
55 lyric = Lyric(client, client_id)
57 async
def async_update_data(force_refresh_token: bool =
False) -> Lyric:
58 """Fetch data from Lyric."""
60 if not force_refresh_token:
61 await oauth_session.async_ensure_token_valid()
63 await oauth_session.force_refresh_token()
64 except ClientResponseError
as exception:
65 if exception.status
in (HTTPStatus.UNAUTHORIZED, HTTPStatus.FORBIDDEN):
66 raise ConfigEntryAuthFailed
from exception
70 async
with asyncio.timeout(60):
71 await lyric.get_locations()
74 lyric.get_thermostat_rooms(
75 location.location_id, device.device_id
77 for location
in lyric.locations
78 for device
in location.devices
79 if device.device_class ==
"Thermostat"
80 and device.device_id.startswith(
"LCC")
84 except LyricAuthenticationException
as exception:
87 _LOGGER.debug(
"Authentication failed. Attempting to refresh token")
88 if not force_refresh_token:
89 return await async_update_data(force_refresh_token=
True)
90 raise ConfigEntryAuthFailed
from exception
91 except (LyricException, ClientResponseError)
as exception:
95 coordinator = DataUpdateCoordinator[Lyric](
100 name=
"lyric_coordinator",
101 update_method=async_update_data,
107 await coordinator.async_config_entry_first_refresh()
108 hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
110 await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
116 """Unload a config entry."""
117 unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
119 hass.data[DOMAIN].pop(entry.entry_id)
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)