mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 17:27:10 +00:00
Bump OpenWeatherMap to 0.1.1 (#120178)
* add owm modes * fix tests * fix modes * remove sensors * Update homeassistant/components/openweathermap/sensor.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
f02fceed5b
commit
4f8a6979d9
@ -5,7 +5,7 @@ from __future__ import annotations
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from pyopenweathermap import OWMClient
|
from pyopenweathermap import create_owm_client
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
@ -33,6 +33,7 @@ class OpenweathermapData:
|
|||||||
"""Runtime data definition."""
|
"""Runtime data definition."""
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
|
mode: str
|
||||||
coordinator: WeatherUpdateCoordinator
|
coordinator: WeatherUpdateCoordinator
|
||||||
|
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ async def async_setup_entry(
|
|||||||
else:
|
else:
|
||||||
async_delete_issue(hass, entry.entry_id)
|
async_delete_issue(hass, entry.entry_id)
|
||||||
|
|
||||||
owm_client = OWMClient(api_key, mode, lang=language)
|
owm_client = create_owm_client(api_key, mode, lang=language)
|
||||||
weather_coordinator = WeatherUpdateCoordinator(
|
weather_coordinator = WeatherUpdateCoordinator(
|
||||||
owm_client, latitude, longitude, hass
|
owm_client, latitude, longitude, hass
|
||||||
)
|
)
|
||||||
@ -61,7 +62,7 @@ async def async_setup_entry(
|
|||||||
|
|
||||||
entry.async_on_unload(entry.add_update_listener(async_update_options))
|
entry.async_on_unload(entry.add_update_listener(async_update_options))
|
||||||
|
|
||||||
entry.runtime_data = OpenweathermapData(name, weather_coordinator)
|
entry.runtime_data = OpenweathermapData(name, mode, weather_coordinator)
|
||||||
|
|
||||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||||
|
|
||||||
|
@ -58,10 +58,17 @@ FORECAST_MODE_DAILY = "daily"
|
|||||||
FORECAST_MODE_FREE_DAILY = "freedaily"
|
FORECAST_MODE_FREE_DAILY = "freedaily"
|
||||||
FORECAST_MODE_ONECALL_HOURLY = "onecall_hourly"
|
FORECAST_MODE_ONECALL_HOURLY = "onecall_hourly"
|
||||||
FORECAST_MODE_ONECALL_DAILY = "onecall_daily"
|
FORECAST_MODE_ONECALL_DAILY = "onecall_daily"
|
||||||
OWM_MODE_V25 = "v2.5"
|
OWM_MODE_FREE_CURRENT = "current"
|
||||||
|
OWM_MODE_FREE_FORECAST = "forecast"
|
||||||
OWM_MODE_V30 = "v3.0"
|
OWM_MODE_V30 = "v3.0"
|
||||||
OWM_MODES = [OWM_MODE_V30, OWM_MODE_V25]
|
OWM_MODE_V25 = "v2.5"
|
||||||
DEFAULT_OWM_MODE = OWM_MODE_V30
|
OWM_MODES = [
|
||||||
|
OWM_MODE_FREE_CURRENT,
|
||||||
|
OWM_MODE_FREE_FORECAST,
|
||||||
|
OWM_MODE_V30,
|
||||||
|
OWM_MODE_V25,
|
||||||
|
]
|
||||||
|
DEFAULT_OWM_MODE = OWM_MODE_FREE_CURRENT
|
||||||
|
|
||||||
LANGUAGES = [
|
LANGUAGES = [
|
||||||
"af",
|
"af",
|
||||||
|
@ -86,8 +86,14 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
"""Format the weather response correctly."""
|
"""Format the weather response correctly."""
|
||||||
_LOGGER.debug("OWM weather response: %s", weather_report)
|
_LOGGER.debug("OWM weather response: %s", weather_report)
|
||||||
|
|
||||||
|
current_weather = (
|
||||||
|
self._get_current_weather_data(weather_report.current)
|
||||||
|
if weather_report.current is not None
|
||||||
|
else {}
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ATTR_API_CURRENT: self._get_current_weather_data(weather_report.current),
|
ATTR_API_CURRENT: current_weather,
|
||||||
ATTR_API_HOURLY_FORECAST: [
|
ATTR_API_HOURLY_FORECAST: [
|
||||||
self._get_hourly_forecast_weather_data(item)
|
self._get_hourly_forecast_weather_data(item)
|
||||||
for item in weather_report.hourly_forecast
|
for item in weather_report.hourly_forecast
|
||||||
@ -122,6 +128,8 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def _get_hourly_forecast_weather_data(self, forecast: HourlyWeatherForecast):
|
def _get_hourly_forecast_weather_data(self, forecast: HourlyWeatherForecast):
|
||||||
|
uv_index = float(forecast.uv_index) if forecast.uv_index is not None else None
|
||||||
|
|
||||||
return Forecast(
|
return Forecast(
|
||||||
datetime=forecast.date_time.isoformat(),
|
datetime=forecast.date_time.isoformat(),
|
||||||
condition=self._get_condition(forecast.condition.id),
|
condition=self._get_condition(forecast.condition.id),
|
||||||
@ -134,12 +142,14 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
wind_speed=forecast.wind_speed,
|
wind_speed=forecast.wind_speed,
|
||||||
native_wind_gust_speed=forecast.wind_gust,
|
native_wind_gust_speed=forecast.wind_gust,
|
||||||
wind_bearing=forecast.wind_bearing,
|
wind_bearing=forecast.wind_bearing,
|
||||||
uv_index=float(forecast.uv_index),
|
uv_index=uv_index,
|
||||||
precipitation_probability=round(forecast.precipitation_probability * 100),
|
precipitation_probability=round(forecast.precipitation_probability * 100),
|
||||||
precipitation=self._calc_precipitation(forecast.rain, forecast.snow),
|
precipitation=self._calc_precipitation(forecast.rain, forecast.snow),
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_daily_forecast_weather_data(self, forecast: DailyWeatherForecast):
|
def _get_daily_forecast_weather_data(self, forecast: DailyWeatherForecast):
|
||||||
|
uv_index = float(forecast.uv_index) if forecast.uv_index is not None else None
|
||||||
|
|
||||||
return Forecast(
|
return Forecast(
|
||||||
datetime=forecast.date_time.isoformat(),
|
datetime=forecast.date_time.isoformat(),
|
||||||
condition=self._get_condition(forecast.condition.id),
|
condition=self._get_condition(forecast.condition.id),
|
||||||
@ -153,7 +163,7 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
wind_speed=forecast.wind_speed,
|
wind_speed=forecast.wind_speed,
|
||||||
native_wind_gust_speed=forecast.wind_gust,
|
native_wind_gust_speed=forecast.wind_gust,
|
||||||
wind_bearing=forecast.wind_bearing,
|
wind_bearing=forecast.wind_bearing,
|
||||||
uv_index=float(forecast.uv_index),
|
uv_index=uv_index,
|
||||||
precipitation_probability=round(forecast.precipitation_probability * 100),
|
precipitation_probability=round(forecast.precipitation_probability * 100),
|
||||||
precipitation=round(forecast.rain + forecast.snow, 2),
|
precipitation=round(forecast.rain + forecast.snow, 2),
|
||||||
)
|
)
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/openweathermap",
|
"documentation": "https://www.home-assistant.io/integrations/openweathermap",
|
||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"loggers": ["pyopenweathermap"],
|
"loggers": ["pyopenweathermap"],
|
||||||
"requirements": ["pyopenweathermap==0.0.9"]
|
"requirements": ["pyopenweathermap==0.1.1"]
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ from homeassistant.const import (
|
|||||||
UnitOfVolumetricFlux,
|
UnitOfVolumetricFlux,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.typing import StateType
|
from homeassistant.helpers.typing import StateType
|
||||||
@ -47,6 +48,7 @@ from .const import (
|
|||||||
DEFAULT_NAME,
|
DEFAULT_NAME,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
MANUFACTURER,
|
MANUFACTURER,
|
||||||
|
OWM_MODE_FREE_FORECAST,
|
||||||
)
|
)
|
||||||
from .coordinator import WeatherUpdateCoordinator
|
from .coordinator import WeatherUpdateCoordinator
|
||||||
|
|
||||||
@ -161,16 +163,23 @@ async def async_setup_entry(
|
|||||||
name = domain_data.name
|
name = domain_data.name
|
||||||
weather_coordinator = domain_data.coordinator
|
weather_coordinator = domain_data.coordinator
|
||||||
|
|
||||||
entities: list[AbstractOpenWeatherMapSensor] = [
|
if domain_data.mode == OWM_MODE_FREE_FORECAST:
|
||||||
OpenWeatherMapSensor(
|
entity_registry = er.async_get(hass)
|
||||||
name,
|
entries = er.async_entries_for_config_entry(
|
||||||
f"{config_entry.unique_id}-{description.key}",
|
entity_registry, config_entry.entry_id
|
||||||
description,
|
)
|
||||||
weather_coordinator,
|
for entry in entries:
|
||||||
|
entity_registry.async_remove(entry.entity_id)
|
||||||
|
else:
|
||||||
|
async_add_entities(
|
||||||
|
OpenWeatherMapSensor(
|
||||||
|
name,
|
||||||
|
f"{config_entry.unique_id}-{description.key}",
|
||||||
|
description,
|
||||||
|
weather_coordinator,
|
||||||
|
)
|
||||||
|
for description in WEATHER_SENSOR_TYPES
|
||||||
)
|
)
|
||||||
for description in WEATHER_SENSOR_TYPES
|
|
||||||
]
|
|
||||||
async_add_entities(entities)
|
|
||||||
|
|
||||||
|
|
||||||
class AbstractOpenWeatherMapSensor(SensorEntity):
|
class AbstractOpenWeatherMapSensor(SensorEntity):
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from pyopenweathermap import OWMClient, RequestError
|
from pyopenweathermap import RequestError, create_owm_client
|
||||||
|
|
||||||
from homeassistant.const import CONF_LANGUAGE, CONF_MODE
|
from homeassistant.const import CONF_LANGUAGE, CONF_MODE
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ async def validate_api_key(api_key, mode):
|
|||||||
api_key_valid = None
|
api_key_valid = None
|
||||||
errors, description_placeholders = {}, {}
|
errors, description_placeholders = {}, {}
|
||||||
try:
|
try:
|
||||||
owm_client = OWMClient(api_key, mode)
|
owm_client = create_owm_client(api_key, mode)
|
||||||
api_key_valid = await owm_client.validate_key()
|
api_key_valid = await owm_client.validate_key()
|
||||||
except RequestError as error:
|
except RequestError as error:
|
||||||
errors["base"] = "cannot_connect"
|
errors["base"] = "cannot_connect"
|
||||||
|
@ -8,6 +8,7 @@ from homeassistant.components.weather import (
|
|||||||
WeatherEntityFeature,
|
WeatherEntityFeature,
|
||||||
)
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
|
UnitOfLength,
|
||||||
UnitOfPrecipitationDepth,
|
UnitOfPrecipitationDepth,
|
||||||
UnitOfPressure,
|
UnitOfPressure,
|
||||||
UnitOfSpeed,
|
UnitOfSpeed,
|
||||||
@ -29,6 +30,7 @@ from .const import (
|
|||||||
ATTR_API_HUMIDITY,
|
ATTR_API_HUMIDITY,
|
||||||
ATTR_API_PRESSURE,
|
ATTR_API_PRESSURE,
|
||||||
ATTR_API_TEMPERATURE,
|
ATTR_API_TEMPERATURE,
|
||||||
|
ATTR_API_VISIBILITY_DISTANCE,
|
||||||
ATTR_API_WIND_BEARING,
|
ATTR_API_WIND_BEARING,
|
||||||
ATTR_API_WIND_GUST,
|
ATTR_API_WIND_GUST,
|
||||||
ATTR_API_WIND_SPEED,
|
ATTR_API_WIND_SPEED,
|
||||||
@ -36,6 +38,9 @@ from .const import (
|
|||||||
DEFAULT_NAME,
|
DEFAULT_NAME,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
MANUFACTURER,
|
MANUFACTURER,
|
||||||
|
OWM_MODE_FREE_FORECAST,
|
||||||
|
OWM_MODE_V25,
|
||||||
|
OWM_MODE_V30,
|
||||||
)
|
)
|
||||||
from .coordinator import WeatherUpdateCoordinator
|
from .coordinator import WeatherUpdateCoordinator
|
||||||
|
|
||||||
@ -48,10 +53,11 @@ async def async_setup_entry(
|
|||||||
"""Set up OpenWeatherMap weather entity based on a config entry."""
|
"""Set up OpenWeatherMap weather entity based on a config entry."""
|
||||||
domain_data = config_entry.runtime_data
|
domain_data = config_entry.runtime_data
|
||||||
name = domain_data.name
|
name = domain_data.name
|
||||||
|
mode = domain_data.mode
|
||||||
weather_coordinator = domain_data.coordinator
|
weather_coordinator = domain_data.coordinator
|
||||||
|
|
||||||
unique_id = f"{config_entry.unique_id}"
|
unique_id = f"{config_entry.unique_id}"
|
||||||
owm_weather = OpenWeatherMapWeather(name, unique_id, weather_coordinator)
|
owm_weather = OpenWeatherMapWeather(name, unique_id, mode, weather_coordinator)
|
||||||
|
|
||||||
async_add_entities([owm_weather], False)
|
async_add_entities([owm_weather], False)
|
||||||
|
|
||||||
@ -66,11 +72,13 @@ class OpenWeatherMapWeather(SingleCoordinatorWeatherEntity[WeatherUpdateCoordina
|
|||||||
_attr_native_pressure_unit = UnitOfPressure.HPA
|
_attr_native_pressure_unit = UnitOfPressure.HPA
|
||||||
_attr_native_temperature_unit = UnitOfTemperature.CELSIUS
|
_attr_native_temperature_unit = UnitOfTemperature.CELSIUS
|
||||||
_attr_native_wind_speed_unit = UnitOfSpeed.METERS_PER_SECOND
|
_attr_native_wind_speed_unit = UnitOfSpeed.METERS_PER_SECOND
|
||||||
|
_attr_native_visibility_unit = UnitOfLength.METERS
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
unique_id: str,
|
unique_id: str,
|
||||||
|
mode: str,
|
||||||
weather_coordinator: WeatherUpdateCoordinator,
|
weather_coordinator: WeatherUpdateCoordinator,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the sensor."""
|
"""Initialize the sensor."""
|
||||||
@ -83,59 +91,71 @@ class OpenWeatherMapWeather(SingleCoordinatorWeatherEntity[WeatherUpdateCoordina
|
|||||||
manufacturer=MANUFACTURER,
|
manufacturer=MANUFACTURER,
|
||||||
name=DEFAULT_NAME,
|
name=DEFAULT_NAME,
|
||||||
)
|
)
|
||||||
self._attr_supported_features = (
|
|
||||||
WeatherEntityFeature.FORECAST_DAILY | WeatherEntityFeature.FORECAST_HOURLY
|
if mode in (OWM_MODE_V30, OWM_MODE_V25):
|
||||||
)
|
self._attr_supported_features = (
|
||||||
|
WeatherEntityFeature.FORECAST_DAILY
|
||||||
|
| WeatherEntityFeature.FORECAST_HOURLY
|
||||||
|
)
|
||||||
|
elif mode == OWM_MODE_FREE_FORECAST:
|
||||||
|
self._attr_supported_features = WeatherEntityFeature.FORECAST_HOURLY
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def condition(self) -> str | None:
|
def condition(self) -> str | None:
|
||||||
"""Return the current condition."""
|
"""Return the current condition."""
|
||||||
return self.coordinator.data[ATTR_API_CURRENT][ATTR_API_CONDITION]
|
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_CONDITION)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cloud_coverage(self) -> float | None:
|
def cloud_coverage(self) -> float | None:
|
||||||
"""Return the Cloud coverage in %."""
|
"""Return the Cloud coverage in %."""
|
||||||
return self.coordinator.data[ATTR_API_CURRENT][ATTR_API_CLOUDS]
|
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_CLOUDS)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_apparent_temperature(self) -> float | None:
|
def native_apparent_temperature(self) -> float | None:
|
||||||
"""Return the apparent temperature."""
|
"""Return the apparent temperature."""
|
||||||
return self.coordinator.data[ATTR_API_CURRENT][ATTR_API_FEELS_LIKE_TEMPERATURE]
|
return self.coordinator.data[ATTR_API_CURRENT].get(
|
||||||
|
ATTR_API_FEELS_LIKE_TEMPERATURE
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_temperature(self) -> float | None:
|
def native_temperature(self) -> float | None:
|
||||||
"""Return the temperature."""
|
"""Return the temperature."""
|
||||||
return self.coordinator.data[ATTR_API_CURRENT][ATTR_API_TEMPERATURE]
|
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_TEMPERATURE)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_pressure(self) -> float | None:
|
def native_pressure(self) -> float | None:
|
||||||
"""Return the pressure."""
|
"""Return the pressure."""
|
||||||
return self.coordinator.data[ATTR_API_CURRENT][ATTR_API_PRESSURE]
|
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_PRESSURE)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def humidity(self) -> float | None:
|
def humidity(self) -> float | None:
|
||||||
"""Return the humidity."""
|
"""Return the humidity."""
|
||||||
return self.coordinator.data[ATTR_API_CURRENT][ATTR_API_HUMIDITY]
|
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_HUMIDITY)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_dew_point(self) -> float | None:
|
def native_dew_point(self) -> float | None:
|
||||||
"""Return the dew point."""
|
"""Return the dew point."""
|
||||||
return self.coordinator.data[ATTR_API_CURRENT][ATTR_API_DEW_POINT]
|
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_DEW_POINT)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_wind_gust_speed(self) -> float | None:
|
def native_wind_gust_speed(self) -> float | None:
|
||||||
"""Return the wind gust speed."""
|
"""Return the wind gust speed."""
|
||||||
return self.coordinator.data[ATTR_API_CURRENT][ATTR_API_WIND_GUST]
|
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_WIND_GUST)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_wind_speed(self) -> float | None:
|
def native_wind_speed(self) -> float | None:
|
||||||
"""Return the wind speed."""
|
"""Return the wind speed."""
|
||||||
return self.coordinator.data[ATTR_API_CURRENT][ATTR_API_WIND_SPEED]
|
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_WIND_SPEED)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def wind_bearing(self) -> float | str | None:
|
def wind_bearing(self) -> float | str | None:
|
||||||
"""Return the wind bearing."""
|
"""Return the wind bearing."""
|
||||||
return self.coordinator.data[ATTR_API_CURRENT][ATTR_API_WIND_BEARING]
|
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_WIND_BEARING)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def visibility(self) -> float | str | None:
|
||||||
|
"""Return visibility."""
|
||||||
|
return self.coordinator.data[ATTR_API_CURRENT].get(ATTR_API_VISIBILITY_DISTANCE)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _async_forecast_daily(self) -> list[Forecast] | None:
|
def _async_forecast_daily(self) -> list[Forecast] | None:
|
||||||
|
@ -2074,7 +2074,7 @@ pyombi==0.1.10
|
|||||||
pyopenuv==2023.02.0
|
pyopenuv==2023.02.0
|
||||||
|
|
||||||
# homeassistant.components.openweathermap
|
# homeassistant.components.openweathermap
|
||||||
pyopenweathermap==0.0.9
|
pyopenweathermap==0.1.1
|
||||||
|
|
||||||
# homeassistant.components.opnsense
|
# homeassistant.components.opnsense
|
||||||
pyopnsense==0.4.0
|
pyopnsense==0.4.0
|
||||||
|
@ -1661,7 +1661,7 @@ pyoctoprintapi==0.1.12
|
|||||||
pyopenuv==2023.02.0
|
pyopenuv==2023.02.0
|
||||||
|
|
||||||
# homeassistant.components.openweathermap
|
# homeassistant.components.openweathermap
|
||||||
pyopenweathermap==0.0.9
|
pyopenweathermap==0.1.1
|
||||||
|
|
||||||
# homeassistant.components.opnsense
|
# homeassistant.components.opnsense
|
||||||
pyopnsense==0.4.0
|
pyopnsense==0.4.0
|
||||||
|
@ -45,7 +45,7 @@ CONFIG = {
|
|||||||
VALID_YAML_CONFIG = {CONF_API_KEY: "foo"}
|
VALID_YAML_CONFIG = {CONF_API_KEY: "foo"}
|
||||||
|
|
||||||
|
|
||||||
def _create_mocked_owm_client(is_valid: bool):
|
def _create_mocked_owm_factory(is_valid: bool):
|
||||||
current_weather = CurrentWeather(
|
current_weather = CurrentWeather(
|
||||||
date_time=datetime.fromtimestamp(1714063536, tz=UTC),
|
date_time=datetime.fromtimestamp(1714063536, tz=UTC),
|
||||||
temperature=6.84,
|
temperature=6.84,
|
||||||
@ -118,18 +118,18 @@ def _create_mocked_owm_client(is_valid: bool):
|
|||||||
def mock_owm_client():
|
def mock_owm_client():
|
||||||
"""Mock config_flow OWMClient."""
|
"""Mock config_flow OWMClient."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.openweathermap.OWMClient",
|
"homeassistant.components.openweathermap.create_owm_client",
|
||||||
) as owm_client_mock:
|
) as mock:
|
||||||
yield owm_client_mock
|
yield mock
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="config_flow_owm_client_mock")
|
@pytest.fixture(name="config_flow_owm_client_mock")
|
||||||
def mock_config_flow_owm_client():
|
def mock_config_flow_owm_client():
|
||||||
"""Mock config_flow OWMClient."""
|
"""Mock config_flow OWMClient."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.openweathermap.utils.OWMClient",
|
"homeassistant.components.openweathermap.utils.create_owm_client",
|
||||||
) as config_flow_owm_client_mock:
|
) as mock:
|
||||||
yield config_flow_owm_client_mock
|
yield mock
|
||||||
|
|
||||||
|
|
||||||
async def test_successful_config_flow(
|
async def test_successful_config_flow(
|
||||||
@ -138,7 +138,7 @@ async def test_successful_config_flow(
|
|||||||
config_flow_owm_client_mock,
|
config_flow_owm_client_mock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that the form is served with valid input."""
|
"""Test that the form is served with valid input."""
|
||||||
mock = _create_mocked_owm_client(True)
|
mock = _create_mocked_owm_factory(True)
|
||||||
owm_client_mock.return_value = mock
|
owm_client_mock.return_value = mock
|
||||||
config_flow_owm_client_mock.return_value = mock
|
config_flow_owm_client_mock.return_value = mock
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ async def test_abort_config_flow(
|
|||||||
config_flow_owm_client_mock,
|
config_flow_owm_client_mock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that the form is served with same data."""
|
"""Test that the form is served with same data."""
|
||||||
mock = _create_mocked_owm_client(True)
|
mock = _create_mocked_owm_factory(True)
|
||||||
owm_client_mock.return_value = mock
|
owm_client_mock.return_value = mock
|
||||||
config_flow_owm_client_mock.return_value = mock
|
config_flow_owm_client_mock.return_value = mock
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ async def test_config_flow_options_change(
|
|||||||
config_flow_owm_client_mock,
|
config_flow_owm_client_mock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that the options form."""
|
"""Test that the options form."""
|
||||||
mock = _create_mocked_owm_client(True)
|
mock = _create_mocked_owm_factory(True)
|
||||||
owm_client_mock.return_value = mock
|
owm_client_mock.return_value = mock
|
||||||
config_flow_owm_client_mock.return_value = mock
|
config_flow_owm_client_mock.return_value = mock
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ async def test_form_invalid_api_key(
|
|||||||
config_flow_owm_client_mock,
|
config_flow_owm_client_mock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that the form is served with no input."""
|
"""Test that the form is served with no input."""
|
||||||
config_flow_owm_client_mock.return_value = _create_mocked_owm_client(False)
|
config_flow_owm_client_mock.return_value = _create_mocked_owm_factory(False)
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
|
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
|
||||||
)
|
)
|
||||||
@ -269,7 +269,7 @@ async def test_form_invalid_api_key(
|
|||||||
assert result["type"] is FlowResultType.FORM
|
assert result["type"] is FlowResultType.FORM
|
||||||
assert result["errors"] == {"base": "invalid_api_key"}
|
assert result["errors"] == {"base": "invalid_api_key"}
|
||||||
|
|
||||||
config_flow_owm_client_mock.return_value = _create_mocked_owm_client(True)
|
config_flow_owm_client_mock.return_value = _create_mocked_owm_factory(True)
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], user_input=CONFIG
|
result["flow_id"], user_input=CONFIG
|
||||||
)
|
)
|
||||||
@ -282,7 +282,7 @@ async def test_form_api_call_error(
|
|||||||
config_flow_owm_client_mock,
|
config_flow_owm_client_mock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test setting up with api call error."""
|
"""Test setting up with api call error."""
|
||||||
config_flow_owm_client_mock.return_value = _create_mocked_owm_client(True)
|
config_flow_owm_client_mock.return_value = _create_mocked_owm_factory(True)
|
||||||
config_flow_owm_client_mock.side_effect = RequestError("oops")
|
config_flow_owm_client_mock.side_effect = RequestError("oops")
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
|
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
|
||||||
|
Loading…
x
Reference in New Issue
Block a user