@@ -64,6 +64,181 @@ def get_moon_phase_name(phase_age: float) -> str:
6464 "imperial" : "temperature_unit=fahrenheit&wind_speed_unit=mph&precipitation_unit=inch"
6565}
6666
67+ # Locale data for date/day name translation.
68+ # days: full weekday names (0=Monday), days_short: abbreviated (0=Monday),
69+ # months: full month names (0=January).
70+ # ui: translated UI strings used in the weather template and data points.
71+ # "en": None uses strftime/English directly.
72+ LOCALE_DATA = {
73+ "de" : {
74+ "days" : ["Montag" , "Dienstag" , "Mittwoch" , "Donnerstag" , "Freitag" , "Samstag" , "Sonntag" ],
75+ "days_short" : ["Mo" , "Di" , "Mi" , "Do" , "Fr" , "Sa" , "So" ],
76+ "months" : ["Januar" , "Februar" , "März" , "April" , "Mai" , "Juni" ,
77+ "Juli" , "August" , "September" , "Oktober" , "November" , "Dezember" ],
78+ "ui" : {
79+ "last_refresh" : "Letzte Aktualisierung" ,
80+ "feels_like" : "Gefühlt" ,
81+ "sunrise" : "Sonnenaufgang" ,
82+ "sunset" : "Sonnenuntergang" ,
83+ "wind" : "Wind" ,
84+ "humidity" : "Luftfeuchtigkeit" ,
85+ "pressure" : "Luftdruck" ,
86+ "uv_index" : "UV-Index" ,
87+ "visibility" : "Sichtweite" ,
88+ "air_quality" : "Luftqualität" ,
89+ "aqi_scale" : ["Gut" , "Mäßig" , "Mittelmäßig" , "Schlecht" , "Sehr schlecht" ],
90+ "aqi_scale_om" : ["Gut" , "Mäßig" , "Mittelmäßig" , "Schlecht" , "Sehr schlecht" , "Extrem schlecht" ],
91+ },
92+ },
93+ "en" : None , # English uses strftime directly
94+ "es" : {
95+ "days" : ["Lunes" , "Martes" , "Miércoles" , "Jueves" , "Viernes" , "Sábado" , "Domingo" ],
96+ "days_short" : ["Lun" , "Mar" , "Mié" , "Jue" , "Vie" , "Sáb" , "Dom" ],
97+ "months" : ["Enero" , "Febrero" , "Marzo" , "Abril" , "Mayo" , "Junio" ,
98+ "Julio" , "Agosto" , "Septiembre" , "Octubre" , "Noviembre" , "Diciembre" ],
99+ "ui" : {
100+ "last_refresh" : "Última actualización" ,
101+ "feels_like" : "Sensación" ,
102+ "sunrise" : "Amanecer" ,
103+ "sunset" : "Atardecer" ,
104+ "wind" : "Viento" ,
105+ "humidity" : "Humedad" ,
106+ "pressure" : "Presión" ,
107+ "uv_index" : "Índice UV" ,
108+ "visibility" : "Visibilidad" ,
109+ "air_quality" : "Calidad aire" ,
110+ "aqi_scale" : ["Buena" , "Aceptable" , "Moderada" , "Mala" , "Muy mala" ],
111+ "aqi_scale_om" : ["Buena" , "Aceptable" , "Moderada" , "Mala" , "Muy mala" , "Extrema" ],
112+ },
113+ },
114+ "fr" : {
115+ "days" : ["Lundi" , "Mardi" , "Mercredi" , "Jeudi" , "Vendredi" , "Samedi" , "Dimanche" ],
116+ "days_short" : ["Lun" , "Mar" , "Mer" , "Jeu" , "Ven" , "Sam" , "Dim" ],
117+ "months" : ["Janvier" , "Février" , "Mars" , "Avril" , "Mai" , "Juin" ,
118+ "Juillet" , "Août" , "Septembre" , "Octobre" , "Novembre" , "Décembre" ],
119+ "ui" : {
120+ "last_refresh" : "Dernière mise à jour" ,
121+ "feels_like" : "Ressenti" ,
122+ "sunrise" : "Lever du soleil" ,
123+ "sunset" : "Coucher du soleil" ,
124+ "wind" : "Vent" ,
125+ "humidity" : "Humidité" ,
126+ "pressure" : "Pression" ,
127+ "uv_index" : "Indice UV" ,
128+ "visibility" : "Visibilité" ,
129+ "air_quality" : "Qualité de l'air" ,
130+ "aqi_scale" : ["Bonne" , "Correcte" , "Moyenne" , "Mauvaise" , "Très mauvaise" ],
131+ "aqi_scale_om" : ["Bonne" , "Correcte" , "Moyenne" , "Mauvaise" , "Très mauvaise" , "Extrêmement mauvaise" ],
132+ },
133+ },
134+ "id" : {
135+ "days" : ["Senin" , "Selasa" , "Rabu" , "Kamis" , "Jumat" , "Sabtu" , "Minggu" ],
136+ "days_short" : ["Sen" , "Sel" , "Rab" , "Kam" , "Jum" , "Sab" , "Min" ],
137+ "months" : ["Januari" , "Februari" , "Maret" , "April" , "Mei" , "Juni" ,
138+ "Juli" , "Agustus" , "September" , "Oktober" , "November" , "Desember" ],
139+ "ui" : {
140+ "last_refresh" : "Pembaruan terakhir" ,
141+ "feels_like" : "Terasa" ,
142+ "sunrise" : "Matahari terbit" ,
143+ "sunset" : "Matahari terbenam" ,
144+ "wind" : "Angin" ,
145+ "humidity" : "Kelembaban" ,
146+ "pressure" : "Tekanan" ,
147+ "uv_index" : "Indeks UV" ,
148+ "visibility" : "Jarak pandang" ,
149+ "air_quality" : "Kualitas udara" ,
150+ "aqi_scale" : ["Baik" , "Sedang" , "Buruk ringan" , "Buruk" , "Sangat buruk" ],
151+ "aqi_scale_om" : ["Baik" , "Sedang" , "Buruk ringan" , "Buruk" , "Sangat buruk" , "Berbahaya" ],
152+ },
153+ },
154+ "it" : {
155+ "days" : ["Lunedì" , "Martedì" , "Mercoledì" , "Giovedì" , "Venerdì" , "Sabato" , "Domenica" ],
156+ "days_short" : ["Lun" , "Mar" , "Mer" , "Gio" , "Ven" , "Sab" , "Dom" ],
157+ "months" : ["Gennaio" , "Febbraio" , "Marzo" , "Aprile" , "Maggio" , "Giugno" ,
158+ "Luglio" , "Agosto" , "Settembre" , "Ottobre" , "Novembre" , "Dicembre" ],
159+ "ui" : {
160+ "last_refresh" : "Ultimo aggiornamento" ,
161+ "feels_like" : "Percepita" ,
162+ "sunrise" : "Alba" ,
163+ "sunset" : "Tramonto" ,
164+ "wind" : "Vento" ,
165+ "humidity" : "Umidità" ,
166+ "pressure" : "Pressione" ,
167+ "uv_index" : "Indice UV" ,
168+ "visibility" : "Visibilità" ,
169+ "air_quality" : "Qualità aria" ,
170+ "aqi_scale" : ["Buona" , "Discreta" , "Moderata" , "Scarsa" , "Pessima" ],
171+ "aqi_scale_om" : ["Buona" , "Discreta" , "Moderata" , "Scarsa" , "Pessima" , "Pericolosa" ],
172+ },
173+ },
174+ "nl" : {
175+ "days" : ["Maandag" , "Dinsdag" , "Woensdag" , "Donderdag" , "Vrijdag" , "Zaterdag" , "Zondag" ],
176+ "days_short" : ["Ma" , "Di" , "Wo" , "Do" , "Vr" , "Za" , "Zo" ],
177+ "months" : ["Januari" , "Februari" , "Maart" , "April" , "Mei" , "Juni" ,
178+ "Juli" , "Augustus" , "September" , "Oktober" , "November" , "December" ],
179+ "ui" : {
180+ "last_refresh" : "Laatste verversing" ,
181+ "feels_like" : "Voelt als" ,
182+ "sunrise" : "Zonsopgang" ,
183+ "sunset" : "Zonsondergang" ,
184+ "wind" : "Wind" ,
185+ "humidity" : "Vochtigheid" ,
186+ "pressure" : "Luchtdruk" ,
187+ "uv_index" : "UV-index" ,
188+ "visibility" : "Zichtbaarheid" ,
189+ "air_quality" : "Luchtkwaliteit" ,
190+ "aqi_scale" : ["Goed" , "Matig" , "Onvoldoende" , "Slecht" , "Zeer slecht" ],
191+ "aqi_scale_om" : ["Goed" , "Matig" , "Onvoldoende" , "Slecht" , "Zeer slecht" , "Gevaarlijk" ],
192+ },
193+ },
194+ "pt" : {
195+ "days" : ["Segunda" , "Terça" , "Quarta" , "Quinta" , "Sexta" , "Sábado" , "Domingo" ],
196+ "days_short" : ["Seg" , "Ter" , "Qua" , "Qui" , "Sex" , "Sáb" , "Dom" ],
197+ "months" : ["Janeiro" , "Fevereiro" , "Março" , "Abril" , "Maio" , "Junho" ,
198+ "Julho" , "Agosto" , "Setembro" , "Outubro" , "Novembro" , "Dezembro" ],
199+ "ui" : {
200+ "last_refresh" : "Última atualização" ,
201+ "feels_like" : "Sensação" ,
202+ "sunrise" : "Nascer do sol" ,
203+ "sunset" : "Pôr do sol" ,
204+ "wind" : "Vento" ,
205+ "humidity" : "Umidade" ,
206+ "pressure" : "Pressão" ,
207+ "uv_index" : "Índice UV" ,
208+ "visibility" : "Visibilidade" ,
209+ "air_quality" : "Qualidade ar" ,
210+ "aqi_scale" : ["Boa" , "Razoável" , "Moderada" , "Ruim" , "Muito ruim" ],
211+ "aqi_scale_om" : ["Boa" , "Razoável" , "Moderada" , "Ruim" , "Muito ruim" , "Péssima" ],
212+ },
213+ },
214+ }
215+
216+
217+ def get_localized_date (dt , language ):
218+ """Return a localized date string equivalent to strftime('%A, %B %d')."""
219+ locale = LOCALE_DATA .get (language )
220+ if locale :
221+ day_name = locale ["days" ][dt .weekday ()]
222+ month_name = locale ["months" ][dt .month - 1 ]
223+ return f"{ day_name } , { month_name } { dt .day :02d} "
224+ return dt .strftime ("%A, %B %d" )
225+
226+
227+ def get_localized_day_short (dt , language ):
228+ """Return a localized abbreviated weekday name equivalent to strftime('%a')."""
229+ locale = LOCALE_DATA .get (language )
230+ if locale :
231+ return locale ["days_short" ][dt .weekday ()]
232+ return dt .strftime ("%a" )
233+
234+
235+ def get_ui_label (key , language , default = None ):
236+ """Return a translated UI string for the given key and language."""
237+ locale = LOCALE_DATA .get (language )
238+ if locale and "ui" in locale :
239+ return locale ["ui" ].get (key , default or key )
240+ return default or key
241+
67242class Weather (BasePlugin ):
68243 def generate_settings_template (self ):
69244 template_params = super ().generate_settings_template ()
@@ -568,7 +743,9 @@ def parse_data_points(self, weather, air_quality, tz, units, time_format, langua
568743 "icon" : self .get_plugin_dir ('icons/visibility.png' )
569744 })
570745
571- aqi = air_quality .get ('list' , [])[0 ].get ("main" , {}).get ("aqi" )
746+ aqi = (air_quality .get ('list' ) or [{}])[0 ].get ("main" , {}).get ("aqi" )
747+ locale = LOCALE_DATA .get (language )
748+ aqi_scale = locale ["ui" ]["aqi_scale" ] if locale and "ui" in locale else ["Good" , "Fair" , "Moderate" , "Poor" , "Very Poor" ]
572749 data_points .append ({
573750 "label" : get_translation (language , "air_quality" ),
574751 "measurement" : aqi ,
0 commit comments