Skip to content

Commit

Permalink
changed decorator to get_or_create_station, updated database
Browse files Browse the repository at this point in the history
  • Loading branch information
Nik Sauer committed Nov 6, 2024
1 parent 07b1c41 commit d2de5ba
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 83 deletions.
40 changes: 40 additions & 0 deletions code/alembic/versions/1d6aadaa77b1_initial_migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""Initial migration
Revision ID: 1d6aadaa77b1
Revises: 0ab739389abd
Create Date: 2024-11-06 10:57:16.506743
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '1d6aadaa77b1'
down_revision: Union[str, None] = '0ab739389abd'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('StationStatus',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('station_id', sa.Integer(), nullable=True),
sa.Column('timestamp', sa.DateTime(), nullable=True),
sa.Column('level', sa.Integer(), nullable=True),
sa.Column('message', sa.String(), nullable=True),
sa.ForeignKeyConstraint(['station_id'], ['stations.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_StationStatus_id'), 'StationStatus', ['id'], unique=False)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_StationStatus_id'), table_name='StationStatus')
op.drop_table('StationStatus')
# ### end Alembic commands ###
30 changes: 30 additions & 0 deletions code/alembic/versions/5516d2dd3e78_initial_migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""Initial migration
Revision ID: 5516d2dd3e78
Revises: 1d6aadaa77b1
Create Date: 2024-11-06 10:57:27.299949
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = '5516d2dd3e78'
down_revision: Union[str, None] = '1d6aadaa77b1'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
2 changes: 1 addition & 1 deletion code/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ def get_db():
try:
yield db
finally:
db.close()
db.close()
92 changes: 12 additions & 80 deletions code/routers/station.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,80 +10,10 @@

from models import Station, Location, Measurement, Values, StationStatus
from schemas import StationDataCreate, SensorsCreate, StationStatusCreate
from utils import get_or_create_location, download_csv
from utils import get_or_create_location, download_csv, get_or_create_station
from services.hourly_average import calculate_hourly_average


def validate_station_info(func):
@wraps(func)
async def wrapper(
station: StationDataCreate,
*args,
db: Session = Depends(get_db),
**kwargs
):
# Prüfen, ob die Station bereits existiert
db_station = db.query(Station).filter(Station.device == station.device).first()

if db_station is None:
# Neue Station und neue Location anlegen
new_location = Location(
lat=station.location.lat,
lon=station.location.lon,
height=float(station.location.height)
)
db.add(new_location)
db.commit()
db.refresh(new_location)

# Neue Station anlegen und das source-Feld überprüfen (Standardwert ist 1)
db_station = Station(
device=station.device,
firmware=station.firmware,
apikey=station.apikey,
location_id=new_location.id,
last_active=station.time,
source=station.source if station.source is not None else 1
)
db.add(db_station)
db.commit()
db.refresh(db_station)
else:
# Station existiert, API-Schlüssel überprüfen
if db_station.apikey != station.apikey:
raise HTTPException(
status_code=401,
detail="Invalid API key"
)

updated = False

# Überprüfen, ob Location aktualisiert werden muss
if db_station.location is None or (
db_station.location.lat != station.location.lat or
db_station.location.lon != station.location.lon or
db_station.location.height != float(station.location.height)
):
new_location = get_or_create_location(db, station.location.lat, station.location.lon, float(station.location.height))
db_station.location_id = new_location.id
updated = True

if db_station.firmware != station.firmware:
db_station.firmware = station.firmware
updated = True

if updated:
db.commit()

return await func(
station
*args,
db_station = db_station,
**kwargs
)
return wrapper


router = APIRouter()


Expand Down Expand Up @@ -193,18 +123,18 @@ async def get_current_station_data(

return Response(content=content, media_type=media_type)


@router.post("/status", tags=["station"])
@validate_station_info
async def create_station_status(
station: StationDataCreate,
status_list: list[StationStatusCreate],

# von @validate_station_info
db_station: Station = Depends(lambda: None),
db: Session = Depends(get_db)
):

db_station = get_or_create_station(
db=db,
station=station
)

for status in status_list:
db_status = StationStatus(
station_id = db_station.id,
Expand All @@ -220,16 +150,18 @@ async def create_station_status(


@router.post("/data", tags=["station"])
@validate_station_info
async def create_station_data(
station: StationDataCreate,
sensors: SensorsCreate,
background_tasks: BackgroundTasks,

# von @validate_station_info
db_station: Station = Depends(lambda: None),
db: Session = Depends(get_db)
):

db_station = get_or_create_station(
db = db,
station = station
)

# Empfangszeit des Requests erfassen
time_received = datetime.now()

Expand Down
62 changes: 60 additions & 2 deletions code/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
from geopy.geocoders import Nominatim
from timezonefinder import TimezoneFinder
from sqlalchemy.orm import Session
from models import City, Country, Location
from fastapi import HTTPException
from models import City, Country, Location, Station
import logging
from schemas import StationDataCreate

# Initialisiere TimezoneFinder
tf = TimezoneFinder()
Expand Down Expand Up @@ -104,4 +106,60 @@ def get_or_create_location(db: Session, lat: float, lon: float, height: float):
db.rollback()
raise

return location
return location

def get_or_create_station(db: Session, station: StationDataCreate):
# Prüfen, ob die Station bereits existiert
db_station = db.query(Station).filter(Station.device == station.device).first()

if db_station is None:
# Neue Station und neue Location anlegen
new_location = Location(
lat=station.location.lat,
lon=station.location.lon,
height=float(station.location.height)
)
db.add(new_location)
db.commit()
db.refresh(new_location)

# Neue Station anlegen und das source-Feld überprüfen (Standardwert ist 1)
db_station = Station(
device=station.device,
firmware=station.firmware,
apikey=station.apikey,
location_id=new_location.id,
last_active=station.time,
source=station.source if station.source is not None else 1
)
db.add(db_station)
db.commit()
db.refresh(db_station)
else:
# Station existiert, API-Schlüssel überprüfen
if db_station.apikey != station.apikey:
raise HTTPException(
status_code=401,
detail="Invalid API key"
)

updated = False

# Überprüfen, ob Location aktualisiert werden muss
if db_station.location is None or (
db_station.location.lat != station.location.lat or
db_station.location.lon != station.location.lon or
db_station.location.height != float(station.location.height)
):
new_location = get_or_create_location(db, station.location.lat, station.location.lon, float(station.location.height))
db_station.location_id = new_location.id
updated = True

if db_station.firmware != station.firmware:
db_station.firmware = station.firmware
updated = True

if updated:
db.commit()

return db_station

0 comments on commit d2de5ba

Please sign in to comment.