diff --git a/homeassistant/components/openweathermap/__init__.py b/homeassistant/components/openweathermap/__init__.py index 737e4fb8e4f..8b2bfb17c95 100644 --- a/homeassistant/components/openweathermap/__init__.py +++ b/homeassistant/components/openweathermap/__init__.py @@ -8,7 +8,7 @@ import logging from pyopenweathermap import create_owm_client from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_API_KEY, CONF_LANGUAGE, CONF_MODE, CONF_NAME +from homeassistant.const import CONF_API_KEY, CONF_LANGUAGE, CONF_MODE from homeassistant.core import HomeAssistant from .const import CONFIG_FLOW_VERSION, DEFAULT_OWM_MODE, OWM_MODES, PLATFORMS @@ -25,7 +25,6 @@ type OpenweathermapConfigEntry = ConfigEntry[OpenweathermapData] class OpenweathermapData: """Runtime data definition.""" - name: str mode: str coordinator: OWMUpdateCoordinator @@ -34,7 +33,6 @@ async def async_setup_entry( hass: HomeAssistant, entry: OpenweathermapConfigEntry ) -> bool: """Set up OpenWeatherMap as config entry.""" - name = entry.data[CONF_NAME] api_key = entry.data[CONF_API_KEY] language = entry.options[CONF_LANGUAGE] mode = entry.options[CONF_MODE] @@ -51,7 +49,7 @@ async def async_setup_entry( entry.async_on_unload(entry.add_update_listener(async_update_options)) - entry.runtime_data = OpenweathermapData(name, mode, owm_coordinator) + entry.runtime_data = OpenweathermapData(mode, owm_coordinator) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) diff --git a/homeassistant/components/openweathermap/config_flow.py b/homeassistant/components/openweathermap/config_flow.py index 5805b602821..64545726f1e 100644 --- a/homeassistant/components/openweathermap/config_flow.py +++ b/homeassistant/components/openweathermap/config_flow.py @@ -14,12 +14,17 @@ from homeassistant.const import ( CONF_API_KEY, CONF_LANGUAGE, CONF_LATITUDE, + CONF_LOCATION, CONF_LONGITUDE, CONF_MODE, - CONF_NAME, ) from homeassistant.core import callback -from homeassistant.helpers import config_validation as cv +from homeassistant.helpers.selector import ( + LanguageSelector, + LanguageSelectorConfig, + LocationSelector, + LocationSelectorConfig, +) from .const import ( CONFIG_FLOW_VERSION, @@ -34,10 +39,12 @@ from .utils import build_data_and_options, validate_api_key USER_SCHEMA = vol.Schema( { - vol.Optional(CONF_NAME, default=DEFAULT_NAME): str, - vol.Optional(CONF_LATITUDE): cv.latitude, - vol.Optional(CONF_LONGITUDE): cv.longitude, - vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): vol.In(LANGUAGES), + vol.Required(CONF_LOCATION): LocationSelector( + LocationSelectorConfig(radius=False) + ), + vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): LanguageSelector( + LanguageSelectorConfig(languages=LANGUAGES, native_name=True) + ), vol.Required(CONF_API_KEY): str, vol.Optional(CONF_MODE, default=DEFAULT_OWM_MODE): vol.In(OWM_MODES), } @@ -45,7 +52,9 @@ USER_SCHEMA = vol.Schema( OPTIONS_SCHEMA = vol.Schema( { - vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): vol.In(LANGUAGES), + vol.Optional(CONF_LANGUAGE, default=DEFAULT_LANGUAGE): LanguageSelector( + LanguageSelectorConfig(languages=LANGUAGES, native_name=True) + ), vol.Optional(CONF_MODE, default=DEFAULT_OWM_MODE): vol.In(OWM_MODES), } ) @@ -70,8 +79,8 @@ class OpenWeatherMapConfigFlow(ConfigFlow, domain=DOMAIN): description_placeholders = {} if user_input is not None: - latitude = user_input[CONF_LATITUDE] - longitude = user_input[CONF_LONGITUDE] + latitude = user_input[CONF_LOCATION][CONF_LATITUDE] + longitude = user_input[CONF_LOCATION][CONF_LONGITUDE] mode = user_input[CONF_MODE] await self.async_set_unique_id(f"{latitude}-{longitude}") @@ -82,15 +91,21 @@ class OpenWeatherMapConfigFlow(ConfigFlow, domain=DOMAIN): ) if not errors: + # Flatten location + location = user_input.pop(CONF_LOCATION) + user_input[CONF_LATITUDE] = location[CONF_LATITUDE] + user_input[CONF_LONGITUDE] = location[CONF_LONGITUDE] data, options = build_data_and_options(user_input) return self.async_create_entry( - title=user_input[CONF_NAME], data=data, options=options + title=DEFAULT_NAME, data=data, options=options ) schema_data = user_input else: schema_data = { - CONF_LATITUDE: self.hass.config.latitude, - CONF_LONGITUDE: self.hass.config.longitude, + CONF_LOCATION: { + CONF_LATITUDE: self.hass.config.latitude, + CONF_LONGITUDE: self.hass.config.longitude, + }, CONF_LANGUAGE: self.hass.config.language, } diff --git a/homeassistant/components/openweathermap/sensor.py b/homeassistant/components/openweathermap/sensor.py index 9a6f5283e88..4cb31b749f0 100644 --- a/homeassistant/components/openweathermap/sensor.py +++ b/homeassistant/components/openweathermap/sensor.py @@ -229,7 +229,6 @@ async def async_setup_entry( ) -> None: """Set up OpenWeatherMap sensor entities based on a config entry.""" domain_data = config_entry.runtime_data - name = domain_data.name unique_id = config_entry.unique_id assert unique_id is not None coordinator = domain_data.coordinator @@ -244,7 +243,6 @@ async def async_setup_entry( elif domain_data.mode == OWM_MODE_AIRPOLLUTION: async_add_entities( OpenWeatherMapSensor( - name, unique_id, description, coordinator, @@ -254,7 +252,6 @@ async def async_setup_entry( else: async_add_entities( OpenWeatherMapSensor( - name, unique_id, description, coordinator, @@ -272,7 +269,6 @@ class AbstractOpenWeatherMapSensor(SensorEntity): def __init__( self, - name: str, unique_id: str, description: SensorEntityDescription, coordinator: OWMUpdateCoordinator, @@ -286,7 +282,6 @@ class AbstractOpenWeatherMapSensor(SensorEntity): entry_type=DeviceEntryType.SERVICE, identifiers={(DOMAIN, unique_id)}, manufacturer=MANUFACTURER, - name=name, ) @property diff --git a/homeassistant/components/openweathermap/strings.json b/homeassistant/components/openweathermap/strings.json index 718ce3e6fdd..e3e5781882c 100644 --- a/homeassistant/components/openweathermap/strings.json +++ b/homeassistant/components/openweathermap/strings.json @@ -12,16 +12,14 @@ "data": { "api_key": "[%key:common::config_flow::data::api_key%]", "language": "[%key:common::config_flow::data::language%]", - "latitude": "[%key:common::config_flow::data::latitude%]", - "longitude": "[%key:common::config_flow::data::longitude%]", + "location": "[%key:common::config_flow::data::location%]", "mode": "[%key:common::config_flow::data::mode%]", "name": "[%key:common::config_flow::data::name%]" }, "data_description": { "api_key": "API key for the OpenWeatherMap integration", "language": "Language for the OpenWeatherMap content", - "latitude": "Latitude of the location", - "longitude": "Longitude of the location", + "location": "Location to get the weather data for", "mode": "Mode for the OpenWeatherMap API", "name": "Name for this OpenWeatherMap location" }, diff --git a/homeassistant/components/openweathermap/weather.py b/homeassistant/components/openweathermap/weather.py index 56f44fa46fb..37f8e117ee1 100644 --- a/homeassistant/components/openweathermap/weather.py +++ b/homeassistant/components/openweathermap/weather.py @@ -57,14 +57,13 @@ async def async_setup_entry( ) -> None: """Set up OpenWeatherMap weather entity based on a config entry.""" domain_data = config_entry.runtime_data - name = domain_data.name mode = domain_data.mode if mode != OWM_MODE_AIRPOLLUTION: weather_coordinator = domain_data.coordinator unique_id = f"{config_entry.unique_id}" - owm_weather = OpenWeatherMapWeather(name, unique_id, mode, weather_coordinator) + owm_weather = OpenWeatherMapWeather(unique_id, mode, weather_coordinator) async_add_entities([owm_weather], False) @@ -93,7 +92,6 @@ class OpenWeatherMapWeather(SingleCoordinatorWeatherEntity[OWMUpdateCoordinator] def __init__( self, - name: str, unique_id: str, mode: str, weather_coordinator: OWMUpdateCoordinator, @@ -105,7 +103,6 @@ class OpenWeatherMapWeather(SingleCoordinatorWeatherEntity[OWMUpdateCoordinator] entry_type=DeviceEntryType.SERVICE, identifiers={(DOMAIN, unique_id)}, manufacturer=MANUFACTURER, - name=name, ) self.mode = mode diff --git a/tests/components/openweathermap/conftest.py b/tests/components/openweathermap/conftest.py index 7c7de776acf..b534d8fd98c 100644 --- a/tests/components/openweathermap/conftest.py +++ b/tests/components/openweathermap/conftest.py @@ -17,14 +17,17 @@ from pyopenweathermap import ( from pyopenweathermap.client.owm_abstract_client import OWMClient import pytest -from homeassistant.components.openweathermap.const import DEFAULT_LANGUAGE, DOMAIN +from homeassistant.components.openweathermap.const import ( + DEFAULT_LANGUAGE, + DEFAULT_NAME, + DOMAIN, +) from homeassistant.const import ( CONF_API_KEY, CONF_LANGUAGE, CONF_LATITUDE, CONF_LONGITUDE, CONF_MODE, - CONF_NAME, ) from tests.common import MockConfigEntry, patch @@ -50,7 +53,6 @@ def mock_config_entry(mode: str) -> MockConfigEntry: CONF_API_KEY: API_KEY, CONF_LATITUDE: LATITUDE, CONF_LONGITUDE: LONGITUDE, - CONF_NAME: NAME, }, options={ CONF_MODE: mode, @@ -59,6 +61,7 @@ def mock_config_entry(mode: str) -> MockConfigEntry: entry_id="test", version=5, unique_id=f"{LATITUDE}-{LONGITUDE}", + title=DEFAULT_NAME, ) diff --git a/tests/components/openweathermap/snapshots/test_sensor.ambr b/tests/components/openweathermap/snapshots/test_sensor.ambr index 512f7b5280c..b184aac02ba 100644 --- a/tests/components/openweathermap/snapshots/test_sensor.ambr +++ b/tests/components/openweathermap/snapshots/test_sensor.ambr @@ -41,7 +41,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'aqi', - 'friendly_name': 'openweathermap Air quality index', + 'friendly_name': 'OpenWeatherMap Air quality index', 'state_class': , }), 'context': , @@ -94,7 +94,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'carbon_monoxide', - 'friendly_name': 'openweathermap Carbon monoxide', + 'friendly_name': 'OpenWeatherMap Carbon monoxide', 'state_class': , 'unit_of_measurement': 'μg/m³', }), @@ -148,7 +148,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'nitrogen_dioxide', - 'friendly_name': 'openweathermap Nitrogen dioxide', + 'friendly_name': 'OpenWeatherMap Nitrogen dioxide', 'state_class': , 'unit_of_measurement': 'μg/m³', }), @@ -202,7 +202,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'nitrogen_monoxide', - 'friendly_name': 'openweathermap Nitrogen monoxide', + 'friendly_name': 'OpenWeatherMap Nitrogen monoxide', 'state_class': , 'unit_of_measurement': 'μg/m³', }), @@ -256,7 +256,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'ozone', - 'friendly_name': 'openweathermap Ozone', + 'friendly_name': 'OpenWeatherMap Ozone', 'state_class': , 'unit_of_measurement': 'μg/m³', }), @@ -310,7 +310,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'pm10', - 'friendly_name': 'openweathermap PM10', + 'friendly_name': 'OpenWeatherMap PM10', 'state_class': , 'unit_of_measurement': 'μg/m³', }), @@ -364,7 +364,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'pm25', - 'friendly_name': 'openweathermap PM2.5', + 'friendly_name': 'OpenWeatherMap PM2.5', 'state_class': , 'unit_of_measurement': 'μg/m³', }), @@ -418,7 +418,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'sulphur_dioxide', - 'friendly_name': 'openweathermap Sulphur dioxide', + 'friendly_name': 'OpenWeatherMap Sulphur dioxide', 'state_class': , 'unit_of_measurement': 'μg/m³', }), @@ -471,7 +471,7 @@ StateSnapshot({ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', - 'friendly_name': 'openweathermap Cloud coverage', + 'friendly_name': 'OpenWeatherMap Cloud coverage', 'state_class': , 'unit_of_measurement': '%', }), @@ -522,7 +522,7 @@ StateSnapshot({ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', - 'friendly_name': 'openweathermap Condition', + 'friendly_name': 'OpenWeatherMap Condition', }), 'context': , 'entity_id': 'sensor.openweathermap_condition', @@ -577,7 +577,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'temperature', - 'friendly_name': 'openweathermap Dew Point', + 'friendly_name': 'OpenWeatherMap Dew Point', 'state_class': , 'unit_of_measurement': , }), @@ -634,7 +634,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'temperature', - 'friendly_name': 'openweathermap Feels like temperature', + 'friendly_name': 'OpenWeatherMap Feels like temperature', 'state_class': , 'unit_of_measurement': , }), @@ -688,7 +688,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'humidity', - 'friendly_name': 'openweathermap Humidity', + 'friendly_name': 'OpenWeatherMap Humidity', 'state_class': , 'unit_of_measurement': '%', }), @@ -739,7 +739,7 @@ StateSnapshot({ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', - 'friendly_name': 'openweathermap Precipitation kind', + 'friendly_name': 'OpenWeatherMap Precipitation kind', }), 'context': , 'entity_id': 'sensor.openweathermap_precipitation_kind', @@ -794,7 +794,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'pressure', - 'friendly_name': 'openweathermap Pressure', + 'friendly_name': 'OpenWeatherMap Pressure', 'state_class': , 'unit_of_measurement': , }), @@ -851,7 +851,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'precipitation_intensity', - 'friendly_name': 'openweathermap Rain', + 'friendly_name': 'OpenWeatherMap Rain', 'state_class': , 'unit_of_measurement': , }), @@ -908,7 +908,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'precipitation_intensity', - 'friendly_name': 'openweathermap Snow', + 'friendly_name': 'OpenWeatherMap Snow', 'state_class': , 'unit_of_measurement': , }), @@ -965,7 +965,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'temperature', - 'friendly_name': 'openweathermap Temperature', + 'friendly_name': 'OpenWeatherMap Temperature', 'state_class': , 'unit_of_measurement': , }), @@ -1018,7 +1018,7 @@ StateSnapshot({ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', - 'friendly_name': 'openweathermap UV Index', + 'friendly_name': 'OpenWeatherMap UV Index', 'state_class': , 'unit_of_measurement': 'UV index', }), @@ -1075,7 +1075,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'distance', - 'friendly_name': 'openweathermap Visibility', + 'friendly_name': 'OpenWeatherMap Visibility', 'state_class': , 'unit_of_measurement': , }), @@ -1126,7 +1126,7 @@ StateSnapshot({ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', - 'friendly_name': 'openweathermap Weather', + 'friendly_name': 'OpenWeatherMap Weather', }), 'context': , 'entity_id': 'sensor.openweathermap_weather', @@ -1175,7 +1175,7 @@ StateSnapshot({ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', - 'friendly_name': 'openweathermap Weather Code', + 'friendly_name': 'OpenWeatherMap Weather Code', }), 'context': , 'entity_id': 'sensor.openweathermap_weather_code', @@ -1227,7 +1227,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'wind_direction', - 'friendly_name': 'openweathermap Wind bearing', + 'friendly_name': 'OpenWeatherMap Wind bearing', 'state_class': , 'unit_of_measurement': '°', }), @@ -1287,7 +1287,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'wind_speed', - 'friendly_name': 'openweathermap Wind gust', + 'friendly_name': 'OpenWeatherMap Wind gust', 'state_class': , 'unit_of_measurement': , }), @@ -1347,7 +1347,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'wind_speed', - 'friendly_name': 'openweathermap Wind speed', + 'friendly_name': 'OpenWeatherMap Wind speed', 'state_class': , 'unit_of_measurement': , }), @@ -1400,7 +1400,7 @@ StateSnapshot({ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', - 'friendly_name': 'openweathermap Cloud coverage', + 'friendly_name': 'OpenWeatherMap Cloud coverage', 'state_class': , 'unit_of_measurement': '%', }), @@ -1451,7 +1451,7 @@ StateSnapshot({ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', - 'friendly_name': 'openweathermap Condition', + 'friendly_name': 'OpenWeatherMap Condition', }), 'context': , 'entity_id': 'sensor.openweathermap_condition', @@ -1506,7 +1506,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'temperature', - 'friendly_name': 'openweathermap Dew Point', + 'friendly_name': 'OpenWeatherMap Dew Point', 'state_class': , 'unit_of_measurement': , }), @@ -1563,7 +1563,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'temperature', - 'friendly_name': 'openweathermap Feels like temperature', + 'friendly_name': 'OpenWeatherMap Feels like temperature', 'state_class': , 'unit_of_measurement': , }), @@ -1617,7 +1617,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'humidity', - 'friendly_name': 'openweathermap Humidity', + 'friendly_name': 'OpenWeatherMap Humidity', 'state_class': , 'unit_of_measurement': '%', }), @@ -1668,7 +1668,7 @@ StateSnapshot({ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', - 'friendly_name': 'openweathermap Precipitation kind', + 'friendly_name': 'OpenWeatherMap Precipitation kind', }), 'context': , 'entity_id': 'sensor.openweathermap_precipitation_kind', @@ -1723,7 +1723,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'pressure', - 'friendly_name': 'openweathermap Pressure', + 'friendly_name': 'OpenWeatherMap Pressure', 'state_class': , 'unit_of_measurement': , }), @@ -1780,7 +1780,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'precipitation_intensity', - 'friendly_name': 'openweathermap Rain', + 'friendly_name': 'OpenWeatherMap Rain', 'state_class': , 'unit_of_measurement': , }), @@ -1837,7 +1837,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'precipitation_intensity', - 'friendly_name': 'openweathermap Snow', + 'friendly_name': 'OpenWeatherMap Snow', 'state_class': , 'unit_of_measurement': , }), @@ -1894,7 +1894,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'temperature', - 'friendly_name': 'openweathermap Temperature', + 'friendly_name': 'OpenWeatherMap Temperature', 'state_class': , 'unit_of_measurement': , }), @@ -1947,7 +1947,7 @@ StateSnapshot({ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', - 'friendly_name': 'openweathermap UV Index', + 'friendly_name': 'OpenWeatherMap UV Index', 'state_class': , 'unit_of_measurement': 'UV index', }), @@ -2004,7 +2004,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'distance', - 'friendly_name': 'openweathermap Visibility', + 'friendly_name': 'OpenWeatherMap Visibility', 'state_class': , 'unit_of_measurement': , }), @@ -2055,7 +2055,7 @@ StateSnapshot({ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', - 'friendly_name': 'openweathermap Weather', + 'friendly_name': 'OpenWeatherMap Weather', }), 'context': , 'entity_id': 'sensor.openweathermap_weather', @@ -2104,7 +2104,7 @@ StateSnapshot({ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', - 'friendly_name': 'openweathermap Weather Code', + 'friendly_name': 'OpenWeatherMap Weather Code', }), 'context': , 'entity_id': 'sensor.openweathermap_weather_code', @@ -2156,7 +2156,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'wind_direction', - 'friendly_name': 'openweathermap Wind bearing', + 'friendly_name': 'OpenWeatherMap Wind bearing', 'state_class': , 'unit_of_measurement': '°', }), @@ -2216,7 +2216,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'wind_speed', - 'friendly_name': 'openweathermap Wind gust', + 'friendly_name': 'OpenWeatherMap Wind gust', 'state_class': , 'unit_of_measurement': , }), @@ -2276,7 +2276,7 @@ 'attributes': ReadOnlyDict({ 'attribution': 'Data provided by OpenWeatherMap', 'device_class': 'wind_speed', - 'friendly_name': 'openweathermap Wind speed', + 'friendly_name': 'OpenWeatherMap Wind speed', 'state_class': , 'unit_of_measurement': , }), diff --git a/tests/components/openweathermap/snapshots/test_weather.ambr b/tests/components/openweathermap/snapshots/test_weather.ambr index be3db7bc594..733545a3f43 100644 --- a/tests/components/openweathermap/snapshots/test_weather.ambr +++ b/tests/components/openweathermap/snapshots/test_weather.ambr @@ -65,7 +65,7 @@ 'attribution': 'Data provided by OpenWeatherMap', 'cloud_coverage': 75, 'dew_point': 4.0, - 'friendly_name': 'openweathermap', + 'friendly_name': 'OpenWeatherMap', 'humidity': 82, 'precipitation_unit': , 'pressure': 1000.0, @@ -129,7 +129,7 @@ 'attribution': 'Data provided by OpenWeatherMap', 'cloud_coverage': 75, 'dew_point': 4.0, - 'friendly_name': 'openweathermap', + 'friendly_name': 'OpenWeatherMap', 'humidity': 82, 'precipitation_unit': , 'pressure': 1000.0, @@ -194,7 +194,7 @@ 'attribution': 'Data provided by OpenWeatherMap', 'cloud_coverage': 75, 'dew_point': 4.0, - 'friendly_name': 'openweathermap', + 'friendly_name': 'OpenWeatherMap', 'humidity': 82, 'precipitation_unit': , 'pressure': 1000.0, diff --git a/tests/components/openweathermap/test_config_flow.py b/tests/components/openweathermap/test_config_flow.py index 0315ca91010..039498e5ec3 100644 --- a/tests/components/openweathermap/test_config_flow.py +++ b/tests/components/openweathermap/test_config_flow.py @@ -7,6 +7,7 @@ import pytest from homeassistant.components.openweathermap.const import ( DEFAULT_LANGUAGE, + DEFAULT_NAME, DEFAULT_OWM_MODE, DOMAIN, OWM_MODE_V30, @@ -16,9 +17,9 @@ from homeassistant.const import ( CONF_API_KEY, CONF_LANGUAGE, CONF_LATITUDE, + CONF_LOCATION, CONF_LONGITUDE, CONF_MODE, - CONF_NAME, ) from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType @@ -28,7 +29,6 @@ from .conftest import LATITUDE, LONGITUDE from tests.common import MockConfigEntry CONFIG = { - CONF_NAME: "openweathermap", CONF_API_KEY: "foo", CONF_LATITUDE: LATITUDE, CONF_LONGITUDE: LONGITUDE, @@ -36,6 +36,13 @@ CONFIG = { CONF_MODE: OWM_MODE_V30, } +USER_INPUT = { + CONF_API_KEY: "foo", + CONF_LOCATION: {CONF_LATITUDE: LATITUDE, CONF_LONGITUDE: LONGITUDE}, + CONF_LANGUAGE: DEFAULT_LANGUAGE, + CONF_MODE: OWM_MODE_V30, +} + VALID_YAML_CONFIG = {CONF_API_KEY: "foo"} @@ -47,31 +54,32 @@ async def test_successful_config_flow( result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER} ) - assert result["type"] is FlowResultType.FORM assert result["step_id"] == "user" assert result["errors"] == {} - result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": SOURCE_USER}, data=CONFIG + # create entry + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + USER_INPUT, ) - await hass.async_block_till_done() + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == DEFAULT_NAME + assert result["data"][CONF_LATITUDE] == USER_INPUT[CONF_LOCATION][CONF_LATITUDE] + assert result["data"][CONF_LONGITUDE] == USER_INPUT[CONF_LOCATION][CONF_LONGITUDE] + assert result["data"][CONF_API_KEY] == USER_INPUT[CONF_API_KEY] + # validate entry state conf_entries = hass.config_entries.async_entries(DOMAIN) entry = conf_entries[0] assert entry.state is ConfigEntryState.LOADED + # unload entry await hass.config_entries.async_unload(conf_entries[0].entry_id) await hass.async_block_till_done() assert entry.state is ConfigEntryState.NOT_LOADED - assert result["type"] is FlowResultType.CREATE_ENTRY - assert result["title"] == CONFIG[CONF_NAME] - assert result["data"][CONF_LATITUDE] == CONFIG[CONF_LATITUDE] - assert result["data"][CONF_LONGITUDE] == CONFIG[CONF_LONGITUDE] - assert result["data"][CONF_API_KEY] == CONFIG[CONF_API_KEY] - @pytest.mark.parametrize("mode", [OWM_MODE_V30], indirect=True) async def test_abort_config_flow( @@ -84,13 +92,14 @@ async def test_abort_config_flow( result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER} ) - assert result["type"] is FlowResultType.FORM assert result["step_id"] == "user" assert result["errors"] == {} - result = await hass.config_entries.flow.async_configure(result["flow_id"], CONFIG) - + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + USER_INPUT, + ) assert result["type"] is FlowResultType.ABORT @@ -156,19 +165,26 @@ async def test_form_invalid_api_key( owm_client_mock: AsyncMock, ) -> None: """Test that the form is served with no input.""" - owm_client_mock.validate_key.return_value = False result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": SOURCE_USER}, data=CONFIG + DOMAIN, context={"source": SOURCE_USER} + ) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + assert result["errors"] == {} + # invalid api key + owm_client_mock.validate_key.return_value = False + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + USER_INPUT, ) - assert result["type"] is FlowResultType.FORM assert result["errors"] == {"base": "invalid_api_key"} - + # valid api key owm_client_mock.validate_key.return_value = True result = await hass.config_entries.flow.async_configure( - result["flow_id"], user_input=CONFIG + result["flow_id"], + USER_INPUT, ) - assert result["type"] is FlowResultType.CREATE_ENTRY @@ -177,17 +193,23 @@ async def test_form_api_call_error( owm_client_mock: AsyncMock, ) -> None: """Test setting up with api call error.""" - owm_client_mock.validate_key.side_effect = RequestError("oops") result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": SOURCE_USER}, data=CONFIG + DOMAIN, context={"source": SOURCE_USER} + ) + assert result["type"] is FlowResultType.FORM + assert result["errors"] == {} + # simulate api call error + owm_client_mock.validate_key.side_effect = RequestError("oops") + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + USER_INPUT, ) - assert result["type"] is FlowResultType.FORM assert result["errors"] == {"base": "cannot_connect"} - + # simulate successful api call owm_client_mock.validate_key.side_effect = None result = await hass.config_entries.flow.async_configure( - result["flow_id"], user_input=CONFIG + result["flow_id"], + USER_INPUT, ) - assert result["type"] is FlowResultType.CREATE_ENTRY