Add morning and evening damping to Forecast solar (#98721)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
This commit is contained in:
parent
a1d554d1cb
commit
30d3df2d96
10 changed files with 132 additions and 21 deletions
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
||||
|
|
|
@ -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%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
)
|
||||
|
|
|
@ -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',
|
||||
}),
|
||||
|
|
27
tests/components/forecast_solar/snapshots/test_init.ambr
Normal file
27
tests/components/forecast_solar/snapshots/test_init.ambr
Normal file
|
@ -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': <ANY>,
|
||||
'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,
|
||||
})
|
||||
# ---
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue