diff --git a/homeassistant/components/forecast_solar/__init__.py b/homeassistant/components/forecast_solar/__init__.py index e10d9651c3b..c6d4236c219 100644 --- a/homeassistant/components/forecast_solar/__init__.py +++ b/homeassistant/components/forecast_solar/__init__.py @@ -5,12 +5,38 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from .const import DOMAIN +from .const import ( + CONF_DAMPING, + CONF_DAMPING_EVENING, + CONF_DAMPING_MORNING, + CONF_MODULES_POWER, + DOMAIN, +) from .coordinator import ForecastSolarDataUpdateCoordinator PLATFORMS = [Platform.SENSOR] +async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: + """Migrate old config entry.""" + + if entry.version == 1: + new_options = entry.options.copy() + new_options |= { + CONF_MODULES_POWER: new_options.pop("modules power"), + CONF_DAMPING_MORNING: new_options.get(CONF_DAMPING, 0.0), + CONF_DAMPING_EVENING: new_options.pop(CONF_DAMPING, 0.0), + } + + entry.version = 2 + + hass.config_entries.async_update_entry( + entry, data=entry.data, options=new_options + ) + + return True + + async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Forecast.Solar from a config entry.""" coordinator = ForecastSolarDataUpdateCoordinator(hass, entry) diff --git a/homeassistant/components/forecast_solar/config_flow.py b/homeassistant/components/forecast_solar/config_flow.py index e74585da35b..47e1afaec7b 100644 --- a/homeassistant/components/forecast_solar/config_flow.py +++ b/homeassistant/components/forecast_solar/config_flow.py @@ -14,7 +14,8 @@ from homeassistant.helpers import config_validation as cv from .const import ( CONF_AZIMUTH, - CONF_DAMPING, + CONF_DAMPING_EVENING, + CONF_DAMPING_MORNING, CONF_DECLINATION, CONF_INVERTER_SIZE, CONF_MODULES_POWER, @@ -27,7 +28,7 @@ RE_API_KEY = re.compile(r"^[a-zA-Z0-9]{16}$") class ForecastSolarFlowHandler(ConfigFlow, domain=DOMAIN): """Handle a config flow for Forecast.Solar.""" - VERSION = 1 + VERSION = 2 @staticmethod @callback @@ -127,8 +128,16 @@ class ForecastSolarOptionFlowHandler(OptionsFlow): default=self.config_entry.options[CONF_MODULES_POWER], ): vol.Coerce(int), vol.Optional( - CONF_DAMPING, - default=self.config_entry.options.get(CONF_DAMPING, 0.0), + CONF_DAMPING_MORNING, + default=self.config_entry.options.get( + CONF_DAMPING_MORNING, 0.0 + ), + ): vol.Coerce(float), + vol.Optional( + CONF_DAMPING_EVENING, + default=self.config_entry.options.get( + CONF_DAMPING_EVENING, 0.0 + ), ): vol.Coerce(float), vol.Optional( CONF_INVERTER_SIZE, diff --git a/homeassistant/components/forecast_solar/const.py b/homeassistant/components/forecast_solar/const.py index e566733413b..24273f32405 100644 --- a/homeassistant/components/forecast_solar/const.py +++ b/homeassistant/components/forecast_solar/const.py @@ -8,6 +8,8 @@ LOGGER = logging.getLogger(__package__) CONF_DECLINATION = "declination" CONF_AZIMUTH = "azimuth" -CONF_MODULES_POWER = "modules power" +CONF_MODULES_POWER = "modules_power" CONF_DAMPING = "damping" +CONF_DAMPING_MORNING = "damping_morning" +CONF_DAMPING_EVENING = "damping_evening" CONF_INVERTER_SIZE = "inverter_size" diff --git a/homeassistant/components/forecast_solar/coordinator.py b/homeassistant/components/forecast_solar/coordinator.py index 273d3a49a2f..2ef6912e5a2 100644 --- a/homeassistant/components/forecast_solar/coordinator.py +++ b/homeassistant/components/forecast_solar/coordinator.py @@ -13,7 +13,8 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import ( CONF_AZIMUTH, - CONF_DAMPING, + CONF_DAMPING_EVENING, + CONF_DAMPING_MORNING, CONF_DECLINATION, CONF_INVERTER_SIZE, CONF_MODULES_POWER, @@ -48,7 +49,8 @@ class ForecastSolarDataUpdateCoordinator(DataUpdateCoordinator[Estimate]): declination=entry.options[CONF_DECLINATION], azimuth=(entry.options[CONF_AZIMUTH] - 180), kwp=(entry.options[CONF_MODULES_POWER] / 1000), - damping=entry.options.get(CONF_DAMPING, 0), + damping_morning=entry.options.get(CONF_DAMPING_MORNING, 0.0), + damping_evening=entry.options.get(CONF_DAMPING_EVENING, 0.0), inverter=inverter_size, ) diff --git a/homeassistant/components/forecast_solar/strings.json b/homeassistant/components/forecast_solar/strings.json index 43e6fca4ada..1413dba23d4 100644 --- a/homeassistant/components/forecast_solar/strings.json +++ b/homeassistant/components/forecast_solar/strings.json @@ -24,10 +24,11 @@ "data": { "api_key": "Forecast.Solar API Key (optional)", "azimuth": "[%key:component::forecast_solar::config::step::user::data::azimuth%]", - "damping": "Damping factor: adjusts the results in the morning and evening", + "damping_morning": "Damping factor: adjusts the results in the morning", + "damping_evening": "Damping factor: adjusts the results in the evening", "inverter_size": "Inverter size (Watt)", "declination": "[%key:component::forecast_solar::config::step::user::data::declination%]", - "modules power": "[%key:component::forecast_solar::config::step::user::data::modules_power%]" + "modules_power": "[%key:component::forecast_solar::config::step::user::data::modules_power%]" } } } diff --git a/tests/components/forecast_solar/conftest.py b/tests/components/forecast_solar/conftest.py index 60e9c9dc5d0..06cf39b4875 100644 --- a/tests/components/forecast_solar/conftest.py +++ b/tests/components/forecast_solar/conftest.py @@ -9,7 +9,8 @@ import pytest from homeassistant.components.forecast_solar.const import ( CONF_AZIMUTH, - CONF_DAMPING, + CONF_DAMPING_EVENING, + CONF_DAMPING_MORNING, CONF_DECLINATION, CONF_INVERTER_SIZE, CONF_MODULES_POWER, @@ -37,6 +38,7 @@ def mock_config_entry() -> MockConfigEntry: return MockConfigEntry( title="Green House", unique_id="unique", + version=2, domain=DOMAIN, data={ CONF_LATITUDE: 52.42, @@ -47,7 +49,8 @@ def mock_config_entry() -> MockConfigEntry: CONF_DECLINATION: 30, CONF_AZIMUTH: 190, CONF_MODULES_POWER: 5100, - CONF_DAMPING: 0.5, + CONF_DAMPING_MORNING: 0.5, + CONF_DAMPING_EVENING: 0.5, CONF_INVERTER_SIZE: 2000, }, ) diff --git a/tests/components/forecast_solar/snapshots/test_diagnostics.ambr b/tests/components/forecast_solar/snapshots/test_diagnostics.ambr index 147c10c1793..686721a9d4a 100644 --- a/tests/components/forecast_solar/snapshots/test_diagnostics.ambr +++ b/tests/components/forecast_solar/snapshots/test_diagnostics.ambr @@ -33,10 +33,11 @@ 'options': dict({ 'api_key': '**REDACTED**', 'azimuth': 190, - 'damping': 0.5, + 'damping_evening': 0.5, + 'damping_morning': 0.5, 'declination': 30, 'inverter_size': 2000, - 'modules power': 5100, + 'modules_power': 5100, }), 'title': 'Green House', }), diff --git a/tests/components/forecast_solar/snapshots/test_init.ambr b/tests/components/forecast_solar/snapshots/test_init.ambr new file mode 100644 index 00000000000..a009105e2e6 --- /dev/null +++ b/tests/components/forecast_solar/snapshots/test_init.ambr @@ -0,0 +1,27 @@ +# serializer version: 1 +# name: test_migration + ConfigEntrySnapshot({ + 'data': dict({ + 'latitude': 52.42, + 'longitude': 4.42, + }), + 'disabled_by': None, + 'domain': 'forecast_solar', + 'entry_id': , + 'options': dict({ + 'api_key': 'abcdef12345', + 'azimuth': 190, + 'damping_evening': 0.5, + 'damping_morning': 0.5, + 'declination': 30, + 'inverter_size': 2000, + 'modules_power': 5100, + }), + 'pref_disable_new_entities': False, + 'pref_disable_polling': False, + 'source': 'user', + 'title': 'Green House', + 'unique_id': 'unique', + 'version': 2, + }) +# --- diff --git a/tests/components/forecast_solar/test_config_flow.py b/tests/components/forecast_solar/test_config_flow.py index 2129821217e..06aeb94542e 100644 --- a/tests/components/forecast_solar/test_config_flow.py +++ b/tests/components/forecast_solar/test_config_flow.py @@ -3,7 +3,8 @@ from unittest.mock import AsyncMock from homeassistant.components.forecast_solar.const import ( CONF_AZIMUTH, - CONF_DAMPING, + CONF_DAMPING_EVENING, + CONF_DAMPING_MORNING, CONF_DECLINATION, CONF_INVERTER_SIZE, CONF_MODULES_POWER, @@ -75,7 +76,8 @@ async def test_options_flow_invalid_api( CONF_DECLINATION: 21, CONF_AZIMUTH: 22, CONF_MODULES_POWER: 2122, - CONF_DAMPING: 0.25, + CONF_DAMPING_MORNING: 0.25, + CONF_DAMPING_EVENING: 0.25, CONF_INVERTER_SIZE: 2000, }, ) @@ -108,7 +110,8 @@ async def test_options_flow( CONF_DECLINATION: 21, CONF_AZIMUTH: 22, CONF_MODULES_POWER: 2122, - CONF_DAMPING: 0.25, + CONF_DAMPING_MORNING: 0.25, + CONF_DAMPING_EVENING: 0.25, CONF_INVERTER_SIZE: 2000, }, ) @@ -120,7 +123,8 @@ async def test_options_flow( CONF_DECLINATION: 21, CONF_AZIMUTH: 22, CONF_MODULES_POWER: 2122, - CONF_DAMPING: 0.25, + CONF_DAMPING_MORNING: 0.25, + CONF_DAMPING_EVENING: 0.25, CONF_INVERTER_SIZE: 2000, } @@ -147,7 +151,8 @@ async def test_options_flow_without_key( CONF_DECLINATION: 21, CONF_AZIMUTH: 22, CONF_MODULES_POWER: 2122, - CONF_DAMPING: 0.25, + CONF_DAMPING_MORNING: 0.25, + CONF_DAMPING_EVENING: 0.25, CONF_INVERTER_SIZE: 2000, }, ) @@ -159,6 +164,7 @@ async def test_options_flow_without_key( CONF_DECLINATION: 21, CONF_AZIMUTH: 22, CONF_MODULES_POWER: 2122, - CONF_DAMPING: 0.25, + CONF_DAMPING_MORNING: 0.25, + CONF_DAMPING_EVENING: 0.25, CONF_INVERTER_SIZE: 2000, } diff --git a/tests/components/forecast_solar/test_init.py b/tests/components/forecast_solar/test_init.py index a7696fe8f53..25dcb41c976 100644 --- a/tests/components/forecast_solar/test_init.py +++ b/tests/components/forecast_solar/test_init.py @@ -2,9 +2,17 @@ from unittest.mock import MagicMock, patch from forecast_solar import ForecastSolarConnectionError +from syrupy import SnapshotAssertion -from homeassistant.components.forecast_solar.const import DOMAIN +from homeassistant.components.forecast_solar.const import ( + CONF_AZIMUTH, + CONF_DAMPING, + CONF_DECLINATION, + CONF_INVERTER_SIZE, + DOMAIN, +) from homeassistant.config_entries import ConfigEntryState +from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component @@ -44,3 +52,29 @@ async def test_config_entry_not_ready( assert mock_request.call_count == 1 assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY + + +async def test_migration(hass: HomeAssistant, snapshot: SnapshotAssertion) -> None: + """Test config entry version 1 -> 2 migration.""" + mock_config_entry = MockConfigEntry( + title="Green House", + unique_id="unique", + domain=DOMAIN, + data={ + CONF_LATITUDE: 52.42, + CONF_LONGITUDE: 4.42, + }, + options={ + CONF_API_KEY: "abcdef12345", + CONF_DECLINATION: 30, + CONF_AZIMUTH: 190, + "modules power": 5100, + CONF_DAMPING: 0.5, + CONF_INVERTER_SIZE: 2000, + }, + ) + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + assert hass.config_entries.async_get_entry(mock_config_entry.entry_id) == snapshot