diff --git a/homeassistant/components/ipma/__init__.py b/homeassistant/components/ipma/__init__.py index 4d675e8cc1d..315362247a2 100644 --- a/homeassistant/components/ipma/__init__.py +++ b/homeassistant/components/ipma/__init__.py @@ -1,19 +1,61 @@ """Component for the Portuguese weather service - IPMA.""" +import logging + +import async_timeout +from pyipma import IPMAException +from pyipma.api import IPMA_API +from pyipma.location import Location + from homeassistant.config_entries import ConfigEntry -from homeassistant.const import Platform +from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, Platform from homeassistant.core import HomeAssistant +from homeassistant.exceptions import ConfigEntryNotReady +from homeassistant.helpers.aiohttp_client import async_get_clientsession from .config_flow import IpmaFlowHandler # noqa: F401 -from .const import DOMAIN # noqa: F401 +from .const import DATA_API, DATA_LOCATION, DOMAIN DEFAULT_NAME = "ipma" PLATFORMS = [Platform.WEATHER] +_LOGGER = logging.getLogger(__name__) -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: + +async def async_get_api(hass): + """Get the pyipma api object.""" + websession = async_get_clientsession(hass) + return IPMA_API(websession) + + +async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Set up IPMA station as config entry.""" - await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) + + latitude = config_entry.data[CONF_LATITUDE] + longitude = config_entry.data[CONF_LONGITUDE] + + api = await async_get_api(hass) + try: + async with async_timeout.timeout(30): + location = await Location.get(api, float(latitude), float(longitude)) + + _LOGGER.debug( + "Initializing for coordinates %s, %s -> station %s (%d, %d)", + latitude, + longitude, + location.station, + location.id_station, + location.global_id_local, + ) + except IPMAException as err: + raise ConfigEntryNotReady( + f"Could not get location for ({latitude},{longitude})" + ) from err + + hass.data.setdefault(DOMAIN, {}) + hass.data[DOMAIN][config_entry.entry_id] = {DATA_API: api, DATA_LOCATION: location} + + await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS) return True diff --git a/homeassistant/components/ipma/const.py b/homeassistant/components/ipma/const.py index 47434d7f76b..60c8115a5c4 100644 --- a/homeassistant/components/ipma/const.py +++ b/homeassistant/components/ipma/const.py @@ -6,3 +6,6 @@ DOMAIN = "ipma" HOME_LOCATION_NAME = "Home" ENTITY_ID_SENSOR_FORMAT_HOME = f"{WEATHER_DOMAIN}.ipma_{HOME_LOCATION_NAME}" + +DATA_LOCATION = "location" +DATA_API = "api" diff --git a/homeassistant/components/ipma/manifest.json b/homeassistant/components/ipma/manifest.json index a391b24e3b4..23558600373 100644 --- a/homeassistant/components/ipma/manifest.json +++ b/homeassistant/components/ipma/manifest.json @@ -3,7 +3,7 @@ "name": "Instituto Portugu\u00eas do Mar e Atmosfera (IPMA)", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/ipma", - "requirements": ["pyipma==3.0.2"], + "requirements": ["pyipma==3.0.4"], "codeowners": ["@dgomes", "@abmantis"], "iot_class": "cloud_polling", "loggers": ["geopy", "pyipma"] diff --git a/homeassistant/components/ipma/weather.py b/homeassistant/components/ipma/weather.py index d20e5cb2f21..a0fe5b235b3 100644 --- a/homeassistant/components/ipma/weather.py +++ b/homeassistant/components/ipma/weather.py @@ -48,11 +48,12 @@ from homeassistant.const import ( ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry -from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.sun import is_up from homeassistant.util import Throttle +from .const import DATA_API, DATA_LOCATION, DOMAIN + _LOGGER = logging.getLogger(__name__) ATTRIBUTION = "Instituto Português do Mar e Atmosfera" @@ -95,13 +96,10 @@ async def async_setup_entry( async_add_entities: AddEntitiesCallback, ) -> None: """Add a weather entity from a config_entry.""" - latitude = config_entry.data[CONF_LATITUDE] - longitude = config_entry.data[CONF_LONGITUDE] + api = hass.data[DOMAIN][config_entry.entry_id][DATA_API] + location = hass.data[DOMAIN][config_entry.entry_id][DATA_LOCATION] mode = config_entry.data[CONF_MODE] - api = await async_get_api(hass) - location = await async_get_location(hass, api, latitude, longitude) - # Migrate old unique_id @callback def _async_migrator(entity_entry: entity_registry.RegistryEntry): @@ -127,29 +125,6 @@ async def async_setup_entry( async_add_entities([IPMAWeather(location, api, config_entry.data)], True) -async def async_get_api(hass): - """Get the pyipma api object.""" - websession = async_get_clientsession(hass) - return IPMA_API(websession) - - -async def async_get_location(hass, api, latitude, longitude): - """Retrieve pyipma location, location name to be used as the entity name.""" - async with async_timeout.timeout(30): - location = await Location.get(api, float(latitude), float(longitude)) - - _LOGGER.debug( - "Initializing for coordinates %s, %s -> station %s (%d, %d)", - latitude, - longitude, - location.station, - location.id_station, - location.global_id_local, - ) - - return location - - class IPMAWeather(WeatherEntity): """Representation of a weather condition.""" diff --git a/requirements_all.txt b/requirements_all.txt index fc3fd2a0f1f..8a87ad1cc6a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1614,7 +1614,7 @@ pyinsteon==1.2.0 pyintesishome==1.8.0 # homeassistant.components.ipma -pyipma==3.0.2 +pyipma==3.0.4 # homeassistant.components.ipp pyipp==0.11.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index ece00d7d630..e83a56b8a28 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1127,7 +1127,7 @@ pyicloud==1.0.0 pyinsteon==1.2.0 # homeassistant.components.ipma -pyipma==3.0.2 +pyipma==3.0.4 # homeassistant.components.ipp pyipp==0.11.0 diff --git a/tests/components/ipma/test_config_flow.py b/tests/components/ipma/test_config_flow.py index c8d53f95a4a..0c17cbe7f4b 100644 --- a/tests/components/ipma/test_config_flow.py +++ b/tests/components/ipma/test_config_flow.py @@ -168,7 +168,7 @@ async def test_config_entry_migration(hass): ) with patch( - "homeassistant.components.ipma.weather.async_get_location", + "pyipma.location.Location.get", return_value=MockLocation(), ): assert await async_setup_component(hass, DOMAIN, {}) diff --git a/tests/components/ipma/test_weather.py b/tests/components/ipma/test_weather.py index 942b9654895..e129216730d 100644 --- a/tests/components/ipma/test_weather.py +++ b/tests/components/ipma/test_weather.py @@ -19,7 +19,6 @@ from homeassistant.components.weather import ( ATTR_WEATHER_TEMPERATURE, ATTR_WEATHER_WIND_BEARING, ATTR_WEATHER_WIND_SPEED, - DOMAIN as WEATHER_DOMAIN, ) from homeassistant.const import STATE_UNKNOWN @@ -181,7 +180,8 @@ async def test_setup_config_flow(hass): return_value=MockLocation(), ): entry = MockConfigEntry(domain="ipma", data=TEST_CONFIG) - await hass.config_entries.async_forward_entry_setup(entry, WEATHER_DOMAIN) + entry.add_to_hass(hass) + await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() state = hass.states.get("weather.hometown") @@ -203,7 +203,8 @@ async def test_daily_forecast(hass): return_value=MockLocation(), ): entry = MockConfigEntry(domain="ipma", data=TEST_CONFIG) - await hass.config_entries.async_forward_entry_setup(entry, WEATHER_DOMAIN) + entry.add_to_hass(hass) + await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() state = hass.states.get("weather.hometown") @@ -227,7 +228,8 @@ async def test_hourly_forecast(hass): return_value=MockLocation(), ): entry = MockConfigEntry(domain="ipma", data=TEST_CONFIG_HOURLY) - await hass.config_entries.async_forward_entry_setup(entry, WEATHER_DOMAIN) + entry.add_to_hass(hass) + await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() state = hass.states.get("weather.hometown") @@ -248,7 +250,8 @@ async def test_failed_get_observation_forecast(hass): return_value=MockBadLocation(), ): entry = MockConfigEntry(domain="ipma", data=TEST_CONFIG) - await hass.config_entries.async_forward_entry_setup(entry, WEATHER_DOMAIN) + entry.add_to_hass(hass) + await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() state = hass.states.get("weather.hometown")