mirror of
https://github.com/jdejaegh/irm-kmi-ha.git
synced 2025-06-27 11:39:26 +02:00
Breaking: remove deprecated 'forecast' attribute
This commit is contained in:
parent
cf71742b2f
commit
3019d700e4
7 changed files with 11 additions and 85 deletions
|
@ -9,8 +9,8 @@ from homeassistant.exceptions import ConfigEntryError
|
||||||
from irm_kmi_api.const import OPTION_STYLE_STD
|
from irm_kmi_api.const import OPTION_STYLE_STD
|
||||||
|
|
||||||
from .const import (CONF_DARK_MODE, CONF_LANGUAGE_OVERRIDE, CONF_STYLE,
|
from .const import (CONF_DARK_MODE, CONF_LANGUAGE_OVERRIDE, CONF_STYLE,
|
||||||
CONF_USE_DEPRECATED_FORECAST, CONFIG_FLOW_VERSION, DOMAIN,
|
CONFIG_FLOW_VERSION, DOMAIN, PLATFORMS, CONF_USE_DEPRECATED_FORECAST,
|
||||||
OPTION_DEPRECATED_FORECAST_NOT_USED, PLATFORMS)
|
OPTION_DEPRECATED_FORECAST_NOT_USED)
|
||||||
from .coordinator import IrmKmiCoordinator
|
from .coordinator import IrmKmiCoordinator
|
||||||
from .weather import IrmKmiWeather
|
from .weather import IrmKmiWeather
|
||||||
|
|
||||||
|
@ -77,6 +77,10 @@ async def async_migrate_entry(hass, config_entry: ConfigEntry):
|
||||||
new[CONF_LANGUAGE_OVERRIDE] = 'none' if new[CONF_LANGUAGE_OVERRIDE] is None else new[CONF_LANGUAGE_OVERRIDE]
|
new[CONF_LANGUAGE_OVERRIDE] = 'none' if new[CONF_LANGUAGE_OVERRIDE] is None else new[CONF_LANGUAGE_OVERRIDE]
|
||||||
hass.config_entries.async_update_entry(config_entry, data=new, version=5)
|
hass.config_entries.async_update_entry(config_entry, data=new, version=5)
|
||||||
|
|
||||||
|
if config_entry.version == 5:
|
||||||
|
del new[CONF_USE_DEPRECATED_FORECAST]
|
||||||
|
hass.config_entries.async_update_entry(config_entry, data=new, version=5)
|
||||||
|
|
||||||
_LOGGER.debug(f"Migration to version {config_entry.version} successful")
|
_LOGGER.debug(f"Migration to version {config_entry.version} successful")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -19,9 +19,7 @@ from irm_kmi_api.api import IrmKmiApiClient
|
||||||
from . import OPTION_STYLE_STD
|
from . import OPTION_STYLE_STD
|
||||||
from .const import (CONF_DARK_MODE, CONF_LANGUAGE_OVERRIDE,
|
from .const import (CONF_DARK_MODE, CONF_LANGUAGE_OVERRIDE,
|
||||||
CONF_LANGUAGE_OVERRIDE_OPTIONS, CONF_STYLE,
|
CONF_LANGUAGE_OVERRIDE_OPTIONS, CONF_STYLE,
|
||||||
CONF_STYLE_OPTIONS, CONF_USE_DEPRECATED_FORECAST,
|
CONF_STYLE_OPTIONS, CONFIG_FLOW_VERSION, DOMAIN,
|
||||||
CONF_USE_DEPRECATED_FORECAST_OPTIONS, CONFIG_FLOW_VERSION,
|
|
||||||
DOMAIN, OPTION_DEPRECATED_FORECAST_NOT_USED,
|
|
||||||
OUT_OF_BENELUX, USER_AGENT)
|
OUT_OF_BENELUX, USER_AGENT)
|
||||||
from .utils import get_config_value
|
from .utils import get_config_value
|
||||||
|
|
||||||
|
@ -75,7 +73,6 @@ class IrmKmiConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||||
data={CONF_ZONE: user_input[CONF_ZONE],
|
data={CONF_ZONE: user_input[CONF_ZONE],
|
||||||
CONF_STYLE: user_input[CONF_STYLE],
|
CONF_STYLE: user_input[CONF_STYLE],
|
||||||
CONF_DARK_MODE: user_input[CONF_DARK_MODE],
|
CONF_DARK_MODE: user_input[CONF_DARK_MODE],
|
||||||
CONF_USE_DEPRECATED_FORECAST: user_input[CONF_USE_DEPRECATED_FORECAST],
|
|
||||||
CONF_LANGUAGE_OVERRIDE: user_input[CONF_LANGUAGE_OVERRIDE]},
|
CONF_LANGUAGE_OVERRIDE: user_input[CONF_LANGUAGE_OVERRIDE]},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -94,11 +91,6 @@ class IrmKmiConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||||
|
|
||||||
vol.Optional(CONF_DARK_MODE, default=False): bool,
|
vol.Optional(CONF_DARK_MODE, default=False): bool,
|
||||||
|
|
||||||
vol.Optional(CONF_USE_DEPRECATED_FORECAST, default=OPTION_DEPRECATED_FORECAST_NOT_USED):
|
|
||||||
SelectSelector(SelectSelectorConfig(options=CONF_USE_DEPRECATED_FORECAST_OPTIONS,
|
|
||||||
mode=SelectSelectorMode.DROPDOWN,
|
|
||||||
translation_key=CONF_USE_DEPRECATED_FORECAST)),
|
|
||||||
|
|
||||||
vol.Optional(CONF_LANGUAGE_OVERRIDE, default='none'):
|
vol.Optional(CONF_LANGUAGE_OVERRIDE, default='none'):
|
||||||
SelectSelector(SelectSelectorConfig(options=CONF_LANGUAGE_OVERRIDE_OPTIONS,
|
SelectSelector(SelectSelectorConfig(options=CONF_LANGUAGE_OVERRIDE_OPTIONS,
|
||||||
mode=SelectSelectorMode.DROPDOWN,
|
mode=SelectSelectorMode.DROPDOWN,
|
||||||
|
@ -129,12 +121,6 @@ class IrmKmiOptionFlow(OptionsFlow):
|
||||||
|
|
||||||
vol.Optional(CONF_DARK_MODE, default=get_config_value(self.current_config_entry, CONF_DARK_MODE)): bool,
|
vol.Optional(CONF_DARK_MODE, default=get_config_value(self.current_config_entry, CONF_DARK_MODE)): bool,
|
||||||
|
|
||||||
vol.Optional(CONF_USE_DEPRECATED_FORECAST,
|
|
||||||
default=get_config_value(self.current_config_entry, CONF_USE_DEPRECATED_FORECAST)):
|
|
||||||
SelectSelector(SelectSelectorConfig(options=CONF_USE_DEPRECATED_FORECAST_OPTIONS,
|
|
||||||
mode=SelectSelectorMode.DROPDOWN,
|
|
||||||
translation_key=CONF_USE_DEPRECATED_FORECAST)),
|
|
||||||
|
|
||||||
vol.Optional(CONF_LANGUAGE_OVERRIDE,
|
vol.Optional(CONF_LANGUAGE_OVERRIDE,
|
||||||
default=get_config_value(self.current_config_entry, CONF_LANGUAGE_OVERRIDE)):
|
default=get_config_value(self.current_config_entry, CONF_LANGUAGE_OVERRIDE)):
|
||||||
SelectSelector(SelectSelectorConfig(options=CONF_LANGUAGE_OVERRIDE_OPTIONS,
|
SelectSelector(SelectSelectorConfig(options=CONF_LANGUAGE_OVERRIDE_OPTIONS,
|
||||||
|
|
|
@ -38,18 +38,9 @@ CONF_STYLE_OPTIONS: Final = [
|
||||||
|
|
||||||
CONF_DARK_MODE: Final = "dark_mode"
|
CONF_DARK_MODE: Final = "dark_mode"
|
||||||
|
|
||||||
|
# TODO delete those two constants when integrating with Home Assistant Core
|
||||||
CONF_USE_DEPRECATED_FORECAST: Final = 'use_deprecated_forecast_attribute'
|
CONF_USE_DEPRECATED_FORECAST: Final = 'use_deprecated_forecast_attribute'
|
||||||
OPTION_DEPRECATED_FORECAST_NOT_USED: Final = 'do_not_use_deprecated_forecast'
|
OPTION_DEPRECATED_FORECAST_NOT_USED: Final = 'do_not_use_deprecated_forecast'
|
||||||
OPTION_DEPRECATED_FORECAST_DAILY: Final = 'daily_in_deprecated_forecast'
|
|
||||||
OPTION_DEPRECATED_FORECAST_TWICE_DAILY: Final = 'twice_daily_in_deprecated_forecast'
|
|
||||||
OPTION_DEPRECATED_FORECAST_HOURLY: Final = 'hourly_in_deprecated_forecast'
|
|
||||||
|
|
||||||
CONF_USE_DEPRECATED_FORECAST_OPTIONS: Final = [
|
|
||||||
OPTION_DEPRECATED_FORECAST_NOT_USED,
|
|
||||||
OPTION_DEPRECATED_FORECAST_DAILY,
|
|
||||||
OPTION_DEPRECATED_FORECAST_TWICE_DAILY,
|
|
||||||
OPTION_DEPRECATED_FORECAST_HOURLY
|
|
||||||
]
|
|
||||||
|
|
||||||
CONF_LANGUAGE_OVERRIDE: Final = 'language_override'
|
CONF_LANGUAGE_OVERRIDE: Final = 'language_override'
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,8 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
from homeassistant.util import dt
|
from homeassistant.util import dt
|
||||||
|
|
||||||
from . import CONF_USE_DEPRECATED_FORECAST, DOMAIN
|
from .const import DOMAIN
|
||||||
from .const import (OPTION_DEPRECATED_FORECAST_DAILY,
|
|
||||||
OPTION_DEPRECATED_FORECAST_HOURLY,
|
|
||||||
OPTION_DEPRECATED_FORECAST_NOT_USED,
|
|
||||||
OPTION_DEPRECATED_FORECAST_TWICE_DAILY)
|
|
||||||
from .coordinator import IrmKmiCoordinator
|
from .coordinator import IrmKmiCoordinator
|
||||||
from .utils import get_config_value
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -60,12 +55,6 @@ class IrmKmiWeather(CoordinatorEntity, WeatherEntity):
|
||||||
self._name = entry.title
|
self._name = entry.title
|
||||||
self._attr_unique_id = entry.entry_id
|
self._attr_unique_id = entry.entry_id
|
||||||
self._attr_device_info = coordinator.shared_device_info
|
self._attr_device_info = coordinator.shared_device_info
|
||||||
self._deprecated_forecast_as = get_config_value(entry, CONF_USE_DEPRECATED_FORECAST)
|
|
||||||
|
|
||||||
if self._deprecated_forecast_as != OPTION_DEPRECATED_FORECAST_NOT_USED:
|
|
||||||
_LOGGER.warning(f"You are using the forecast attribute for {entry.title} weather. Home Assistant deleted "
|
|
||||||
f"that attribute in 2024.4. Consider using the service weather.get_forecasts instead "
|
|
||||||
f"as the attribute will be delete from this integration in a future release.")
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supported_features(self) -> WeatherEntityFeature:
|
def supported_features(self) -> WeatherEntityFeature:
|
||||||
|
@ -164,27 +153,3 @@ class IrmKmiWeather(CoordinatorEntity, WeatherEntity):
|
||||||
|
|
||||||
return {'forecast': [f for f in self.coordinator.data.get('radar_forecast')
|
return {'forecast': [f for f in self.coordinator.data.get('radar_forecast')
|
||||||
if include_past_forecasts or datetime.fromisoformat(f.get('datetime')) >= now]}
|
if include_past_forecasts or datetime.fromisoformat(f.get('datetime')) >= now]}
|
||||||
|
|
||||||
# TODO remove on next breaking changes
|
|
||||||
@property
|
|
||||||
def extra_state_attributes(self) -> dict:
|
|
||||||
"""Here to keep the DEPRECATED forecast attribute.
|
|
||||||
This attribute is deprecated by Home Assistant by still implemented for compatibility
|
|
||||||
with older components. Newer components should use the service weather.get_forecasts instead.
|
|
||||||
"""
|
|
||||||
data: List[Forecast] = list()
|
|
||||||
if self._deprecated_forecast_as == OPTION_DEPRECATED_FORECAST_NOT_USED:
|
|
||||||
return {}
|
|
||||||
elif self._deprecated_forecast_as == OPTION_DEPRECATED_FORECAST_HOURLY:
|
|
||||||
data = self.coordinator.data.get('hourly_forecast')
|
|
||||||
elif self._deprecated_forecast_as == OPTION_DEPRECATED_FORECAST_DAILY:
|
|
||||||
data = self.daily_forecast()
|
|
||||||
elif self._deprecated_forecast_as == OPTION_DEPRECATED_FORECAST_TWICE_DAILY:
|
|
||||||
data = self.coordinator.data.get('daily_forecast')
|
|
||||||
|
|
||||||
for forecast in data:
|
|
||||||
for k in list(forecast.keys()):
|
|
||||||
if k.startswith('native_'):
|
|
||||||
forecast[k[7:]] = forecast[k]
|
|
||||||
|
|
||||||
return {'forecast': data}
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
||||||
import json
|
import json
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
from unittest.mock import AsyncMock, MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from homeassistant.const import CONF_ZONE
|
from homeassistant.const import CONF_ZONE
|
||||||
|
@ -18,8 +18,7 @@ from custom_components.irm_kmi import OPTION_STYLE_STD
|
||||||
from custom_components.irm_kmi.const import (
|
from custom_components.irm_kmi.const import (
|
||||||
CONF_DARK_MODE, CONF_LANGUAGE_OVERRIDE, CONF_STYLE,
|
CONF_DARK_MODE, CONF_LANGUAGE_OVERRIDE, CONF_STYLE,
|
||||||
CONF_USE_DEPRECATED_FORECAST, DOMAIN, IRM_KMI_TO_HA_CONDITION_MAP,
|
CONF_USE_DEPRECATED_FORECAST, DOMAIN, IRM_KMI_TO_HA_CONDITION_MAP,
|
||||||
OPTION_DEPRECATED_FORECAST_NOT_USED,
|
OPTION_DEPRECATED_FORECAST_NOT_USED)
|
||||||
OPTION_DEPRECATED_FORECAST_TWICE_DAILY)
|
|
||||||
|
|
||||||
|
|
||||||
def get_api_data(fixture: str) -> dict:
|
def get_api_data(fixture: str) -> dict:
|
||||||
|
@ -52,21 +51,6 @@ def mock_config_entry() -> MockConfigEntry:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def mock_config_entry_with_deprecated() -> MockConfigEntry:
|
|
||||||
"""Return the default mocked config entry."""
|
|
||||||
return MockConfigEntry(
|
|
||||||
title="Home",
|
|
||||||
domain=DOMAIN,
|
|
||||||
data={CONF_ZONE: "zone.home",
|
|
||||||
CONF_STYLE: OPTION_STYLE_STD,
|
|
||||||
CONF_DARK_MODE: True,
|
|
||||||
CONF_USE_DEPRECATED_FORECAST: OPTION_DEPRECATED_FORECAST_TWICE_DAILY,
|
|
||||||
CONF_LANGUAGE_OVERRIDE: 'none'},
|
|
||||||
unique_id="zone.home",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_setup_entry() -> Generator[None, None, None]:
|
def mock_setup_entry() -> Generator[None, None, None]:
|
||||||
"""Mock setting up a config entry."""
|
"""Mock setting up a config entry."""
|
||||||
|
|
|
@ -41,7 +41,6 @@ async def test_full_user_flow(
|
||||||
assert result2.get("data") == {CONF_ZONE: ENTITY_ID_HOME,
|
assert result2.get("data") == {CONF_ZONE: ENTITY_ID_HOME,
|
||||||
CONF_STYLE: OPTION_STYLE_STD,
|
CONF_STYLE: OPTION_STYLE_STD,
|
||||||
CONF_DARK_MODE: False,
|
CONF_DARK_MODE: False,
|
||||||
CONF_USE_DEPRECATED_FORECAST: OPTION_DEPRECATED_FORECAST_NOT_USED,
|
|
||||||
CONF_LANGUAGE_OVERRIDE: 'none'}
|
CONF_LANGUAGE_OVERRIDE: 'none'}
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,7 +121,6 @@ async def test_option_flow(
|
||||||
user_input={
|
user_input={
|
||||||
CONF_STYLE: OPTION_STYLE_SATELLITE,
|
CONF_STYLE: OPTION_STYLE_SATELLITE,
|
||||||
CONF_DARK_MODE: True,
|
CONF_DARK_MODE: True,
|
||||||
CONF_USE_DEPRECATED_FORECAST: OPTION_DEPRECATED_FORECAST_NOT_USED
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -130,7 +128,6 @@ async def test_option_flow(
|
||||||
assert result["data"] == {
|
assert result["data"] == {
|
||||||
CONF_STYLE: OPTION_STYLE_SATELLITE,
|
CONF_STYLE: OPTION_STYLE_SATELLITE,
|
||||||
CONF_DARK_MODE: True,
|
CONF_DARK_MODE: True,
|
||||||
CONF_USE_DEPRECATED_FORECAST: OPTION_DEPRECATED_FORECAST_NOT_USED,
|
|
||||||
CONF_LANGUAGE_OVERRIDE: 'none'
|
CONF_LANGUAGE_OVERRIDE: 'none'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,6 @@ async def test_config_entry_migration(
|
||||||
CONF_ZONE: "zone.castle",
|
CONF_ZONE: "zone.castle",
|
||||||
CONF_STYLE: OPTION_STYLE_STD,
|
CONF_STYLE: OPTION_STYLE_STD,
|
||||||
CONF_DARK_MODE: True,
|
CONF_DARK_MODE: True,
|
||||||
CONF_USE_DEPRECATED_FORECAST: OPTION_DEPRECATED_FORECAST_NOT_USED,
|
|
||||||
CONF_LANGUAGE_OVERRIDE: 'none'
|
CONF_LANGUAGE_OVERRIDE: 'none'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue