diff --git a/src/plugins/weather/settings.html b/src/plugins/weather/settings.html
index 8e137ef86..82dc4afc6 100644
--- a/src/plugins/weather/settings.html
+++ b/src/plugins/weather/settings.html
@@ -1,6 +1,20 @@
@@ -200,6 +214,12 @@
Select Location
});
if (loadPluginSettings) {
+ const language = document.getElementById('language');
+ const hasConfiguredLanguage = Array.from(language.options).some(
+ (option) => option.value === pluginSettings.language
+ );
+ language.value = hasConfiguredLanguage ? pluginSettings.language : 'en';
+
document.getElementById('latitude').value = pluginSettings.latitude;
document.getElementById('longitude').value = pluginSettings.longitude;
@@ -236,6 +256,7 @@ Select Location
document.getElementById('customTitle').value = pluginSettings.customTitle || '';
} else {
// set default values
+ document.getElementById('language').value = 'en';
document.getElementById('units').value = "imperial";
document.getElementById('displayRefreshTime').checked = true;
document.getElementById('displayRefreshTime').value = "true";
diff --git a/src/plugins/weather/weather.py b/src/plugins/weather/weather.py
index e5d829e83..362a1d999 100644
--- a/src/plugins/weather/weather.py
+++ b/src/plugins/weather/weather.py
@@ -60,6 +60,181 @@ def get_moon_phase_name(phase_age: float) -> str:
"imperial": "temperature_unit=fahrenheit&wind_speed_unit=mph&precipitation_unit=inch"
}
+# Locale data for date/day name translation.
+# days: full weekday names (0=Monday), days_short: abbreviated (0=Monday),
+# months: full month names (0=January).
+# ui: translated UI strings used in the weather template and data points.
+# "en": None uses strftime/English directly.
+LOCALE_DATA = {
+ "de": {
+ "days": ["Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"],
+ "days_short": ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"],
+ "months": ["Januar", "Februar", "März", "April", "Mai", "Juni",
+ "Juli", "August", "September", "Oktober", "November", "Dezember"],
+ "ui": {
+ "last_refresh": "Letzte Aktualisierung",
+ "feels_like": "Gefühlt",
+ "sunrise": "Sonnenaufgang",
+ "sunset": "Sonnenuntergang",
+ "wind": "Wind",
+ "humidity": "Luftfeuchtigkeit",
+ "pressure": "Luftdruck",
+ "uv_index": "UV-Index",
+ "visibility": "Sichtweite",
+ "air_quality": "Luftqualität",
+ "aqi_scale": ["Gut", "Mäßig", "Mittelmäßig", "Schlecht", "Sehr schlecht"],
+ "aqi_scale_om": ["Gut", "Mäßig", "Mittelmäßig", "Schlecht", "Sehr schlecht", "Extrem schlecht"],
+ },
+ },
+ "en": None, # English uses strftime directly
+ "es": {
+ "days": ["Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"],
+ "days_short": ["Lun", "Mar", "Mié", "Jue", "Vie", "Sáb", "Dom"],
+ "months": ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",
+ "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"],
+ "ui": {
+ "last_refresh": "Última actualización",
+ "feels_like": "Sensación",
+ "sunrise": "Amanecer",
+ "sunset": "Atardecer",
+ "wind": "Viento",
+ "humidity": "Humedad",
+ "pressure": "Presión",
+ "uv_index": "Índice UV",
+ "visibility": "Visibilidad",
+ "air_quality": "Calidad aire",
+ "aqi_scale": ["Buena", "Aceptable", "Moderada", "Mala", "Muy mala"],
+ "aqi_scale_om": ["Buena", "Aceptable", "Moderada", "Mala", "Muy mala", "Extrema"],
+ },
+ },
+ "fr": {
+ "days": ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"],
+ "days_short": ["Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"],
+ "months": ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin",
+ "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"],
+ "ui": {
+ "last_refresh": "Dernière mise à jour",
+ "feels_like": "Ressenti",
+ "sunrise": "Lever du soleil",
+ "sunset": "Coucher du soleil",
+ "wind": "Vent",
+ "humidity": "Humidité",
+ "pressure": "Pression",
+ "uv_index": "Indice UV",
+ "visibility": "Visibilité",
+ "air_quality": "Qualité de l'air",
+ "aqi_scale": ["Bonne", "Correcte", "Moyenne", "Mauvaise", "Très mauvaise"],
+ "aqi_scale_om": ["Bonne", "Correcte", "Moyenne", "Mauvaise", "Très mauvaise", "Extrêmement mauvaise"],
+ },
+ },
+ "id": {
+ "days": ["Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu", "Minggu"],
+ "days_short": ["Sen", "Sel", "Rab", "Kam", "Jum", "Sab", "Min"],
+ "months": ["Januari", "Februari", "Maret", "April", "Mei", "Juni",
+ "Juli", "Agustus", "September", "Oktober", "November", "Desember"],
+ "ui": {
+ "last_refresh": "Pembaruan terakhir",
+ "feels_like": "Terasa",
+ "sunrise": "Matahari terbit",
+ "sunset": "Matahari terbenam",
+ "wind": "Angin",
+ "humidity": "Kelembaban",
+ "pressure": "Tekanan",
+ "uv_index": "Indeks UV",
+ "visibility": "Jarak pandang",
+ "air_quality": "Kualitas udara",
+ "aqi_scale": ["Baik", "Sedang", "Buruk ringan", "Buruk", "Sangat buruk"],
+ "aqi_scale_om": ["Baik", "Sedang", "Buruk ringan", "Buruk", "Sangat buruk", "Berbahaya"],
+ },
+ },
+ "it": {
+ "days": ["Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato", "Domenica"],
+ "days_short": ["Lun", "Mar", "Mer", "Gio", "Ven", "Sab", "Dom"],
+ "months": ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno",
+ "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"],
+ "ui": {
+ "last_refresh": "Ultimo aggiornamento",
+ "feels_like": "Percepita",
+ "sunrise": "Alba",
+ "sunset": "Tramonto",
+ "wind": "Vento",
+ "humidity": "Umidità",
+ "pressure": "Pressione",
+ "uv_index": "Indice UV",
+ "visibility": "Visibilità",
+ "air_quality": "Qualità aria",
+ "aqi_scale": ["Buona", "Discreta", "Moderata", "Scarsa", "Pessima"],
+ "aqi_scale_om": ["Buona", "Discreta", "Moderata", "Scarsa", "Pessima", "Pericolosa"],
+ },
+ },
+ "nl": {
+ "days": ["Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag", "Zondag"],
+ "days_short": ["Ma", "Di", "Wo", "Do", "Vr", "Za", "Zo"],
+ "months": ["Januari", "Februari", "Maart", "April", "Mei", "Juni",
+ "Juli", "Augustus", "September", "Oktober", "November", "December"],
+ "ui": {
+ "last_refresh": "Laatste verversing",
+ "feels_like": "Voelt als",
+ "sunrise": "Zonsopgang",
+ "sunset": "Zonsondergang",
+ "wind": "Wind",
+ "humidity": "Vochtigheid",
+ "pressure": "Luchtdruk",
+ "uv_index": "UV-index",
+ "visibility": "Zichtbaarheid",
+ "air_quality": "Luchtkwaliteit",
+ "aqi_scale": ["Goed", "Matig", "Onvoldoende", "Slecht", "Zeer slecht"],
+ "aqi_scale_om": ["Goed", "Matig", "Onvoldoende", "Slecht", "Zeer slecht", "Gevaarlijk"],
+ },
+ },
+ "pt": {
+ "days": ["Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado", "Domingo"],
+ "days_short": ["Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom"],
+ "months": ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho",
+ "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"],
+ "ui": {
+ "last_refresh": "Última atualização",
+ "feels_like": "Sensação",
+ "sunrise": "Nascer do sol",
+ "sunset": "Pôr do sol",
+ "wind": "Vento",
+ "humidity": "Umidade",
+ "pressure": "Pressão",
+ "uv_index": "Índice UV",
+ "visibility": "Visibilidade",
+ "air_quality": "Qualidade ar",
+ "aqi_scale": ["Boa", "Razoável", "Moderada", "Ruim", "Muito ruim"],
+ "aqi_scale_om": ["Boa", "Razoável", "Moderada", "Ruim", "Muito ruim", "Péssima"],
+ },
+ },
+}
+
+
+def get_localized_date(dt, language):
+ """Return a localized date string equivalent to strftime('%A, %B %d')."""
+ locale = LOCALE_DATA.get(language)
+ if locale:
+ day_name = locale["days"][dt.weekday()]
+ month_name = locale["months"][dt.month - 1]
+ return f"{day_name}, {month_name} {dt.day:02d}"
+ return dt.strftime("%A, %B %d")
+
+
+def get_localized_day_short(dt, language):
+ """Return a localized abbreviated weekday name equivalent to strftime('%a')."""
+ locale = LOCALE_DATA.get(language)
+ if locale:
+ return locale["days_short"][dt.weekday()]
+ return dt.strftime("%a")
+
+
+def get_ui_label(key, language, default=None):
+ """Return a translated UI string for the given key and language."""
+ locale = LOCALE_DATA.get(language)
+ if locale and "ui" in locale:
+ return locale["ui"].get(key, default or key)
+ return default or key
+
class Weather(BasePlugin):
def generate_settings_template(self):
template_params = super().generate_settings_template()
@@ -83,6 +258,9 @@ def generate_image(self, settings, device_config):
weather_provider = settings.get('weatherProvider', 'OpenWeatherMap')
title = settings.get('customTitle', '')
+ language = settings.get('language', 'en')
+ if language not in LOCALE_DATA:
+ language = 'en'
timezone = device_config.get_config("timezone", default="America/New_York")
time_format = device_config.get_config("time_format", default="12h")
@@ -100,15 +278,15 @@ def generate_image(self, settings, device_config):
if settings.get('weatherTimeZone', 'locationTimeZone') == 'locationTimeZone':
logger.info("Using location timezone for OpenWeatherMap data.")
wtz = self.parse_timezone(weather_data)
- template_params = self.parse_weather_data(weather_data, aqi_data, wtz, units, time_format, lat)
+ template_params = self.parse_weather_data(weather_data, aqi_data, wtz, units, time_format, lat, language)
else:
logger.info("Using configured timezone for OpenWeatherMap data.")
- template_params = self.parse_weather_data(weather_data, aqi_data, tz, units, time_format, lat)
+ template_params = self.parse_weather_data(weather_data, aqi_data, tz, units, time_format, lat, language)
elif weather_provider == "OpenMeteo":
forecast_days = 7
weather_data = self.get_open_meteo_data(lat, long, units, forecast_days + 1)
aqi_data = self.get_open_meteo_air_quality(lat, long)
- template_params = self.parse_open_meteo_data(weather_data, aqi_data, tz, units, time_format, lat)
+ template_params = self.parse_open_meteo_data(weather_data, aqi_data, tz, units, time_format, lat, language)
else:
raise RuntimeError(f"Unknown weather provider: {weather_provider}")
@@ -137,7 +315,7 @@ def generate_image(self, settings, device_config):
raise RuntimeError("Failed to take screenshot, please check logs.")
return image
- def parse_weather_data(self, weather_data, aqi_data, tz, units, time_format, lat):
+ def parse_weather_data(self, weather_data, aqi_data, tz, units, time_format, lat, language="en"):
current = weather_data.get("current")
daily_forecast = weather_data.get("daily", [])
dt = datetime.fromtimestamp(current.get('dt'), tz=timezone.utc).astimezone(tz)
@@ -150,7 +328,7 @@ def parse_weather_data(self, weather_data, aqi_data, tz, units, time_format, lat
if current_icon.endswith('n'):
current_icon = current_icon.replace("n", "d")
data = {
- "current_date": dt.strftime("%A, %B %d"),
+ "current_date": get_localized_date(dt, language),
"current_day_icon": self.get_plugin_dir(f'icons/{current_icon}.png'),
"current_temperature": str(round(current.get("temp"))),
"feels_like": str(round(current.get("feels_like"))),
@@ -158,13 +336,15 @@ def parse_weather_data(self, weather_data, aqi_data, tz, units, time_format, lat
"units": units,
"time_format": time_format
}
- data['forecast'] = self.parse_forecast(weather_data.get('daily'), tz, current_suffix, lat)
- data['data_points'] = self.parse_data_points(weather_data, aqi_data, tz, units, time_format)
+ data['forecast'] = self.parse_forecast(weather_data.get('daily'), tz, current_suffix, lat, language)
+ data['data_points'] = self.parse_data_points(weather_data, aqi_data, tz, units, time_format, language)
+ data['feels_like_label'] = get_ui_label('feels_like', language, 'Feels Like')
+ data['last_refresh_label'] = get_ui_label('last_refresh', language, 'Last refresh')
data['hourly_forecast'] = self.parse_hourly(weather_data.get('hourly'), tz, time_format, units, daily_forecast)
return data
- def parse_open_meteo_data(self, weather_data, aqi_data, tz, units, time_format, lat):
+ def parse_open_meteo_data(self, weather_data, aqi_data, tz, units, time_format, lat, language="en"):
current = weather_data.get("current", {})
daily = weather_data.get('daily', {})
dt = datetime.fromisoformat(current.get('time')).astimezone(tz) if current.get('time') else datetime.now(tz)
@@ -175,7 +355,7 @@ def parse_open_meteo_data(self, weather_data, aqi_data, tz, units, time_format,
temperature_conversion = 273.15 if units == "standard" else 0.
data = {
- "current_date": dt.strftime("%A, %B %d"),
+ "current_date": get_localized_date(dt, language),
"current_day_icon": self.get_plugin_dir(f'icons/{current_icon}.png'),
"current_temperature": str(round(current.get("temperature", 0) + temperature_conversion)),
"feels_like": str(round(current.get("apparent_temperature", current.get("temperature", 0)) + temperature_conversion)),
@@ -184,8 +364,10 @@ def parse_open_meteo_data(self, weather_data, aqi_data, tz, units, time_format,
"time_format": time_format
}
- data['forecast'] = self.parse_open_meteo_forecast(weather_data.get('daily', {}), units, tz, is_day, lat)
- data['data_points'] = self.parse_open_meteo_data_points(weather_data, aqi_data, units, tz, time_format)
+ data['forecast'] = self.parse_open_meteo_forecast(weather_data.get('daily', {}), units, tz, is_day, lat, language)
+ data['data_points'] = self.parse_open_meteo_data_points(weather_data, aqi_data, units, tz, time_format, language)
+ data['feels_like_label'] = get_ui_label('feels_like', language, 'Feels Like')
+ data['last_refresh_label'] = get_ui_label('last_refresh', language, 'Last refresh')
data['hourly_forecast'] = self.parse_open_meteo_hourly(weather_data.get('hourly', {}), units, tz, time_format, daily.get('sunrise', []), daily.get('sunset', []))
return data
@@ -260,7 +442,7 @@ def get_moon_phase_icon_path(self, phase_name: str, lat: float) -> str:
return self.get_plugin_dir(f"icons/{phase_name}.png")
- def parse_forecast(self, daily_forecast, tz, current_suffix, lat):
+ def parse_forecast(self, daily_forecast, tz, current_suffix, lat, language="en"):
"""
- daily_forecast: list of daily entries from One‑Call v3 (each has 'dt', 'weather', 'temp', 'moon_phase')
- tz: your target tzinfo (e.g. from zoneinfo or pytz)
@@ -311,7 +493,7 @@ def choose_phase_name(phase: float) -> str:
# --- date & temps ---
dt = datetime.fromtimestamp(day["dt"], tz=timezone.utc).astimezone(tz)
- day_label = dt.strftime("%a")
+ day_label = get_localized_day_short(dt, language)
forecast.append(
{
@@ -326,7 +508,7 @@ def choose_phase_name(phase: float) -> str:
return forecast
- def parse_open_meteo_forecast(self, daily_data, units, tz, is_day, lat):
+ def parse_open_meteo_forecast(self, daily_data, units, tz, is_day, lat, language="en"):
"""
Parse the daily forecast from Open-Meteo API and calculate moon phase and illumination using the local 'astral' library.
"""
@@ -342,7 +524,7 @@ def parse_open_meteo_forecast(self, daily_data, units, tz, is_day, lat):
for i in range(0, len(times)):
dt = datetime.fromisoformat(times[i]).replace(tzinfo=timezone.utc).astimezone(tz)
- day_label = dt.strftime("%a")
+ day_label = get_localized_day_short(dt, language)
code = weather_codes[i] if i < len(weather_codes) else 0
weather_icon = self.map_weather_code_to_icon(code, is_day=1)
@@ -466,14 +648,15 @@ def parse_open_meteo_hourly(self, hourly_data, units, tz, time_format, sunrises,
hourly.append(hour_forecast)
return hourly
- def parse_data_points(self, weather, air_quality, tz, units, time_format):
+ def parse_data_points(self, weather, air_quality, tz, units, time_format, language="en"):
data_points = []
sunrise_epoch = weather.get('current', {}).get("sunrise")
if sunrise_epoch:
sunrise_dt = datetime.fromtimestamp(sunrise_epoch, tz=timezone.utc).astimezone(tz)
data_points.append({
- "label": "Sunrise",
+ "key": "Sunrise",
+ "label": get_ui_label("sunrise", language, "Sunrise"),
"measurement": self.format_time(sunrise_dt, time_format, include_am_pm=False),
"unit": "" if time_format == "24h" else sunrise_dt.strftime('%p'),
"icon": self.get_plugin_dir('icons/sunrise.png')
@@ -485,7 +668,8 @@ def parse_data_points(self, weather, air_quality, tz, units, time_format):
if sunset_epoch:
sunset_dt = datetime.fromtimestamp(sunset_epoch, tz=timezone.utc).astimezone(tz)
data_points.append({
- "label": "Sunset",
+ "key": "Sunset",
+ "label": get_ui_label("sunset", language, "Sunset"),
"measurement": self.format_time(sunset_dt, time_format, include_am_pm=False),
"unit": "" if time_format == "24h" else sunset_dt.strftime('%p'),
"icon": self.get_plugin_dir('icons/sunset.png')
@@ -496,7 +680,8 @@ def parse_data_points(self, weather, air_quality, tz, units, time_format):
wind_deg = weather.get('current', {}).get("wind_deg", 0)
wind_arrow = self.get_wind_arrow(wind_deg)
data_points.append({
- "label": "Wind",
+ "key": "Wind",
+ "label": get_ui_label("wind", language, "Wind"),
"measurement": weather.get('current', {}).get("wind_speed"),
"unit": UNITS[units]["speed"],
"icon": self.get_plugin_dir('icons/wind.png'),
@@ -504,21 +689,24 @@ def parse_data_points(self, weather, air_quality, tz, units, time_format):
})
data_points.append({
- "label": "Humidity",
+ "key": "Humidity",
+ "label": get_ui_label("humidity", language, "Humidity"),
"measurement": weather.get('current', {}).get("humidity"),
"unit": '%',
"icon": self.get_plugin_dir('icons/humidity.png')
})
data_points.append({
- "label": "Pressure",
+ "key": "Pressure",
+ "label": get_ui_label("pressure", language, "Pressure"),
"measurement": weather.get('current', {}).get("pressure"),
"unit": 'hPa',
"icon": self.get_plugin_dir('icons/pressure.png')
})
data_points.append({
- "label": "UV Index",
+ "key": "UV Index",
+ "label": get_ui_label("uv_index", language, "UV Index"),
"measurement": weather.get('current', {}).get("uvi"),
"unit": '',
"icon": self.get_plugin_dir('icons/uvi.png')
@@ -537,23 +725,27 @@ def parse_data_points(self, weather, air_quality, tz, units, time_format):
if at_max_visibility:
visibility_str = u"\u2265" + visibility_str
data_points.append({
- "label": "Visibility",
+ "key": "Visibility",
+ "label": get_ui_label("visibility", language, "Visibility"),
"measurement": visibility_str,
"unit": UNITS[units]["distance"],
"icon": self.get_plugin_dir('icons/visibility.png')
})
- aqi = air_quality.get('list', [])[0].get("main", {}).get("aqi")
+ aqi = (air_quality.get('list') or [{}])[0].get("main", {}).get("aqi")
+ locale = LOCALE_DATA.get(language)
+ aqi_scale = locale["ui"]["aqi_scale"] if locale and "ui" in locale else ["Good", "Fair", "Moderate", "Poor", "Very Poor"]
data_points.append({
- "label": "Air Quality",
+ "key": "Air Quality",
+ "label": get_ui_label("air_quality", language, "Air Quality"),
"measurement": aqi,
- "unit": ["Good", "Fair", "Moderate", "Poor", "Very Poor"][int(aqi)-1],
+ "unit": aqi_scale[int(aqi)-1] if (aqi is not None and str(aqi).isdigit() and 1 <= int(aqi) <= len(aqi_scale)) else "N/A",
"icon": self.get_plugin_dir('icons/aqi.png')
})
return data_points
- def parse_open_meteo_data_points(self, weather_data, aqi_data, units, tz, time_format):
+ def parse_open_meteo_data_points(self, weather_data, aqi_data, units, tz, time_format, language="en"):
"""Parses current data points from Open-Meteo API response."""
data_points = []
daily_data = weather_data.get('daily', {})
@@ -567,7 +759,8 @@ def parse_open_meteo_data_points(self, weather_data, aqi_data, units, tz, time_f
if sunrise_times:
sunrise_dt = datetime.fromisoformat(sunrise_times[0]).astimezone(tz)
data_points.append({
- "label": "Sunrise",
+ "key": "Sunrise",
+ "label": get_ui_label("sunrise", language, "Sunrise"),
"measurement": self.format_time(sunrise_dt, time_format, include_am_pm=False),
"unit": "" if time_format == "24h" else sunrise_dt.strftime('%p'),
"icon": self.get_plugin_dir('icons/sunrise.png')
@@ -580,7 +773,8 @@ def parse_open_meteo_data_points(self, weather_data, aqi_data, units, tz, time_f
if sunset_times:
sunset_dt = datetime.fromisoformat(sunset_times[0]).astimezone(tz)
data_points.append({
- "label": "Sunset",
+ "key": "Sunset",
+ "label": get_ui_label("sunset", language, "Sunset"),
"measurement": self.format_time(sunset_dt, time_format, include_am_pm=False),
"unit": "" if time_format == "24h" else sunset_dt.strftime('%p'),
"icon": self.get_plugin_dir('icons/sunset.png')
@@ -594,7 +788,8 @@ def parse_open_meteo_data_points(self, weather_data, aqi_data, units, tz, time_f
wind_arrow = self.get_wind_arrow(wind_deg)
wind_unit = UNITS[units]["speed"]
data_points.append({
- "label": "Wind", "measurement": wind_speed, "unit": wind_unit,
+ "key": "Wind", "label": get_ui_label("wind", language, "Wind"),
+ "measurement": wind_speed, "unit": wind_unit,
"icon": self.get_plugin_dir('icons/wind.png'), "arrow": wind_arrow
})
@@ -611,7 +806,8 @@ def parse_open_meteo_data_points(self, weather_data, aqi_data, units, tz, time_f
logger.warning(f"Could not parse time string {time_str} for humidity.")
continue
data_points.append({
- "label": "Humidity", "measurement": current_humidity, "unit": '%',
+ "key": "Humidity", "label": get_ui_label("humidity", language, "Humidity"),
+ "measurement": current_humidity, "unit": '%',
"icon": self.get_plugin_dir('icons/humidity.png')
})
@@ -628,7 +824,8 @@ def parse_open_meteo_data_points(self, weather_data, aqi_data, units, tz, time_f
logger.warning(f"Could not parse time string {time_str} for pressure.")
continue
data_points.append({
- "label": "Pressure", "measurement": current_pressure, "unit": 'hPa',
+ "key": "Pressure", "label": get_ui_label("pressure", language, "Pressure"),
+ "measurement": current_pressure, "unit": 'hPa',
"icon": self.get_plugin_dir('icons/pressure.png')
})
@@ -645,12 +842,14 @@ def parse_open_meteo_data_points(self, weather_data, aqi_data, units, tz, time_f
logger.warning(f"Could not parse time string {time_str} for UV Index.")
continue
data_points.append({
- "label": "UV Index", "measurement": current_uv_index, "unit": '',
+ "key": "UV Index", "label": get_ui_label("uv_index", language, "UV Index"),
+ "measurement": current_uv_index, "unit": '',
"icon": self.get_plugin_dir('icons/uvi.png')
})
# Visibility
- current_visibility = "N/A"
+ current_visibility = None
+ at_max_visibility = False
visibility_hourly_times = hourly_data.get('time', [])
visibility_values = hourly_data.get('visibility', [])
if units == "imperial":
@@ -668,11 +867,15 @@ def parse_open_meteo_data_points(self, weather_data, aqi_data, units, tz, time_f
except ValueError:
logger.warning(f"Could not parse time string {time_str} for visibility.")
continue
- visibility_str = f"{current_visibility:.1f}"
- if at_max_visibility:
- visibility_str = u"\u2265" + visibility_str
+ if current_visibility is None:
+ visibility_str = "N/A"
+ else:
+ visibility_str = f"{current_visibility:.1f}"
+ if at_max_visibility:
+ visibility_str = u"\u2265" + visibility_str
data_points.append({
- "label": "Visibility",
+ "key": "Visibility",
+ "label": get_ui_label("visibility", language, "Visibility"),
"measurement": visibility_str,
"unit": UNITS[units]["distance"],
"icon": self.get_plugin_dir('icons/visibility.png')
@@ -692,9 +895,12 @@ def parse_open_meteo_data_points(self, weather_data, aqi_data, units, tz, time_f
continue
scale = ""
if current_aqi and current_aqi != "N/A":
- scale = ["Good","Fair","Moderate","Poor","Very Poor","Ext Poor"][min(current_aqi//20,5)]
+ locale = LOCALE_DATA.get(language)
+ aqi_scale_om = locale["ui"]["aqi_scale_om"] if locale and "ui" in locale else ["Good","Fair","Moderate","Poor","Very Poor","Ext Poor"]
+ scale = aqi_scale_om[min(int(current_aqi)//20, 5)]
data_points.append({
- "label": "Air Quality", "measurement": current_aqi,
+ "key": "Air Quality", "label": get_ui_label("air_quality", language, "Air Quality"),
+ "measurement": current_aqi,
"unit": scale, "icon": self.get_plugin_dir('icons/aqi.png')
})