107 lines
3.7 KiB
Python
107 lines
3.7 KiB
Python
import json
|
|
import uuid
|
|
from datetime import timezone as dt_timezone
|
|
|
|
from django.shortcuts import get_object_or_404
|
|
from django.utils import timezone
|
|
from rest_framework import status
|
|
from rest_framework.response import Response
|
|
from rest_framework.views import APIView
|
|
|
|
from .cassandra import cassandra_service
|
|
from .models import SensorDevice
|
|
from .serializers import (
|
|
HandshakeSerializer,
|
|
SensorDeviceSerializer,
|
|
SensorIngestSerializer,
|
|
SensorPayloadQuerySerializer,
|
|
)
|
|
from .services import translation_service
|
|
|
|
|
|
class DeviceHandshakeView(APIView):
|
|
def post(self, request):
|
|
serializer = HandshakeSerializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
data = serializer.validated_data
|
|
|
|
device, created = SensorDevice.objects.update_or_create(
|
|
device_identifier=data["device_identifier"],
|
|
defaults={
|
|
"device_name": data.get("device_name", ""),
|
|
"handshake_token": data.get("handshake_token", ""),
|
|
"metadata": data.get("metadata", {}),
|
|
"translation_config": data.get("translation_config", {}),
|
|
"is_active": True,
|
|
},
|
|
)
|
|
|
|
response_status = status.HTTP_201_CREATED if created else status.HTTP_200_OK
|
|
return Response(
|
|
{
|
|
"message": "Handshake completed successfully.",
|
|
"sensor_uuid": str(device.sensor_uuid),
|
|
"device": SensorDeviceSerializer(device).data,
|
|
},
|
|
status=response_status,
|
|
)
|
|
|
|
|
|
class SensorIngestView(APIView):
|
|
def post(self, request):
|
|
serializer = SensorIngestSerializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
data = serializer.validated_data
|
|
|
|
device = get_object_or_404(SensorDevice, sensor_uuid=data["sensor_uuid"], is_active=True)
|
|
reading_at = data.get("reading_at") or timezone.now()
|
|
if reading_at.tzinfo is None:
|
|
reading_at = reading_at.replace(tzinfo=dt_timezone.utc)
|
|
|
|
translated_payload, translation_status = translation_service.translate(
|
|
data["payload"],
|
|
config=device.translation_config,
|
|
)
|
|
payload_id = uuid.uuid4()
|
|
created_at = timezone.now()
|
|
|
|
stored = cassandra_service.save_payload(
|
|
sensor_uuid=str(device.sensor_uuid),
|
|
payload_id=payload_id,
|
|
reading_at=reading_at,
|
|
original_payload=json.dumps(data["payload"], ensure_ascii=False),
|
|
translated_payload=json.dumps(translated_payload, ensure_ascii=False),
|
|
translation_status=translation_status,
|
|
created_at=created_at,
|
|
)
|
|
|
|
return Response(
|
|
{
|
|
"message": "Payload processed successfully.",
|
|
"sensor_uuid": str(device.sensor_uuid),
|
|
"payload_id": str(payload_id),
|
|
"translation_status": translation_status,
|
|
"stored_in_cassandra": stored,
|
|
},
|
|
status=status.HTTP_201_CREATED,
|
|
)
|
|
|
|
|
|
class SensorPayloadListView(APIView):
|
|
def get(self, request, sensor_uuid):
|
|
query_serializer = SensorPayloadQuerySerializer(data=request.query_params)
|
|
query_serializer.is_valid(raise_exception=True)
|
|
limit = query_serializer.validated_data["limit"]
|
|
|
|
device = get_object_or_404(SensorDevice, sensor_uuid=sensor_uuid, is_active=True)
|
|
rows = cassandra_service.get_payloads(str(device.sensor_uuid), limit=limit)
|
|
|
|
return Response(
|
|
{
|
|
"sensor_uuid": str(device.sensor_uuid),
|
|
"device_identifier": device.device_identifier,
|
|
"count": len(rows),
|
|
"results": rows,
|
|
}
|
|
)
|