def main() -> None: """Create the aiohttp session and run the example.""" logging.basicConfig(level=logging.DEBUG) client = Client(API_KEY, LATITUDE, LONGITUDE, altitude=ALTITUDE) start = time.time() try: # Get current UV info: _LOGGER.info("CURRENT UV DATA:") _LOGGER.info(client.uv_index()) # Get forecasted UV info: _LOGGER.info("FORECASTED UV DATA:") _LOGGER.info(client.uv_forecast()) # Get UV protection window: _LOGGER.info("UV PROTECTION WINDOW:") _LOGGER.info(client.uv_protection_window()) except OpenUvError as err: _LOGGER.info(err) end = time.time() _LOGGER.info("Execution time: %s seconds", end - start)
async def test_custom_logger(aresponses, caplog): """Test that a custom logger is used when provided to the client.""" caplog.set_level(logging.DEBUG) custom_logger = logging.getLogger("custom") aresponses.add( "api.openuv.io", "/api/v1/protection", "get", aresponses.Response( text=load_fixture("protection_window_response.json"), status=200, headers={"Content-Type": "application/json"}, ), ) async with aiohttp.ClientSession() as session: client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, altitude=TEST_ALTITUDE, session=session, logger=custom_logger, ) await client.uv_protection_window() assert any( record.name == "custom" and "Received data" in record.message for record in caplog.records ) aresponses.assert_plan_strictly_followed()
async def run(websession: ClientSession): """Run.""" try: # Create a client: client = Client("<API_KEY>", 39.7974509, -104.8887227, websession, altitude=1609.3) # Get current UV info: print("CURRENT UV DATA:") print(await client.uv_index()) # Get forecasted UV info: print() print("FORECASTED UV DATA:") print(await client.uv_forecast()) # Get UV protection window: print() print("UV PROTECTION WINDOW:") print(await client.uv_protection_window()) except OpenUvError as err: print(err)
async def test_protection_window(aresponses): """Test successfully retrieving the protection window.""" aresponses.add( "api.openuv.io", "/api/v1/protection", "get", aresponses.Response( text=load_fixture("protection_window_response.json"), status=200, headers={"Content-Type": "application/json"}, ), ) async with aiohttp.ClientSession() as session: client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, altitude=TEST_ALTITUDE, session=session, ) data = await client.uv_protection_window() assert data["result"]["from_uv"] == 3.2509 aresponses.assert_plan_strictly_followed()
async def test_uv_index_async(aresponses): """Test successfully retrieving UV index info (async).""" aresponses.add( "api.openuv.io", "/api/v1/uv", "get", aresponses.Response( text=load_fixture("uv_index_response.json"), status=200, headers={"Content-Type": "application/json"}, ), ) async with aiohttp.ClientSession() as session: client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, altitude=TEST_ALTITUDE, session=session, ) data = await client.uv_index() assert data["result"]["uv"] == 8.2342 aresponses.assert_plan_strictly_followed()
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Set up OpenUV as config entry.""" hass.data.setdefault(DOMAIN, {DATA_CLIENT: {}, DATA_LISTENER: {}}) _verify_domain_control = verify_domain_control(hass, DOMAIN) try: websession = aiohttp_client.async_get_clientsession(hass) openuv = OpenUV( config_entry, Client( config_entry.data[CONF_API_KEY], config_entry.data.get(CONF_LATITUDE, hass.config.latitude), config_entry.data.get(CONF_LONGITUDE, hass.config.longitude), altitude=config_entry.data.get(CONF_ELEVATION, hass.config.elevation), session=websession, ), ) await openuv.async_update() hass.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] = openuv except OpenUvError as err: LOGGER.error("Config entry failed: %s", err) raise ConfigEntryNotReady from err hass.config_entries.async_setup_platforms(config_entry, PLATFORMS) @_verify_domain_control async def update_data(_: ServiceCall) -> None: """Refresh all OpenUV data.""" LOGGER.debug("Refreshing all OpenUV data") await openuv.async_update() async_dispatcher_send(hass, TOPIC_UPDATE) @_verify_domain_control async def update_uv_index_data(_: ServiceCall) -> None: """Refresh OpenUV UV index data.""" LOGGER.debug("Refreshing OpenUV UV index data") await openuv.async_update_uv_index_data() async_dispatcher_send(hass, TOPIC_UPDATE) @_verify_domain_control async def update_protection_data(_: ServiceCall) -> None: """Refresh OpenUV protection window data.""" LOGGER.debug("Refreshing OpenUV protection window data") await openuv.async_update_protection_data() async_dispatcher_send(hass, TOPIC_UPDATE) for service, method in ( ("update_data", update_data), ("update_uv_index_data", update_uv_index_data), ("update_protection_data", update_protection_data), ): hass.services.async_register(DOMAIN, service, method) return True
async def async_setup_entry(hass, config_entry): """Set up OpenUV as config entry.""" _verify_domain_control = verify_domain_control(hass, DOMAIN) try: websession = aiohttp_client.async_get_clientsession(hass) openuv = OpenUV( Client( config_entry.data[CONF_API_KEY], config_entry.data.get(CONF_LATITUDE, hass.config.latitude), config_entry.data.get(CONF_LONGITUDE, hass.config.longitude), websession, altitude=config_entry.data.get(CONF_ELEVATION, hass.config.elevation), )) await openuv.async_update() hass.data[DOMAIN][DATA_OPENUV_CLIENT][config_entry.entry_id] = openuv except OpenUvError as err: _LOGGER.error("Config entry failed: %s", err) raise ConfigEntryNotReady for component in ("binary_sensor", "sensor"): hass.async_create_task( hass.config_entries.async_forward_entry_setup( config_entry, component)) @_verify_domain_control async def update_data(service): """Refresh all OpenUV data.""" _LOGGER.debug("Refreshing all OpenUV data") await openuv.async_update() async_dispatcher_send(hass, TOPIC_UPDATE) hass.services.async_register(DOMAIN, "update_data", update_data) @_verify_domain_control async def update_uv_index_data(service): """Refresh OpenUV UV index data.""" _LOGGER.debug("Refreshing OpenUV UV index data") await openuv.async_update_uv_index_data() async_dispatcher_send(hass, TOPIC_UPDATE) hass.services.async_register(DOMAIN, "update_uv_index_data", update_uv_index_data) @_verify_domain_control async def update_protection_data(service): """Refresh OpenUV protection window data.""" _LOGGER.debug("Refreshing OpenUV protection window data") await openuv.async_update_protection_data() async_dispatcher_send(hass, TOPIC_UPDATE) hass.services.async_register(DOMAIN, "update_protection_data", update_protection_data) return True
async def async_setup_entry(hass, config_entry): """Set up OpenUV as config entry.""" from pyopenuv import Client from pyopenuv.errors import OpenUvError _verify_domain_control = verify_domain_control(hass, DOMAIN) try: websession = aiohttp_client.async_get_clientsession(hass) openuv = OpenUV( Client( config_entry.data[CONF_API_KEY], config_entry.data.get(CONF_LATITUDE, hass.config.latitude), config_entry.data.get(CONF_LONGITUDE, hass.config.longitude), websession, altitude=config_entry.data.get(CONF_ELEVATION, hass.config.elevation), ), config_entry.data.get(CONF_BINARY_SENSORS, {}).get(CONF_MONITORED_CONDITIONS, list(BINARY_SENSORS)), config_entry.data.get(CONF_SENSORS, {}).get(CONF_MONITORED_CONDITIONS, list(SENSORS)), ) await openuv.async_update() hass.data[DOMAIN][DATA_OPENUV_CLIENT][config_entry.entry_id] = openuv except OpenUvError as err: _LOGGER.error("Config entry failed: %s", err) raise ConfigEntryNotReady for component in ("binary_sensor", "sensor"): hass.async_create_task( hass.config_entries.async_forward_entry_setup( config_entry, component)) @_verify_domain_control async def update_data(service): """Refresh OpenUV data.""" _LOGGER.debug("Refreshing OpenUV data") try: await openuv.async_update() except OpenUvError as err: _LOGGER.error("Error during data update: %s", err) return async_dispatcher_send(hass, TOPIC_UPDATE) hass.services.async_register(DOMAIN, "update_data", update_data) return True
async def async_setup_entry(opp, config_entry): """Set up OpenUV as config entry.""" _verify_domain_control = verify_domain_control(opp, DOMAIN) try: websession = aiohttp_client.async_get_clientsession(opp) openuv = OpenUV( Client( config_entry.data[CONF_API_KEY], config_entry.data.get(CONF_LATITUDE, opp.config.latitude), config_entry.data.get(CONF_LONGITUDE, opp.config.longitude), websession, altitude=config_entry.data.get(CONF_ELEVATION, opp.config.elevation), )) await openuv.async_update() opp.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] = openuv except OpenUvError as err: LOGGER.error("Config entry failed: %s", err) raise ConfigEntryNotReady from err opp.config_entries.async_setup_platforms(config_entry, PLATFORMS) @_verify_domain_control async def update_data(service): """Refresh all OpenUV data.""" LOGGER.debug("Refreshing all OpenUV data") await openuv.async_update() async_dispatcher_send(opp, TOPIC_UPDATE) @_verify_domain_control async def update_uv_index_data(service): """Refresh OpenUV UV index data.""" LOGGER.debug("Refreshing OpenUV UV index data") await openuv.async_update_uv_index_data() async_dispatcher_send(opp, TOPIC_UPDATE) @_verify_domain_control async def update_protection_data(service): """Refresh OpenUV protection window data.""" LOGGER.debug("Refreshing OpenUV protection window data") await openuv.async_update_protection_data() async_dispatcher_send(opp, TOPIC_UPDATE) for service, method in [ ("update_data", update_data), ("update_uv_index_data", update_uv_index_data), ("update_protection_data", update_protection_data), ]: opp.services.async_register(DOMAIN, service, method) return True
async def test_create(event_loop): """Test the creation of a client.""" async with aiohttp.ClientSession(loop=event_loop) as websession: client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, websession, altitude=TEST_ALTITUDE, ) assert client.altitude == TEST_ALTITUDE assert client.latitude == TEST_LATITUDE assert client.longitude == TEST_LONGITUDE
def test_uv_index_sync(aresponses, event_loop): """Test successfully retrieving UV index info (sync).""" aresponses.add( "api.openuv.io", "/api/v1/uv", "get", aresponses.Response( text=load_fixture("uv_index_response.json"), status=200, headers={"Content-Type": "application/json"}, ), ) client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, altitude=TEST_ALTITUDE, event_loop=event_loop, ) data = client.uv_index() assert data["result"]["uv"] == 8.2342
async def async_setup_entry(hass, config_entry): """Set up OpenUV as config entry.""" from pyopenuv import Client from pyopenuv.errors import OpenUvError try: websession = aiohttp_client.async_get_clientsession(hass) openuv = OpenUV( Client(config_entry.data[CONF_API_KEY], config_entry.data.get(CONF_LATITUDE, hass.config.latitude), config_entry.data.get(CONF_LONGITUDE, hass.config.longitude), websession, altitude=config_entry.data.get(CONF_ELEVATION, hass.config.elevation)), config_entry.data.get(CONF_BINARY_SENSORS, {}).get(CONF_MONITORED_CONDITIONS, list(BINARY_SENSORS)), config_entry.data.get(CONF_SENSORS, {}).get(CONF_MONITORED_CONDITIONS, list(SENSORS))) await openuv.async_update() hass.data[DOMAIN][DATA_OPENUV_CLIENT][config_entry.entry_id] = openuv except OpenUvError as err: _LOGGER.error('An error occurred: %s', str(err)) hass.components.persistent_notification.create( 'Error: {0}<br />' 'You will need to restart hass after fixing.' ''.format(err), title=NOTIFICATION_TITLE, notification_id=NOTIFICATION_ID) return False for component in ('binary_sensor', 'sensor'): hass.async_create_task( hass.config_entries.async_forward_entry_setup( config_entry, component)) async def refresh_sensors(event_time): """Refresh OpenUV data.""" _LOGGER.debug('Refreshing OpenUV data') await openuv.async_update() async_dispatcher_send(hass, TOPIC_UPDATE) hass.data[DOMAIN][DATA_OPENUV_LISTENER][ config_entry.entry_id] = async_track_time_interval( hass, refresh_sensors, hass.data[DOMAIN].get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)) return True
async def async_setup(hass, config): """Set up the OpenUV component.""" from pyopenuv import Client from pyopenuv.errors import OpenUvError conf = config[DOMAIN] api_key = conf[CONF_API_KEY] elevation = conf.get(CONF_ELEVATION, hass.config.elevation) latitude = conf.get(CONF_LATITUDE, hass.config.latitude) longitude = conf.get(CONF_LONGITUDE, hass.config.longitude) try: websession = aiohttp_client.async_get_clientsession(hass) openuv = OpenUV( Client(api_key, latitude, longitude, websession, altitude=elevation), conf[CONF_BINARY_SENSORS][CONF_MONITORED_CONDITIONS] + conf[CONF_SENSORS][CONF_MONITORED_CONDITIONS]) await openuv.async_update() hass.data[DOMAIN] = openuv except OpenUvError as err: _LOGGER.error('An error occurred: %s', str(err)) hass.components.persistent_notification.create( 'Error: {0}<br />' 'You will need to restart hass after fixing.' ''.format(err), title=NOTIFICATION_TITLE, notification_id=NOTIFICATION_ID) return False for component, schema in [ ('binary_sensor', conf[CONF_BINARY_SENSORS]), ('sensor', conf[CONF_SENSORS]), ]: hass.async_create_task( discovery.async_load_platform(hass, component, DOMAIN, schema, config)) async def refresh_sensors(event_time): """Refresh OpenUV data.""" _LOGGER.debug('Refreshing OpenUV data') await openuv.async_update() async_dispatcher_send(hass, TOPIC_UPDATE) async_track_time_interval(hass, refresh_sensors, conf[CONF_SCAN_INTERVAL]) return True
async def test_timeout(): """Test that a timeout raises an exception.""" async with aiohttp.ClientSession() as session: client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, altitude=TEST_ALTITUDE, session=session, request_retries=1, ) with patch("aiohttp.ClientSession.request", side_effect=asyncio.TimeoutError): with pytest.raises(RequestError): await client.uv_forecast()
async def test_create(): """Test the creation of a client.""" async with aiohttp.ClientSession() as session: client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, altitude=TEST_ALTITUDE, session=session, use_async=True, ) assert client.altitude == TEST_ALTITUDE assert client.latitude == TEST_LATITUDE assert client.longitude == TEST_LONGITUDE # Test that session with no use_async fails: with pytest.raises(ValueError): _ = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, altitude=TEST_ALTITUDE, session=session, )
async def test_request_retries(aresponses): """Test the request retry logic.""" aresponses.add( "api.openuv.io", "/api/v1/uv", "get", aresponses.Response( text="Not Found", status=404, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "api.openuv.io", "/api/v1/uv", "get", aresponses.Response( text="Not Found", status=404, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "api.openuv.io", "/api/v1/uv", "get", aresponses.Response( text=load_fixture("uv_index_response.json"), status=200, headers={"Content-Type": "application/json"}, ), ) async with aiohttp.ClientSession() as session: client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, altitude=TEST_ALTITUDE, session=session, ) client.disable_request_retries() with pytest.raises(RequestError): await client.uv_index() client.enable_request_retries() data = await client.uv_index() assert data["result"]["uv"] == 8.2342 aresponses.assert_plan_strictly_followed()
async def test_session_from_scratch(aresponses): """Test that an aiohttp ClientSession is created on the fly if needed.""" aresponses.add( "api.openuv.io", "/api/v1/forecast", "get", aresponses.Response( text=load_fixture("uv_forecast_response.json"), status=200, headers={"Content-Type": "application/json"}, ), ) client = Client(TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, altitude=TEST_ALTITUDE) data = await client.uv_forecast() assert len(data["result"]) == 2 aresponses.assert_plan_strictly_followed()
async def async_setup_entry(hass, config_entry): """Set up OpenUV as config entry.""" from pyopenuv import Client from pyopenuv.errors import OpenUvError try: websession = aiohttp_client.async_get_clientsession(hass) openuv = OpenUV( Client(config_entry.data[CONF_API_KEY], config_entry.data.get(CONF_LATITUDE, hass.config.latitude), config_entry.data.get(CONF_LONGITUDE, hass.config.longitude), websession, altitude=config_entry.data.get(CONF_ELEVATION, hass.config.elevation)), config_entry.data.get(CONF_BINARY_SENSORS, {}).get(CONF_MONITORED_CONDITIONS, list(BINARY_SENSORS)), config_entry.data.get(CONF_SENSORS, {}).get(CONF_MONITORED_CONDITIONS, list(SENSORS))) await openuv.async_update() hass.data[DOMAIN][DATA_OPENUV_CLIENT][config_entry.entry_id] = openuv except OpenUvError as err: _LOGGER.error('Config entry failed: %s', err) raise ConfigEntryNotReady for component in ('binary_sensor', 'sensor'): hass.async_create_task( hass.config_entries.async_forward_entry_setup( config_entry, component)) async def refresh(event_time): """Refresh OpenUV data.""" _LOGGER.debug('Refreshing OpenUV data') await openuv.async_update() async_dispatcher_send(hass, TOPIC_UPDATE) hass.data[DOMAIN][DATA_OPENUV_LISTENER][ config_entry.entry_id] = async_track_time_interval( hass, refresh, timedelta(seconds=config_entry.data[CONF_SCAN_INTERVAL])) return True
async def test_uv_forecast(aresponses, event_loop, fixture_uv_forecast): """Test successfully retrieving UV forecast info.""" aresponses.add( "api.openuv.io", "/api/v1/forecast", "get", aresponses.Response(text=json.dumps(fixture_uv_forecast), status=200), ) async with aiohttp.ClientSession(loop=event_loop) as websession: client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, websession, altitude=TEST_ALTITUDE, ) data = await client.uv_forecast() assert len(data["result"]) == 2
async def test_bad_api_key(aresponses, event_loop): """Test the that the property exception is raised with a bad API key.""" aresponses.add( "api.openuv.io", "/api/v1/protection", "get", aresponses.Response(text="", status=403), ) with pytest.raises(InvalidApiKeyError): async with aiohttp.ClientSession(loop=event_loop) as websession: client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, websession, altitude=TEST_ALTITUDE, ) await client.uv_protection_window()
async def test_bad_request(aresponses, event_loop): """Test that the proper exception is raised during a bad request.""" aresponses.add( "api.openuv.io", "/api/v1/bad_endpoint", "get", aresponses.Response(text="", status=500), ) with pytest.raises(RequestError): async with aiohttp.ClientSession(loop=event_loop) as websession: client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, websession, altitude=TEST_ALTITUDE, ) await client.request("get", "bad_endpoint")
async def async_step_user(self, user_input: dict[str, Any] | None = None ) -> FlowResult: """Handle the start of the config flow.""" if not user_input: return await self._show_form() identifier = f"{user_input[CONF_LATITUDE]}, {user_input[CONF_LONGITUDE]}" await self.async_set_unique_id(identifier) self._abort_if_unique_id_configured() websession = aiohttp_client.async_get_clientsession(self.hass) client = Client(user_input[CONF_API_KEY], 0, 0, session=websession) try: await client.uv_index() except OpenUvError: return await self._show_form({CONF_API_KEY: "invalid_api_key"}) return self.async_create_entry(title=identifier, data=user_input)
async def async_step_user(self, user_input=None): """Handle the start of the config flow.""" if not user_input: return await self._show_form() identifier = ( f"{user_input.get(CONF_LATITUDE, self.hass.config.latitude)}, " f"{user_input.get(CONF_LONGITUDE, self.hass.config.longitude)}") if identifier in configured_instances(self.hass): return await self._show_form({CONF_LATITUDE: "identifier_exists"}) websession = aiohttp_client.async_get_clientsession(self.hass) client = Client(user_input[CONF_API_KEY], 0, 0, websession) try: await client.uv_index() except OpenUvError: return await self._show_form({CONF_API_KEY: "invalid_api_key"}) return self.async_create_entry(title=identifier, data=user_input)
async def test_protection_window(aresponses, event_loop, fixture_protection_window): """Test successfully retrieving the protection window.""" aresponses.add( "api.openuv.io", "/api/v1/protection", "get", aresponses.Response(text=json.dumps(fixture_protection_window), status=200), ) async with aiohttp.ClientSession(loop=event_loop) as websession: client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, websession, altitude=TEST_ALTITUDE, ) data = await client.uv_protection_window() assert data["result"]["from_uv"] == 3.2509
async def async_step_user(self, user_input=None): """Handle the start of the config flow.""" if not user_input: return await self._show_form() if user_input.get(CONF_LATITUDE): identifier = f"{user_input[CONF_LATITUDE]}, {user_input[CONF_LONGITUDE]}" else: identifier = "Default Coordinates" await self.async_set_unique_id(identifier) self._abort_if_unique_id_configured() websession = aiohttp_client.async_get_clientsession(self.opp) client = Client(user_input[CONF_API_KEY], 0, 0, websession) try: await client.uv_index() except OpenUvError: return await self._show_form({CONF_API_KEY: "invalid_api_key"}) return self.async_create_entry(title=identifier, data=user_input)
async def test_bad_api_key(aresponses): """Test the that the proper exception is raised with a bad API key.""" aresponses.add( "api.openuv.io", "/api/v1/protection", "get", aresponses.Response(text="", status=403), ) with pytest.raises(InvalidApiKeyError): async with aiohttp.ClientSession() as session: client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, altitude=TEST_ALTITUDE, session=session, request_retries=1, ) await client.uv_protection_window() aresponses.assert_plan_strictly_followed()
async def test_bad_request(aresponses): """Test that the proper exception is raised during a bad request.""" aresponses.add( "api.openuv.io", "/api/v1/bad_endpoint", "get", aresponses.Response(text="", status=500), ) with pytest.raises(RequestError): async with aiohttp.ClientSession() as session: client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, altitude=TEST_ALTITUDE, session=session, request_retries=1, ) await client.async_request("get", "bad_endpoint") aresponses.assert_plan_strictly_followed()
async def async_step_user(self, user_input=None): """Handle the start of the config flow.""" from pyopenuv import Client from pyopenuv.errors import OpenUvError if not user_input: return await self._show_form() identifier = '{0}, {1}'.format( user_input.get(CONF_LATITUDE, self.hass.config.latitude), user_input.get(CONF_LONGITUDE, self.hass.config.longitude)) if identifier in configured_instances(self.hass): return await self._show_form({CONF_LATITUDE: 'identifier_exists'}) websession = aiohttp_client.async_get_clientsession(self.hass) client = Client(user_input[CONF_API_KEY], 0, 0, websession) try: await client.uv_index() except OpenUvError: return await self._show_form({CONF_API_KEY: 'invalid_api_key'}) return self.async_create_entry(title=identifier, data=user_input)
async def test_uv_forecast(aresponses): """Test successfully retrieving UV forecast info.""" aresponses.add( "api.openuv.io", "/api/v1/forecast", "get", aresponses.Response( text=load_fixture("uv_forecast_response.json"), status=200, headers={"Content-Type": "application/json"}, ), ) async with aiohttp.ClientSession() as session: client = Client( TEST_API_KEY, TEST_LATITUDE, TEST_LONGITUDE, altitude=TEST_ALTITUDE, session=session, use_async=True, ) data = await client.uv_forecast() assert len(data["result"]) == 2
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up OpenUV as config entry.""" _verify_domain_control = verify_domain_control(hass, DOMAIN) websession = aiohttp_client.async_get_clientsession(hass) openuv = OpenUV( entry, Client( entry.data[CONF_API_KEY], entry.data.get(CONF_LATITUDE, hass.config.latitude), entry.data.get(CONF_LONGITUDE, hass.config.longitude), altitude=entry.data.get(CONF_ELEVATION, hass.config.elevation), session=websession, ), ) # We disable the client's request retry abilities here to avoid a lengthy (and # blocking) startup: openuv.client.disable_request_retries() try: await openuv.async_update() except HomeAssistantError as err: LOGGER.error("Config entry failed: %s", err) raise ConfigEntryNotReady from err # Once we've successfully authenticated, we re-enable client request retries: openuv.client.enable_request_retries() hass.data.setdefault(DOMAIN, {}) hass.data[DOMAIN][entry.entry_id] = openuv hass.config_entries.async_setup_platforms(entry, PLATFORMS) @_verify_domain_control async def update_data(_: ServiceCall) -> None: """Refresh all OpenUV data.""" LOGGER.debug("Refreshing all OpenUV data") await openuv.async_update() async_dispatcher_send(hass, TOPIC_UPDATE) @_verify_domain_control async def update_uv_index_data(_: ServiceCall) -> None: """Refresh OpenUV UV index data.""" LOGGER.debug("Refreshing OpenUV UV index data") await openuv.async_update_uv_index_data() async_dispatcher_send(hass, TOPIC_UPDATE) @_verify_domain_control async def update_protection_data(_: ServiceCall) -> None: """Refresh OpenUV protection window data.""" LOGGER.debug("Refreshing OpenUV protection window data") await openuv.async_update_protection_data() async_dispatcher_send(hass, TOPIC_UPDATE) for service, method in ( ("update_data", update_data), ("update_uv_index_data", update_uv_index_data), ("update_protection_data", update_protection_data), ): hass.services.async_register(DOMAIN, service, method) return True