Skip to content
Snippets Groups Projects
Routes.py 5.54 KiB
Newer Older
  • Learn to ignore specific revisions
  • import json
    import os
    
    from enum import Enum
    
    Robert Goldmann's avatar
    Robert Goldmann committed
    from typing import Dict
    
    import yaml
    
    Robert Goldmann's avatar
    Robert Goldmann committed
    from flask import Blueprint, request, jsonify, render_template
    
    from logic import Constants
    
    from logic.AuthenticationWrapper import require_api_key
    
    from logic.Database import Database
    from logic.RequestValidator import ValidationError, RequestValidator
    
    
    class DeviceParameters(Enum):
    
        DEVICE = 'device'
    
        SENSORS = 'sensors'
    
        @staticmethod
        def get_values():
            return [m.value for m in DeviceParameters]
    
    
    class SensorParameters(Enum):
        NAME = 'name'
        TYPE = 'type'
        VALUE = 'value'
    
        @staticmethod
        def get_values():
            return [m.value for m in SensorParameters]
    
    def construct_blueprint(settings, version):
    
    Robert Goldmann's avatar
    Robert Goldmann committed
        routes = Blueprint('routes', __name__)
    
        @routes.route('/', methods=['GET'])
        def index():
    
            yamlPath = os.path.join(Constants.ROOT_DIR, 'docs', 'api.yml')
            with open(yamlPath, 'r') as yamlFile:
                specification = yaml.load(yamlFile, Loader=yaml.FullLoader)
    
    
    Robert Goldmann's avatar
    Robert Goldmann committed
            specification['servers'][0]['url'] = settings['api']['url']
    
            specification['info']['version'] = version['name']
    
            specification = json.dumps(specification)
            return render_template('api.html',
                                   appName=Constants.APP_NAME,
                                   openApiSpecification=specification)
    
    Robert Goldmann's avatar
    Robert Goldmann committed
    
    
        @routes.route('/devices', methods=['GET'])
        def get_all_devices():
            database = Database(settings['database']['databasePath'])
            return jsonify(database.get_all_devices())
    
    
    Robert Goldmann's avatar
    Robert Goldmann committed
        @routes.route('/device/<int:deviceID>', methods=['GET'])
        def get_device(deviceID):
    
            database = Database(settings['database']['databasePath'])
    
    Robert Goldmann's avatar
    Robert Goldmann committed
            return jsonify(database.get_device(deviceID))
    
        @routes.route('/sensors', methods=['GET'])
        def get_all_sensors():
            database = Database(settings['database']['databasePath'])
            return jsonify(database.get_all_sensors())
    
    
    Robert Goldmann's avatar
    Robert Goldmann committed
        @routes.route('/sensor/<int:sensorID>', methods=['GET'])
        def get_sensor(sensorID):
    
            database = Database(settings['database']['databasePath'])
    
    Robert Goldmann's avatar
    Robert Goldmann committed
            return jsonify(database.get_sensor(sensorID))
    
    Robert Goldmann's avatar
    Robert Goldmann committed
        @routes.route('/device/<int:deviceID>/sensors/', methods=['GET'])
        def get_all_sensors_for_device(deviceID):
    
            database = Database(settings['database']['databasePath'])
    
    Robert Goldmann's avatar
    Robert Goldmann committed
            device = database.get_device(deviceID)
    
            if not device:
    
    Robert Goldmann's avatar
    Robert Goldmann committed
                return jsonify({'success': False, 'msg': f'No device with id "{deviceID}" existing'})
    
    Robert Goldmann's avatar
    Robert Goldmann committed
            return jsonify(database.get_all_sensors_for_device(deviceID))
    
        @routes.route('/measurements', methods=['GET'])
        def get_all_measurements():
            database = Database(settings['database']['databasePath'])
            return jsonify(database.get_all_measurements())
    
        @routes.route('/measurement/<int:measurementID>', methods=['GET'])
        def get_measurement(measurementID):
            database = Database(settings['database']['databasePath'])
            return jsonify(database.get_measurement(measurementID))
    
        @routes.route('/sensor/<sensorID>/measurements', methods=['GET'])
        def get_all_measurements_for_sensor(sensorID):
            database = Database(settings['database']['databasePath'])
            sensor = database.get_sensor(sensorID)
            if not sensor:
                return jsonify({'success': False, 'msg': f'No sensor with id "{sensorID}" existing'})
    
            return jsonify(database.get_all_measurements_for_sensor(sensorID))
    
    
        @routes.route('/sensor/<sensorID>/measurements/latest', methods=['GET'])
        def get_latest_measurements_for_sensor(sensorID):
            database = Database(settings['database']['databasePath'])
            sensor = database.get_sensor(sensorID)
            if not sensor:
                return jsonify({'success': False, 'msg': f'No sensor with id "{sensorID}" existing'})
    
            return jsonify(database.get_latest_measurements_for_sensor(sensorID))
    
    
        @routes.route('/measurements', methods=['POST'])
    
        @require_api_key(password=settings['api']['key'])
    
        def addMeasurement():
    
            try:
                parameters = RequestValidator.validate(request, DeviceParameters.get_values())
    
                database = Database(settings['database']['databasePath'])
    
    
                deviceName = parameters[DeviceParameters.DEVICE.value]
    
    Robert Goldmann's avatar
    Robert Goldmann committed
                if not database.get_device_by_name(deviceName):
    
                    database.add_device(deviceName)
    
    Robert Goldmann's avatar
    Robert Goldmann committed
                device = database.get_device_by_name(deviceName)
    
                sensors = parameters[DeviceParameters.SENSORS.value]
                for sensor in sensors:
                    sensorParams = RequestValidator.validate_parameters(sensor,
                                                                        SensorParameters.get_values(),
                                                                        f'sensor "{sensor}"')
    
    Robert Goldmann's avatar
    Robert Goldmann committed
                    sensor = __add_sensor_if_not_exists(database, int(device['id']), sensorParams)
                    database.add_measurement(int(sensor['id']), sensorParams[SensorParameters.VALUE.value])
    
            except ValidationError as e:
                return e.response, 400
    
    
            return jsonify({'success': True})
    
    Robert Goldmann's avatar
    Robert Goldmann committed
        def __add_sensor_if_not_exists(database: Database, deviceID: int, sensorParams: Dict) -> Dict[str, str]:
    
    Robert Goldmann's avatar
    Robert Goldmann committed
            sensorName = sensorParams[SensorParameters.NAME.value]
            sensorType = sensorParams[SensorParameters.TYPE.value]
    
    Robert Goldmann's avatar
    Robert Goldmann committed
            sensor = database.get_sensor_by_name_and_device_id(deviceID, sensorName)
    
    Robert Goldmann's avatar
    Robert Goldmann committed
            if sensor:
    
    Robert Goldmann's avatar
    Robert Goldmann committed
                return sensor
    
            database.add_sensor(deviceID, sensorName, sensorType)
            return database.get_sensor_by_name_and_device_id(deviceID, sensorName)
    
    
    Robert Goldmann's avatar
    Robert Goldmann committed
        return routes