Files
wetter_station/api/README.md

515 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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=<passwort>
```
## 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=<passwort> \
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.