Parcourir la source

气象要素工具:新增:获取设备配置列表接口

zhaiyifei il y a 2 ans
Parent
commit
9f3af2828e

+ 0 - 0
apps/QxzApp/__init__.py


+ 3 - 0
apps/QxzApp/admin.py

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 5 - 0
apps/QxzApp/apps.py

@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class QxzappConfig(AppConfig):
+    name = 'apps.QxzApp'

+ 0 - 0
apps/QxzApp/migrations/__init__.py


+ 61 - 0
apps/QxzApp/models.py

@@ -0,0 +1,61 @@
+from django.db import models
+
+# Create your models here.
+
+
+class QxzTypeConfigModel(models.Model):
+    """要素类型配置表"""
+    eNum = models.CharField(verbose_name="要素编号", max_length=10)
+    cName = models.CharField(verbose_name="中文名称", max_length=64)
+    units = models.CharField(verbose_name="要素单位", max_length=64, null=True, blank=True)
+
+    is_default = models.BooleanField(verbose_name="是否默认要素类型", default=False)
+
+    create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
+
+    class Meta:
+        db_table = "qxz_type_config"
+
+
+class QxzElementConfigModel(models.Model):
+    """气象要素配置表"""
+    eNum = models.CharField(verbose_name="要素编号", max_length=10)
+    cName = models.CharField(verbose_name="中文名称", max_length=64)
+    units = models.CharField(verbose_name="要素单位", max_length=64)
+    eName = models.CharField(verbose_name="要素英文名称", max_length=64)
+    is_standard = models.BooleanField(verbose_name="是否标配", default=False)
+    sensor_addr = models.IntegerField(verbose_name="从机地址")
+    start_reg = models.IntegerField(verbose_name="起始寄存器")
+    count = models.IntegerField(verbose_name="读取数量")
+    d_pos = models.IntegerField(verbose_name="有效数据位置")
+    d_length = models.IntegerField(verbose_name="位宽")
+    factor = models.IntegerField(verbose_name="系数")
+    dotled_s = models.CharField(verbose_name="LED屏幕内容", max_length=256)
+
+    create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
+
+    class Meta:
+        db_table = "qxz_element_config"
+
+
+class QxzDeviceConfigModel(models.Model):
+    """气象设备配置表"""
+    DEVICE_TYPE_CHOICE = [
+        ("0", "气象站"),
+        ("1", "墒情站"),
+        ("2", "扬尘监测站")
+    ]
+
+    device_id = models.CharField(verbose_name="设备编号", max_length=20)
+    order_num = models.CharField(verbose_name="任务单号", max_length=20)
+    device_type = models.CharField(verbose_name="设备类型", max_length=4, choices=DEVICE_TYPE_CHOICE, default="0")
+    is_standard = models.BooleanField(verbose_name="是否标准配置", default=False)
+    ele_cnf = models.TextField(verbose_name="要素配置")
+    led_cnf = models.TextField(verbose_name="led配置")
+    ele_name = models.TextField(verbose_name="要素名称列表")
+
+    create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
+
+    class Meta:
+        db_table = "qxz_device_config"
+

+ 397 - 0
apps/QxzApp/serializers.py

@@ -0,0 +1,397 @@
+import datetime
+import json
+import modulefinder
+
+from rest_framework import serializers
+
+
+class QxzTypeConfigAddSerializer(serializers.Serializer):
+    eNum = serializers.CharField(help_text="要素编号", required=True, max_length=10)
+    cName = serializers.CharField(help_text="中文名称", required=True, max_length=64)
+    units = serializers.CharField(help_text="要素单位", required=True, max_length=64)
+
+    def validate_eNum(self, value):
+        try:
+            eNum = int(value)
+            if eNum < 0:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("编号必须是大于0的有效整数")
+        return str(value)
+
+    def validate_cName(self, value):
+        try:
+            value = value.strip()
+            if len(value) > 10:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("要素类型名称必须在10个字符以内")
+        return value
+
+
+class QxzTypeConfigDeleteSerializer(serializers.Serializer):
+    qsc_id = serializers.IntegerField(help_text="要素类型配置id", required=True)
+
+    def validate_qsc_id(self, value):
+        try:
+            value = int(value)
+            if value < 0:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("要素类型配置id必须是大于0的有效整数")
+        return value
+
+
+class QxzTypeConfigModifySerializer(serializers.Serializer):
+    cName = serializers.CharField(help_text="中文名称", required=True, max_length=64)
+    units = serializers.CharField(help_text="要素单位", required=True, max_length=64)
+    qsc_id = serializers.IntegerField(help_text="要素类型配置id", required=True)
+
+    def validate_qsc_id(self, value):
+        try:
+            value = int(value)
+            if value < 0:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("要素类型配置id必须是大于0的有效整数")
+        return value
+
+    def validate_cName(self, value):
+        try:
+            value = value.strip()
+            if len(value) > 10:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("要素类型名称必须在10个字符以内")
+        return value
+
+
+class QxzTypeConfigListSerializer(serializers.Serializer):
+    cName = serializers.CharField(help_text="中文名称", required=False, max_length=64, allow_null=True, allow_blank=True)
+    is_default = serializers.BooleanField(help_text="是否默认要素类型", required=False, allow_null=True, default=None)
+
+    def to_representation(self, instance):
+        return {
+            'qsc_id': instance.id,
+            'cName': instance.cName,
+            'units': instance.units,
+            'eNum': instance.eNum,
+            'is_default': instance.is_default
+        }
+
+
+class QxzElementAddSerializer(serializers.Serializer):
+    cName = serializers.CharField(help_text="中文名称", required=False, max_length=64)
+    eName = serializers.CharField(help_text="英文名称", required=False, max_length=64)
+    eNum = serializers.CharField(help_text="要素编号", required=True, max_length=10)
+    units = serializers.CharField(help_text="要素单位", required=True, max_length=64)
+    is_standard = serializers.BooleanField(help_text="是否标配", required=True)
+    sensor_addr = serializers.IntegerField(help_text="从机地址", required=True)
+    start_reg = serializers.IntegerField(help_text="起始寄存器", required=True)
+    count = serializers.IntegerField(help_text="读取数量", required=True)
+    d_pos = serializers.IntegerField(help_text="有效数据位置", required=True)
+    d_length = serializers.IntegerField(help_text="位宽", required=True)
+    factor = serializers.IntegerField(help_text="系数", required=True)
+    dotled_s = serializers.CharField(help_text="LED屏幕内容", required=True, max_length=256)
+
+    def validate_cName(self, value):
+        try:
+            value = value.strip()
+            if len(value) > 4:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("中文名称必须在4个字符以内")
+        return value
+
+    def validate_eName(self, value):
+        try:
+            value = value.strip()
+            if len(value) > 30:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("英文名称必须在30个字符以内")
+        return value
+
+    def validate_eNum(self, value):
+        try:
+            eNum = int(value)
+            if eNum < 0:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("编号必须是大于0的有效整数")
+        return str(value)
+
+    def validate_sensor_addr(self, value):
+        try:
+            value = int(value)
+            if not (1 <= value <= 254):
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("从机地址必须是1-254之间的有效整数")
+        return value
+
+    def validate_start_reg(self, value):
+        try:
+            value = int(value)
+            if not (0 <= value <= 254):
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("起始寄存器必须是0-254之间的有效整数")
+        return value
+
+    def validate_count(self, value):
+        try:
+            value = int(value)
+            if not (1 <= value <= 10):
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("读取数量必须是1-10之间的有效整数")
+        return value
+
+    def validate_d_pos(self, value):
+        try:
+            value = int(value)
+            if not (0 <= value <= 10):
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("有效数据位置必须是0-10之间的有效整数")
+        return value
+
+    def validate_d_length(self, value):
+        try:
+            value = int(value)
+            if not (1 <= value <= 2):
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("d_length必须是1-2之间的有效整数")
+        return value
+
+    def validate_factor(self, value):
+        try:
+            value = int(value)
+            if value not in [1, 10, -10, -100]:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("系数不符合要求")
+        return value
+
+    def validate_dotled_s(self, value):
+        if len(value) > 256:
+            raise serializers.ValidationError("LED屏幕内容过长")
+        return value
+
+
+class QxzElementModifySerializer(serializers.Serializer):
+    qec_id = serializers.IntegerField(help_text="要素信息id", required=True)
+    cName = serializers.CharField(help_text="中文名称", required=False, max_length=64)
+    eName = serializers.CharField(help_text="英文名称", required=False, max_length=64)
+    is_standard = serializers.BooleanField(help_text="是否标配", required=True)
+    sensor_addr = serializers.IntegerField(help_text="从机地址", required=True)
+    start_reg = serializers.IntegerField(help_text="起始寄存器", required=True)
+    count = serializers.IntegerField(help_text="读取数量", required=True)
+    d_pos = serializers.IntegerField(help_text="有效数据位置", required=True)
+    d_length = serializers.IntegerField(help_text="位宽", required=True)
+    factor = serializers.IntegerField(help_text="系数", required=True)
+    dotled_s = serializers.CharField(help_text="LED屏幕内容", required=True, max_length=256)
+
+    def validate_qec_id(self, value):
+        try:
+            value = int(value)
+            if value < 0:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("要素信息id必须大于0的整数")
+        return value
+
+
+    def validate_cName(self, value):
+        try:
+            value = value.strip()
+            if len(value) > 4:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("中文名称必须在4个字符以内")
+        return value
+
+    def validate_eName(self, value):
+        try:
+            value = value.strip()
+            if len(value) > 30:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("英文名称必须在30个字符以内")
+        return value
+
+    def validate_sensor_addr(self, value):
+        try:
+            value = int(value)
+            if not (1 <= value <= 254):
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("从机地址必须是1-254之间的有效整数")
+        return value
+
+    def validate_start_reg(self, value):
+        try:
+            value = int(value)
+            if not (0 <= value <= 254):
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("起始寄存器必须是0-254之间的有效整数")
+        return value
+
+    def validate_count(self, value):
+        try:
+            value = int(value)
+            if not (1 <= value <= 10):
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("读取数量必须是1-10之间的有效整数")
+        return value
+
+    def validate_d_pos(self, value):
+        try:
+            value = int(value)
+            if not (0 <= value <= 10):
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("有效数据位置必须是0-10之间的有效整数")
+        return value
+
+    def validate_d_length(self, value):
+        try:
+            value = int(value)
+            if not (1 <= value <= 2):
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("d_length必须是1-2之间的有效整数")
+        return value
+
+    def validate_factor(self, value):
+        try:
+            value = int(value)
+            if value not in [1, 10, -10, -100]:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("系数不符合要求")
+        return value
+
+    def validate_dotled_s(self, value):
+        if len(value) > 256:
+            raise serializers.ValidationError("LED屏幕内容过长")
+        return value
+
+
+class QxzElementDeleteSerializer(serializers.Serializer):
+    qec_id = serializers.IntegerField(help_text="要素信息id", required=True)
+
+    def validate_qec_id(self, value):
+        try:
+            value = int(value)
+            if value < 0:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError("要素信息id必须大于0的整数")
+        return value
+
+
+class QxzElementListSerializer(serializers.Serializer):
+    ele_name = serializers.CharField(help_text="要素名称", required=False, max_length=64, allow_blank=True, allow_null=True)
+    is_standard = serializers.BooleanField(help_text="是否标配", required=False, allow_null=True, default=None)
+
+    def to_representation(self, instance):
+        return {
+            'qec_id': instance.id,
+            'cName': instance.cName,
+            'eName': instance.eName,
+            'units': instance.units,
+            'eNum': instance.eNum,
+            'is_standard': instance.is_standard,
+            'sensor_addr': instance.sensor_addr,
+            'start_reg': instance.start_reg,
+            'count': instance.count,
+            'd_pos': instance.d_pos,
+            'd_length': instance.d_length,
+            'factor': instance.factor,
+            'dotled_s': instance.dotled_s
+        }
+
+
+class QxzDeviceAddSerializer(serializers.Serializer):
+    device_id = serializers.CharField(help_text="设备编号", max_length=20, required=True)
+    order_num = serializers.CharField(help_text="任务单号", max_length=20, required=True)
+    device_type = serializers.CharField(help_text="设备类型", max_length=4, required=True)
+    is_standard = serializers.BooleanField(help_text="是否标配", required=True)
+    ele_cnf = serializers.JSONField(help_text="要素配置", required=True)
+    led_cnf = serializers.JSONField(help_text="led配置", required=False, default=None, allow_null=True)
+
+    def validate_device_type(self, value):
+        try:
+            value = value.strip()
+            if value not in ['0', '1', '2']:
+                raise Exception()
+        except Exception as e:
+            raise serializers.ValidationError('设备类型参数异常')
+        return value
+
+    def validate_ele_cnf(self, value):
+        v = list(value.values())
+        if len(v) != len(set(v)):
+            raise serializers.ValidationError('英文名称不能重复')
+        try:
+            key_list = sorted(value.keys(), key=lambda x: int(x.replace('c', '')))
+            for i, k in enumerate(key_list):
+                t = int(k.replace('c', ''))
+                if not (0 <= t <= 29):
+                    raise serializers.ValidationError('要素序号必须在0-29之间')
+                if i != t:
+                    raise serializers.ValidationError('要素序号顺序必须连续')
+        except Exception as e:
+            raise serializers.ValidationError('要素序号参数异常')
+        return value
+
+    def validate_led_conf(self, value):
+        if value:
+            try:
+                if value['Control_card'] not in [1, 2, 3]:
+                    raise Exception()
+                if value['front'] not in [12, 16]:
+                    raise Exception()
+                if not (1 <= value['keep_time'] <= 72):
+                    raise Exception()
+                if 0 <= value['Start_x'] <= 1024:
+                    raise Exception()
+                if 0 <= value['Start_y'] <= 1024:
+                    raise Exception()
+                if 1 <= value['Width'] <= 1024:
+                    raise Exception()
+                if 1 <= value['Height'] <= 1024:
+                    raise Exception()
+            except Exception as e:
+                raise serializers.ValidationError('led参数异常')
+        return value
+
+
+class QxzDeviceListSerializer(serializers.Serializer):
+    device_id = serializers.CharField(help_text="设备编号", max_length=20, required=False, allow_null=True, allow_blank=True)
+
+    def to_representation(self, instance):
+
+        return {
+            'device_id': instance.device_id,
+            'order_num': instance.order_num,
+            'device_type': instance.device_type,
+            'is_standard': instance.is_standard,
+            'create_time': instance.create_time.strftime("%Y-%m-%d %H:%S:%M"),
+            'ele_cnf': json.loads(instance.ele_cnf),
+            'led_cnf': json.loads(instance.led_cnf),
+            'ele_name': json.loads(instance.ele_name)
+        }
+
+
+
+
+
+
+
+

+ 26 - 0
apps/QxzApp/tests.py

@@ -0,0 +1,26 @@
+import json
+
+from django.test import TestCase
+
+# Create your tests here.
+
+c = '2022-11-29 05:00:08'
+import datetime
+
+from dateutil.relativedelta import relativedelta
+
+c = {
+		"c0": "Temperature2",
+		"c1": "Temperature3"
+	}
+
+c = {
+		"Control_card": 3,
+		"front": 12,
+		"keep_time": 10,
+		"Start_x": 5,
+		"Start_y": 10,
+		"Width": 96,
+		"Height": 48
+	}
+print(json.dumps(c))

+ 19 - 0
apps/QxzApp/urls.py

@@ -0,0 +1,19 @@
+from django.conf.urls import url
+
+from . import views
+
+urlpatterns = [
+    url(r'^type/list/$', views.QxzTypeConfigListView.as_view()),
+    url(r'^type/add/$', views.QxzTypeConfigAddView.as_view()),
+    url(r'^type/modify/$', views.QxzTypeConfigModifyView.as_view()),
+    url(r'^type/delete/$', views.QxzTypeConfigDeleteView.as_view()),
+
+    url(r'^element/add/$', views.QxzElementAddView.as_view()),
+    url(r'^element/modify/$', views.QxzElementModifyView.as_view()),
+    url(r'^element/delete/$', views.QxzElementDeleteView.as_view()),
+    url(r'^element/list/$', views.QxzElementListView.as_view()),
+
+    url(r'^device/add/$', views.QxzDeviceAddView.as_view()),
+    url(r'^device/modify/$', views.QxzDeviceModifyView.as_view()),
+    url(r'^device/list/$', views.QxzDeviceListView.as_view())
+]

+ 611 - 0
apps/QxzApp/views.py

@@ -0,0 +1,611 @@
+import json
+import os
+
+from django.shortcuts import render
+
+from rest_framework.response import Response
+from rest_framework import status
+from rest_framework.generics import GenericAPIView
+from django.db.models import ObjectDoesNotExist, Q
+from utils.JWTAuthentication_diy import MyJWTAuthentication
+from utils.permissions import ModulePermission
+from utils.paginations import CustomPagination
+from .serializers import QxzTypeConfigAddSerializer, QxzTypeConfigModifySerializer, QxzTypeConfigDeleteSerializer, \
+    QxzTypeConfigListSerializer, QxzElementAddSerializer, QxzElementModifySerializer, QxzElementDeleteSerializer, \
+    QxzElementListSerializer, QxzDeviceAddSerializer, QxzDeviceListSerializer
+from .models import QxzTypeConfigModel, QxzElementConfigModel, QxzDeviceConfigModel
+
+
+class QxzTypeConfigAddView(GenericAPIView):
+    # authentication_classes = [MyJWTAuthentication]
+    # permission_classes = [ModulePermission]
+    serializer_class = QxzTypeConfigAddSerializer
+    queryset = QxzTypeConfigModel.objects.all()
+
+    def post(self, request, *args, **kwargs):
+        """新增要素类型配置信息接口"""
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        data = serializer.validated_data
+        eNum = data['eNum']
+        cName = data['cName']
+        units = data['units']
+
+        queryset = self.get_queryset()
+        if queryset.filter(eNum=eNum):
+            return Response(data={"msg": "eNum已存在", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+
+        if queryset.filter(cName=cName):
+            return Response(data={"msg": "要素类型名称已存在", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+
+        qsc = QxzTypeConfigModel()
+        qsc.eNum = eNum
+        qsc.cName = cName
+        qsc.units = units
+        qsc.save()
+
+        return Response(data={"msg": "要素类型配置创建成功", "data": ""}, status=status.HTTP_200_OK)
+
+
+class QxzTypeConfigModifyView(GenericAPIView):
+    # authentication_classes = [MyJWTAuthentication]
+    # permission_classes = [ModulePermission]
+    serializer_class = QxzTypeConfigModifySerializer
+    queryset = QxzTypeConfigModel.objects.all()
+
+    def post(self, request, *args, **kwargs):
+        """修改要素类型配置信息接口"""
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        data = serializer.validated_data
+        qsc_id = data['qsc_id']
+        cName = data['cName']
+        units = data['units']
+
+        queryset = self.get_queryset().exclude(id=qsc_id)
+        # if queryset.filter(eNum=eNum):
+        #     return Response(data={"msg": "eNum已存在", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+
+        if queryset.filter(cName=cName):
+            return Response(data={"msg": "要素类型名称已存在", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+
+        try:
+            qsc = QxzTypeConfigModel.objects.get(id=qsc_id)
+        except ObjectDoesNotExist as e:
+            return Response(data={"msg": "要素类型配置不存在", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+
+        if qsc.is_default:
+            return Response(data={"msg": "默认要素类型不允许修改", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+
+        qsc.cName = cName
+        qsc.units = units
+        qsc.save()
+
+        return Response(data={"msg": "要素类型配置修改成功", "data": ""}, status=status.HTTP_200_OK)
+
+
+class QxzTypeConfigDeleteView(GenericAPIView):
+    # authentication_classes = [MyJWTAuthentication]
+    # permission_classes = [ModulePermission]
+    serializer_class = QxzTypeConfigDeleteSerializer
+    queryset = QxzTypeConfigModel.objects.all()
+
+    def post(self, request, *args, **kwargs):
+        """删除要素类型配置信息接口"""
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        data = serializer.validated_data
+        qsc_id = data['qsc_id']
+
+        try:
+            qsc = QxzTypeConfigModel.objects.get(id=qsc_id)
+        except ObjectDoesNotExist as e:
+            return Response(data={"msg": "要素类型配置不存在", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+        if qsc.is_default:
+            return Response(data={"msg": "默认要素类型不允许删除", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+
+        QxzElementConfigModel.objects.filter(eNum=qsc.eNum).delete()
+        qsc.delete()
+
+        return Response(data={"msg": "要素类型配置删除成功", "data": ""}, status=status.HTTP_200_OK)
+
+
+class QxzTypeConfigListView(GenericAPIView):
+    # authentication_classes = [MyJWTAuthentication]
+    # permission_classes = [ModulePermission]
+    pagination_class = CustomPagination
+    serializer_class = QxzTypeConfigListSerializer
+    queryset = QxzTypeConfigModel.objects.all().order_by('-id')
+
+    def post(self, request, *args, **kwargs):
+        """获取要素类型配置列表接口"""
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        data = serializer.validated_data
+        cName = data.get('cName', '').strip()
+        is_default = data.get('is_default')
+        queryset = self.get_queryset()
+        if cName:
+            queryset = queryset.filter(cName__contains=cName)
+        if is_default in [True, False]:
+            queryset = queryset.filter(is_default=is_default)
+
+        page = self.paginate_queryset(queryset)
+        serializer = self.get_serializer(page, many=True)
+        return self.get_paginated_response(serializer.data)
+
+
+class QxzElementAddView(GenericAPIView):
+    # authentication_classes = [MyJWTAuthentication]
+    # permission_classes = [ModulePermission]
+    serializer_class = QxzElementAddSerializer
+    queryset = QxzElementConfigModel.objects.all().order_by('-id')
+
+    def post(self, request, *args, **kwargs):
+        """新增要素信息接口"""
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        data = serializer.validated_data
+
+        eName = data['eName']
+        cName = data['cName']
+        eNum = data['eNum']
+        units = data['units']
+        is_standard = data['is_standard']
+        sensor_addr = data['sensor_addr']
+        start_reg = data['start_reg']
+        count = data['count']
+        d_pos = data['d_pos']
+        d_length = data['d_length']
+        factor = data['factor']
+        dotled_s = data['dotled_s']
+
+        queryset = self.get_queryset()
+        if queryset.filter(eName=eName):
+            return Response(data={"msg": "英文名称不能重复", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+
+        try:
+            t = QxzTypeConfigModel.objects.get(eNum=eNum)
+            if t.units != units:
+                raise Exception()
+        except Exception as e:
+            return Response(data={"msg": "要素类型异常", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+
+        qec = QxzElementConfigModel()
+        qec.eName = eName
+        qec.cName = cName
+        qec.units = units
+        qec.eNum = eNum
+        qec.is_standard = is_standard
+        qec.sensor_addr = sensor_addr
+        qec.start_reg = start_reg
+        qec.count = count
+        qec.d_pos = d_pos
+        qec.d_length = d_length
+        qec.factor = factor
+        qec.dotled_s = dotled_s
+        qec.save()
+
+        return Response(data={"msg": "创建要素成功", "data": ""}, status=status.HTTP_200_OK)
+
+
+class QxzElementModifyView(GenericAPIView):
+    # authentication_classes = [MyJWTAuthentication]
+    # permission_classes = [ModulePermission]
+    serializer_class = QxzElementModifySerializer
+    queryset = QxzElementConfigModel.objects.all().order_by('-id')
+
+    def post(self, request, *args, **kwargs):
+        """修改要素信息接口"""
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        data = serializer.validated_data
+        qec_id = data['qec_id']
+        eName = data['eName']
+        cName = data['cName']
+        is_standard = data['is_standard']
+        sensor_addr = data['sensor_addr']
+        start_reg = data['start_reg']
+        count = data['count']
+        d_pos = data['d_pos']
+        d_length = data['d_length']
+        factor = data['factor']
+        dotled_s = data['dotled_s']
+
+        try:
+            qec = self.get_queryset().get(id=qec_id)
+        except ObjectDoesNotExist as e:
+            return Response(data={"msg": "要素不存在", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+
+        queryset = self.get_queryset().exclude(id=qec_id)
+        if queryset.filter(eName=eName):
+            return Response(data={"msg": "英文名称不能重复", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+
+        qec.eName = eName
+        qec.cName = cName
+        qec.is_standard = is_standard
+        qec.sensor_addr = sensor_addr
+        qec.start_reg = start_reg
+        qec.count = count
+        qec.d_pos = d_pos
+        qec.d_length = d_length
+        qec.factor = factor
+        qec.dotled_s = dotled_s
+        qec.save()
+
+        return Response(data={"msg": "修改要素成功", "data": ""}, status=status.HTTP_200_OK)
+
+
+class QxzElementDeleteView(GenericAPIView):
+    # authentication_classes = [MyJWTAuthentication]
+    # permission_classes = [ModulePermission]
+    serializer_class = QxzElementDeleteSerializer
+    queryset = QxzElementConfigModel.objects.all().order_by('-id')
+
+    def post(self, request, *args, **kwargs):
+        """删除要素信息接口"""
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        data = serializer.validated_data
+        qec_id = data['qec_id']
+
+        try:
+            qec = self.get_queryset().get(id=qec_id)
+        except ObjectDoesNotExist as e:
+            return Response(data={"msg": "要素不存在", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+        qec.delete()
+
+        return Response(data={"msg": "删除要素成功", "data": ""}, status=status.HTTP_200_OK)
+
+
+class QxzElementListView(GenericAPIView):
+    # authentication_classes = [MyJWTAuthentication]
+    # permission_classes = [ModulePermission]
+    pagination_class = CustomPagination
+    serializer_class = QxzElementListSerializer
+    queryset = QxzElementConfigModel.objects.all().order_by('-id')
+
+    def post(self, request, *args, **kwargs):
+        """获取要素列表接口"""
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        data = serializer.validated_data
+        ele_name = data.get('ele_name', '')
+        is_standard = data.get('is_standard')
+
+        queryset = self.get_queryset()
+        if ele_name:
+            queryset = queryset.filter(Q(cName__contains=ele_name) | Q(eName__contains=ele_name))
+        if is_standard is not None:
+            queryset = queryset.filter(is_standard=is_standard)
+        page = self.paginate_queryset(queryset)
+        serializer = self.get_serializer(page, many=True)
+        return self.get_paginated_response(serializer.data)
+
+
+class QxzDeviceAddView(GenericAPIView):
+    # authentication_classes = [MyJWTAuthentication]
+    # permission_classes = [ModulePermission]
+    serializer_class = QxzDeviceAddSerializer
+    queryset = QxzDeviceConfigModel.objects.all().order_by('-id')
+
+    def post(self, request, *args, **kwargs):
+        """创建气象配置信息接口"""
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        data = serializer.validated_data
+
+        device_id = data['device_id']
+        order_num = data['order_num']
+        device_type = data['device_type']
+        is_standard = data['is_standard']
+        ele_cnf = data['ele_cnf']
+        led_cnf = data['led_cnf']
+        file = request.FILES.get('file')
+
+        queryset = self.get_queryset().filter(device_id=device_id)
+        if queryset:
+            return Response(data={"msg": "设备配置已存在,请勿重复创建", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+
+        base_dir = f"/data/qxz/element/config/{device_id}"
+        if not os.path.isdir(base_dir):
+            os.makedirs(base_dir)
+
+        if file:
+            file_name = f"{device_id}.rbl"
+            file_path = os.path.join(base_dir, file_name)
+            with open(file_path, 'wb') as wb:
+                for chunk in file.chunks():
+                    wb.write(chunk)
+
+        config_sh_dict = {
+            "config": "ch_conf",
+            "ext": {
+                "App_mod": device_type,
+            }
+        }
+
+        e_name_list = list(ele_cnf.values())
+        e_value_dict = {}
+        for k, v in ele_cnf.items():
+            config_sh_dict["ext"][k] = v
+            e_value_dict[v] = k
+
+        sh_file_path = os.path.join(base_dir, 'configch.c')
+        with open(sh_file_path, 'w') as fw:
+            json.dump(config_sh_dict, fw, ensure_ascii=False)
+
+        if led_cnf:
+            led_dict = {
+                "cmd": "dotled_para",
+                "ext": led_cnf
+            }
+            sh_file_path = os.path.join(base_dir, 'configled.c')
+            with open(sh_file_path, 'w') as fw:
+                json.dump(led_dict, fw, ensure_ascii=False)
+
+        c_name_list = []
+        config_list = []
+        queryset = QxzElementConfigModel.objects.filter(eName__in=e_name_list)
+        num = 0
+        for item in queryset:
+            eName = item.eName
+            cName = f"{item.cName}:"
+            ekey = e_value_dict[eName]
+            c_name_list.append(item.cName)
+            config_list.append({
+                'num': num, 'sensor_addr': item.sensor_addr, 'start_reg': item.start_reg, 'count': item.count,
+                'd_pos': item.d_pos, 'factor': item.factor, 'd_length': item.d_length, 'err_cnt': 0, 'online_flag': 0,
+                'value': 0, 'cName': cName, 'units': item.units, 'eName': item.eName, 'eValue': '0',
+                'eKey': ekey, 'eNum': item.eNum, 'dotled_s': item.dotled_s
+            })
+            num += 1
+
+        c_num = 1
+        for i in range(0, len(config_list), 15):
+            c_list = config_list[i: i+15]
+            c_path = os.path.join(base_dir, f'config0{c_num}.c')
+            with open(c_path, 'w') as fw:
+                c_data = {
+                    "element": c_list
+                }
+                json.dump(c_data, fw, ensure_ascii=False)
+            c_num += 1
+
+        qdc = QxzDeviceConfigModel()
+        qdc.device_id = device_id
+        qdc.order_num = order_num
+        qdc.device_type = device_type
+        qdc.is_standard = is_standard
+        qdc.ele_cnf = json.dumps(ele_cnf, ensure_ascii=False)
+        qdc.led_cnf = json.dumps(led_cnf, ensure_ascii=False)
+        qdc.ele_name = json.dumps(c_name_list, ensure_ascii=False)
+        qdc.save()
+
+        return Response(data={"msg": "创建设备配置成功", "data": ""}, status=status.HTTP_200_OK)
+
+
+class QxzDeviceModifyView(GenericAPIView):
+    # authentication_classes = [MyJWTAuthentication]
+    # permission_classes = [ModulePermission]
+    serializer_class = QxzDeviceAddSerializer
+    queryset = QxzDeviceConfigModel.objects.all().order_by('-id')
+
+    def post(self, request, *args, **kwargs):
+        """修改气象配置信息接口"""
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        data = serializer.validated_data
+
+        device_id = data['device_id']
+        order_num = data['order_num']
+        device_type = data['device_type']
+        is_standard = data['is_standard']
+        ele_cnf = data['ele_cnf']
+        led_cnf = data['led_cnf']
+        file = request.FILES.get('file')
+
+        try:
+            qdc = self.get_queryset().get(device_id=device_id)
+        except ObjectDoesNotExist as e:
+            return Response(data={"msg": "设备配置不存在", "data": ""}, status=status.HTTP_400_BAD_REQUEST)
+
+        base_dir = f"/data/qxz/element/config/{device_id}"
+        if not os.path.isdir(base_dir):
+            os.makedirs(base_dir)
+
+        if file:
+            file_name = f"{device_id}.rbl"
+            file_path = os.path.join(base_dir, file_name)
+            with open(file_path, 'wb') as wb:
+                for chunk in file.chunks():
+                    wb.write(chunk)
+
+        config_sh_dict = {
+            "config": "ch_conf",
+            "ext": {
+                "App_mod": device_type,
+            }
+        }
+
+        e_name_list = list(ele_cnf.values())
+        e_value_dict = {}
+        for k, v in ele_cnf.items():
+            config_sh_dict["ext"][k] = v
+            e_value_dict[v] = k
+
+        sh_file_path = os.path.join(base_dir, 'configch.c')
+        with open(sh_file_path, 'w') as fw:
+            json.dump(config_sh_dict, fw, ensure_ascii=False)
+
+        if led_cnf:
+            led_dict = {
+                "cmd": "dotled_para",
+                "ext": led_cnf
+            }
+            sh_file_path = os.path.join(base_dir, 'configled.c')
+            with open(sh_file_path, 'w') as fw:
+                json.dump(led_dict, fw, ensure_ascii=False)
+
+        c_name_list = []
+        config_list = []
+        queryset = QxzElementConfigModel.objects.filter(eName__in=e_name_list)
+        num = 0
+        for item in queryset:
+            eName = item.eName
+            cName = f"{item.cName}:"
+            ekey = e_value_dict[eName]
+            c_name_list.append(item.cName)
+            config_list.append({
+                'num': num, 'sensor_addr': item.sensor_addr, 'start_reg': item.start_reg, 'count': item.count,
+                'd_pos': item.d_pos, 'factor': item.factor, 'd_length': item.d_length, 'err_cnt': 0, 'online_flag': 0,
+                'value': 0, 'cName': cName, 'units': item.units, 'eName': item.eName, 'eValue': '0',
+                'eKey': ekey, 'eNum': item.eNum, 'dotled_s': item.dotled_s
+            })
+            num += 1
+
+        c_num = 1
+        for i in range(0, len(config_list), 15):
+            c_list = config_list[i: i+15]
+            c_path = os.path.join(base_dir, f'config0{c_num}.c')
+            with open(c_path, 'w') as fw:
+                c_data = {
+                    "element": c_list
+                }
+                json.dump(c_data, fw, ensure_ascii=False)
+            c_num += 1
+
+        qdc.order_num = order_num
+        qdc.device_type = device_type
+        qdc.is_standard = is_standard
+        qdc.ele_cnf = json.dumps(ele_cnf, ensure_ascii=False)
+        qdc.led_cnf = json.dumps(led_cnf, ensure_ascii=False)
+        qdc.ele_name = json.dumps(c_name_list, ensure_ascii=False)
+        qdc.save()
+
+        return Response(data={"msg": "修改设备配置成功", "data": ""}, status=status.HTTP_200_OK)
+
+
+class QxzDeviceListView(GenericAPIView):
+    # authentication_classes = [MyJWTAuthentication]
+    # permission_classes = [ModulePermission]
+    pagination_class = CustomPagination
+    serializer_class = QxzDeviceListSerializer
+    queryset = QxzDeviceConfigModel.objects.all().order_by('-id')
+
+    def post(self, request, *args, **kwargs):
+        """获取气象配置列表接口"""
+        serializer = self.get_serializer(data=request.data)
+        serializer.is_valid(raise_exception=True)
+        data = serializer.validated_data
+
+        device_id = data['device_id']
+        queryset = self.get_queryset()
+        if device_id:
+            queryset = queryset.filter(Q(device_id__contains=device_id) | Q(order_num__contains=device_id))
+        page = self.paginate_queryset(queryset)
+        serializer = self.get_serializer(page, many=True)
+        return self.get_paginated_response(serializer.data)
+
+
+
+def init_data():
+    data = {
+        '101': ['101', '大气温度', '℃'],
+        '102': ['102', '大气湿度', '%RH'],
+        '103': ['103', '模拟气压', 'hpa'],
+        '104': ['104', '雨量', 'mm'],
+        '105': ['105', '简易总辐射', 'w/㎡'],
+        '106': ['106', '土壤温度', '℃'],
+        '107': ['107', '土壤湿度', '%RH'],
+        '108': ['108', '风速', 'm/s'],
+        '109': ['109', '风向', '°'],
+        '110': ['110', '蒸发', 'mm'],
+        '111': ['111', '雪量', 'mm'],
+        '112': ['112', '照度', 'LUX'],
+        '113': ['113', '日照时数', 'h'],
+        '114': ['114', '光合', 'w/㎡'],
+        '115': ['115', '雨量累计', 'mm'],
+        '116': ['116', '辐射累计', 'MJ/㎡'],
+        '117': ['117', '有无雨雪', ''],
+        '118': ['118', '噪声', '分贝'],
+        '119': ['119', '水位', 'cm'],
+        '120': ['120', '二氧化碳', 'PPM'],
+        '121': ['121', '曝辐量', 'cal/cm2'],
+        '122': ['122', '液位', 'mm'],
+        '123': ['123', '光合有效辐射', 'W/m2'],
+        '124': ['124', '电压', 'V'],
+        '125': ['125', '紫外线', 'w/㎡'],
+        '126': ['126', '粉尘', 'ug/m3'],
+        '127': ['127', '数字气压', 'hpa'],
+        '128': ['128', 'PH值', ''],
+        '129': ['129', '最大风速', 'm/s'],
+        '130': ['130', '平均风速', 'm/s'],
+        '131': ['131', '经度', '°'],
+        '132': ['132', '纬度', '°'],
+        '133': ['133', '海拔高度', 'm'],
+        '134': ['134', 'TBQ总辐射', 'W/m2'],
+        '135': ['135', '直接辐射', 'W/m2'],
+        '136': ['136', '散射辐射', 'W/m2'],
+        '138': ['138', '紫外辐射', 'W/m2'],
+        '139': ['139', '贴片温度', '℃'],
+        '140': ['140', '露点温度', '℃'],
+        '141': ['141', '一氧化碳', 'PPM'],
+        '142': ['142', '电流', 'mA'],
+        '143': ['143', '超声波风速', 'm/s'],
+        '144': ['144', '水温', '℃'],
+        '145': ['145', 'PM2.5', 'ug/m3'],
+        '146': ['146', 'PM10', 'ug/m3'],
+        '147': ['147', 'PH', ''],
+        '148': ['148', '溶解氧', 'mg/l'],
+        '149': ['149', '氨氮', 'mg/l'],
+        '150': ['150', '电导率', 'mS/cm'],
+        '151': ['151', '浊度', 'NTU'],
+        '152': ['152', '能见度', 'm'],
+        '153': ['153', '氨气', 'ppm'],
+        '154': ['154', '盐分', 'mg/L'],
+        '155': ['155', '氮', 'mg/kg'],
+        '156': ['156', '磷', 'mg/kg'],
+        '157': ['157', '钾', 'mg/kg'],
+        '158': ['158', '热通量', 'W/m2'],
+        '159': ['159', '叶面温度', '℃'],
+        '160': ['160', '叶面湿度', '%RH'],
+        '161': ['161', '茎秆', 'mm'],
+        '162': ['162', '负氧离子', '个/cm3'],
+        '201': ['201', '土壤水势', 'KPA'],
+        '202': ['202', '露点温度', '℃'],
+        '203': ['203', 'PM100', 'ug/m3'],
+        '208': ['208', '照度', 'Lux'],
+        '211': ['211', '电导率', 'uS/cm'],
+        '212': ['212', '净辐射', 'W/m2'],
+        '213': ['213', '流速', 'm/s'],
+        '214': ['214', '空高', 'm'],
+        '215': ['215', '瞬时流量', 'm3/s'],
+        '216': ['216', '累积流量', 'm3'],
+        '217': ['217', '热通量累计', 'MJ/m2'],
+        '218': ['218', '果实直径', 'mm'],
+        '219': ['219', '硫化氢', 'ppm'],
+        '220': ['220', '氧气', 'ppm'],
+        '221': ['221', '臭氧', 'ppm'],
+        '222': ['222', '茎流', 'ml/h'],
+        '223': ['223', 'COD', 'mg/L'],
+        '224': ['224', '信号强度', 'dBm'],
+        '225': ['225', '盐度', 'PSU'],
+        '226': ['226', 'ORP', 'mV'],
+        '227': ['227', '光量子', 'W/m2'],
+        '228': ['228', '水质pH', ' '],
+        '229': ['229', '氨氮', 'ppm'],
+        '230': ['230', '水位', 'm'],
+        '251': ['251', '湿球温度', '℃'],
+        '252': ['252', '最大阵风', 'm/s'],
+        '255': ['255', '土壤张力', 'kpa']
+    }
+
+    for item in data.values():
+        c = QxzTypeConfigModel()
+        c.eNum = item[0]
+        c.cName = item[1]
+        c.units = item[2]
+        c.save()
+
+

+ 1 - 0
bigdataAPI/settings.py

@@ -57,6 +57,7 @@ INSTALLED_APPS = [
     'apps.IOTCard',
     'apps.PestAnalysis',
     'apps.Equipment',
+    'apps.QxzApp'
 ]
 
 MIDDLEWARE = [

+ 1 - 0
bigdataAPI/urls.py

@@ -22,4 +22,5 @@ urlpatterns = [
     path('user/', include('apps.UserApp.urls')),
     path('equipment/', include('apps.Equipment.urls')),
     path('pestanalysis/', include('apps.PestAnalysis.urls')),
+    path('qxzconfig/', include('apps.QxzApp.urls'))
 ]