# 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.
