From b2426ec4a80c0a35734389ee3409d12c6128ce3e Mon Sep 17 00:00:00 2001
From: Robert Goldmann <deadlocker@gmx.de>
Date: Fri, 25 Sep 2020 14:21:30 +0200
Subject: [PATCH] #8 - post route for sensor

---
 docs/api.yml                   | 51 ++++++++++++++++++++++++++++++++--
 src/blueprints/Measurements.py |  4 ++-
 src/blueprints/Sensors.py      | 32 ++++++++++++++++++++-
 src/logic/Parameters.py        |  1 +
 4 files changed, 83 insertions(+), 5 deletions(-)

diff --git a/docs/api.yml b/docs/api.yml
index dbf8491..69c2391 100644
--- a/docs/api.yml
+++ b/docs/api.yml
@@ -238,6 +238,34 @@ paths:
                 type: array
                 items:
                   $ref: '#/components/schemas/Measurement'
+  /sensor:
+    post:
+      tags:
+        - sensor
+      summary: Adds a new sensor. If a sensor with the provided name already exists for the given device id an error response is returned.
+      operationId: addSensor
+      security:
+        - bearerAuth: []
+      requestBody:
+        description: Sensor to add
+        required: true
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/NewSensor'
+      responses:
+        '200':
+          description: success response
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/SuccessResponse'
+        default:
+          description: error response
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ErrorResponse'
 
   /measurements:
     get:
@@ -374,7 +402,7 @@ components:
         - id
         - device_id
         - name
-        - sensor_type
+        - type
       properties:
         id:
           type: integer
@@ -384,8 +412,8 @@ components:
           example: 1
         name:
           type: string
-          example: "My Device"
-        sensor_type:
+          example: "My Sensor"
+        type:
           type: string
           example: "temperature"
 
@@ -453,6 +481,23 @@ components:
           type: string
           example: "myDevice"
 
+    NewSensor:
+      type: object
+      required:
+        - device_id
+        - name
+        - type
+      properties:
+        device_id:
+          type: integer
+          example: 1
+        name:
+          type: string
+          example: "My Sensor"
+        type:
+          type: string
+          example: "temperature"
+
     SuccessResponse:
       required:
         - success
diff --git a/src/blueprints/Measurements.py b/src/blueprints/Measurements.py
index 535c9db..6ddcdf4 100644
--- a/src/blueprints/Measurements.py
+++ b/src/blueprints/Measurements.py
@@ -36,7 +36,9 @@ def construct_blueprint(settings):
             sensors = parameters[DeviceParameters.SENSORS.value]
             for sensor in sensors:
                 sensorParams = RequestValidator.validate_parameters(sensor,
-                                                                    SensorParameters.get_values(),
+                                                                    [SensorParameters.NAME.value,
+                                                                     SensorParameters.TYPE.value,
+                                                                     SensorParameters.VALUE.value],
                                                                     f'sensor "{sensor}"')
                 sensor = __add_sensor_if_not_exists(database, int(device['id']), sensorParams)
                 database.measurementAccess.add_measurement(int(sensor['id']),
diff --git a/src/blueprints/Sensors.py b/src/blueprints/Sensors.py
index 310a657..5994489 100644
--- a/src/blueprints/Sensors.py
+++ b/src/blueprints/Sensors.py
@@ -1,6 +1,8 @@
-from flask import Blueprint, jsonify
+from flask import Blueprint, jsonify, request
 
 from logic.AuthenticationWrapper import require_api_key
+from logic.Parameters import SensorParameters
+from logic.RequestValidator import RequestValidator, ValidationError
 from logic.database.Database import Database
 
 
@@ -46,4 +48,32 @@ def construct_blueprint(settings):
         database.sensorAccess.delete_sensor(sensorID)
         return jsonify({'success': True})
 
+    @sensors.route('/sensor', methods=['POST'])
+    @require_api_key(password=settings['api']['key'])
+    def add_sensor():
+        try:
+            parameters = RequestValidator.validate(request, [SensorParameters.NAME.value,
+                                                             SensorParameters.TYPE.value,
+                                                             SensorParameters.DEVICE_ID.value])
+            database = Database(settings['database']['databasePath'])
+
+            deviceID = parameters[SensorParameters.DEVICE_ID.value]
+            sensorName = parameters[SensorParameters.NAME.value]
+            sensorType = parameters[SensorParameters.TYPE.value]
+
+            device = database.deviceAccess.get_device(deviceID)
+            if not device:
+                return jsonify({'success': False, 'msg': f'No device with id "{deviceID}" existing'})
+
+            existingSensor = database.sensorAccess.get_sensor_by_name_and_device_id(deviceID, sensorName)
+            if existingSensor:
+                return jsonify({'success': False,
+                                'msg': f'A sensor called "{sensorName}" already exists (ID: {existingSensor["id"]}) for device {deviceID}'})
+
+            database.sensorAccess.add_sensor(deviceID, sensorName, sensorType)
+        except ValidationError as e:
+            return e.response, 400
+
+        return jsonify({'success': True})
+
     return sensors
diff --git a/src/logic/Parameters.py b/src/logic/Parameters.py
index 4b0ea00..b9f4478 100644
--- a/src/logic/Parameters.py
+++ b/src/logic/Parameters.py
@@ -14,6 +14,7 @@ class SensorParameters(Enum):
     NAME = 'name'
     TYPE = 'type'
     VALUE = 'value'
+    DEVICE_ID = 'device_id'
 
     @staticmethod
     def get_values():
-- 
GitLab