Fix openweathermap config entry migration (#118526)

* Fix openweathermap config entry migration

The options keys were accidentally migrated to data so
they could no longer be changed in the options flow

* more fixes

* adjust

* reduce

* fix

* adjust
This commit is contained in:
J. Nick Koston 2024-05-31 09:51:38 -05:00 committed by GitHub
parent bff2d3e2ee
commit d67f14ac0b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 34 additions and 15 deletions

View File

@ -4,7 +4,6 @@ from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
import logging import logging
from typing import Any
from pyopenweathermap import OWMClient from pyopenweathermap import OWMClient
@ -22,6 +21,7 @@ from homeassistant.core import HomeAssistant
from .const import CONFIG_FLOW_VERSION, OWM_MODE_V25, PLATFORMS from .const import CONFIG_FLOW_VERSION, OWM_MODE_V25, PLATFORMS
from .coordinator import WeatherUpdateCoordinator from .coordinator import WeatherUpdateCoordinator
from .repairs import async_create_issue, async_delete_issue from .repairs import async_create_issue, async_delete_issue
from .utils import build_data_and_options
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -44,8 +44,8 @@ async def async_setup_entry(
api_key = entry.data[CONF_API_KEY] api_key = entry.data[CONF_API_KEY]
latitude = entry.data.get(CONF_LATITUDE, hass.config.latitude) latitude = entry.data.get(CONF_LATITUDE, hass.config.latitude)
longitude = entry.data.get(CONF_LONGITUDE, hass.config.longitude) longitude = entry.data.get(CONF_LONGITUDE, hass.config.longitude)
language = _get_config_value(entry, CONF_LANGUAGE) language = entry.options[CONF_LANGUAGE]
mode = _get_config_value(entry, CONF_MODE) mode = entry.options[CONF_MODE]
if mode == OWM_MODE_V25: if mode == OWM_MODE_V25:
async_create_issue(hass, entry.entry_id) async_create_issue(hass, entry.entry_id)
@ -77,10 +77,14 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
_LOGGER.debug("Migrating OpenWeatherMap entry from version %s", version) _LOGGER.debug("Migrating OpenWeatherMap entry from version %s", version)
if version < 4: if version < 5:
new_data = {**data, **options, CONF_MODE: OWM_MODE_V25} combined_data = {**data, **options, CONF_MODE: OWM_MODE_V25}
new_data, new_options = build_data_and_options(combined_data)
config_entries.async_update_entry( config_entries.async_update_entry(
entry, data=new_data, options={}, version=CONFIG_FLOW_VERSION entry,
data=new_data,
options=new_options,
version=CONFIG_FLOW_VERSION,
) )
_LOGGER.info("Migration to version %s successful", CONFIG_FLOW_VERSION) _LOGGER.info("Migration to version %s successful", CONFIG_FLOW_VERSION)
@ -98,9 +102,3 @@ async def async_unload_entry(
) -> bool: ) -> bool:
"""Unload a config entry.""" """Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
def _get_config_value(config_entry: ConfigEntry, key: str) -> Any:
if config_entry.options and key in config_entry.options:
return config_entry.options[key]
return config_entry.data[key]

View File

@ -30,7 +30,7 @@ from .const import (
LANGUAGES, LANGUAGES,
OWM_MODES, OWM_MODES,
) )
from .utils import validate_api_key from .utils import build_data_and_options, validate_api_key
class OpenWeatherMapConfigFlow(ConfigFlow, domain=DOMAIN): class OpenWeatherMapConfigFlow(ConfigFlow, domain=DOMAIN):
@ -64,8 +64,9 @@ class OpenWeatherMapConfigFlow(ConfigFlow, domain=DOMAIN):
) )
if not errors: if not errors:
data, options = build_data_and_options(user_input)
return self.async_create_entry( return self.async_create_entry(
title=user_input[CONF_NAME], data=user_input title=user_input[CONF_NAME], data=data, options=options
) )
schema = vol.Schema( schema = vol.Schema(

View File

@ -25,7 +25,7 @@ DEFAULT_NAME = "OpenWeatherMap"
DEFAULT_LANGUAGE = "en" DEFAULT_LANGUAGE = "en"
ATTRIBUTION = "Data provided by OpenWeatherMap" ATTRIBUTION = "Data provided by OpenWeatherMap"
MANUFACTURER = "OpenWeather" MANUFACTURER = "OpenWeather"
CONFIG_FLOW_VERSION = 4 CONFIG_FLOW_VERSION = 5
ATTR_API_PRECIPITATION = "precipitation" ATTR_API_PRECIPITATION = "precipitation"
ATTR_API_PRECIPITATION_KIND = "precipitation_kind" ATTR_API_PRECIPITATION_KIND = "precipitation_kind"
ATTR_API_DATETIME = "datetime" ATTR_API_DATETIME = "datetime"

View File

@ -1,7 +1,15 @@
"""Util functions for OpenWeatherMap.""" """Util functions for OpenWeatherMap."""
from typing import Any
from pyopenweathermap import OWMClient, RequestError from pyopenweathermap import OWMClient, RequestError
from homeassistant.const import CONF_LANGUAGE, CONF_MODE
from .const import DEFAULT_LANGUAGE, DEFAULT_OWM_MODE
OPTION_DEFAULTS = {CONF_LANGUAGE: DEFAULT_LANGUAGE, CONF_MODE: DEFAULT_OWM_MODE}
async def validate_api_key(api_key, mode): async def validate_api_key(api_key, mode):
"""Validate API key.""" """Validate API key."""
@ -18,3 +26,15 @@ async def validate_api_key(api_key, mode):
errors["base"] = "invalid_api_key" errors["base"] = "invalid_api_key"
return errors, description_placeholders return errors, description_placeholders
def build_data_and_options(
combined_data: dict[str, Any],
) -> tuple[dict[str, Any], dict[str, Any]]:
"""Split combined data and options."""
data = {k: v for k, v in combined_data.items() if k not in OPTION_DEFAULTS}
options = {
option: combined_data.get(option, default)
for option, default in OPTION_DEFAULTS.items()
}
return (data, options)