import io import json import os from django.http import HttpResponse from django.shortcuts import render from rest_framework.response import Response from rest_framework import status from rest_framework.generics import GenericAPIView from rest_framework.views import APIView from django.db.models import ObjectDoesNotExist, Q from utils.JWTAuthentication_diy import MyJWTAuthentication from utils.permissions import QxzLoginPermission from utils.paginations import CustomPagination from .serializers import QxzTypeConfigAddSerializer, QxzTypeConfigModifySerializer, QxzTypeConfigDeleteSerializer, \ QxzTypeConfigListSerializer, QxzElementAddSerializer, QxzElementModifySerializer, QxzElementDeleteSerializer, \ QxzElementListSerializer, QxzDeviceAddSerializer, QxzDeviceListSerializer from .models import QxzTypeConfigModel, QxzElementConfigModel, QxzDeviceConfigModel import jwt class UserLoginView(APIView): def post(self, request, *args, **kwargs): """用户登录接口""" username = request.data.get('username') password = request.data.get('password') print(username, password) if username == "admin" and password == "hnyfqxz": token = jwt.encode({"username": username, "password": password}, "secret", algorithm="HS256").decode('utf-8') request.session["hnyfqxz"] = token request.session.save() return Response({'msg': "登录成功", "token": token}, status=200) return Response({'msg': "登录失败,用户名或密码不正确"}, status=400) class UserLogoutView(APIView): permission_classes = [QxzLoginPermission] def post(self, request, *args, **kwargs): """用户退出接口""" try: del request.session['hnyfqxz'] request.session.save() except Exception as e: pass return Response({'msg': "退出成功"}, status=200) class QxzTypeConfigAddView(GenericAPIView): # authentication_classes = [MyJWTAuthentication] permission_classes = [QxzLoginPermission] 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 = [QxzLoginPermission] 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 = [QxzLoginPermission] 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 = [QxzLoginPermission] 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 = [QxzLoginPermission] 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 = [QxzLoginPermission] 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 = [QxzLoginPermission] 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 = [QxzLoginPermission] 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 = [QxzLoginPermission] 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 = [QxzLoginPermission] 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 = [QxzLoginPermission] 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.get('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) class QxzConfigDownView(APIView): def get(self, request, device_id, file_name, *args, **kwargs): file_path = f"/data/qxz/element/config/{device_id}/{file_name}" if os.path.exists(file_path): with open(file_path, 'rb') as fr: content = fr.read() else: file_name = "null.c" content = b'' response = HttpResponse(content, content_type="application/octet-stream") response['Content-Disposition'] = f'attachment; filename={file_name}' response['Access-Control-Allow-Origin'] = "*" return response 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.is_default = True c.save()