async def delete_device(deviceId: int, db: Session = Depends(get_database)): device = Crud.get_device(db, deviceId=deviceId) if device is None: raise HTTPException(status_code=404, detail='Device not found') Crud.delete_device(db, device) return Status(message=f"Deleted device {device.id}")
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}')
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}')
async def create_measurement(measurement: Schemas.MeasurementCreate, db: Session = Depends(get_database)): existingSensor = Crud.get_sensor(db, measurement.sensor_id) if not existingSensor: raise HTTPException( status_code=404, detail=f'No sensor with id "{measurement.sensor_id}" existing') return Crud.create_measurement(db=db, measurement=measurement)
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)
async def update_measurement(measurementId: int, measurement: Schemas.MeasurementUpdate, db: Session = Depends(get_database)): existingMeasurement = Crud.get_measurement(db, measurementId) if existingMeasurement is None: raise HTTPException(status_code=404, detail='Measurement not found') return Crud.update_measurement(db, measurementId=measurementId, measurement=measurement)
async def update_device(deviceId: int, device: Schemas.DeviceCreate, db: Session = Depends(get_database)): existingDevice = Crud.get_device(db, deviceId) if not existingDevice: raise HTTPException(status_code=404, detail='Device not found') existingDevice = Crud.get_device_by_name(db, device.name) if existingDevice: raise HTTPException(status_code=400, detail='Device with this name already exists') return Crud.update_device(db=db, deviceId=deviceId, device=device)
def _cleanup_measurements_for_day(db: Session, date: datetime.date, policy: RetentionPolicy, sensor_id: int): measurementIds, idsToDelete = DatabaseCleaner._categorize_measurements_for_day( db, date=date, policy=policy, sensorId=sensor_id) if not idsToDelete: return LOGGER.debug( f'Scheduled {len(idsToDelete)} measurements for deletion ' f'(keeping: {len(measurementIds)}, max allowed: {policy.numberOfMeasurementsPerDay})' ) Crud.delete_multiple_measurements(db, idsToDelete)
def _categorize_measurements_for_day( db: Session, date: datetime.date, policy: RetentionPolicy, sensorId: int) -> Tuple[List[int], Set[int]]: points = policy.determine_measurement_points(date) measurementIdsToKeep = [] allMeasurementIds = set() for index, point in enumerate(points): previousItem = DatabaseCleaner.__get_previous_item( index, point, points) nextItem = DatabaseCleaner.__get_next_item(index, point, points) possibleMeasurements = Crud.get_measurements_for_sensor( db, previousItem.strftime(Crud.DATE_FORMAT), nextItem.strftime(Crud.DATE_FORMAT), sensorId) allMeasurementIds.update([m.id for m in possibleMeasurements]) closestMeasurement = DatabaseCleaner._get_closest_measurement_for_point( possibleMeasurements, point) if closestMeasurement is not None: measurementIdsToKeep.append(closestMeasurement.id) return measurementIdsToKeep, { m for m in allMeasurementIds if m not in measurementIdsToKeep }
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)
def get_database_info(db: Session) -> Schemas.DatabaseInfo: numberOfMeasurements = Crud.get_total_number_of_measurements(db) sizeInBytes = os.path.getsize(SETTINGS['database']['databasePath']) sizeInMegaBytes = sizeInBytes // 1024 // 1024 return Schemas.DatabaseInfo(number_of_measurements=numberOfMeasurements, size_on_disk_in_mb=sizeInMegaBytes)
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)
def clean(self, db: Session, currentDate: datetime.date): LOGGER.info('Performing database cleanup...') for policy in self._policies: LOGGER.debug(f'Enforcing retention policy: {policy}') policyStart = currentDate - timedelta(days=policy.ageInDays) allSensors = Crud.get_sensors(db, skip=0, limit=1000000) for sensor in allSensors: self._cleanup_measurements_for_sensor(sensor, db, policy, policyStart) LOGGER.debug('Performing database vacuum...') Crud.perform_vacuum(db) LOGGER.info('Database cleanup done') if self._forceBackupAfterCleanup: Crud.BACKUP_SERVICE.backup()
async def get_min_and_max_for_sensor_ids(sensorIds: List[int] = Query(None), startDateTime: str = START_DATE_TIME, endDateTime: str = END_DATE_TIME, db: Session = Depends(get_database)): values = [] for sensorId in sensorIds: measurementsForSensor = Crud.get_measurements_for_sensor( db, startDateTime, endDateTime, sensorId) for measurement in measurementsForSensor: values.append(float(measurement.value)) if values: return MinMax(min=min(values), max=max(values)) return MinMax()
def _cleanup_measurements_for_sensor(sensor: Schemas.Sensor, db: Session, policy: RetentionPolicy, policyStart: datetime.date): firstMeasurement = Crud.get_first_measurement_for_sensor( db=db, sensorId=sensor.id) if firstMeasurement is None: return minDate = datetime.strptime(firstMeasurement.timestamp, Crud.DATE_FORMAT).date() LOGGER.debug( f'Cleaning measurements for sensor "{sensor.name}" ' f'from now to {minDate.strftime(DatabaseCleaner.DATE_FORMAT)} ' f'(id: {sensor.id}, device_id: {sensor.device_id})') processedDate = policyStart while processedDate > minDate: LOGGER.debug( f'Cleaning {processedDate.strftime(DatabaseCleaner.DATE_FORMAT)}...' ) DatabaseCleaner._cleanup_measurements_for_day( db, processedDate, policy, sensor.id) processedDate = processedDate - timedelta(days=1)
async def create_multiple_measurements( measurementsToAdd: Schemas.MultipleMeasurements, db: Session = Depends(get_database)): existingDevice = Crud.get_device_by_name(db, measurementsToAdd.deviceName) if not existingDevice: existingDevice = Crud.create_device( db, Schemas.DeviceCreate(name=measurementsToAdd.deviceName)) for sensor in measurementsToAdd.sensors: existingSensor = Crud.get_sensor_by_name_and_device_id( db, sensor.name, existingDevice.id) if not existingSensor: existingSensor = Crud.create_sensor( db, Schemas.SensorCreate(name=sensor.name, type=sensor.type, device_id=existingDevice.id)) Crud.create_measurement( db, Schemas.MeasurementCreate(value=sensor.value, sensor_id=existingSensor.id)) return Status(message=f'Success')
async def read_device(deviceId: int, db: Session = Depends(get_database)): device = Crud.get_device(db, deviceId=deviceId) if device is None: raise HTTPException(status_code=404, detail='Device not found') return device
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
async def read_sensors(skip: int = 0, limit: int = 100, db: Session = Depends(get_database)): return Crud.get_sensors(db, skip=skip, limit=limit)
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)
async def read_measurements(startDateTime: str = START_DATE_TIME, endDateTime: str = END_DATE_TIME, db: Session = Depends(get_database)): return Crud.get_measurements(db, startDateTime=startDateTime, endDateTime=endDateTime)
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