Retry on unavailable IPMA api (#78332)
Co-authored-by: J. Nick Koston <nick@koston.org>pull/78410/head
parent
6a197332c7
commit
7b83807baa
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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."""
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, {})
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue