modified: app.py
modified: static/css/style.css modified: templates/weather.html
This commit is contained in:
69
app.py
69
app.py
@@ -73,6 +73,20 @@ MOSMIX_PARAMS = [
|
||||
"hourly/large/uv_index",
|
||||
]
|
||||
|
||||
# ── Wetter-Icons (OpenWeatherMap CDN) ────────────────────────────────────────
|
||||
_OWM = "https://openweathermap.org/img/wn/"
|
||||
ICON_URLS = {
|
||||
"☀️": _OWM + "01d@2x.png", # klar
|
||||
"⛅": _OWM + "02d@2x.png", # leicht bewölkt
|
||||
"☁️": _OWM + "04d@2x.png", # bedeckt
|
||||
"🌧️": _OWM + "10d@2x.png", # Regen
|
||||
"🌦️": _OWM + "09d@2x.png", # Regenschauer
|
||||
"❄️": _OWM + "13d@2x.png", # Schnee
|
||||
}
|
||||
|
||||
def _icon_url(emoji):
|
||||
return ICON_URLS.get(str(emoji), _OWM + "03d@2x.png")
|
||||
|
||||
def _get_berlin():
|
||||
try:
|
||||
import zoneinfo
|
||||
@@ -341,41 +355,43 @@ def pick_daily_icon(hours):
|
||||
return "☀️"
|
||||
|
||||
def feels_like(temp_c, wind_kmh, cloud_pct):
|
||||
"""Apparent temperature.
|
||||
"""Apparent / perceived temperature.
|
||||
|
||||
* Below 10 °C with wind > 4.8 km/h: Windchill (JAG/TI formula)
|
||||
* Above 27 °C: Heat index (Rothfusz, assumed RH 60 %)
|
||||
* Otherwise: actual temp ± sunshine/wind adjustments
|
||||
- Wind cools by up to ~3 °C even in the mild range
|
||||
- Sunshine (low clouds, no wind) warms by up to +4 °C
|
||||
Uses the JAG/TI wind-chill formula blended smoothly across the full
|
||||
temperature range so there is no abrupt jump at the old 10 °C threshold.
|
||||
Above 27 °C the Rothfusz heat index (assumed RH 60 %) is applied.
|
||||
|
||||
The previous cloud-based sunshine bonus has been removed: cloud cover
|
||||
fluctuates strongly hour to hour, which caused the felt temperature to
|
||||
jump by several degrees without any real change in conditions.
|
||||
"""
|
||||
if temp_c is None:
|
||||
return None
|
||||
# ── Cold range: wind chill ────────────────────────────────────────
|
||||
if temp_c <= 10 and wind_kmh is not None and wind_kmh > 4.8:
|
||||
v = wind_kmh
|
||||
wc = 13.12 + 0.6215*temp_c - 11.37*(v**0.16) + 0.3965*temp_c*(v**0.16)
|
||||
return round(wc, 1)
|
||||
# ── Hot range: heat index ─────────────────────────────────────────
|
||||
|
||||
# ── Hot range: heat index (Rothfusz, RH 60 %) ────────────────────
|
||||
if temp_c >= 27:
|
||||
rh = 60
|
||||
hi = (-8.78469475556 + 1.61139411*temp_c + 2.33854883889*rh
|
||||
- 0.14611605*temp_c*rh - 0.012308094*temp_c**2
|
||||
- 0.016424828*rh**2 + 0.002211732*temp_c**2*rh
|
||||
+ 0.00072546*temp_c*rh**2 - 0.000003582*temp_c**2*rh**2)
|
||||
hi = (-8.78469475556 + 1.61139411 * temp_c + 2.33854883889 * rh
|
||||
- 0.14611605 * temp_c * rh - 0.012308094 * temp_c ** 2
|
||||
- 0.016424828 * rh ** 2 + 0.002211732 * temp_c ** 2 * rh
|
||||
+ 0.00072546 * temp_c * rh ** 2
|
||||
- 0.000003582 * temp_c ** 2 * rh ** 2)
|
||||
return round(hi, 1)
|
||||
# ── Mild range: sunshine bonus + light wind cooling ───────────────
|
||||
|
||||
# ── Wind-chill (JAG/TI), blended into mild range ──────────────────
|
||||
# Full wind-chill effect at ≤ 5 °C, linearly faded to zero at ≥ 20 °C.
|
||||
# This avoids the hard jump that the old ≤ 10 °C threshold caused.
|
||||
wind = wind_kmh or 0
|
||||
adjusted = float(temp_c)
|
||||
# Sunshine bonus: clear sky (cloud_pct < 30) adds up to +4 °C
|
||||
if cloud_pct is not None and cloud_pct < 30:
|
||||
sunshine_bonus = (30 - cloud_pct) / 30 * 4.0
|
||||
adjusted += sunshine_bonus
|
||||
# Moderate wind cooling: >10 km/h removes up to 3 °C
|
||||
if wind_kmh is not None and wind_kmh > 10:
|
||||
wind_penalty = _clamp((wind_kmh - 10) / 40 * 3.0, 0, 3.0)
|
||||
adjusted -= wind_penalty
|
||||
if wind > 4.8:
|
||||
wc = (13.12
|
||||
+ 0.6215 * temp_c
|
||||
- 11.37 * (wind ** 0.16)
|
||||
+ 0.3965 * temp_c * (wind ** 0.16))
|
||||
blend = _clamp((20.0 - temp_c) / 15.0, 0.0, 1.0)
|
||||
adjusted = temp_c * (1.0 - blend) + wc * blend
|
||||
|
||||
result = round(adjusted, 1)
|
||||
# Only return a value if it meaningfully differs from actual temp
|
||||
return result if abs(result - temp_c) >= 0.5 else temp_c
|
||||
|
||||
def get_sun_times(lat, lon, date=None):
|
||||
@@ -747,6 +763,7 @@ def wetter():
|
||||
chart_precip=chart_precip, chart_rain_prob=chart_rain_prob,
|
||||
wind_dir_name=wind_direction_name,
|
||||
uv_risk_info=uv_risk_info,
|
||||
icon_url=_icon_url,
|
||||
)
|
||||
|
||||
@app.route("/api/suggest")
|
||||
|
||||
Reference in New Issue
Block a user