diff --git a/sensorsafrica/api/v1/router.py b/sensorsafrica/api/v1/router.py index 88901a3..b90b3b0 100644 --- a/sensorsafrica/api/v1/router.py +++ b/sensorsafrica/api/v1/router.py @@ -1,7 +1,6 @@ # The base version is entirely based on feinstaub from feinstaub.main.views import UsersView from feinstaub.sensors.views import ( - PostSensorDataView, SensorView, StatisticsView, SensorDataView, @@ -11,6 +10,7 @@ FilterView, NodeView, NowView, + PostSensorDataView, SensorDataView as SensorsAfricaSensorDataView, ) diff --git a/sensorsafrica/api/v1/serializers.py b/sensorsafrica/api/v1/serializers.py index 252d45d..1aba22d 100644 --- a/sensorsafrica/api/v1/serializers.py +++ b/sensorsafrica/api/v1/serializers.py @@ -1,10 +1,23 @@ from rest_framework import serializers from feinstaub.sensors.models import ( + Node, SensorData, SensorDataValue, SensorLocation ) +from feinstaub.sensors.serializers import ( + NestedSensorLocationSerializer, + NestedSensorSerializer, + SensorDataSerializer as PostSensorDataSerializer +) + +class NodeSerializer(serializers.ModelSerializer): + sensors = NestedSensorSerializer(many=True) + location = NestedSensorLocationSerializer() + class Meta: + model = Node + fields = ('id', 'sensors', 'uid', 'owner', 'location', 'last_notify') class SensorLocationSerializer(serializers.ModelSerializer): class Meta: @@ -25,3 +38,19 @@ class SensorDataSerializer(serializers.ModelSerializer): class Meta: model = SensorData fields = ['location', 'timestamp', 'sensordatavalues'] + +class LastNotifySensorDataSerializer(PostSensorDataSerializer): + + def create(self, validated_data): + sd = super().create(validated_data) + # use node from authenticator + successful_authenticator = self.context['request'].successful_authenticator + node, pin = successful_authenticator.authenticate(self.context['request']) + + #sometimes we post historical data (eg: from other network) + #this means we have to update last_notify only if current timestamp is greater than what's there + if node.last_notify is None or node.last_notify < sd.timestamp: + node.last_notify = sd.timestamp + node.save() + + return sd diff --git a/sensorsafrica/api/v1/views.py b/sensorsafrica/api/v1/views.py index a51aecc..c984da3 100644 --- a/sensorsafrica/api/v1/views.py +++ b/sensorsafrica/api/v1/views.py @@ -15,11 +15,12 @@ from rest_framework.permissions import IsAuthenticatedOrReadOnly from feinstaub.sensors.models import Node, SensorData -from feinstaub.sensors.serializers import NodeSerializer, NowSerializer +from feinstaub.sensors.serializers import NowSerializer from feinstaub.sensors.views import StandardResultsSetPagination +from feinstaub.sensors.authentication import NodeUidAuthentication -from .serializers import SensorDataSerializer from .filters import NodeFilter +from .serializers import LastNotifySensorDataSerializer, NodeSerializer, SensorDataSerializer class FilterView(mixins.ListModelMixin, viewsets.GenericViewSet): serializer_class = SensorDataSerializer @@ -83,6 +84,15 @@ def get_queryset(self): sensor__public=True, modified__range=[startdate, now] ) +class PostSensorDataView(mixins.CreateModelMixin, + viewsets.GenericViewSet): + """ This endpoint is to POST data from the sensor to the api. + """ + authentication_classes = (NodeUidAuthentication,) + permission_classes = tuple() + serializer_class = LastNotifySensorDataSerializer + queryset = SensorData.objects.all() + class SensorDataView(mixins.ListModelMixin, viewsets.GenericViewSet): serializer_class = SensorDataSerializer @@ -96,3 +106,4 @@ def get_queryset(self): .only("sensor", "timestamp") .prefetch_related("sensordatavalues") ) +