From 8bed7f033cf7b165024bbedf5f0e20b60ee1be14 Mon Sep 17 00:00:00 2001 From: Robert Goldmann <deadlocker@gmx.de> Date: Wed, 14 Oct 2020 21:00:19 +0200 Subject: [PATCH] Fixed #10 - convert measurement limit to "time interval" --- docs/api.yml | 95 ++++++++++++++++--------- src/blueprints/Measurements.py | 26 +++++-- src/logic/database/MeasurementAccess.py | 34 ++++++--- 3 files changed, 103 insertions(+), 52 deletions(-) diff --git a/docs/api.yml b/docs/api.yml index a54fc6c..4028e5b 100644 --- a/docs/api.yml +++ b/docs/api.yml @@ -275,46 +275,29 @@ paths: schema: $ref: '#/components/schemas/ErrorResponse' - /measurements/{limit}: + /measurements: get: tags: - measurement - summary: Gets all measurements (Maximum number of results can be limited with parameter "limit". Set to "0" to disable limit.) + summary: Gets all measurements (Number of results can be limited by specifying a date range) operationId: measurements parameters: - - in: path - name: limit - description: Maximum number of results. Set to "0" to disable limit. - required: true + - in: query + name: startDateTime + description: The start date and time of the date range that should be taken into account. + required: false schema: - type: integer - responses: - '200': - description: All available measurements - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Measurement' - - /measurements/minMax: - get: - tags: - - measurement - summary: Gets the minimum and maximum values for the given sensor ids. - operationId: measurementsMinMax - parameters: + type: string + format: date-time + example: '2020-01-20 18:15:22' - in: query - name: sensorIds - description: The sensor ids to calculate the min and max value for. - required: true - style: form - explode: false + name: endDateTime + description: The end date and time of the date range that should be taken into account. + required: false schema: - type: array - items: - type: integer + type: string + format: date-time + example: '2020-01-20 19:15:22' responses: '200': description: All available measurements @@ -324,15 +307,13 @@ paths: type: array items: $ref: '#/components/schemas/Measurement' - - /measurements: post: tags: - measurement summary: Adds multiple measurements. Non-existent device and sensors will be created automatically. operationId: addMeasurements security: - - bearerAuth: [] + - bearerAuth: [ ] requestBody: description: Measurements to add required: true @@ -353,6 +334,50 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorResponse' + + /measurements/minMax: + get: + tags: + - measurement + summary: Gets the minimum and maximum values for the given sensor ids. + operationId: measurementsMinMax + parameters: + - in: query + name: sensorIds + description: The sensor ids to calculate the min and max value for. + required: true + style: form + explode: false + schema: + type: array + items: + type: integer + - in: query + name: startDateTime + description: The start date and time of the date range that should be taken into account. + required: true + schema: + type: string + format: date-time + example: '2020-01-20 18:15:22' + - in: query + name: endDateTime + description: The end date and time of the date range that should be taken into account. + required: true + schema: + type: string + format: date-time + example: '2020-01-20 19:15:22' + responses: + '200': + description: All available measurements + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Measurement' + /measurement/{measurementID}: get: tags: diff --git a/src/blueprints/Measurements.py b/src/blueprints/Measurements.py index 3dd7ee9..436e748 100644 --- a/src/blueprints/Measurements.py +++ b/src/blueprints/Measurements.py @@ -12,25 +12,39 @@ from logic.database.Database import Database def construct_blueprint(settings: Dict, backupService: BackupService): measurements = Blueprint('measurements', __name__) - @measurements.route('/measurements/<int:limit>', methods=['GET']) - def get_all_measurements(limit: int): + @measurements.route('/measurements', methods=['GET']) + def get_all_measurements(): + startDateTime = request.args.get('startDateTime') + endDateTime = request.args.get('endDateTime') + database = Database(settings['database']['databasePath'], backupService) - return jsonify(database.measurementAccess.get_all_measurements(limit)) + return jsonify(database.measurementAccess.get_all_measurements(startDateTime, endDateTime)) @measurements.route('/measurements/minMax', methods=['GET']) def get_min_and_max_for_sensor_ids(): if 'sensorIds' not in request.args: return jsonify({'message': 'Parameter "sensorIds" missing'}), 400 + if 'startDateTime' not in request.args: + return jsonify({'message': 'Parameter "startDateTime" missing'}), 400 + + if 'endDateTime' not in request.args: + return jsonify({'message': 'Parameter "endDateTime" missing'}), 400 + sensorIds = request.args.get('sensorIds').split(',') + startDateTime = request.args.get('startDateTime') + endDateTime = request.args.get('endDateTime') + database = Database(settings['database']['databasePath'], backupService) values = [] for sensorId in sensorIds: sensorId = int(sensorId) - latestValue = database.measurementAccess.get_latest_measurements_for_sensor(sensorId) - if latestValue: - values.append(float(latestValue['value'])) + measurementsForSensor = database.measurementAccess.get_all_measurements_for_sensor(sensorId, + startDateTime, + endDateTime) + for measurement in measurementsForSensor: + values.append(float(measurement['value'])) if values: return jsonify({ diff --git a/src/logic/database/MeasurementAccess.py b/src/logic/database/MeasurementAccess.py index e120131..a9e0493 100644 --- a/src/logic/database/MeasurementAccess.py +++ b/src/logic/database/MeasurementAccess.py @@ -21,12 +21,17 @@ class MeasurementAccess(DatabaseAccess): def __get_current_datetime(self): return datetime.strftime(datetime.now(), self.DATE_FORMAT) - def get_all_measurements(self, limit: int) -> List[Dict[str, str]]: - limitParameter = '' - if limit > 0: - limitParameter = f'LIMIT {limit}' + def get_all_measurements(self, startDateTime: str, endDateTime: str) -> List[Dict[str, str]]: + if startDateTime and endDateTime: + return self._query(f'SELECT * FROM {self.TABLE_NAME} WHERE ' + f'DATETIME(timestamp) BETWEEN DATETIME(?) AND DATETIME(?) ' + f'ORDER BY sensor_id ASC, datetime(timestamp) DESC', + startDateTime, + endDateTime, + fetch_type=FetchType.ALL) + return self._query(f'SELECT * FROM {self.TABLE_NAME} ORDER BY sensor_id ASC, ' - f'datetime(timestamp) DESC {limitParameter}', + f'datetime(timestamp) DESC', fetch_type=FetchType.ALL) def get_measurement(self, measurementID: int) -> Dict[str, str] or None: @@ -34,12 +39,19 @@ class MeasurementAccess(DatabaseAccess): measurementID, fetch_type=FetchType.ALL) - def get_all_measurements_for_sensor(self, sensorID: int, limit: int) -> List[Dict[str, str]]: - limitParameter = '' - if limit > 0: - limitParameter = f'LIMIT {limit}' - return self._query(f'SELECT * FROM {self.TABLE_NAME} WHERE sensor_id = ? ' - f'ORDER BY datetime(timestamp) DESC {limitParameter}', + def get_all_measurements_for_sensor(self, sensorID: int, + startDateTime: str, + endDateTime: str) -> List[Dict[str, str]]: + if startDateTime and endDateTime: + return self._query(f'SELECT * FROM {self.TABLE_NAME} WHERE sensor_id = ? ' + f'AND DATETIME(timestamp) BETWEEN DATETIME(?) AND DATETIME(?) ' + f'ORDER BY datetime(timestamp) DESC', + sensorID, + startDateTime, + endDateTime, + fetch_type=FetchType.ALL) + + return self._query(f'SELECT * FROM {self.TABLE_NAME} WHERE sensor_id = ? ORDER BY datetime(timestamp) DESC', sensorID, fetch_type=FetchType.ALL) -- GitLab