First commit

This commit is contained in:
2026-02-19 01:19:22 +03:30
commit a39d83c241
32 changed files with 1350 additions and 0 deletions
View File
+132
View File
@@ -0,0 +1,132 @@
{
"info": {
"name": "Sensor Hub",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
"description": "Sensor Hub API. GET list, GET by uuid (detail), POST add, PATCH update, DELETE delete, POST active/deactive. Authenticated user required. Static responses only."
},
"item": [
{
"name": "List sensors",
"request": {
"method": "GET",
"header": [
{"key": "Content-Type", "value": "application/json"},
{"key": "Authorization", "value": "Bearer {{token}}", "description": "Required: user must be authenticated"}
],
"url": "{{baseUrl}}/api/sensor-hub/",
"description": "Get list of sensors. GET on base route."
},
"response": [
{
"name": "Success",
"status": "OK",
"code": 200,
"body": "{\n \"status\": \"success\",\n \"data\": {\n \"name\": \"sensor-hub-static\",\n \"uuid_sensor\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"last_updated\": \"2025-02-18T12:00:00Z\",\n \"specifications\": {\n \"model\": \"SH-1\",\n \"firmware\": \"1.0.0\",\n \"capabilities\": [\"temperature\", \"humidity\", \"light\"]\n },\n \"power_source\": {\n \"type\": \"battery\",\n \"voltage\": 3.3,\n \"backup\": \"solar\"\n },\n \"customized_sensors\": {\n \"thresholds\": {\"temperature_min\": 10, \"temperature_max\": 35},\n \"report_interval_sec\": 300\n }\n }\n}"
}
]
},
{
"name": "Get sensor details (by uuid)",
"request": {
"method": "GET",
"header": [
{"key": "Content-Type", "value": "application/json"},
{"key": "Authorization", "value": "Bearer {{token}}", "description": "Required: user must be authenticated"}
],
"url": "{{baseUrl}}/api/sensor-hub/{{uuid}}/",
"description": "Get one sensor by uuid in path."
},
"response": [
{
"name": "Success",
"status": "OK",
"code": 200,
"body": "{\n \"status\": \"success\",\n \"data\": {\n \"name\": \"sensor-hub-static\",\n \"uuid_sensor\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"last_updated\": \"2025-02-18T12:00:00Z\",\n \"specifications\": {\n \"model\": \"SH-1\",\n \"firmware\": \"1.0.0\",\n \"capabilities\": [\"temperature\", \"humidity\", \"light\"]\n },\n \"power_source\": {\n \"type\": \"battery\",\n \"voltage\": 3.3,\n \"backup\": \"solar\"\n },\n \"customized_sensors\": {\n \"thresholds\": {\"temperature_min\": 10, \"temperature_max\": 35},\n \"report_interval_sec\": 300\n }\n }\n}"
}
]
},
{
"name": "Add sensor",
"request": {
"method": "POST",
"header": [
{"key": "Content-Type", "value": "application/json"},
{"key": "Authorization", "value": "Bearer {{token}}", "description": "Required: user must be authenticated"}
],
"body": {"mode": "raw", "raw": "{}"},
"url": "{{baseUrl}}/api/sensor-hub/",
"description": "Add a new sensor. POST on base route."
},
"response": [
{"name": "Success", "status": "OK", "code": 200, "body": "{\n \"status\": \"success\"\n}"}
]
},
{
"name": "Update sensor",
"request": {
"method": "PATCH",
"header": [
{"key": "Content-Type", "value": "application/json"},
{"key": "Authorization", "value": "Bearer {{token}}", "description": "Required: user must be authenticated"}
],
"body": {"mode": "raw", "raw": "{}"},
"url": "{{baseUrl}}/api/sensor-hub/{{uuid}}/",
"description": "Update sensor by uuid in path. PATCH."
},
"response": [
{"name": "Success", "status": "OK", "code": 200, "body": "{\n \"status\": \"success\"\n}"}
]
},
{
"name": "Delete sensor",
"request": {
"method": "DELETE",
"header": [
{"key": "Authorization", "value": "Bearer {{token}}", "description": "Required: user must be authenticated"}
],
"url": "{{baseUrl}}/api/sensor-hub/{{uuid}}/",
"description": "Delete sensor by uuid in path."
},
"response": [
{"name": "Success", "status": "OK", "code": 200, "body": "{\n \"status\": \"success\"\n}"}
]
},
{
"name": "Activate",
"request": {
"method": "POST",
"header": [
{"key": "Content-Type", "value": "application/json"},
{"key": "Authorization", "value": "Bearer {{token}}", "description": "Required: user must be authenticated"}
],
"body": {"mode": "raw", "raw": "{}"},
"url": "{{baseUrl}}/api/sensor-hub/active/",
"description": "Activate. POST on active/ route."
},
"response": [
{"name": "Success", "status": "OK", "code": 200, "body": "{\n \"status\": \"success\"\n}"}
]
},
{
"name": "Deactivate",
"request": {
"method": "POST",
"header": [
{"key": "Content-Type", "value": "application/json"},
{"key": "Authorization", "value": "Bearer {{token}}", "description": "Required: user must be authenticated"}
],
"body": {"mode": "raw", "raw": "{}"},
"url": "{{baseUrl}}/api/sensor-hub/deactive/",
"description": "Deactivate. POST on deactive/ route."
},
"response": [
{"name": "Success", "status": "OK", "code": 200, "body": "{\n \"status\": \"success\"\n}"}
]
}
],
"variable": [
{"key": "baseUrl", "value": "http://localhost:8000"},
{"key": "token", "value": ""},
{"key": "uuid", "value": "550e8400-e29b-41d4-a716-446655440000"}
]
}
+12
View File
@@ -0,0 +1,12 @@
from rest_framework import serializers
class SensorStoreResponseSerializer(serializers.Serializer):
"""Schema for static sensor store response (name, uuid_sensor, last_updated, specifications, power_source, customized_sensors)."""
name = serializers.CharField()
uuid_sensor = serializers.CharField()
last_updated = serializers.CharField()
specifications = serializers.JSONField()
power_source = serializers.JSONField()
customized_sensors = serializers.JSONField()
+10
View File
@@ -0,0 +1,10 @@
from django.urls import path
from .views import SensorHubView
urlpatterns = [
path("active/", SensorHubView.as_view(), name="sensor-hub-active", kwargs={"action": "active"}),
path("deactive/", SensorHubView.as_view(), name="sensor-hub-deactive", kwargs={"action": "deactive"}),
path("<uuid:uuid>/", SensorHubView.as_view(), name="sensor-hub-detail"),
path("", SensorHubView.as_view(), name="sensor-hub-list"),
]
+96
View File
@@ -0,0 +1,96 @@
"""
Sensor Hub module.
All endpoints require authenticated user (must be registered).
All responses are static; no processing or validation on inputs.
"""
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from .serializers import SensorStoreResponseSerializer
# Static sensor payload for store (list/get) response.
STORE_DATA = {
"name": "sensor-hub-static",
"uuid_sensor": "550e8400-e29b-41d4-a716-446655440000",
"last_updated": "2025-02-18T12:00:00Z",
"specifications": {
"model": "SH-1",
"firmware": "1.0.0",
"capabilities": ["temperature", "humidity", "light"],
},
"power_source": {
"type": "battery",
"voltage": 3.3,
"backup": "solar",
},
"customized_sensors": {
"thresholds": {"temperature_min": 10, "temperature_max": 35},
"report_interval_sec": 300,
},
}
# Static payload for single-sensor detail response (same shape as store).
SENSOR_DETAIL_DATA = {
"name": "sensor-hub-static",
"uuid_sensor": "550e8400-e29b-41d4-a716-446655440000",
"last_updated": "2025-02-18T12:00:00Z",
"specifications": {
"model": "SH-1",
"firmware": "1.0.0",
"capabilities": ["temperature", "humidity", "light"],
},
"power_source": {
"type": "battery",
"voltage": 3.3,
"backup": "solar",
},
"customized_sensors": {
"thresholds": {"temperature_min": 10, "temperature_max": 35},
"report_interval_sec": 300,
},
}
class SensorHubView(APIView):
"""
Sensor-hub endpoints. Behavior depends on URL and HTTP method.
No processing or validation is performed on inputs; responses are static.
Routes:
- GET "" → List: returns code 200, msg "success", data with static sensor list.
- GET "<uuid>/" → Detail: uuid (path). Returns code 200, msg "success", data with static sensor payload.
- POST "" → Add: body/query may be sent but not used. Returns code 200, msg "success". No data field.
- PATCH "<uuid>/" → Update: uuid (path), body/query may be sent but not used. Returns code 200, msg "success". No data field.
- DELETE "<uuid>/" → Delete: uuid (path). Returns code 200, msg "success". No data field.
- POST "active/" → Activate: no input. Returns code 200, msg "success". No data field.
- POST "deactive/" → Deactivate: no input. Returns code 200, msg "success". No data field.
"""
# permission_classes = [IsAuthenticated]
def get(self, request, *args, **kwargs):
uuid = kwargs.get("uuid")
if uuid is not None:
data = SensorStoreResponseSerializer(SENSOR_DETAIL_DATA).data
else:
data = SensorStoreResponseSerializer(STORE_DATA).data
return Response({"code": 200, "msg": "success", "data": data}, status=status.HTTP_200_OK)
def post(self, request, *args, **kwargs):
action = kwargs.get("action")
if action == "active":
return Response({"code": 200, "msg": "success"}, status=status.HTTP_200_OK)
if action == "deactive":
return Response({"code": 200, "msg": "success"}, status=status.HTTP_200_OK)
# POST without action = add
return Response({"code": 200, "msg": "success"}, status=status.HTTP_200_OK)
def patch(self, request, *args, **kwargs):
return Response({"code": 200, "msg": "success"}, status=status.HTTP_200_OK)
def delete(self, request, *args, **kwargs):
return Response({"code": 200, "msg": "success"}, status=status.HTTP_200_OK)