mirror of
https://github.com/jdejaegh/irm-kmi-ha.git
synced 2025-06-27 11:39:26 +02:00
Add language picker to override Home Assistant server language
This commit is contained in:
parent
7ff9705536
commit
377601cf4d
12 changed files with 126 additions and 36 deletions
|
@ -7,8 +7,8 @@ from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryError
|
from homeassistant.exceptions import ConfigEntryError
|
||||||
|
|
||||||
from .const import (CONF_DARK_MODE, CONF_STYLE, CONF_USE_DEPRECATED_FORECAST,
|
from .const import (CONF_DARK_MODE, CONF_LANGUAGE_OVERRIDE, CONF_STYLE,
|
||||||
CONFIG_FLOW_VERSION, DOMAIN,
|
CONF_USE_DEPRECATED_FORECAST, CONFIG_FLOW_VERSION, DOMAIN,
|
||||||
OPTION_DEPRECATED_FORECAST_NOT_USED, OPTION_STYLE_STD,
|
OPTION_DEPRECATED_FORECAST_NOT_USED, OPTION_STYLE_STD,
|
||||||
PLATFORMS)
|
PLATFORMS)
|
||||||
from .coordinator import IrmKmiCoordinator
|
from .coordinator import IrmKmiCoordinator
|
||||||
|
@ -68,6 +68,11 @@ async def async_migrate_entry(hass, config_entry: ConfigEntry):
|
||||||
config_entry.version = 3
|
config_entry.version = 3
|
||||||
hass.config_entries.async_update_entry(config_entry, data=new)
|
hass.config_entries.async_update_entry(config_entry, data=new)
|
||||||
|
|
||||||
|
if config_entry.version == 3:
|
||||||
|
new = new | {CONF_LANGUAGE_OVERRIDE: None}
|
||||||
|
config_entry.version = 4
|
||||||
|
hass.config_entries.async_update_entry(config_entry, data=new)
|
||||||
|
|
||||||
_LOGGER.debug(f"Migration to version {config_entry.version} successful")
|
_LOGGER.debug(f"Migration to version {config_entry.version} successful")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -16,8 +16,9 @@ from homeassistant.helpers.selector import (EntitySelector,
|
||||||
SelectSelectorMode)
|
SelectSelectorMode)
|
||||||
|
|
||||||
from .api import IrmKmiApiClient
|
from .api import IrmKmiApiClient
|
||||||
from .const import (CONF_DARK_MODE, CONF_STYLE, CONF_STYLE_OPTIONS,
|
from .const import (CONF_DARK_MODE, CONF_LANGUAGE_OVERRIDE,
|
||||||
CONF_USE_DEPRECATED_FORECAST,
|
CONF_LANGUAGE_OVERRIDE_OPTIONS, CONF_STYLE,
|
||||||
|
CONF_STYLE_OPTIONS, CONF_USE_DEPRECATED_FORECAST,
|
||||||
CONF_USE_DEPRECATED_FORECAST_OPTIONS, CONFIG_FLOW_VERSION,
|
CONF_USE_DEPRECATED_FORECAST_OPTIONS, CONFIG_FLOW_VERSION,
|
||||||
DOMAIN, OPTION_DEPRECATED_FORECAST_NOT_USED,
|
DOMAIN, OPTION_DEPRECATED_FORECAST_NOT_USED,
|
||||||
OPTION_STYLE_STD, OUT_OF_BENELUX)
|
OPTION_STYLE_STD, OUT_OF_BENELUX)
|
||||||
|
@ -40,6 +41,9 @@ class IrmKmiConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||||
errors = {}
|
errors = {}
|
||||||
|
|
||||||
if user_input:
|
if user_input:
|
||||||
|
if CONF_LANGUAGE_OVERRIDE in user_input:
|
||||||
|
user_input[CONF_LANGUAGE_OVERRIDE] = None if user_input[CONF_LANGUAGE_OVERRIDE] == 'None' \
|
||||||
|
else user_input[CONF_LANGUAGE_OVERRIDE]
|
||||||
_LOGGER.debug(f"Provided config user is: {user_input}")
|
_LOGGER.debug(f"Provided config user is: {user_input}")
|
||||||
|
|
||||||
if (zone := self.hass.states.get(user_input[CONF_ZONE])) is None:
|
if (zone := self.hass.states.get(user_input[CONF_ZONE])) is None:
|
||||||
|
@ -49,7 +53,7 @@ class IrmKmiConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||||
if not errors:
|
if not errors:
|
||||||
api_data = {}
|
api_data = {}
|
||||||
try:
|
try:
|
||||||
async with async_timeout.timeout(10):
|
async with async_timeout.timeout(60):
|
||||||
api_data = await IrmKmiApiClient(
|
api_data = await IrmKmiApiClient(
|
||||||
session=async_get_clientsession(self.hass)).get_forecasts_coord(
|
session=async_get_clientsession(self.hass)).get_forecasts_coord(
|
||||||
{'lat': zone.attributes[ATTR_LATITUDE],
|
{'lat': zone.attributes[ATTR_LATITUDE],
|
||||||
|
@ -71,7 +75,8 @@ 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_USE_DEPRECATED_FORECAST: user_input[CONF_USE_DEPRECATED_FORECAST],
|
||||||
|
CONF_LANGUAGE_OVERRIDE: user_input[CONF_LANGUAGE_OVERRIDE]},
|
||||||
)
|
)
|
||||||
|
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
|
@ -92,7 +97,12 @@ class IrmKmiConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||||
vol.Optional(CONF_USE_DEPRECATED_FORECAST, default=OPTION_DEPRECATED_FORECAST_NOT_USED):
|
vol.Optional(CONF_USE_DEPRECATED_FORECAST, default=OPTION_DEPRECATED_FORECAST_NOT_USED):
|
||||||
SelectSelector(SelectSelectorConfig(options=CONF_USE_DEPRECATED_FORECAST_OPTIONS,
|
SelectSelector(SelectSelectorConfig(options=CONF_USE_DEPRECATED_FORECAST_OPTIONS,
|
||||||
mode=SelectSelectorMode.DROPDOWN,
|
mode=SelectSelectorMode.DROPDOWN,
|
||||||
translation_key=CONF_USE_DEPRECATED_FORECAST))
|
translation_key=CONF_USE_DEPRECATED_FORECAST)),
|
||||||
|
|
||||||
|
vol.Optional(CONF_LANGUAGE_OVERRIDE, default='None'):
|
||||||
|
SelectSelector(SelectSelectorConfig(options=CONF_LANGUAGE_OVERRIDE_OPTIONS,
|
||||||
|
mode=SelectSelectorMode.DROPDOWN,
|
||||||
|
translation_key=CONF_LANGUAGE_OVERRIDE))
|
||||||
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -105,6 +115,10 @@ class IrmKmiOptionFlow(OptionsFlow):
|
||||||
async def async_step_init(self, user_input: dict | None = None) -> FlowResult:
|
async def async_step_init(self, user_input: dict | None = None) -> FlowResult:
|
||||||
"""Manage the options."""
|
"""Manage the options."""
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
|
if CONF_LANGUAGE_OVERRIDE in user_input:
|
||||||
|
user_input[CONF_LANGUAGE_OVERRIDE] = None if user_input[CONF_LANGUAGE_OVERRIDE] == 'None' \
|
||||||
|
else user_input[CONF_LANGUAGE_OVERRIDE]
|
||||||
|
_LOGGER.debug(user_input)
|
||||||
return self.async_create_entry(data=user_input)
|
return self.async_create_entry(data=user_input)
|
||||||
|
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
|
@ -122,7 +136,13 @@ class IrmKmiOptionFlow(OptionsFlow):
|
||||||
default=get_config_value(self.config_entry, CONF_USE_DEPRECATED_FORECAST)):
|
default=get_config_value(self.config_entry, CONF_USE_DEPRECATED_FORECAST)):
|
||||||
SelectSelector(SelectSelectorConfig(options=CONF_USE_DEPRECATED_FORECAST_OPTIONS,
|
SelectSelector(SelectSelectorConfig(options=CONF_USE_DEPRECATED_FORECAST_OPTIONS,
|
||||||
mode=SelectSelectorMode.DROPDOWN,
|
mode=SelectSelectorMode.DROPDOWN,
|
||||||
translation_key=CONF_USE_DEPRECATED_FORECAST))
|
translation_key=CONF_USE_DEPRECATED_FORECAST)),
|
||||||
|
|
||||||
|
vol.Optional(CONF_LANGUAGE_OVERRIDE,
|
||||||
|
default=str(get_config_value(self.config_entry, CONF_LANGUAGE_OVERRIDE))):
|
||||||
|
SelectSelector(SelectSelectorConfig(options=CONF_LANGUAGE_OVERRIDE_OPTIONS,
|
||||||
|
mode=SelectSelectorMode.DROPDOWN,
|
||||||
|
translation_key=CONF_LANGUAGE_OVERRIDE))
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -15,7 +15,7 @@ from homeassistant.const import Platform
|
||||||
|
|
||||||
DOMAIN: Final = 'irm_kmi'
|
DOMAIN: Final = 'irm_kmi'
|
||||||
PLATFORMS: Final = [Platform.WEATHER, Platform.CAMERA, Platform.BINARY_SENSOR, Platform.SENSOR]
|
PLATFORMS: Final = [Platform.WEATHER, Platform.CAMERA, Platform.BINARY_SENSOR, Platform.SENSOR]
|
||||||
CONFIG_FLOW_VERSION = 3
|
CONFIG_FLOW_VERSION = 4
|
||||||
|
|
||||||
OUT_OF_BENELUX: Final = ["außerhalb der Benelux (Brussels)",
|
OUT_OF_BENELUX: Final = ["außerhalb der Benelux (Brussels)",
|
||||||
"Hors de Belgique (Bxl)",
|
"Hors de Belgique (Bxl)",
|
||||||
|
@ -58,6 +58,12 @@ CONF_USE_DEPRECATED_FORECAST_OPTIONS: Final = [
|
||||||
OPTION_DEPRECATED_FORECAST_HOURLY
|
OPTION_DEPRECATED_FORECAST_HOURLY
|
||||||
]
|
]
|
||||||
|
|
||||||
|
CONF_LANGUAGE_OVERRIDE: Final = 'language_override'
|
||||||
|
|
||||||
|
CONF_LANGUAGE_OVERRIDE_OPTIONS: Final = [
|
||||||
|
'None', "fr", "nl", "de", "en"
|
||||||
|
]
|
||||||
|
|
||||||
REPAIR_SOLUTION: Final = "repair_solution"
|
REPAIR_SOLUTION: Final = "repair_solution"
|
||||||
REPAIR_OPT_MOVE: Final = "repair_option_move"
|
REPAIR_OPT_MOVE: Final = "repair_option_move"
|
||||||
REPAIR_OPT_DELETE: Final = "repair_option_delete"
|
REPAIR_OPT_DELETE: Final = "repair_option_delete"
|
||||||
|
|
|
@ -27,7 +27,7 @@ from .data import (AnimationFrameData, CurrentWeatherData, IrmKmiForecast,
|
||||||
ProcessedCoordinatorData, RadarAnimationData, WarningData)
|
ProcessedCoordinatorData, RadarAnimationData, WarningData)
|
||||||
from .pollen import PollenParser
|
from .pollen import PollenParser
|
||||||
from .rain_graph import RainGraph
|
from .rain_graph import RainGraph
|
||||||
from .utils import disable_from_config, get_config_value
|
from .utils import disable_from_config, get_config_value, preferred_language
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator):
|
||||||
localisation = images_from_api[0]
|
localisation = images_from_api[0]
|
||||||
images_from_api = images_from_api[1:]
|
images_from_api = images_from_api[1:]
|
||||||
|
|
||||||
lang = self.hass.config.language if self.hass.config.language in LANGS else 'en'
|
lang = preferred_language(self.hass, self._config_entry)
|
||||||
radar_animation = RadarAnimationData(
|
radar_animation = RadarAnimationData(
|
||||||
hint=api_data.get('animation', {}).get('sequenceHint', {}).get(lang),
|
hint=api_data.get('animation', {}).get('sequenceHint', {}).get(lang),
|
||||||
unit=api_data.get('animation', {}).get('unit', {}).get(lang),
|
unit=api_data.get('animation', {}).get('unit', {}).get(lang),
|
||||||
|
@ -340,6 +340,7 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator):
|
||||||
|
|
||||||
forecasts = list()
|
forecasts = list()
|
||||||
n_days = 0
|
n_days = 0
|
||||||
|
lang = preferred_language(self.hass, self._config_entry)
|
||||||
|
|
||||||
for (idx, f) in enumerate(data):
|
for (idx, f) in enumerate(data):
|
||||||
precipitation = None
|
precipitation = None
|
||||||
|
@ -377,7 +378,7 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator):
|
||||||
precipitation_probability=f.get('precipChance', None),
|
precipitation_probability=f.get('precipChance', None),
|
||||||
wind_bearing=wind_bearing,
|
wind_bearing=wind_bearing,
|
||||||
is_daytime=is_daytime,
|
is_daytime=is_daytime,
|
||||||
text=f.get('text', {}).get(self.hass.config.language, ""),
|
text=f.get('text', {}).get(lang, ""),
|
||||||
)
|
)
|
||||||
# Swap temperature and templow if needed
|
# Swap temperature and templow if needed
|
||||||
if (forecast['native_templow'] is not None
|
if (forecast['native_templow'] is not None
|
||||||
|
@ -441,6 +442,7 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator):
|
||||||
if warning_data is None or not isinstance(warning_data, list) or len(warning_data) == 0:
|
if warning_data is None or not isinstance(warning_data, list) or len(warning_data) == 0:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
lang = preferred_language(self.hass, self._config_entry)
|
||||||
result = list()
|
result = list()
|
||||||
for data in warning_data:
|
for data in warning_data:
|
||||||
try:
|
try:
|
||||||
|
@ -456,7 +458,6 @@ class IrmKmiCoordinator(TimestampDataUpdateCoordinator):
|
||||||
except TypeError:
|
except TypeError:
|
||||||
level = None
|
level = None
|
||||||
|
|
||||||
lang = self.hass.config.language if self.hass.config.language in LANGS else 'en'
|
|
||||||
result.append(
|
result.append(
|
||||||
WarningData(
|
WarningData(
|
||||||
slug=SLUG_MAP.get(warning_id, 'unknown'),
|
slug=SLUG_MAP.get(warning_id, 'unknown'),
|
||||||
|
|
|
@ -9,9 +9,11 @@
|
||||||
"user": {
|
"user": {
|
||||||
"title": "Configuration",
|
"title": "Configuration",
|
||||||
"data": {
|
"data": {
|
||||||
|
"zone": "Zone",
|
||||||
"style": "Style of the radar",
|
"style": "Style of the radar",
|
||||||
"dark_mode": "Radar dark mode",
|
"dark_mode": "Radar dark mode",
|
||||||
"use_deprecated_forecast_attribute": "Use the deprecated forecat attribute"
|
"use_deprecated_forecast_attribute": "Use the deprecated forecat attribute",
|
||||||
|
"language_override": "Language"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -43,6 +45,15 @@
|
||||||
"repair_option_move": "I moved the zone in Benelux",
|
"repair_option_move": "I moved the zone in Benelux",
|
||||||
"repair_option_delete": "Delete that config entry"
|
"repair_option_delete": "Delete that config entry"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"language_override": {
|
||||||
|
"options": {
|
||||||
|
"None": "Follow Home Assistant server language",
|
||||||
|
"fr": "French",
|
||||||
|
"nl": "Dutch",
|
||||||
|
"de": "German",
|
||||||
|
"en": "English"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
|
@ -52,7 +63,8 @@
|
||||||
"data": {
|
"data": {
|
||||||
"style": "Style of the radar",
|
"style": "Style of the radar",
|
||||||
"dark_mode": "Radar dark mode",
|
"dark_mode": "Radar dark mode",
|
||||||
"use_deprecated_forecast_attribute": "Use the deprecated forecat attribute"
|
"use_deprecated_forecast_attribute": "Use the deprecated forecat attribute",
|
||||||
|
"language_override": "Language"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,11 @@
|
||||||
"user": {
|
"user": {
|
||||||
"title": "Configuration",
|
"title": "Configuration",
|
||||||
"data": {
|
"data": {
|
||||||
|
"zone": "Zone",
|
||||||
"style": "Style du radar",
|
"style": "Style du radar",
|
||||||
"dark_mode": "Radar en mode sombre",
|
"dark_mode": "Radar en mode sombre",
|
||||||
"use_deprecated_forecast_attribute": "Utiliser l'attribut forecat (déprécié)"
|
"use_deprecated_forecast_attribute": "Utiliser l'attribut forecat (déprécié)",
|
||||||
|
"language_override": "Langue"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -43,6 +45,15 @@
|
||||||
"repair_option_move": "J'ai déplacé la zone dans le Benelux",
|
"repair_option_move": "J'ai déplacé la zone dans le Benelux",
|
||||||
"repair_option_delete": "Supprimer cette configuration"
|
"repair_option_delete": "Supprimer cette configuration"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"language_override": {
|
||||||
|
"options": {
|
||||||
|
"None": "Langue du serveur Home Assistant",
|
||||||
|
"fr": "Français",
|
||||||
|
"nl": "Néerlandais",
|
||||||
|
"de": "Allemand",
|
||||||
|
"en": "Anglais"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
|
@ -52,7 +63,8 @@
|
||||||
"data": {
|
"data": {
|
||||||
"style": "Style du radar",
|
"style": "Style du radar",
|
||||||
"dark_mode": "Radar en mode sombre",
|
"dark_mode": "Radar en mode sombre",
|
||||||
"use_deprecated_forecast_attribute": "Utiliser l'attribut forecat (déprécié)"
|
"use_deprecated_forecast_attribute": "Utiliser l'attribut forecat (déprécié)",
|
||||||
|
"language_override": "Langue"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,11 @@
|
||||||
"user": {
|
"user": {
|
||||||
"title": "Instellingen",
|
"title": "Instellingen",
|
||||||
"data": {
|
"data": {
|
||||||
|
"zone": "Zone",
|
||||||
"style": "Radarstijl",
|
"style": "Radarstijl",
|
||||||
"dark_mode": "Radar in donkere modus",
|
"dark_mode": "Radar in donkere modus",
|
||||||
"use_deprecated_forecast_attribute": "Gebruik het forecat attribuut (afgeschaft)"
|
"use_deprecated_forecast_attribute": "Gebruik het forecat attribuut (afgeschaft)",
|
||||||
|
"language_override": "Taal"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -43,6 +45,15 @@
|
||||||
"repair_option_move": "Ik heb de zone verplaats naar de Benelux",
|
"repair_option_move": "Ik heb de zone verplaats naar de Benelux",
|
||||||
"repair_option_delete": "Deze configuratie verwijderen"
|
"repair_option_delete": "Deze configuratie verwijderen"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"language_override": {
|
||||||
|
"options": {
|
||||||
|
"None": "Zelfde als Home Assistant server taal",
|
||||||
|
"fr": "Frans",
|
||||||
|
"nl": "Nederlands",
|
||||||
|
"de": "Duits",
|
||||||
|
"en": "Engels"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
|
@ -52,7 +63,8 @@
|
||||||
"data": {
|
"data": {
|
||||||
"style": "Radarstijl",
|
"style": "Radarstijl",
|
||||||
"dark_mode": "Radar in donkere modus",
|
"dark_mode": "Radar in donkere modus",
|
||||||
"use_deprecated_forecast_attribute": "Gebruik het forecat attribuut (afgeschaft)"
|
"use_deprecated_forecast_attribute": "Gebruik het forecat attribuut (afgeschaft)",
|
||||||
|
"language_override": "Taal"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import device_registry
|
from homeassistant.helpers import device_registry
|
||||||
|
|
||||||
|
from .const import CONF_LANGUAGE_OVERRIDE, LANGS
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +28,16 @@ def modify_from_config(hass: HomeAssistant, config_entry_id: str, enable: bool):
|
||||||
|
|
||||||
|
|
||||||
def get_config_value(config_entry: ConfigEntry, key: str) -> Any:
|
def get_config_value(config_entry: ConfigEntry, key: str) -> Any:
|
||||||
if config_entry.options and key in config_entry.options:
|
try:
|
||||||
return config_entry.options[key]
|
if config_entry.options and key in config_entry.options:
|
||||||
return config_entry.data[key]
|
return config_entry.options[key]
|
||||||
|
return config_entry.data[key]
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def preferred_language(hass: HomeAssistant, config_entry: ConfigEntry) -> str:
|
||||||
|
if get_config_value(config_entry, CONF_LANGUAGE_OVERRIDE) is None:
|
||||||
|
return hass.config.language if hass.config.language in LANGS else 'en'
|
||||||
|
|
||||||
|
return get_config_value(config_entry, CONF_LANGUAGE_OVERRIDE)
|
||||||
|
|
|
@ -162,6 +162,8 @@ class IrmKmiWeather(CoordinatorEntity, WeatherEntity):
|
||||||
now = dt.now()
|
now = dt.now()
|
||||||
now = now.replace(minute=(now.minute // 10) * 10, second=0, microsecond=0)
|
now = now.replace(minute=(now.minute // 10) * 10, second=0, microsecond=0)
|
||||||
|
|
||||||
|
# TODO adapt the return value to match the weather.get_forecasts in next breaking change release
|
||||||
|
# return { 'forecast': [...] }
|
||||||
return [f for f in self.coordinator.data.get('radar_forecast')
|
return [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]
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,10 @@ from pytest_homeassistant_custom_component.common import MockConfigEntry
|
||||||
|
|
||||||
from custom_components.irm_kmi import async_migrate_entry
|
from custom_components.irm_kmi import async_migrate_entry
|
||||||
from custom_components.irm_kmi.const import (
|
from custom_components.irm_kmi.const import (
|
||||||
CONF_DARK_MODE, CONF_STYLE, CONF_USE_DEPRECATED_FORECAST,
|
CONF_DARK_MODE, CONF_LANGUAGE_OVERRIDE, CONF_STYLE,
|
||||||
CONFIG_FLOW_VERSION, DOMAIN, OPTION_DEPRECATED_FORECAST_NOT_USED,
|
CONF_USE_DEPRECATED_FORECAST, CONFIG_FLOW_VERSION, DOMAIN,
|
||||||
OPTION_STYLE_SATELLITE, OPTION_STYLE_STD)
|
OPTION_DEPRECATED_FORECAST_NOT_USED, OPTION_STYLE_SATELLITE,
|
||||||
|
OPTION_STYLE_STD)
|
||||||
|
|
||||||
|
|
||||||
async def test_full_user_flow(
|
async def test_full_user_flow(
|
||||||
|
@ -40,7 +41,8 @@ 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_USE_DEPRECATED_FORECAST: OPTION_DEPRECATED_FORECAST_NOT_USED,
|
||||||
|
CONF_LANGUAGE_OVERRIDE: None}
|
||||||
|
|
||||||
|
|
||||||
async def test_config_flow_out_benelux_zone(
|
async def test_config_flow_out_benelux_zone(
|
||||||
|
@ -128,7 +130,8 @@ 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_USE_DEPRECATED_FORECAST: OPTION_DEPRECATED_FORECAST_NOT_USED,
|
||||||
|
CONF_LANGUAGE_OVERRIDE: None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ from homeassistant.components.weather import (ATTR_CONDITION_CLOUDY,
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from pytest_homeassistant_custom_component.common import MockConfigEntry
|
from pytest_homeassistant_custom_component.common import MockConfigEntry
|
||||||
|
|
||||||
|
from custom_components.irm_kmi.const import CONF_LANGUAGE_OVERRIDE
|
||||||
from custom_components.irm_kmi.coordinator import IrmKmiCoordinator
|
from custom_components.irm_kmi.coordinator import IrmKmiCoordinator
|
||||||
from custom_components.irm_kmi.data import (CurrentWeatherData, IrmKmiForecast,
|
from custom_components.irm_kmi.data import (CurrentWeatherData, IrmKmiForecast,
|
||||||
ProcessedCoordinatorData,
|
ProcessedCoordinatorData,
|
||||||
|
@ -91,6 +92,7 @@ async def test_daily_forecast(
|
||||||
) -> None:
|
) -> None:
|
||||||
api_data = get_api_data("forecast.json").get('for', {}).get('daily')
|
api_data = get_api_data("forecast.json").get('for', {}).get('daily')
|
||||||
|
|
||||||
|
mock_config_entry.data = {CONF_LANGUAGE_OVERRIDE: 'fr'}
|
||||||
coordinator = IrmKmiCoordinator(hass, mock_config_entry)
|
coordinator = IrmKmiCoordinator(hass, mock_config_entry)
|
||||||
result = coordinator.daily_list_to_forecast(api_data)
|
result = coordinator.daily_list_to_forecast(api_data)
|
||||||
|
|
||||||
|
@ -108,7 +110,7 @@ async def test_daily_forecast(
|
||||||
precipitation_probability=0,
|
precipitation_probability=0,
|
||||||
wind_bearing=180,
|
wind_bearing=180,
|
||||||
is_daytime=True,
|
is_daytime=True,
|
||||||
text='Hey!',
|
text='Bar',
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result[1] == expected
|
assert result[1] == expected
|
||||||
|
@ -163,13 +165,13 @@ async def test_refresh_succeed_even_when_pollen_and_radar_fail(
|
||||||
assert result.get('pollen') == PollenParser.get_unavailable_data()
|
assert result.get('pollen') == PollenParser.get_unavailable_data()
|
||||||
|
|
||||||
existing_data = ProcessedCoordinatorData(
|
existing_data = ProcessedCoordinatorData(
|
||||||
current_weather=CurrentWeatherData(),
|
current_weather=CurrentWeatherData(),
|
||||||
daily_forecast=[],
|
daily_forecast=[],
|
||||||
hourly_forecast=[],
|
hourly_forecast=[],
|
||||||
animation=RadarAnimationData(hint="This will remain unchanged"),
|
animation=RadarAnimationData(hint="This will remain unchanged"),
|
||||||
warnings=[],
|
warnings=[],
|
||||||
pollen={'foo': 'bar'}
|
pollen={'foo': 'bar'}
|
||||||
)
|
)
|
||||||
coordinator.data = existing_data
|
coordinator.data = existing_data
|
||||||
result = await coordinator._async_update_data()
|
result = await coordinator._async_update_data()
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ from pytest_homeassistant_custom_component.common import MockConfigEntry
|
||||||
|
|
||||||
from custom_components.irm_kmi import IrmKmiCoordinator
|
from custom_components.irm_kmi import IrmKmiCoordinator
|
||||||
from custom_components.irm_kmi.binary_sensor import IrmKmiWarning
|
from custom_components.irm_kmi.binary_sensor import IrmKmiWarning
|
||||||
|
from custom_components.irm_kmi.const import CONF_LANGUAGE_OVERRIDE
|
||||||
from custom_components.irm_kmi.sensor import IrmKmiNextWarning
|
from custom_components.irm_kmi.sensor import IrmKmiNextWarning
|
||||||
from tests.conftest import get_api_data
|
from tests.conftest import get_api_data
|
||||||
|
|
||||||
|
@ -65,6 +66,8 @@ async def test_next_warning_when_data_available(
|
||||||
mock_config_entry: MockConfigEntry
|
mock_config_entry: MockConfigEntry
|
||||||
) -> None:
|
) -> None:
|
||||||
api_data = get_api_data("be_forecast_warning.json")
|
api_data = get_api_data("be_forecast_warning.json")
|
||||||
|
mock_config_entry.data = {CONF_LANGUAGE_OVERRIDE: 'de'}
|
||||||
|
|
||||||
coordinator = IrmKmiCoordinator(hass, mock_config_entry)
|
coordinator = IrmKmiCoordinator(hass, mock_config_entry)
|
||||||
|
|
||||||
result = coordinator.warnings_from_data(api_data.get('for', {}).get('warning'))
|
result = coordinator.warnings_from_data(api_data.get('for', {}).get('warning'))
|
||||||
|
@ -76,7 +79,7 @@ async def test_next_warning_when_data_available(
|
||||||
assert warning.state == "2024-01-12T06:00:00+00:00"
|
assert warning.state == "2024-01-12T06:00:00+00:00"
|
||||||
assert len(warning.extra_state_attributes['next_warnings']) == 2
|
assert len(warning.extra_state_attributes['next_warnings']) == 2
|
||||||
|
|
||||||
assert warning.extra_state_attributes['next_warnings_friendly_names'] == "Fog, Ice or snow"
|
assert warning.extra_state_attributes['next_warnings_friendly_names'] == "Nebel, Glätte"
|
||||||
|
|
||||||
|
|
||||||
@freeze_time(datetime.fromisoformat('2024-01-12T07:30:00+01:00'))
|
@freeze_time(datetime.fromisoformat('2024-01-12T07:30:00+01:00'))
|
||||||
|
|
Loading…
Add table
Reference in a new issue