# Wetterstation API REST API zum Abrufen von Wetterdaten aus der PostgreSQL-Datenbank. ## Übersicht Die API basiert auf **FastAPI** und bietet Endpunkte für aktuelle Wetterdaten, historische Zeitreihen, Statistiken und aggregierte Daten. - **Version:** 1.0.0 - **Framework:** FastAPI mit Uvicorn - **Datenbank:** PostgreSQL - **Interaktive API-Dokumentation:** `/docs` (Swagger UI) oder `/redoc` (ReDoc) ## Starten der API ### Lokal (Development) ```bash cd api python main.py ``` Die API läuft dann auf `http://localhost:8000` ### Docker (Production) ```bash docker compose up -d ``` ## Umgebungsvariablen Die API benötigt folgende Umgebungsvariablen (definiert in `.env`): ```env DB_HOST=localhost DB_PORT=5432 DB_NAME=wetterstation DB_USER=wetterstation_user DB_PASSWORD= ``` ## Endpunkte ### 📋 General #### `GET /` **Root-Endpunkt mit API-Informationen** **Response:** ```json { "message": "Wetterstation API", "version": "1.0.0", "docs": "/docs" } ``` --- #### `GET /health` **Health Check - Prüft API- und Datenbankstatus** **Response:** ```json { "status": "ok", "database": "connected", "timestamp": "2026-03-23T14:30:00" } ``` --- ### 🌡️ Weather Data #### `GET /weather/latest` **Gibt die neuesten Wetterdaten zurück** **Response Model:** `WeatherData` **Beispiel:** ```json { "id": 123456, "datetime": "2026-03-23T14:30:00Z", "temperature": 15.5, "humidity": 65, "pressure": 1013.2, "wind_speed": 12.5, "wind_gust": 18.7, "wind_dir": 225.0, "rain": 0.0, "rain_rate": 0.0, "received_at": "2026-03-23T14:30:05" } ``` --- #### `GET /weather/current` **Alias für `/weather/latest` - gibt aktuelle Wetterdaten zurück** --- #### `GET /weather/history` **Gibt historische Wetterdaten der letzten X Stunden zurück** **Query Parameter:** - `hours` (optional): Anzahl Stunden zurück (1-168, default: 24) - `limit` (optional): Maximale Anzahl Datensätze (1-10000, default: 1000) **Beispiel:** ```bash GET /weather/history?hours=48&limit=500 ``` **Response:** Array von `WeatherData` --- #### `GET /weather/range` **Gibt Wetterdaten für einen bestimmten Zeitraum zurück** **Query Parameter:** - `start` (erforderlich): Startdatum (ISO 8601) - `end` (erforderlich): Enddatum (ISO 8601) - `limit` (optional): Maximale Anzahl Datensätze (1-50000, default: 10000) **Beispiel:** ```bash GET /weather/range?start=2026-03-01T00:00:00Z&end=2026-03-23T23:59:59Z&limit=5000 ``` **Response:** Array von `WeatherData` --- #### `GET /weather/temperature` **Gibt nur Temperatur-Zeitreihen zurück (optimiert für Diagramme)** **Query Parameter:** - `hours` (optional): Anzahl Stunden zurück (1-168, default: 24) **Response:** ```json [ { "datetime": "2026-03-23T14:00:00Z", "temperature": 15.3 }, { "datetime": "2026-03-23T14:05:00Z", "temperature": 15.5 } ] ``` --- #### `GET /weather/wind` **Gibt nur Wind-Daten zurück (Geschwindigkeit, Richtung, Böen)** **Query Parameter:** - `hours` (optional): Anzahl Stunden zurück (1-168, default: 24) **Response:** ```json [ { "datetime": "2026-03-23T14:00:00Z", "wind_speed": 12.5, "wind_gust": 18.7, "wind_dir": 225.0 } ] ``` --- #### `GET /weather/rain` **Gibt nur Regen-Daten zurück** **Query Parameter:** - `hours` (optional): Anzahl Stunden zurück (1-168, default: 24) **Response:** ```json [ { "datetime": "2026-03-23T14:00:00Z", "rain": 0.5, "rain_rate": 2.3 } ] ``` --- ### 📊 Statistics #### `GET /weather/stats` **Gibt aggregierte Statistiken für den angegebenen Zeitraum zurück** **Query Parameter:** - `hours` (optional): Zeitraum in Stunden (1-168, default: 24) **Response Model:** `WeatherStats` **Beispiel:** ```json { "avg_temperature": 15.2, "min_temperature": 8.5, "max_temperature": 22.1, "avg_humidity": 65.3, "avg_pressure": 1013.5, "avg_wind_speed": 10.2, "max_wind_gust": 28.5, "total_rain": 3.2, "data_points": 288 } ``` --- #### `GET /weather/daily` **Gibt tägliche Statistiken für die letzten X Tage zurück** **Query Parameter:** - `days` (optional): Anzahl Tage zurück (1-90, default: 7) **Response:** Array von `WeatherStats` mit `date` Feld --- ### 📈 Aggregated Data Die aggregierten Endpunkte sind optimiert für Langzeit-Visualisierungen und reduzieren die Datenmenge durch Mittelwertbildung. #### `GET /weather/hourly-aggregated` **Gibt stündlich aggregierte Wetterdaten zurück (Stundenmittel)** **Query Parameter:** - `days` (optional): Anzahl Tage zurück (1-60, default: 7) **Response:** Array von `WeatherData` (stündlich aggregiert) **Verwendung:** Ideal für 7-Tage- und 30-Tage-Ansichten --- #### `GET /weather/daily-aggregated` **Gibt täglich aggregierte Wetterdaten zurück (Tagesmittel)** **Query Parameter:** - `days` (optional): Anzahl Tage zurück (1-730, default: 365) **Response:** Array von `WeatherData` (täglich aggregiert) **Besonderheit:** Bei `days >= 365` werden automatisch **alle verfügbaren Daten** zurückgegeben (nicht nur die letzten 365 Tage). **Verwendung:** Ideal für Jahresübersicht (365-Tage-Ansicht) --- #### `GET /weather/rain-daily` **Gibt tägliche Regensummen zurück** **Query Parameter:** - `days` (optional): Anzahl Tage zurück (1-365, default: 30) **Response:** ```json [ { "date": "2026-03-23T00:00:00Z", "total_rain": 5.2 }, { "date": "2026-03-22T00:00:00Z", "total_rain": 0.0 } ] ``` **Verwendung:** Ideal für 7-Tage- und 30-Tage-Regen-Diagramme --- #### `GET /weather/rain-weekly` **Gibt wöchentliche Regensummen zurück (Woche = Mo-So)** **Query Parameter:** - `days` (optional): Anzahl Tage zurück (1-730, default: 365) **Response:** ```json [ { "week_start": "2026-03-17T00:00:00Z", "total_rain": 12.5 } ] ``` **Besonderheit:** Bei `days >= 365` werden automatisch **alle verfügbaren Daten** zurückgegeben. **Verwendung:** Ideal für Jahresübersicht (365-Tage-Ansicht) --- ## Datenmodelle ### WeatherData ```typescript { id: number datetime: string (ISO 8601) temperature: number | null // °C humidity: number | null // % pressure: number | null // hPa wind_speed: number | null // km/h (konvertiert von mph) wind_gust: number | null // km/h (konvertiert von mph) wind_dir: number | null // Grad (0-360) rain: number | null // mm rain_rate: number | null // mm/h received_at: string (ISO 8601) } ``` ### WeatherStats ```typescript { avg_temperature: number | null min_temperature: number | null max_temperature: number | null avg_humidity: number | null avg_pressure: number | null avg_wind_speed: number | null max_wind_gust: number | null total_rain: number | null data_points: number } ``` ### HealthResponse ```typescript { status: string // "ok" | "error" database: string // "connected" | "disconnected" timestamp: string (ISO 8601) } ``` --- ## Einheitenkonvertierung Die API konvertiert automatisch folgende Einheiten aus der Datenbank: | Wert | Datenbank | API-Ausgabe | |------|-----------|-------------| | Windgeschwindigkeit | mph | km/h (× 1.60934) | | Windböen | mph | km/h (× 1.60934) | | Temperatur | °C | °C (unverändert) | | Luftdruck | hPa | hPa (unverändert) | | Regen | mm | mm (unverändert) | --- ## CORS Die API erlaubt CORS-Anfragen von allen Origins (`allow_origins=["*"]`). In Production sollte dies auf spezifische Domains eingeschränkt werden. --- ## Fehlerbehandlung ### HTTP Status Codes - `200 OK` - Erfolgreiche Anfrage - `400 Bad Request` - Ungültige Parameter - `404 Not Found` - Keine Daten gefunden - `500 Internal Server Error` - Datenbankfehler ### Fehler-Response ```json { "detail": "Keine Daten verfügbar" } ``` --- ## Interaktive Dokumentation FastAPI generiert automatisch eine interaktive API-Dokumentation: - **Swagger UI:** [http://localhost:8000/docs](http://localhost:8000/docs) - **ReDoc:** [http://localhost:8000/redoc](http://localhost:8000/redoc) Dort können alle Endpunkte direkt getestet werden. --- ## Beispiele ### cURL ```bash # Aktuelle Wetterdaten abrufen curl http://localhost:8000/weather/current # Letzte 48 Stunden curl "http://localhost:8000/weather/history?hours=48" # Jahresübersicht (alle verfügbaren Daten) curl "http://localhost:8000/weather/daily-aggregated?days=365" # Statistiken für letzte 7 Tage curl "http://localhost:8000/weather/stats?hours=168" ``` ### JavaScript (Fetch) ```javascript // Aktuelle Wetterdaten const response = await fetch('http://localhost:8000/weather/current') const data = await response.json() console.log(`Temperatur: ${data.temperature}°C`) // Tägliche Aggregation für 365 Tage const yearData = await fetch('http://localhost:8000/weather/daily-aggregated?days=365') const year = await yearData.json() console.log(`${year.length} Tage verfügbar`) ``` ### Python (requests) ```python import requests # Aktuelle Daten response = requests.get('http://localhost:8000/weather/current') data = response.json() print(f"Temperatur: {data['temperature']}°C") # Statistiken stats = requests.get('http://localhost:8000/weather/stats?hours=24') print(f"Durchschnittstemperatur: {stats.json()['avg_temperature']}°C") ``` --- ## Entwicklung ### Abhängigkeiten installieren ```bash pip install -r requirements.txt ``` ### Server starten (Development mit Auto-Reload) ```bash uvicorn main:app --reload --host 0.0.0.0 --port 8000 ``` ### Logging Die API verwendet Python's `logging`-Modul. Log-Level: `INFO` --- ## Deployment Die API wird als Docker-Container deployed. Siehe `Dockerfile` und `docker-compose.yml` im Hauptverzeichnis. ### Docker Image bauen ```bash docker build -t wetterstation-api ./api ``` ### Container starten ```bash docker run -d \ -p 8000:8000 \ -e DB_HOST=db \ -e DB_USER=wetterstation_user \ -e DB_PASSWORD= \ wetterstation-api ``` --- ## Performance-Tipps 1. **Aggregierte Endpunkte verwenden** für Langzeit-Visualisierungen (reduziert Datenmenge) 2. **Limit-Parameter** nutzen, um nur benötigte Datenmenge abzurufen 3. **Spezifische Endpunkte** verwenden (`/weather/temperature` statt `/weather/history` wenn nur Temperatur benötigt wird) 4. **Caching** auf Client-Seite implementieren für historische Daten --- ## Lizenz Siehe Hauptprojekt-Repository.