"""
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()