from typing import List from fastapi import APIRouter, HTTPException, Depends from sqlalchemy.orm import Session from logic.Dependencies import get_database, check_api_key, START_DATE_TIME, END_DATE_TIME from logic.database import Schemas, Crud from logic.database.Schemas import Status router = APIRouter( prefix='/sensor', tags=['sensor'] ) @router.get('/', response_model=List[Schemas.Sensor], summary='Gets all sensors') async def read_sensors(skip: int = 0, limit: int = 100, db: Session = Depends(get_database)): return Crud.get_sensors(db, skip=skip, limit=limit) @router.get('/{sensorId}', response_model=Schemas.Sensor, summary='Gets a specific sensor', responses={404: {'description': 'Sensor not found'}}) async def read_sensor(sensorId: int, db: Session = Depends(get_database)): sensor = Crud.get_sensor(db, sensorId=sensorId) if sensor is None: raise HTTPException(status_code=404, detail='Sensor not found') return sensor @router.post('/', response_model=Schemas.Sensor, summary='Adds a new sensor', responses={400: {'description': 'A sensor called "{sensor.name}" already exists ' '(ID: {existingSensor.id}) for device {sensor.device_id}'}, 404: {'description': 'No device with id "{sensor.device_id}" existing'}}, dependencies=[Depends(check_api_key)]) async def create_sensor(sensor: Schemas.SensorCreate, db: Session = Depends(get_database)): existingDevice = Crud.get_device(db, sensor.device_id) if not existingDevice: raise HTTPException(status_code=404, detail=f'No device with id "{sensor.device_id}" existing') existingSensor = Crud.get_sensor_by_name_and_device_id(db, sensor.name, sensor.device_id) if existingSensor: raise HTTPException(status_code=400, detail=f'A sensor called "{sensor.name}" already exists ' f'(ID: {existingSensor.id}) for device {sensor.device_id}') return Crud.create_sensor(db=db, sensor=sensor) @router.put('/{sensorId}', response_model=Schemas.Sensor, summary='Updates a sensor', responses={404: {'description': 'Sensor not found'}}, dependencies=[Depends(check_api_key)]) async def update_sensor(sensorId: int, sensor: Schemas.SensorUpdate, db: Session = Depends(get_database)): sensorToUpdate = Crud.get_sensor(db, sensorId) if not sensorToUpdate: raise HTTPException(status_code=404, detail='Sensor not found') if sensorToUpdate.name != sensor.name: existingSensor = Crud.get_sensor_by_name_and_device_id(db, sensor.name, sensorToUpdate.device_id) if existingSensor: raise HTTPException(status_code=400, detail=f'A sensor called "{sensor.name}" already exists ' f'(ID: {existingSensor.id}) for device {sensorToUpdate.device_id}') return Crud.update_sensor(db=db, sensorId=sensorId, sensor=sensor) @router.delete('/{sensorId}', response_model=Status, summary='Deletes a specific sensor', description='All corresponding measurements will be deleted too.', responses={404: {'description': 'Sensor not found'}}, dependencies=[Depends(check_api_key)]) async def delete_sensor(sensorId: int, db: Session = Depends(get_database)): sensor = Crud.get_sensor(db, sensorId=sensorId) if sensor is None: raise HTTPException(status_code=404, detail='Sensor not found') Crud.delete_sensor(db, sensor) return Status(message=f'Deleted sensor {sensor.id}') @router.get('/{sensorId}/measurements', response_model=List[Schemas.Measurement], summary='Gets all measurements for a specific sensor', description='Number of results can be limited by specifying a date range', responses={404: {'description': 'Sensor not found'}}) async def get_sensor_measurements(sensorId: int, startDateTime: str = START_DATE_TIME, endDateTime: str = END_DATE_TIME, db: Session = Depends(get_database)): sensor = Crud.get_sensor(db, sensorId=sensorId) if sensor is None: raise HTTPException(status_code=404, detail='Sensor not found') return Crud.get_measurements_for_sensor(db, startDateTime, endDateTime, sensorId) @router.get('/{sensorId}/measurements/latest', response_model=Schemas.Measurement, summary='Gets the latest measurement for a specific sensor', responses={404: {'description': 'Sensor not found'}}) async def get_latest_measurements_for_sensor(sensorId: int, db: Session = Depends(get_database)): sensor = Crud.get_sensor(db, sensorId=sensorId) if sensor is None: raise HTTPException(status_code=404, detail='Sensor not found') return Crud.get_latest_measurement_for_sensor(db, sensorId)