Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sensors): adds fetch_one sensor endpoint to API #759

Merged
merged 6 commits into from Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions documentation/api/change_log.rst
Expand Up @@ -5,6 +5,11 @@ API change log

.. note:: The FlexMeasures API follows its own versioning scheme. This is also reflected in the URL, allowing developers to upgrade at their own pace.

v3.0-11 | 2023-07-20
""""""""""""""""""""

- Added REST endpoint for fetching one sensor: `/sensors/<id>` (GET)

v3.0-10 | 2023-06-12
""""""""""""""""""""

Expand Down
1 change: 1 addition & 0 deletions documentation/changelog.rst
Expand Up @@ -15,6 +15,7 @@ New features
* Make it a lot easier to read off the color legend on the asset page, especially when showing many sensors, as they will now be ordered from top to bottom in the same order as they appear in the chart (as defined in the ``sensors_to_show`` attribute), rather than alphabetically [see `PR #742 <https://www.github.com/FlexMeasures/flexmeasures/pull/742>`_]
* Having percentages within the [0, 100] domain is such a common use case that we now always include it in sensor charts with % units, making it easier to read off individual charts and also to compare across charts [see `PR #739 <https://www.github.com/FlexMeasures/flexmeasures/pull/739>`_]
* DataSource table now allows storing arbitrary attributes as a JSON (without content validation), similar to the Sensor and GenericAsset tables [see `PR #750 <https://www.github.com/FlexMeasures/flexmeasures/pull/750>`_]
* Added API endpoint `/sensor/<id>` for fetching a single sensor. [see `PR #433 <https://www.github.com/FlexMeasures/flexmeasures/pull/433>`_]

Bugfixes
-----------
Expand Down
36 changes: 36 additions & 0 deletions flexmeasures/api/v3_0/sensors.py
Expand Up @@ -46,6 +46,7 @@
get_sensor_schema = GetSensorDataSchema()
post_sensor_schema = PostSensorDataSchema()
sensors_schema = SensorSchema(many=True)
sensor_schema = SensorSchema()


class SensorAPI(FlaskView):
Expand Down Expand Up @@ -494,3 +495,38 @@ def get_schedule(self, sensor: Sensor, job_id: str, duration: timedelta, **kwarg

d, s = request_processed()
return dict(**response, **d), s

@route("/<id>", methods=["GET"])
@use_kwargs({"sensor": SensorIdField(data_key="id")}, location="path")
@permission_required_for_context("read", arg_name="sensor")
@as_json
def fetch_one(self, id, sensor):
"""Fetch a given sensor.

.. :quickref: Sensor; Get a sensor

This endpoint gets a sensor.

**Example response**

.. sourcecode:: json

{
"name": "some gas sensor",
"unit": "m³/h",
"entity_address": "ea1.2023-08.localhost:fm1.1",
"event_resolution": 10,
"generic_asset_id": 4,
"timezone": "UTC",
}

:reqheader Authorization: The authentication token
:reqheader Content-Type: application/json
:resheader Content-Type: application/json
:status 200: PROCESSED
:status 400: INVALID_REQUEST, REQUIRED_INFO_MISSING, UNEXPECTED_PARAMS
:status 401: UNAUTHORIZED
:status 403: INVALID_SENDER
:status 422: UNPROCESSABLE_ENTITY
"""
return sensor_schema.dump(sensor), 200
33 changes: 33 additions & 0 deletions flexmeasures/api/v3_0/tests/test_sensors_api.py
@@ -0,0 +1,33 @@
from __future__ import annotations


from flask import url_for


from flexmeasures import Sensor
from flexmeasures.api.tests.utils import get_auth_token


def test_fetch_one_sensor(
client,
setup_api_test_data: dict[str, Sensor],
):
sensor_id = 1
headers = make_headers_for("test_supplier_user_4@seita.nl", client)
response = client.get(
url_for("SensorAPI:fetch_one", id=sensor_id),
headers=headers,
)
print("Server responded with:\n%s" % response.json)
assert response.status_code == 200
assert response.json["name"] == "some gas sensor"
assert response.json["unit"] == "m³/h"
assert response.json["generic_asset_id"] == 4
assert response.json["timezone"] == "UTC"


def make_headers_for(user_email: str | None, client) -> dict:
headers = {"content-type": "application/json"}
if user_email:
headers["Authorization"] = get_auth_token(client, user_email, "testtest")
return headers