diff --git a/src/logic/databaseNew/Crud.py b/src/logic/databaseNew/Crud.py index 4fbe5037785d9b910cb4d10d032905d0aa75099a..ae4f2d656f42c515a32127a8ea16b143550caaa6 100644 --- a/src/logic/databaseNew/Crud.py +++ b/src/logic/databaseNew/Crud.py @@ -1,7 +1,11 @@ +from datetime import datetime + from sqlalchemy.orm import Session from logic.databaseNew import Models, Schemas +DATE_FORMAT = '%Y-%m-%d %H:%M:%S' + # ===== devices ===== @@ -57,3 +61,30 @@ def create_sensor(db: Session, sensor: Schemas.SensorCreate): def delete_sensor(db: Session, sensor: Schemas.Sensor): db.delete(sensor) db.commit() + + +# ===== measurements ===== + +def get_measurements(db: Session, skip: int = 0, limit: int = 100): + return db.query(Models.Measurement).offset(skip).limit(limit).all() + + +def get_measurement(db: Session, measurementId: int): + return db.query(Models.Measurement).filter(Models.Measurement.id == measurementId).first() + + +def create_measurement(db: Session, measurement: Schemas.MeasurementCreate): + dbMeasurement = Models.Measurement(**measurement.dict(), timestamp=__get_current_datetime()) + db.add(dbMeasurement) + db.commit() + db.refresh(dbMeasurement) + return dbMeasurement + + +def delete_measurement(db: Session, measurement: Schemas.Measurement): + db.delete(measurement) + db.commit() + + +def __get_current_datetime(): + return datetime.strftime(datetime.now(), DATE_FORMAT) diff --git a/src/logic/databaseNew/Models.py b/src/logic/databaseNew/Models.py index 8d73068c2c0459e2c0ab9ab4147ff13c9ee0ad1f..c6fb22b0c22ebb5315ae8511d9ca1cbf4a41b6f6 100644 --- a/src/logic/databaseNew/Models.py +++ b/src/logic/databaseNew/Models.py @@ -22,3 +22,15 @@ class Sensor(Base): deviceId = Column(Integer, ForeignKey('device.id')) device = relationship('Device', back_populates='sensors') + measurements = relationship('Measurement', back_populates='sensor', cascade='all,delete') + + +class Measurement(Base): + __tablename__ = 'measurement' + + id = Column(Integer, primary_key=True, index=True) + timestamp = Column(String, index=True, nullable=False) + value = Column(String, index=True, nullable=False) + sensorId = Column(Integer, ForeignKey('sensor.id')) + + sensor = relationship('Sensor', back_populates='measurements') diff --git a/src/logic/databaseNew/Schemas.py b/src/logic/databaseNew/Schemas.py index 7d1594349abcf11c183aa748abc86c732386ac23..711864fe86d211900655b0dc97bc3f7b1eabe79b 100644 --- a/src/logic/databaseNew/Schemas.py +++ b/src/logic/databaseNew/Schemas.py @@ -7,6 +7,22 @@ class Status(BaseModel): message: str +# ===== measurement ===== +class Measurement(BaseModel): + id: int + value: str + timestamp: str + sensorId: int + + class Config: + orm_mode = True + + +class MeasurementCreate(BaseModel): + value: str + sensorId: int + + # ===== sensor ===== class SensorBase(BaseModel): id: int @@ -23,7 +39,7 @@ class SensorCreate(BaseModel): deviceId: int -class Sensor(BaseModel): +class Sensor(SensorBase): id: int name: str type: str @@ -34,17 +50,14 @@ class Sensor(BaseModel): # ===== device ===== -class DeviceBase(BaseModel): +class Device(BaseModel): id: int name: str - - -class DeviceCreate(BaseModel): - name: str - - -class Device(DeviceBase): sensors: List[SensorBase] class Config: orm_mode = True + + +class DeviceCreate(BaseModel): + name: str diff --git a/src/main.py b/src/main.py index 39099cfea74f63e09b337a6e412ab1997d4165dc..0a98307e8fccb383c27b9272701c3b392f72975e 100644 --- a/src/main.py +++ b/src/main.py @@ -9,7 +9,7 @@ from Settings import SETTINGS from logic import Constants from logic.databaseNew import Models from logic.databaseNew.Database import engine -from routers import DeviceRouter, SensorRouter +from routers import DeviceRouter, SensorRouter, MeasurementRouter LOGGER = DefaultLogger().create_logger_if_not_exists(Constants.APP_NAME) @@ -25,6 +25,7 @@ app = FastAPI(title=Constants.APP_NAME, servers=[{'url': SETTINGS['api']['url'], 'description': f'{Constants.APP_NAME} API'}]) app.include_router(DeviceRouter.router) app.include_router(SensorRouter.router) +app.include_router(MeasurementRouter.router) @app.get('/') diff --git a/src/routers/MeasurementRouter.py b/src/routers/MeasurementRouter.py new file mode 100644 index 0000000000000000000000000000000000000000..6b961510b432e90880c1a95730cf147ee2ab430e --- /dev/null +++ b/src/routers/MeasurementRouter.py @@ -0,0 +1,54 @@ +from typing import List + +from fastapi import APIRouter, HTTPException, Depends +from sqlalchemy.orm import Session + +from Dependencies import get_database, check_api_key +from logic.databaseNew import Schemas, Crud +from logic.databaseNew.Schemas import Status + +router = APIRouter( + prefix='/measurement', + tags=['measurement'] +) + + +@router.get('/', response_model=List[Schemas.Measurement], + summary='Gets all measurements') +async def read_measurements(skip: int = 0, limit: int = 100, db: Session = Depends(get_database)): + return Crud.get_measurements(db, skip=skip, limit=limit) + + +@router.get('/{measurementId}', response_model=Schemas.Measurement, + summary='Gets a specific measurement', + responses={404: {'description': 'Measurement not found'}}) +async def read_measurement(measurementId: int, db: Session = Depends(get_database)): + measurement = Crud.get_measurement(db, measurementId=measurementId) + if measurement is None: + raise HTTPException(status_code=404, detail='Measurement not found') + return measurement + + +@router.post('/', response_model=Schemas.Measurement, + summary='Adds a new measurement', + responses={404: {'description': 'No sensor with id "{measurement.sensorId}" existing'}}, + dependencies=[Depends(check_api_key)]) +async def create_measurement(measurement: Schemas.MeasurementCreate, db: Session = Depends(get_database)): + existingSensor = Crud.get_sensor(db, measurement.sensorId) + if not existingSensor: + raise HTTPException(status_code=404, detail=f'No sensor with id "{measurement.sensorId}" existing') + + return Crud.create_measurement(db=db, measurement=measurement) + + +@router.delete('/{measurementId}', response_model=Status, + summary='Deletes a specific measurementId', + responses={404: {'description': 'Measurement not found'}}, + dependencies=[Depends(check_api_key)]) +async def delete_measurement(measurementId: int, db: Session = Depends(get_database)): + measurement = Crud.get_measurement(db, measurementId=measurementId) + if measurement is None: + raise HTTPException(status_code=404, detail='Measurement not found') + + Crud.delete_measurement(db, measurement) + return Status(message=f'Deleted measurement {measurement.id}')