Feature: User-Feedback, Regen-Uhrzeit im Wetter-Chip, Admin-Karten klickbar (SW by-v833)
- Feedback-Modal im Settings (Kategorie + Text → E-Mail an support@banyaro.app) - Wetter-Chip (Karte + Gassi-Score): zeigt nächste Regenstunde ab ≥20% Wahrscheinlichkeit - Gassi-Score-Chip: zweizeilige Wetter-Info, linksbündig, volle Chipbreite - Admin-Übersicht: Stat-Karten anklickbar → navigiert direkt zum jeweiligen Tab - ui.js: visualViewport-Listener hebt Modal über Tastatur (alle Modals) - api.js: Pydantic v2 Array-Detail korrekt als Fehlermeldung extrahiert - map.js: Wetter-Fallback über watchPosition wenn getCurrentPosition scheitert - Update-Loop-Fix: index.html ?v= synchron mit APP_VER halten (alle 4 Stellen)
This commit is contained in:
parent
d18c592ef0
commit
70af387147
12 changed files with 211 additions and 42 deletions
|
|
@ -58,6 +58,7 @@ async def get_weather_for_location(lat: float, lon: float) -> dict:
|
|||
f"?latitude={lat}&longitude={lon}"
|
||||
"¤t=temperature_2m,apparent_temperature,weathercode,windspeed_10m,is_day"
|
||||
"&daily=precipitation_probability_max,uv_index_max"
|
||||
"&hourly=precipitation_probability"
|
||||
"&timezone=Europe%2FBerlin&forecast_days=1"
|
||||
)
|
||||
async with httpx.AsyncClient(timeout=8.0) as client:
|
||||
|
|
@ -65,8 +66,9 @@ async def get_weather_for_location(lat: float, lon: float) -> dict:
|
|||
resp.raise_for_status()
|
||||
raw = resp.json()
|
||||
|
||||
cur = raw.get('current', {})
|
||||
daily = raw.get('daily', {})
|
||||
cur = raw.get('current', {})
|
||||
daily = raw.get('daily', {})
|
||||
hourly = raw.get('hourly', {})
|
||||
|
||||
temp = cur.get('temperature_2m')
|
||||
feels_like = cur.get('apparent_temperature')
|
||||
|
|
@ -85,17 +87,36 @@ async def get_weather_for_location(lat: float, lon: float) -> dict:
|
|||
if temp is not None and temp > 7.0 and 3 <= month <= 10:
|
||||
zecken = 'hoch' if temp > 20 else ('mittel' if temp > 12 else 'niedrig')
|
||||
|
||||
# Nächste Regenstunde: erstes stündliches Fenster (jetzt+1h bis +12h) mit ≥60% Niederschlag
|
||||
next_rain_time = None
|
||||
already_raining = wcode >= 51
|
||||
if not already_raining:
|
||||
now_h = datetime.now().hour
|
||||
h_times = hourly.get('time', [])
|
||||
h_precip = hourly.get('precipitation_probability', [])
|
||||
for t, p in zip(h_times, h_precip):
|
||||
try:
|
||||
entry_h = int(t[11:13])
|
||||
except Exception:
|
||||
continue
|
||||
if entry_h <= now_h or entry_h > now_h + 12:
|
||||
continue
|
||||
if p is not None and p >= 20:
|
||||
next_rain_time = f"{entry_h:02d}:00"
|
||||
break
|
||||
|
||||
data = {
|
||||
'temp_c': temp,
|
||||
'feels_like_c': feels_like,
|
||||
'weathercode': wcode,
|
||||
'desc': desc,
|
||||
'icon': icon,
|
||||
'wind_kmh': wind,
|
||||
'precip_prob': precip,
|
||||
'uv_index': uv,
|
||||
'is_day': bool(is_day),
|
||||
'zecken_warnung': zecken,
|
||||
'temp_c': temp,
|
||||
'feels_like_c': feels_like,
|
||||
'weathercode': wcode,
|
||||
'desc': desc,
|
||||
'icon': icon,
|
||||
'wind_kmh': wind,
|
||||
'precip_prob': precip,
|
||||
'uv_index': uv,
|
||||
'is_day': bool(is_day),
|
||||
'zecken_warnung': zecken,
|
||||
'next_rain_time': next_rain_time,
|
||||
}
|
||||
_location_cache[key] = (now, data)
|
||||
return data
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue