# -*- coding: utf-8 -*- """ Hilfsfunktionen fuer das Weather-Plugin. WMO-Code-Tabelle, Bright-Sky-Condition-Tabelle, TTS-Formatierung und Windrichtungs-Konvertierung. """ from plugins.weather.models import ForecastDay, WeatherData # ========================================================================= # WMO-Wettercode-Tabelle (Open-Meteo) # https://www.noaa.gov/weather/wmo-weather-codes # ========================================================================= WMO_DESCRIPTIONS: dict[int, str] = { 0: "Klarer Himmel", 1: "Ueberwiegend klar", 2: "Teilweise bewoelkt", 3: "Bedeckt", 45: "Nebel", 48: "Gefrierender Nebel", 51: "Leichter Nieselregen", 53: "Maessiger Nieselregen", 55: "Starker Nieselregen", 56: "Leichter gefrierender Nieselregen", 57: "Starker gefrierender Nieselregen", 61: "Leichter Regen", 63: "Maessiger Regen", 65: "Starker Regen", 66: "Leichter gefrierender Regen", 67: "Starker gefrierender Regen", 71: "Leichter Schneefall", 73: "Maessiger Schneefall", 75: "Starker Schneefall", 77: "Schneegriesel", 80: "Leichte Regenschauer", 81: "Maessige Regenschauer", 82: "Starke Regenschauer", 85: "Leichte Schneeschauer", 86: "Starke Schneeschauer", 95: "Gewitter", 96: "Gewitter mit leichtem Hagel", 99: "Gewitter mit starkem Hagel", } # ========================================================================= # Bright Sky (DWD) Condition-Tabelle # ========================================================================= BRIGHTSKY_CONDITIONS: dict[str, str] = { "dry": "Trocken", "fog": "Nebel", "rain": "Regen", "sleet": "Schneeregen", "snow": "Schnee", "hail": "Hagel", "thunderstorm": "Gewitter", "wind": "Windig", } # ========================================================================= # Windrichtung # ========================================================================= _WIND_DIRECTIONS = [ (0, 22.5, "Nord"), (22.5, 67.5, "Nordost"), (67.5, 112.5, "Ost"), (112.5, 157.5, "Suedost"), (157.5, 202.5, "Sued"), (202.5, 247.5, "Suedwest"), (247.5, 292.5, "West"), (292.5, 337.5, "Nordwest"), (337.5, 360.1, "Nord"), ] def format_wind_direction(degrees: int) -> str: """ Konvertiert Windrichtung in Grad zu Himmelsrichtung. Args: degrees: Windrichtung in Grad (0-360) Returns: Himmelsrichtung als String (z.B. "Suedwest") """ degrees = degrees % 360 for low, high, name in _WIND_DIRECTIONS: if low <= degrees < high: return name return "Nord" # ========================================================================= # Lookup-Funktionen # ========================================================================= def get_wmo_description(code: int) -> str: """ Gibt die deutsche Beschreibung fuer einen WMO-Wettercode zurueck. Args: code: WMO-Wettercode Returns: Deutsche Wetterbeschreibung """ return WMO_DESCRIPTIONS.get(code, f"Unbekannt ({code})") def get_brightsky_description(condition: str) -> str: """ Gibt die deutsche Beschreibung fuer eine Bright-Sky-Condition zurueck. Args: condition: Bright-Sky-Condition-String Returns: Deutsche Wetterbeschreibung """ return BRIGHTSKY_CONDITIONS.get(condition, condition.capitalize()) # ========================================================================= # TTS-Formatierung # ========================================================================= def format_weather_for_tts(data: WeatherData) -> str: """ Formatiert aktuelle Wetterdaten fuer die Sprachausgabe. Beispiel: "In Sinsheim sind es 8 Grad, leichter Regen bei 12 km/h Wind aus Suedwest." Args: data: Aktuelle Wetterdaten Returns: TTS-formatierter String """ temp = round(data.temperature) parts = [f"In {data.location} sind es {temp} Grad"] if data.feels_like is not None: diff = abs(round(data.feels_like) - temp) if diff >= 3: parts.append(f"gefuehlt {round(data.feels_like)} Grad") parts.append(data.description) if data.wind_speed >= 5: wind_dir = format_wind_direction(data.wind_direction) parts.append(f"bei {round(data.wind_speed)} km/h Wind aus {wind_dir}") if data.precipitation > 0: parts.append( f"mit {data.precipitation:.1f} Millimeter Niederschlag" ) return ", ".join(parts) + "." def format_forecast_for_tts(day: ForecastDay, date_label: str) -> str: """ Formatiert eine Tagesvorhersage fuer die Sprachausgabe. Beispiel: "Morgen in Sinsheim: 5 bis 12 Grad, bewoelkt." Args: day: Vorhersagedaten fuer einen Tag date_label: Datum-Label (z.B. "Morgen", "Am Freitag") Returns: TTS-formatierter String """ temp_min = round(day.temp_min) temp_max = round(day.temp_max) parts = [f"{date_label}: {temp_min} bis {temp_max} Grad, {day.description}"] if day.precipitation > 0: parts.append( f"{day.precipitation:.1f} Millimeter Niederschlag" ) if day.wind_speed_max >= 30: parts.append(f"Windboeen bis {round(day.wind_speed_max)} km/h") return ", ".join(parts) + "."