mirror of
https://github.com/home-assistant/core.git
synced 2025-04-27 18:57:57 +00:00
Add DataUpdateCoordinator to met integration (#38405)
* Add DataUpdateCoordinator to met integration * isort * redundant fetch_data * Update homeassistant/components/met/weather.py Co-authored-by: Chris Talkington <chris@talkingtontech.com> * Update homeassistant/components/met/weather.py Co-authored-by: Chris Talkington <chris@talkingtontech.com> * Update homeassistant/components/met/__init__.py Co-authored-by: Chris Talkington <chris@talkingtontech.com> * Update homeassistant/components/met/__init__.py Co-authored-by: Chris Talkington <chris@talkingtontech.com> * Update homeassistant/components/met/__init__.py Co-authored-by: Chris Talkington <chris@talkingtontech.com> * Update homeassistant/components/met/__init__.py Co-authored-by: Chris Talkington <chris@talkingtontech.com> * Update homeassistant/components/met/weather.py Co-authored-by: Chris Talkington <chris@talkingtontech.com> * Update homeassistant/components/met/__init__.py Co-authored-by: Chris Talkington <chris@talkingtontech.com> * Update homeassistant/components/met/__init__.py Co-authored-by: Chris Talkington <chris@talkingtontech.com> * Update homeassistant/components/met/__init__.py Co-authored-by: Chris Talkington <chris@talkingtontech.com> * Update homeassistant/components/met/__init__.py Co-authored-by: Chris Talkington <chris@talkingtontech.com> * Update homeassistant/components/met/__init__.py Co-authored-by: Chris Talkington <chris@talkingtontech.com> * Update homeassistant/components/met/weather.py Co-authored-by: Chris Talkington <chris@talkingtontech.com> * Update homeassistant/components/met/weather.py Co-authored-by: Chris Talkington <chris@talkingtontech.com> * fix black, isort, flake8, hassfest, mypy * remove unused async_setup method * replace fetch_data by coordinator request_refresh * remove redundant async_update * track_home * Apply suggestions from code review * Apply suggestions from code review * Update homeassistant/components/met/__init__.py * Apply suggestions from code review * Update homeassistant/components/met/__init__.py * Apply suggestions from code review * Update homeassistant/components/met/__init__.py * Apply suggestions from code review * Update test_config_flow.py * Apply suggestions from code review * Apply suggestions from code review * Update __init__.py * Create test_init.py * Update homeassistant/components/met/__init__.py * Update __init__.py * Update __init__.py * Update homeassistant/components/met/__init__.py Co-authored-by: Chris Talkington <chris@talkingtontech.com>
This commit is contained in:
parent
761067559d
commit
b258e757c2
@ -1,24 +1,153 @@
|
|||||||
"""The met component."""
|
"""The met component."""
|
||||||
from homeassistant.core import Config, HomeAssistant
|
from datetime import timedelta
|
||||||
|
import logging
|
||||||
|
from random import randrange
|
||||||
|
|
||||||
from .config_flow import MetFlowHandler # noqa: F401
|
import metno
|
||||||
from .const import DOMAIN # noqa: F401
|
|
||||||
|
from homeassistant.const import (
|
||||||
|
CONF_ELEVATION,
|
||||||
|
CONF_LATITUDE,
|
||||||
|
CONF_LONGITUDE,
|
||||||
|
EVENT_CORE_CONFIG_UPDATE,
|
||||||
|
LENGTH_FEET,
|
||||||
|
LENGTH_METERS,
|
||||||
|
)
|
||||||
|
from homeassistant.core import Config, HomeAssistant
|
||||||
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
from homeassistant.util.distance import convert as convert_distance
|
||||||
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
|
from .const import CONF_TRACK_HOME, DOMAIN
|
||||||
|
|
||||||
|
URL = "https://aa015h6buqvih86i1.api.met.no/weatherapi/locationforecast/1.9/"
|
||||||
|
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass: HomeAssistant, config: Config) -> bool:
|
async def async_setup(hass: HomeAssistant, config: Config) -> bool:
|
||||||
"""Set up configured Met."""
|
"""Set up configured Met."""
|
||||||
|
hass.data.setdefault(DOMAIN, {})
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry):
|
async def async_setup_entry(hass, config_entry):
|
||||||
"""Set up Met as config entry."""
|
"""Set up Met as config entry."""
|
||||||
|
coordinator = MetDataUpdateCoordinator(hass, config_entry)
|
||||||
|
await coordinator.async_refresh()
|
||||||
|
|
||||||
|
if not coordinator.last_update_success:
|
||||||
|
raise ConfigEntryNotReady
|
||||||
|
|
||||||
|
if config_entry.data.get(CONF_TRACK_HOME, False):
|
||||||
|
coordinator.track_home()
|
||||||
|
|
||||||
|
hass.data[DOMAIN][config_entry.entry_id] = coordinator
|
||||||
|
|
||||||
hass.async_create_task(
|
hass.async_create_task(
|
||||||
hass.config_entries.async_forward_entry_setup(config_entry, "weather")
|
hass.config_entries.async_forward_entry_setup(config_entry, "weather")
|
||||||
)
|
)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def async_unload_entry(hass, config_entry):
|
async def async_unload_entry(hass, config_entry):
|
||||||
"""Unload a config entry."""
|
"""Unload a config entry."""
|
||||||
await hass.config_entries.async_forward_entry_unload(config_entry, "weather")
|
await hass.config_entries.async_forward_entry_unload(config_entry, "weather")
|
||||||
|
hass.data[DOMAIN][config_entry.entry_id].untrack_home()
|
||||||
|
hass.data[DOMAIN].pop(config_entry.entry_id)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class MetDataUpdateCoordinator(DataUpdateCoordinator):
|
||||||
|
"""Class to manage fetching Met data."""
|
||||||
|
|
||||||
|
def __init__(self, hass, config_entry):
|
||||||
|
"""Initialize global Met data updater."""
|
||||||
|
self._unsub_track_home = None
|
||||||
|
self.weather = MetWeatherData(
|
||||||
|
hass, config_entry.data, hass.config.units.is_metric
|
||||||
|
)
|
||||||
|
self.weather.init_data()
|
||||||
|
|
||||||
|
update_interval = timedelta(minutes=randrange(55, 65))
|
||||||
|
|
||||||
|
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
|
||||||
|
|
||||||
|
async def _async_update_data(self):
|
||||||
|
"""Fetch data from Met."""
|
||||||
|
try:
|
||||||
|
return await self.weather.fetch_data()
|
||||||
|
except Exception as err:
|
||||||
|
raise UpdateFailed(f"Update failed: {err}")
|
||||||
|
|
||||||
|
def track_home(self):
|
||||||
|
"""Start tracking changes to HA home setting."""
|
||||||
|
if self._unsub_track_home:
|
||||||
|
return
|
||||||
|
|
||||||
|
async def _async_update_weather_data(_event=None):
|
||||||
|
"""Update weather data."""
|
||||||
|
self.weather.init_data()
|
||||||
|
await self.async_refresh()
|
||||||
|
|
||||||
|
self._unsub_track_home = self.hass.bus.async_listen(
|
||||||
|
EVENT_CORE_CONFIG_UPDATE, _async_update_weather_data
|
||||||
|
)
|
||||||
|
|
||||||
|
def untrack_home(self):
|
||||||
|
"""Stop tracking changes to HA home setting."""
|
||||||
|
if self._unsub_track_home:
|
||||||
|
self._unsub_track_home()
|
||||||
|
self._unsub_track_home = None
|
||||||
|
|
||||||
|
|
||||||
|
class MetWeatherData:
|
||||||
|
"""Keep data for Met.no weather entities."""
|
||||||
|
|
||||||
|
def __init__(self, hass, config, is_metric):
|
||||||
|
"""Initialise the weather entity data."""
|
||||||
|
self.hass = hass
|
||||||
|
self._config = config
|
||||||
|
self._is_metric = is_metric
|
||||||
|
self._weather_data = None
|
||||||
|
self.current_weather_data = {}
|
||||||
|
self.forecast_data = None
|
||||||
|
|
||||||
|
def init_data(self):
|
||||||
|
"""Weather data inialization - get the coordinates."""
|
||||||
|
if self._config.get(CONF_TRACK_HOME, False):
|
||||||
|
latitude = self.hass.config.latitude
|
||||||
|
longitude = self.hass.config.longitude
|
||||||
|
elevation = self.hass.config.elevation
|
||||||
|
else:
|
||||||
|
latitude = self._config[CONF_LATITUDE]
|
||||||
|
longitude = self._config[CONF_LONGITUDE]
|
||||||
|
elevation = self._config[CONF_ELEVATION]
|
||||||
|
|
||||||
|
if not self._is_metric:
|
||||||
|
elevation = int(
|
||||||
|
round(convert_distance(elevation, LENGTH_FEET, LENGTH_METERS))
|
||||||
|
)
|
||||||
|
|
||||||
|
coordinates = {
|
||||||
|
"lat": str(latitude),
|
||||||
|
"lon": str(longitude),
|
||||||
|
"msl": str(elevation),
|
||||||
|
}
|
||||||
|
|
||||||
|
self._weather_data = metno.MetWeatherData(
|
||||||
|
coordinates, async_get_clientsession(self.hass), URL
|
||||||
|
)
|
||||||
|
|
||||||
|
async def fetch_data(self):
|
||||||
|
"""Fetch data from API - (current weather and forecast)."""
|
||||||
|
await self._weather_data.fetching_data()
|
||||||
|
self.current_weather_data = self._weather_data.get_current_weather()
|
||||||
|
time_zone = dt_util.DEFAULT_TIME_ZONE
|
||||||
|
self.forecast_data = self._weather_data.get_forecast(time_zone)
|
||||||
|
return self
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
"""Config flow to configure Met component."""
|
"""Config flow to configure Met component."""
|
||||||
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
@ -71,6 +73,12 @@ class MetFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
errors=self._errors,
|
errors=self._errors,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def async_step_import(
|
||||||
|
self, user_input: Optional[Dict] = None
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""Handle configuration by yaml file."""
|
||||||
|
return await self.async_step_user(user_input)
|
||||||
|
|
||||||
async def async_step_onboarding(self, data=None):
|
async def async_step_onboarding(self, data=None):
|
||||||
"""Handle a flow initialized by onboarding."""
|
"""Handle a flow initialized by onboarding."""
|
||||||
return self.async_create_entry(
|
return self.async_create_entry(
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
"""Support for Met.no weather service."""
|
"""Support for Met.no weather service."""
|
||||||
import logging
|
import logging
|
||||||
from random import randrange
|
|
||||||
|
|
||||||
import metno
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.weather import PLATFORM_SCHEMA, WeatherEntity
|
from homeassistant.components.weather import PLATFORM_SCHEMA, WeatherEntity
|
||||||
|
from homeassistant.config_entries import SOURCE_IMPORT
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_ELEVATION,
|
CONF_ELEVATION,
|
||||||
CONF_LATITUDE,
|
CONF_LATITUDE,
|
||||||
CONF_LONGITUDE,
|
CONF_LONGITUDE,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
EVENT_CORE_CONFIG_UPDATE,
|
|
||||||
LENGTH_FEET,
|
|
||||||
LENGTH_METERS,
|
LENGTH_METERS,
|
||||||
LENGTH_MILES,
|
LENGTH_MILES,
|
||||||
PRESSURE_HPA,
|
PRESSURE_HPA,
|
||||||
@ -20,13 +17,10 @@ from homeassistant.const import (
|
|||||||
TEMP_CELSIUS,
|
TEMP_CELSIUS,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|
||||||
from homeassistant.helpers.event import async_call_later
|
|
||||||
from homeassistant.util.distance import convert as convert_distance
|
from homeassistant.util.distance import convert as convert_distance
|
||||||
import homeassistant.util.dt as dt_util
|
|
||||||
from homeassistant.util.pressure import convert as convert_pressure
|
from homeassistant.util.pressure import convert as convert_pressure
|
||||||
|
|
||||||
from .const import CONF_TRACK_HOME
|
from .const import CONF_TRACK_HOME, DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -36,7 +30,6 @@ ATTRIBUTION = (
|
|||||||
)
|
)
|
||||||
DEFAULT_NAME = "Met.no"
|
DEFAULT_NAME = "Met.no"
|
||||||
|
|
||||||
URL = "https://aa015h6buqvih86i1.api.met.no/weatherapi/locationforecast/2.0/classic"
|
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
@ -62,100 +55,39 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||||||
if config.get(CONF_LATITUDE) is None:
|
if config.get(CONF_LATITUDE) is None:
|
||||||
config[CONF_TRACK_HOME] = True
|
config[CONF_TRACK_HOME] = True
|
||||||
|
|
||||||
async_add_entities([MetWeather(config, hass.config.units.is_metric)])
|
hass.async_create_task(
|
||||||
|
hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": SOURCE_IMPORT}, data=config
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
"""Add a weather entity from a config_entry."""
|
"""Add a weather entity from a config_entry."""
|
||||||
async_add_entities([MetWeather(config_entry.data, hass.config.units.is_metric)])
|
coordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
|
async_add_entities(
|
||||||
|
[MetWeather(coordinator, config_entry.data, hass.config.units.is_metric)]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class MetWeather(WeatherEntity):
|
class MetWeather(WeatherEntity):
|
||||||
"""Implementation of a Met.no weather condition."""
|
"""Implementation of a Met.no weather condition."""
|
||||||
|
|
||||||
def __init__(self, config, is_metric):
|
def __init__(self, coordinator, config, is_metric):
|
||||||
"""Initialise the platform with a data instance and site."""
|
"""Initialise the platform with a data instance and site."""
|
||||||
self._config = config
|
self._config = config
|
||||||
|
self._coordinator = coordinator
|
||||||
self._is_metric = is_metric
|
self._is_metric = is_metric
|
||||||
self._unsub_track_home = None
|
|
||||||
self._unsub_fetch_data = None
|
|
||||||
self._weather_data = None
|
|
||||||
self._current_weather_data = {}
|
|
||||||
self._coordinates = {}
|
|
||||||
self._forecast_data = None
|
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
async def async_added_to_hass(self):
|
||||||
"""Start fetching data."""
|
"""Start fetching data."""
|
||||||
await self._init_data()
|
self.async_on_remove(
|
||||||
if self._config.get(CONF_TRACK_HOME):
|
self._coordinator.async_add_listener(self.async_write_ha_state)
|
||||||
self._unsub_track_home = self.hass.bus.async_listen(
|
|
||||||
EVENT_CORE_CONFIG_UPDATE, self._init_data
|
|
||||||
)
|
|
||||||
|
|
||||||
async def _init_data(self, _event=None):
|
|
||||||
"""Initialize and fetch data object."""
|
|
||||||
if self.track_home:
|
|
||||||
latitude = self.hass.config.latitude
|
|
||||||
longitude = self.hass.config.longitude
|
|
||||||
elevation = self.hass.config.elevation
|
|
||||||
else:
|
|
||||||
conf = self._config
|
|
||||||
latitude = conf[CONF_LATITUDE]
|
|
||||||
longitude = conf[CONF_LONGITUDE]
|
|
||||||
elevation = conf[CONF_ELEVATION]
|
|
||||||
|
|
||||||
if not self._is_metric:
|
|
||||||
elevation = convert_distance(elevation, LENGTH_FEET, LENGTH_METERS)
|
|
||||||
coordinates = {
|
|
||||||
"lat": latitude,
|
|
||||||
"lon": longitude,
|
|
||||||
"msl": elevation,
|
|
||||||
}
|
|
||||||
if coordinates == self._coordinates:
|
|
||||||
return
|
|
||||||
self._coordinates = coordinates
|
|
||||||
|
|
||||||
self._weather_data = metno.MetWeatherData(
|
|
||||||
coordinates, async_get_clientsession(self.hass), URL
|
|
||||||
)
|
|
||||||
await self._fetch_data()
|
|
||||||
|
|
||||||
async def will_remove_from_hass(self):
|
|
||||||
"""Handle entity will be removed from hass."""
|
|
||||||
if self._unsub_track_home:
|
|
||||||
self._unsub_track_home()
|
|
||||||
self._unsub_track_home = None
|
|
||||||
|
|
||||||
if self._unsub_fetch_data:
|
|
||||||
self._unsub_fetch_data()
|
|
||||||
self._unsub_fetch_data = None
|
|
||||||
|
|
||||||
async def _fetch_data(self, *_):
|
|
||||||
"""Get the latest data from met.no."""
|
|
||||||
if self._unsub_fetch_data:
|
|
||||||
self._unsub_fetch_data()
|
|
||||||
self._unsub_fetch_data = None
|
|
||||||
|
|
||||||
if not await self._weather_data.fetching_data():
|
|
||||||
# Retry in 15 to 20 minutes.
|
|
||||||
minutes = 15 + randrange(6)
|
|
||||||
_LOGGER.error("Retrying in %i minutes", minutes)
|
|
||||||
self._unsub_fetch_data = async_call_later(
|
|
||||||
self.hass, minutes * 60, self._fetch_data
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Wait between 55-65 minutes. If people update HA on the hour, this
|
|
||||||
# will make sure it will spread it out.
|
|
||||||
|
|
||||||
self._unsub_fetch_data = async_call_later(
|
|
||||||
self.hass, randrange(55, 65) * 60, self._fetch_data
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self._current_weather_data = self._weather_data.get_current_weather()
|
async def async_update(self):
|
||||||
time_zone = dt_util.DEFAULT_TIME_ZONE
|
"""Only used by the generic entity update service."""
|
||||||
self._forecast_data = self._weather_data.get_forecast(time_zone)
|
await self._coordinator.async_request_refresh()
|
||||||
self.async_write_ha_state()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def track_home(self):
|
def track_home(self):
|
||||||
@ -191,12 +123,12 @@ class MetWeather(WeatherEntity):
|
|||||||
@property
|
@property
|
||||||
def condition(self):
|
def condition(self):
|
||||||
"""Return the current condition."""
|
"""Return the current condition."""
|
||||||
return self._current_weather_data.get("condition")
|
return self._coordinator.data.current_weather_data.get("condition")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def temperature(self):
|
def temperature(self):
|
||||||
"""Return the temperature."""
|
"""Return the temperature."""
|
||||||
return self._current_weather_data.get("temperature")
|
return self._coordinator.data.current_weather_data.get("temperature")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def temperature_unit(self):
|
def temperature_unit(self):
|
||||||
@ -206,7 +138,7 @@ class MetWeather(WeatherEntity):
|
|||||||
@property
|
@property
|
||||||
def pressure(self):
|
def pressure(self):
|
||||||
"""Return the pressure."""
|
"""Return the pressure."""
|
||||||
pressure_hpa = self._current_weather_data.get("pressure")
|
pressure_hpa = self._coordinator.data.current_weather_data.get("pressure")
|
||||||
if self._is_metric or pressure_hpa is None:
|
if self._is_metric or pressure_hpa is None:
|
||||||
return pressure_hpa
|
return pressure_hpa
|
||||||
|
|
||||||
@ -215,12 +147,12 @@ class MetWeather(WeatherEntity):
|
|||||||
@property
|
@property
|
||||||
def humidity(self):
|
def humidity(self):
|
||||||
"""Return the humidity."""
|
"""Return the humidity."""
|
||||||
return self._current_weather_data.get("humidity")
|
return self._coordinator.data.current_weather_data.get("humidity")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def wind_speed(self):
|
def wind_speed(self):
|
||||||
"""Return the wind speed."""
|
"""Return the wind speed."""
|
||||||
speed_m_s = self._current_weather_data.get("wind_speed")
|
speed_m_s = self._coordinator.data.current_weather_data.get("wind_speed")
|
||||||
if self._is_metric or speed_m_s is None:
|
if self._is_metric or speed_m_s is None:
|
||||||
return speed_m_s
|
return speed_m_s
|
||||||
|
|
||||||
@ -231,7 +163,7 @@ class MetWeather(WeatherEntity):
|
|||||||
@property
|
@property
|
||||||
def wind_bearing(self):
|
def wind_bearing(self):
|
||||||
"""Return the wind direction."""
|
"""Return the wind direction."""
|
||||||
return self._current_weather_data.get("wind_bearing")
|
return self._coordinator.data.current_weather_data.get("wind_bearing")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def attribution(self):
|
def attribution(self):
|
||||||
@ -241,4 +173,4 @@ class MetWeather(WeatherEntity):
|
|||||||
@property
|
@property
|
||||||
def forecast(self):
|
def forecast(self):
|
||||||
"""Return the forecast array."""
|
"""Return the forecast array."""
|
||||||
return self._forecast_data
|
return self._coordinator.data.forecast_data
|
||||||
|
@ -1 +1,26 @@
|
|||||||
"""Tests for Met.no."""
|
"""Tests for Met.no."""
|
||||||
|
from homeassistant.components.met.const import DOMAIN
|
||||||
|
from homeassistant.const import CONF_ELEVATION, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME
|
||||||
|
|
||||||
|
from tests.async_mock import patch
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
async def init_integration(hass) -> MockConfigEntry:
|
||||||
|
"""Set up the Met integration in Home Assistant."""
|
||||||
|
entry_data = {
|
||||||
|
CONF_NAME: "test",
|
||||||
|
CONF_LATITUDE: 0,
|
||||||
|
CONF_LONGITUDE: 0,
|
||||||
|
CONF_ELEVATION: 0,
|
||||||
|
}
|
||||||
|
entry = MockConfigEntry(domain=DOMAIN, data=entry_data)
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.met.metno.MetWeatherData.fetching_data",
|
||||||
|
return_value=True,
|
||||||
|
):
|
||||||
|
entry.add_to_hass(hass)
|
||||||
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
return entry
|
||||||
|
@ -103,3 +103,21 @@ async def test_onboarding_step(hass):
|
|||||||
assert result["type"] == "create_entry"
|
assert result["type"] == "create_entry"
|
||||||
assert result["title"] == HOME_LOCATION_NAME
|
assert result["title"] == HOME_LOCATION_NAME
|
||||||
assert result["data"] == {"track_home": True}
|
assert result["data"] == {"track_home": True}
|
||||||
|
|
||||||
|
|
||||||
|
async def test_import_step(hass):
|
||||||
|
"""Test initializing via import step."""
|
||||||
|
test_data = {
|
||||||
|
"name": "home",
|
||||||
|
CONF_LONGITUDE: None,
|
||||||
|
CONF_LATITUDE: None,
|
||||||
|
CONF_ELEVATION: 0,
|
||||||
|
"track_home": True,
|
||||||
|
}
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": "import"}, data=test_data
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == "create_entry"
|
||||||
|
assert result["title"] == "home"
|
||||||
|
assert result["data"] == test_data
|
||||||
|
19
tests/components/met/test_init.py
Normal file
19
tests/components/met/test_init.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
"""Test the Met integration init."""
|
||||||
|
from homeassistant.components.met.const import DOMAIN
|
||||||
|
from homeassistant.config_entries import ENTRY_STATE_LOADED, ENTRY_STATE_NOT_LOADED
|
||||||
|
|
||||||
|
from . import init_integration
|
||||||
|
|
||||||
|
|
||||||
|
async def test_unload_entry(hass):
|
||||||
|
"""Test successful unload of entry."""
|
||||||
|
entry = await init_integration(hass)
|
||||||
|
|
||||||
|
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||||
|
assert entry.state == ENTRY_STATE_LOADED
|
||||||
|
|
||||||
|
assert await hass.config_entries.async_unload(entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert entry.state == ENTRY_STATE_NOT_LOADED
|
||||||
|
assert not hass.data.get(DOMAIN)
|
Loading…
x
Reference in New Issue
Block a user