Explorer
/tmp/aa021_weather.py
← Zurück ↓ Download
"""
Weather Intake -- Open-Meteo API (kostenlos, kein API-Key)
Mallorca: Palma de Mallorca lat=39.5696, lon=2.6502

Kein hardcodierter Score mehr -- verwendet die Scoring-Engine.
"""

import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent))

import json
import urllib.request
from datetime import datetime, timezone, timedelta
from signal_db import insert_signal
from classification.signal_classifier import score_signal

MALLORCA_LAT = 39.5696
MALLORCA_LON = 2.6502

HUMIDITY_HIGH   = 80   # % -- Signal bei Ueberschreitung
PRECIP_HIGH     = 8    # mm/24h -- Starkregen
TEMP_DELTA_HIGH = 10   # Grad -- Temperaturwechsel

API_URL = (
    "https://api.open-meteo.com/v1/forecast"
    f"?latitude={MALLORCA_LAT}&longitude={MALLORCA_LON}"
    "&hourly=relative_humidity_2m,precipitation,temperature_2m"
    "&daily=precipitation_sum,temperature_2m_max,temperature_2m_min"
    "&timezone=Europe%2FMadrid"
    "&forecast_days=3"
)


def fetch_weather() -> dict:
    req = urllib.request.urlopen(API_URL, timeout=15)
    return json.loads(req.read().decode("utf-8"))


def _make_weather_signal(topic: str, summary: str, expires_at: str) -> dict:
    """
    Erstellt ein Signal-Dict fuer ein Wetter-Ereignis.
    Score wird durch die Scoring-Engine berechnet (kein hardcoded Wert).
    """
    # Wetter-Text fuer Scorer: topic + summary + Mallorca-Kontext
    score_text = f"{topic} Mallorca Feuchterisiko Immobilien unbeaufsichtigt Schimmel"
    sd = score_signal(score_text, language="de", base_category="wetter_klima")

    return {
        "source_type":          "weather",
        "source_name":          "Open-Meteo Mallorca",
        "source_url":           "https://open-meteo.com",
        "language":             "de",
        "signal_category":      "wetter_klima",
        "topic":                topic,
        "short_summary":        summary,
        "extracted_hook":       summary[:150],
        "emotional_direction":  sd["emotional_direction"],
        "urgency_level":        sd["urgency_level"],
        "mallorca_relevance":   sd["mallorca_relevance"],
        "seasonal_relevance":   50,
        "risk_relevance":       sd["risk_relevance"],
        "estimated_noise_level": sd["estimated_noise_level"],
        "suggested_case_types": "feuchtefall,schimmel_risiko,ferienimmobilie",
        "suggested_platforms":  "facebook,instagram,whatsapp_status",
        "suggested_cta":        "feuchte_check,remotecheck",
        "confidence_score":     sd["confidence_score"],
        "radar_score":          sd["radar_score"],
        "decay_rate":           2.0,
        "expires_at":           expires_at,
        # Qualitaetsfaktoren
        "virality_level":       sd["virality_level"],
        "emotionality_level":   sd["emotionality_level"],
        "comment_potential":    sd["comment_potential"],
        "content_potential":    sd["content_potential"],
        "score_breakdown":      sd["score_breakdown"],
    }


def analyze_weather(data: dict) -> list:
    signals = []
    now = datetime.now(timezone.utc)

    daily  = data.get("daily", {})
    hourly = data.get("hourly", {})

    precip_daily = daily.get("precipitation_sum", [])
    temp_max     = daily.get("temperature_2m_max", [])
    temp_min     = daily.get("temperature_2m_min", [])
    dates        = daily.get("time", [])
    humidity_h   = hourly.get("relative_humidity_2m", [])

    # 1. Starkregen
    for i, (date, precip) in enumerate(zip(dates, precip_daily)):
        if precip and precip >= PRECIP_HIGH:
            expires = (now + timedelta(hours=48 if i == 0 else 96)).isoformat()
            topic   = f"Starkregen Mallorca {date}"
            summary = (f"Starkregen auf Mallorca: {precip:.1f}mm erwartet am {date} -- "
                       f"Feuchterisiko fuer unbeaufsichtigte Immobilien und Ferienwohnungen steigt.")
            signals.append(_make_weather_signal(topic, summary, expires))

    # 2. Extreme Luftfeuchte
    high_h = [h for h in humidity_h[:48] if h and h >= HUMIDITY_HIGH]
    if len(high_h) >= 6:
        avg_hum = sum(high_h) / len(high_h)
        expires = (now + timedelta(hours=72)).isoformat()
        topic   = "Hohe Luftfeuchte Mallorca"
        summary = (f"Luftfeuchte auf Mallorca durchschnittlich {avg_hum:.0f}% ueber {len(high_h)} Stunden -- "
                   f"Schimmelrisiko fuer leerstehende und unbeaufsichtigte Immobilien.")
        signals.append(_make_weather_signal(topic, summary, expires))

    # 3. Starker Temperaturwechsel (Kondensat-Risiko)
    if len(temp_max) >= 2 and len(temp_min) >= 2:
        delta = abs(temp_max[0] - temp_min[1]) if (temp_max[0] and temp_min[1]) else 0
        if delta >= TEMP_DELTA_HIGH:
            expires = (now + timedelta(hours=36)).isoformat()
            topic   = "Temperaturwechsel Mallorca"
            summary = (f"Temperaturwechsel {delta:.0f} Grad auf Mallorca -- "
                       f"Kondensationsrisiko an Fenstern und Waenden in Ferienwohnungen.")
            signals.append(_make_weather_signal(topic, summary, expires))

    return signals


def run():
    print("[WEATHER] Lade Wetterdaten Mallorca...")
    try:
        data    = fetch_weather()
        signals = analyze_weather(data)
        for s in signals:
            sid = insert_signal(s)
            status = "DUPLIKAT" if sid is None else f"ID={sid[:8]}"
            print(f"[WEATHER] {s['topic']} score={s['radar_score']} [{status}]")
        if not signals:
            print("[WEATHER] Keine auffaelligen Wetterereignisse erkannt.")
        return len(signals)
    except Exception as e:
        print(f"[WEATHER] Fehler: {e}")
        return 0


if __name__ == "__main__":
    run()