瀏覽代碼

气象站对接接口封装,可供客户直接调用数据

yf_fyh 3 年之前
父節點
當前提交
403c5852d3

+ 33 - 1
apps/Equipment/models.py

@@ -1,3 +1,35 @@
 from django.db import models
-
+from apps.UserApp.models import MyUser
 # Create your models here.
+
+class Device(models.Model):
+    TYPE_CHOICES = {
+        1: '气象站',
+    }
+    device_id = models.CharField(u'设备id', max_length=30, primary_key=True)
+    owner = models.ForeignKey(
+        MyUser, blank=True, null=True, on_delete = models.DO_NOTHING, verbose_name=u'设备所属用户')
+    device_type = models.SmallIntegerField(u'设备类型', default=1, choices=TYPE_CHOICES.items())
+    lng = models.CharField(u'经度', max_length=10, default="")
+    lat = models.CharField(u'纬度', max_length=10, default="")
+    iccid = models.CharField(u'设备卡号', max_length=20, default="")
+    volt = models.CharField(u'电压', max_length=10, default="")
+    rssi = models.CharField(u'信号强度', max_length=10, default="")
+    version = models.CharField(u'设备版本号', max_length=50, default="")
+    is_online = models.SmallIntegerField(u'是否在线', default=1)
+    upl_time = models.IntegerField(default=0)
+    class Meta:
+        db_table = "device"
+        verbose_name = u'设备列表'
+        verbose_name_plural = verbose_name
+
+
+class QXZData(models.Model):
+    device_id = models.ForeignKey(Device, on_delete = models.CASCADE)
+    device_data = models.TextField()
+    add_time = models.IntegerField(default=0)
+
+    class Meta:
+        db_table = "qxz_data"
+        verbose_name = u'气象站数据'
+        verbose_name_plural = verbose_name

+ 17 - 3
apps/Equipment/serializers.py

@@ -1,7 +1,6 @@
-# coding:utf-8
-import datetime
-
 from rest_framework import serializers
+import ast
+from .models import Device
 
 
 class SearchEquipSerializer(serializers.Serializer):
@@ -14,3 +13,18 @@ class SearchEquipSerializer(serializers.Serializer):
             raise serializers.ValidationError("设备号长度不能小于4位")
         else:
             return value
+
+
+class DeviceListSerializer(serializers.ModelSerializer):
+
+    class Meta:
+        model = Device
+        exclude = ('owner','device_type')
+
+
+class DeviceDetailSerializer(serializers.Serializer):
+    def to_representation(self, instance):
+        value = ast.literal_eval(instance.device_data)
+        addtime = instance.add_time
+        data = {"value":value,"time":addtime}
+        return data

+ 3 - 0
apps/Equipment/urls.py

@@ -5,4 +5,7 @@ from . import views
 
 urlpatterns = [
     url(r'^search/$', views.SearchEquip.as_view(), name='equip_search'),
+    url(r'^qxz/$', views.ReceiveQXZ.as_view(), name='equip_search'),
+    url(r'^list/$', views.DeviceList.as_view(), name='equip_search'),
+    url(r'^detail/$', views.DeviceDetail.as_view(), name='equip_search'),
 ]

+ 96 - 1
apps/Equipment/views.py

@@ -1,9 +1,15 @@
 from rest_framework.views import APIView
+from rest_framework.generics import GenericAPIView
 from rest_framework.response import Response
+import time
 
-from .serializers import SearchEquipSerializer
+from .serializers import SearchEquipSerializer,DeviceListSerializer,DeviceDetailSerializer
 from utils.utils import get_equip_list
+from utils.JWTAuthentication_diy import MyJWTAuthentication
+from utils.permissions import ModulePermission, DeviceDetailPermission
+from utils.MyRateThrottle import DeviceListRateThrottle,DeviceDetailRateThrottle
 
+from .models import Device, QXZData
 
 # Create your views here.
 
@@ -17,3 +23,92 @@ class SearchEquip(APIView):
             isfullId=request_data.get("isfullId")
         )
         return Response(data)
+
+
+class ReceiveQXZ(APIView):
+    def post(self,request):
+        data = request.data
+        if data.get("cmd") == "offline":
+            imei = data["ext"]["imei"]
+            try:
+                device = Device.objects.get(device_id=imei)
+                device.upl_time = int(time.time())
+                device.is_online = 0
+                device.save()
+            except Exception as e:
+                print("离线数据保存异常",e)
+        elif "terminalStatus" in data:
+            imei = data["StationID"]
+            status_data = data["terminalStatus"]
+            if Device.objects.filter(device_id=imei).exists():
+                device = Device.objects.get(device_id=imei)
+            else:
+                device = Device.objects.create(
+                    device_id=imei,
+                    device_type=1
+                )
+            if status_data.get("VOLT"):
+                device.volt = status_data.get("VOLT")
+            if status_data.get("RSSI"):
+                device.rssi = status_data.get("RSSI")
+            if status_data.get("ICCID"):
+                device.iccid = status_data.get("ICCID")
+            if status_data.get("longitude"):
+                device.lng = status_data.get("longitude")
+            if status_data.get("latitude"):
+                device.lat = status_data.get("latitude")
+            if status_data.get("Version"):
+                device.version = status_data.get("Version")
+            device.is_online = 1
+            device.upl_time = int(time.time())
+            device.save()
+            
+        elif 'data' in data:
+            imei = data["StationID"]
+            save_data = data["data"]
+            if Device.objects.filter(device_id=imei).exists():
+                device = Device.objects.get(device_id=imei)
+            else:
+                device = Device.objects.create(
+                    device_id=imei,
+                    device_type=1
+                )
+            device.is_online = 1
+            device.upl_time = int(time.time())
+            device.save()
+
+            QXZData.objects.create(
+                device_id=device,
+                device_data=save_data,
+                add_time=int(time.time())
+            )
+        return Response("已接收保存")
+        
+
+class DeviceList(GenericAPIView):
+    authentication_classes = [MyJWTAuthentication]
+    permission_classes = [ModulePermission]
+    throttle_classes = [DeviceListRateThrottle]
+    serializer_class = DeviceListSerializer
+    queryset = Device.objects.all()
+    def post(self,request):
+        uid = int(request.user.get("uid"))
+        device_queryset = self.get_queryset().filter(owner=uid)
+        serializer = self.get_serializer(instance=device_queryset, many=True)
+        return Response(serializer.data)
+
+        
+
+class DeviceDetail(GenericAPIView):
+    authentication_classes = [MyJWTAuthentication]
+    permission_classes = [DeviceDetailPermission]
+    throttle_classes = [DeviceDetailRateThrottle]
+    serializer_class = DeviceDetailSerializer
+    queryset = QXZData.objects.all().order_by("-id")
+    def post(self, request):
+        deviceId = request.data.get("deviceId")
+        start_time = int(request.data.get("start_time"))
+        device_queryset = self.get_queryset().filter(device_id_id=deviceId,add_time__gt=start_time)
+        serializer = self.get_serializer(instance=device_queryset, many=True)
+        return Response(serializer.data)
+

+ 4 - 0
apps/UserApp/views.py

@@ -4,12 +4,15 @@ from rest_framework.response import Response
 from rest_framework import status
 from django.contrib.auth import authenticate
 from utils.JWTAuthentication_diy import get_token, MyJWTAuthentication
+from utils.permissions import RegisterViewPermission
+from utils.MyRateThrottle import LoginRateThrottle
 from .serializers import RegisterViewSerializer
 
 # Create your views here.
 
 
 class LoginView(APIView):
+    throttle_classes = [LoginRateThrottle,]
     def post(self,request):
         username = request.data.get('username')
         password = request.data.get('password')
@@ -24,6 +27,7 @@ class LoginView(APIView):
 class RegisterView(GenericAPIView):
     authentication_classes = [MyJWTAuthentication]
     serializer_class = RegisterViewSerializer
+    permission_classes = [RegisterViewPermission]
     def post(self,request):
         serializer = self.get_serializer(data=request.data)
         serializer.is_valid()

+ 6 - 5
bigdataAPI/settings.py

@@ -142,13 +142,14 @@ REST_FRAMEWORK = {
     'DEFAULT_RENDERER_CLASSES': (
         'utils.rendererresponse.CustomRender',
     ),
-    # 全局配置权限,写法上根据路径进行判断可全局配置
-    'DEFAULT_PERMISSION_CLASSES': (
-        'utils.permissions.CustomPermission',
-    ),
+    'DEFAULT_THROTTLE_RATES': {
+        'login':'10/m',
+        'devicelist':'10/h',
+        'devicedetail':'10/h'
+    }
 }
 
 
 JWT_AUTH = {
-    'JWT_EXPIRATION_DELTA':datetime.timedelta(days=3),
+    'JWT_EXPIRATION_DELTA':datetime.timedelta(days=1),
 }

+ 21 - 0
utils/MyRateThrottle.py

@@ -0,0 +1,21 @@
+from rest_framework.throttling import SimpleRateThrottle
+
+class LoginRateThrottle(SimpleRateThrottle):
+    scope = "login"
+    def get_cache_key(self, request, view):
+        return self.get_ident(request)
+
+class DeviceListRateThrottle(SimpleRateThrottle):
+    scope = "devicelist"
+    def get_cache_key(self, request, view):
+        user = request.user
+        uid = user["uid"]
+        return uid
+
+class DeviceDetailRateThrottle(SimpleRateThrottle):
+    scope = "devicedetail"
+    def get_cache_key(self, request, view):
+        user = request.user
+        uid = user["uid"]
+        deviceId = request.data.get("deviceId")
+        return uid + deviceId

+ 2 - 2
utils/exception.py

@@ -13,13 +13,13 @@ def custom_exception_handler(exc, context):
     if response is None:
         return Response({
             'code': status.HTTP_500_INTERNAL_SERVER_ERROR,
-            'msg': 'error:{exc}'.format(exc=exc),
+            'msg': '{exc}'.format(exc=exc),
             'data': ''
         }, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
 
     else:
         return Response({
             'code': response.status_code,
-            'msg': 'error:{exc}'.format(exc=exc),
+            'msg': '{exc}'.format(exc=exc),
             'data': ''
         }, status=200, exception=True)

+ 34 - 7
utils/permissions.py

@@ -1,17 +1,44 @@
 # coding:utf-8
 
 from rest_framework.permissions import BasePermission
+from apps.Equipment.models import Device
 
+class RegisterViewPermission(BasePermission):
+    def has_permission(self, request, view):
+        try:
+            user = request.user
+            if user['username'] == "管理员":
+                return True
+            else:
+                return False
+        except:
+            return False
 
-class CustomPermission(BasePermission):
+class ModulePermission(BasePermission):
+    def has_permission(self,request,view):
+        try:
+            user = request.user
+            user_modules = user.get("user_modules")
+            path = request.path
+            if path.startswith("/equipment") and user_modules == "1":
+                return True
+            else:
+                return False
+        except:
+            return False
 
+
+class DeviceDetailPermission(BasePermission):
     def has_permission(self, request, view):
-        path = request.path
-        user = request.user
-        if path == '/user/register/':
-            if user['username'] == "管理员":
+        try:
+            user = request.user
+            uid = user.get("uid")
+            user_modules = user.get("user_modules")
+            deviceId = request.data.get("deviceId")
+            device = Device.objects.filter(device_id=deviceId,owner=int(uid))
+            if user_modules == "1" and device.exists():
                 return True
             else:
                 return False
-        else:
-            return True
+        except:
+            return False