**WIP**
This commit is contained in:
121
api/main.py
121
api/main.py
@@ -1,6 +1,6 @@
|
||||
from fastapi import FastAPI, HTTPException, Query
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from pydantic import BaseModel, Field
|
||||
from pydantic import BaseModel, Field, ConfigDict
|
||||
from typing import List, Optional
|
||||
from datetime import datetime, timedelta
|
||||
import os
|
||||
@@ -47,6 +47,8 @@ app.add_middleware(
|
||||
|
||||
# Pydantic Models
|
||||
class WeatherData(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
id: int
|
||||
datetime: datetime
|
||||
temperature: Optional[float] = None
|
||||
@@ -59,9 +61,6 @@ class WeatherData(BaseModel):
|
||||
rain_rate: Optional[float] = None
|
||||
received_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class WeatherStats(BaseModel):
|
||||
avg_temperature: Optional[float] = None
|
||||
@@ -343,6 +342,120 @@ async def get_rain_data(
|
||||
conn.close()
|
||||
|
||||
|
||||
@app.get("/weather/hourly-aggregated", response_model=List[WeatherData], tags=["Aggregated Data"])
|
||||
async def get_hourly_aggregated_data(
|
||||
days: int = Query(7, ge=1, le=60, description="Anzahl Tage zurück (max 60)")
|
||||
):
|
||||
"""Gibt stündlich aggregierte Wetterdaten zurück (Stundenmittel)"""
|
||||
conn = get_db_connection()
|
||||
try:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
0 as id,
|
||||
date_trunc('hour', datetime) as datetime,
|
||||
AVG(temperature) as temperature,
|
||||
ROUND(AVG(humidity)) as humidity,
|
||||
AVG(pressure) as pressure,
|
||||
AVG(wind_speed * 1.60934) as wind_speed,
|
||||
MAX(wind_gust * 1.60934) as wind_gust,
|
||||
AVG(wind_dir) as wind_dir,
|
||||
AVG(rain) as rain,
|
||||
AVG(rain_rate) as rain_rate,
|
||||
MAX(received_at) as received_at
|
||||
FROM weather_data
|
||||
WHERE datetime >= NOW() - make_interval(days => %s)
|
||||
GROUP BY date_trunc('hour', datetime)
|
||||
ORDER BY datetime ASC
|
||||
""", (days,))
|
||||
results = cursor.fetchall()
|
||||
|
||||
return [dict(row) for row in results]
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
@app.get("/weather/daily-aggregated", response_model=List[WeatherData], tags=["Aggregated Data"])
|
||||
async def get_daily_aggregated_data(
|
||||
days: int = Query(365, ge=1, le=730, description="Anzahl Tage zurück (max 730)")
|
||||
):
|
||||
"""Gibt täglich aggregierte Wetterdaten zurück (Tagesmittel)"""
|
||||
conn = get_db_connection()
|
||||
try:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
0 as id,
|
||||
date_trunc('day', datetime) as datetime,
|
||||
AVG(temperature) as temperature,
|
||||
ROUND(AVG(humidity)) as humidity,
|
||||
AVG(pressure) as pressure,
|
||||
AVG(wind_speed * 1.60934) as wind_speed,
|
||||
MAX(wind_gust * 1.60934) as wind_gust,
|
||||
AVG(wind_dir) as wind_dir,
|
||||
AVG(rain) as rain,
|
||||
AVG(rain_rate) as rain_rate,
|
||||
MAX(received_at) as received_at
|
||||
FROM weather_data
|
||||
WHERE datetime >= NOW() - make_interval(days => %s)
|
||||
GROUP BY date_trunc('day', datetime)
|
||||
ORDER BY datetime ASC
|
||||
""", (days,))
|
||||
results = cursor.fetchall()
|
||||
|
||||
return [dict(row) for row in results]
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
@app.get("/weather/rain-daily", response_model=List[dict], tags=["Aggregated Data"])
|
||||
async def get_daily_rain_data(
|
||||
days: int = Query(30, ge=1, le=365, description="Anzahl Tage zurück")
|
||||
):
|
||||
"""Gibt tägliche Regensummen zurück"""
|
||||
conn = get_db_connection()
|
||||
try:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
date_trunc('day', datetime) as date,
|
||||
SUM(rain) as total_rain
|
||||
FROM weather_data
|
||||
WHERE datetime >= NOW() - make_interval(days => %s)
|
||||
GROUP BY date_trunc('day', datetime)
|
||||
ORDER BY date ASC
|
||||
""", (days,))
|
||||
results = cursor.fetchall()
|
||||
|
||||
return [dict(row) for row in results]
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
@app.get("/weather/rain-weekly", response_model=List[dict], tags=["Aggregated Data"])
|
||||
async def get_weekly_rain_data(
|
||||
days: int = Query(365, ge=1, le=730, description="Anzahl Tage zurück")
|
||||
):
|
||||
"""Gibt wöchentliche Regensummen zurück (Woche = Mo-So)"""
|
||||
conn = get_db_connection()
|
||||
try:
|
||||
with conn.cursor() as cursor:
|
||||
cursor.execute("""
|
||||
SELECT
|
||||
date_trunc('week', datetime) as week_start,
|
||||
SUM(rain) as total_rain
|
||||
FROM weather_data
|
||||
WHERE datetime >= NOW() - make_interval(days => %s)
|
||||
GROUP BY date_trunc('week', datetime)
|
||||
ORDER BY week_start ASC
|
||||
""", (days,))
|
||||
results = cursor.fetchall()
|
||||
|
||||
return [dict(row) for row in results]
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||
|
||||
Reference in New Issue
Block a user