modified: app.py

modified:   static/css/style.css
	modified:   templates/weather.html
This commit is contained in:
simon
2026-04-22 14:33:00 +02:00
parent 7b3b66c6fc
commit 3294ccf45a
3 changed files with 85 additions and 4 deletions

27
app.py
View File

@@ -193,6 +193,22 @@ def _round_temp(k):
def _clamp(value, min_value, max_value):
return max(min_value, min(max_value, value))
def _estimate_uv(dt_local, lat, cloud_pct):
"""Rough UV index estimate for Central Europe when the MOSMIX station doesn't
provide the UVI parameter. Uses time-of-day, season, latitude, and cloud cover."""
hour = dt_local.hour + dt_local.minute / 60.0
if hour < 5.5 or hour > 20.5:
return 0.0
noon = 13.0 # approximate solar noon in Germany (CET)
hour_factor = max(0.0, math.cos(math.pi * (hour - noon) / 14.0))
# Typical clear-sky peak UV at solar noon for ~51°N, JanDec
monthly_peak = [1.0, 1.8, 3.5, 5.0, 6.5, 7.5, 7.2, 6.2, 4.5, 2.5, 1.2, 0.8]
seasonal = monthly_peak[dt_local.month - 1]
lat_factor = max(0.5, 1.0 - (float(lat) - 51.0) * 0.015)
cloud_factor = 1.0 - (cloud_pct or 0) / 100.0 * 0.75
uv = seasonal * hour_factor * lat_factor * cloud_factor
return round(max(0.0, uv), 1)
def uv_risk_info(uv_index):
if uv_index is None:
return "", "na"
@@ -286,9 +302,9 @@ def temp_trend_info(forecast, step_hours=6):
return None, None
delta = round(t1 - t0, 1)
if delta >= 1.0:
return delta, "waermer"
return delta, "wärmer"
if delta <= -1.0:
return delta, "kaelter"
return delta, "kälter"
return delta, "konstant"
def _parse_warning_datetime(value):
@@ -489,12 +505,15 @@ def get_mosmix_forecast(lat, lon, hours=72):
wd = p.get("wind_direction")
wind_dir = float(wd) if not _isnan(wd) else None
uv_raw = p.get("uv_index")
uv = round(float(uv_raw),1) if not _isnan(uv_raw) else None
dt_local = pd.Timestamp(date_val).tz_convert(berlin).tz_localize(None)
if not _isnan(uv_raw):
uv = round(float(uv_raw), 1)
else:
uv = _estimate_uv(dt_local, lat, clouds)
uv_label, uv_level = uv_risk_info(uv)
feels = feels_like(temp_c, wind_kmh, clouds)
confidence_score, confidence_label = hour_confidence_score(temp_c, precip, rain_prob, wind_kmh, gust_kmh, clouds)
a_score = activity_score(temp_c, precip, rain_prob, wind_kmh, gust_kmh, uv)
dt_local = pd.Timestamp(date_val).tz_convert(berlin).tz_localize(None)
forecast.append({
"datetime": dt_local,
"temp_c": temp_c,