yf_yzl 2 years ago
parent
commit
719c5ebdcc

BIN
bigdata_django/zhijian/qxz/__pycache__/mongoclient.cpython-36.pyc


BIN
bigdata_django/zhijian/qxz/__pycache__/special.cpython-36.pyc


BIN
bigdata_django/zhijian/qxz/__pycache__/utils.cpython-36.pyc


+ 165 - 0
bigdata_django/zhijian/qxz/main.py

@@ -0,0 +1,165 @@
+# encoding=utf-8
+
+from cgi import print_arguments
+from multiprocessing.managers import DictProxy
+from operator import delitem
+from unittest import result
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+import os
+import sys
+import re
+import ast
+from urllib import parse
+import json
+import time
+import datetime
+import requests
+import uuid
+import pymongo
+import pymysql
+from collections import defaultdict, Counter
+
+from xlsxwriter.workbook import Workbook
+from mongoclient import (
+    get_qxz_conf, 
+    device_detail_deivce_id, 
+    get_sa_qxz_info_record,
+    get_sa_qxz_data,
+    get_conf_data,
+    get_sim_info
+)
+from utils import (
+    merge_title_format, 
+    toji_format, 
+    formal_format, 
+    error_format, 
+    common_format, 
+    default_formal,
+    get_excel_content,
+    head_dict,
+    sim_info
+)
+
+
+def run():
+    start = "2023-08-28 10:00:00"
+    end = "2023-08-31 20:00:00"
+    dever_num = "111"
+    # 获取所有的device_id
+    device_list = get_excel_content("F:\\scripting_tools\\热通量增加测试.xlsx")
+    workbook = Workbook("F:\\test.xlsx")
+    worksheet = workbook.add_worksheet()
+    merge_title_style = workbook.add_format(merge_title_format)
+    toji_style = workbook.add_format(toji_format)
+    default_style = workbook.add_format(default_formal)
+    red_style = workbook.add_format(error_format)
+    green_style = workbook.add_format(formal_format)
+    yellow_style = workbook.add_format(common_format)
+    style_dict = {
+        2: red_style,
+        1: green_style,
+        3: yellow_style,
+        4: default_style
+    }
+
+    title_name_list = [
+        "ID", 
+        "检验项目", 
+        "电压", 
+        "信号强度", 
+        "经度", 
+        "纬度", 
+        "固件版本号", 
+        "sim卡信息",
+        "位置信息"
+    ]
+    # 查找第一台设备的配置文件,获取配置项
+    device_id, _, _, _, _ = device_detail_deivce_id(device_list[0])
+    conf = get_qxz_conf(device_id)
+    title_name_list += [v.split("#")[0] for k, v in conf.items()]
+    title_name_list.append("单台合格数")
+    head_list = [i.split("#")[0] for i in title_name_list]
+    worksheet.merge_range(0, 0, 0, len(head_list) - 1, "物联网气象站设备质检表格", merge_title_style)
+    toji_data = [
+        "任务单号", 
+        "set_order", 
+        "检验时间", 
+        "start_time_str", 
+        "end_time_str",
+        "报告日期", 
+        (datetime.datetime.now()).strftime("%y-%m-%d %H:%M:%S"), 
+        "合格数"
+    ]
+    # 生成Excel表格第2行, 本次数据概要
+    for index, k in enumerate(toji_data):
+        value = str(k)
+        worksheet.write(1, index, value, toji_style)
+    # 生成Excel表格第3行, 检测标题
+    for index, k in enumerate(title_name_list):
+        worksheet.write(2, index, k, default_style)
+    # 生成Excel表格第4行, 检测标准
+    for index, k in enumerate(title_name_list):
+        value = (head_dict.get(k, ["无判定条件", ""]))[0]
+        worksheet.write(3, index, value, default_style)
+        plus = 12 if index in [0, 1] else 8
+        c_n = len(value) / 2 + plus
+        worksheet.set_column(index, index, c_n)
+    # 输入数据
+    is_pass_count = 0
+    for index, id in enumerate(device_list):
+        device_id, dver_num, lng, lat, position = device_detail_deivce_id(id)
+        # 获取电压,信号强度历史数据
+        valt_rssi = get_sa_qxz_info_record(device_id, start, end)
+        # 获取sim卡信息
+        sim = get_sim_info(device_id, start, end)
+        sim_in = sim_info(sim)
+        # 第一部分拼接 表头及数据
+        org_data = {
+            "id_1": {"data": id, "explan": "ID"},
+            "id_2": {"data": device_id, "explan": "检验项目"},
+            "id_3": valt_rssi.get("volt"),  # 电压
+            "id_4": valt_rssi.get("rssi"),  # 信号强度
+            "id_5": {"data": lng, "explan": "经度"},
+            "id_6": {"data": lat, "explan": "纬度"},
+            "id_7": {"data": [dver_num.replace("/", "-"), dever_num], "explan": "固件版本号"},
+            "id_8": {"data": sim_in, "explan": "sim卡信息"},
+            "id_9": {"data": position, "explan": "位置信息"},
+        }
+        conf = get_qxz_conf(device_id)
+        # 获取数据
+        qx_data = get_sa_qxz_data(device_id, start, end, conf)
+        # 第二部分拼接 表头及数据   获取气象与数据结合
+        conf_data = get_conf_data(conf, qx_data)
+        org_data.update(conf_data)
+        i = 0
+        is_right = 0
+        for t, v in org_data.items():
+            # 执行方法
+            name = v.get("explan")
+            data = v.get("data")
+            func = head_dict.get(name)[1]
+            if data:
+                print(name)
+                print(data)
+                print("-"*100)
+                temp = func(data)
+                if temp[0] == 1:
+                    is_right += 1
+            else:
+                temp = [2, "没有数据"]
+            worksheet.write(index + 4, i, temp[1], style_dict[temp[0]])
+            i += 1
+        last = []
+        if is_right == len(title_name_list) - 3:
+            last = [1, "合格"]
+            is_pass_count += 1
+        else:
+            last = [2, f"不合格: {len(title_name_list) - is_right - 3}"]
+        worksheet.write(index + 4, i, last[1], style_dict[last[0]])
+    worksheet.write(1, 8, is_pass_count, toji_style)
+    workbook.close()
+
+
+if __name__ == "__main__":
+    run()

+ 50 - 7
bigdata_django/zhijian/qxz/mongoclient.py

@@ -1,6 +1,8 @@
+from distutils.command.config import config
 import pymongo
 from urllib import parse
 import datetime
+import re
 
 
 def get_table():
@@ -20,7 +22,7 @@ def get_device_info(device_id):
     return device
 
 
-def get_qxz_base_info(device_id, start, end):
+def get_sim_info(device_id, start, end):
     start = int((datetime.datetime.strptime(start, "%Y-%m-%d %H:%M:%S")).timestamp())
     end = int((datetime.datetime.strptime(end, "%Y-%m-%d %H:%M:%S")).timestamp())
     # sim卡信息
@@ -39,7 +41,11 @@ def get_sa_qxz_info_record(device_id, start, end):
     qxz_info_record = db.sa_qxz_info_record
     query = {'device_id': device_id, 'uptime': {"$lte": end, "$gte": start}}
     info_record = qxz_info_record.find(query, {"_id": 0, 'volt': 1, "rssi": 1})
-    return info_record
+    result = {"volt": {"data": [], "explan": "电压"}, "rssi": {"data": [], "explan": "信号强度"}}
+    for k in info_record:
+        result["volt"]["data"].append(float(k.get("volt")))
+        result["rssi"]["data"].append(float(k.get("rssi")))
+    return result
 
 
 def get_sa_qxz_data(device_id, start, end, conf):
@@ -51,18 +57,20 @@ def get_sa_qxz_data(device_id, start, end, conf):
     query = {'device_id': device_id, 'uptime': {"$lte": end, "$gte": start}}
     field = conf.keys()
     fields = {i: 1 for i in field}
-    fields.update({"_id": 0})
-    data = qxz_data.find(query, fields)
+    fields.update({"_id": 0, "uptime": 1})
+    data = qxz_data.find(query, fields).sort("uptime", pymongo.DESCENDING)
     return list(data)
 
 
 def get_qxz_conf(device_id):
+    print(device_id)
     # 获取配置文件
     db = get_table()
     qxz_conf = db.sa_qxz_conf
     query = {'device_id': device_id}
     conf = qxz_conf.find_one(query, {"_id": 0, "uptime": 0, "device_id": 0, "id": 0})
     conf = {k: v for k, v in conf.items() if v is not None and v != ""}
+    conf.update({"uptime": "上传数据条数#999#个"})
     return conf
 
 
@@ -70,19 +78,54 @@ def get_conf_data(conf, data):
     conf_keys = conf.keys()
     results = {}
     for i in conf_keys:
+        temp = []
+        for detail in data:
+            value = str(detail.get(i))
+            va_sp = value.split("#")
+            # if len(va_sp) == 3:
+            vk = float(va_sp[0])
+            if vk > 9999999999:
+                temp.append(9999999999)
+            elif vk < -9999999999:
+                temp.append(-9999999999)
+            else:
+                temp.append(vk)
         results[i] = {
-            "data": [k.get(i) for k in data],
-            "explan": conf.get(i)
+            "data": temp,
+            "explan": (conf.get(i)).split("#")[0]
         }
     return results
 
 
+def device_detail_deivce_id(short_id):
+    """确定设备所在平台以及完整设备号"""
+    db = get_table()
+    regex = re.compile('.*{}$'.format(short_id))
+    bd_device_dict = db.sa_device.find_one(
+        filter = {"device_id":regex,"device_type_id":5},
+        projection = {'_id': 0},
+        sort = [('uptime', pymongo.DESCENDING)]
+    )
+    if bd_device_dict:
+        device_id = bd_device_dict.get("device_id")
+        position = bd_device_dict.get("province") + bd_device_dict.get("city")+ bd_device_dict.get("district")
+        lng, lat = "", ""
+        try:
+            lng = float(bd_device_dict.get("lng"))
+            lat = float(bd_device_dict.get("lat"))
+        except Exception as e:
+            print(e)
+        return device_id, bd_device_dict.get("dver_num"), lng, lat, position
+    else:
+        return None, "", "", "", ""
+
+
 if __name__ == "__main__":
     device_id = '864865060471399'
     get_device_info(device_id)
     start = "2023-08-28 10:00:00"
     end = "2023-08-31 20:00:00"
-    base_info = get_qxz_base_info(device_id, start, end)
+    base_info = get_sim_info(device_id, start, end)
     conf = get_qxz_conf(device_id)
     data = get_sa_qxz_data(device_id, start, end, conf)
     result = get_conf_data(conf, data)

+ 635 - 0
bigdata_django/zhijian/qxz/special.py

@@ -0,0 +1,635 @@
+def check_id(data):
+    return 1, data 
+
+
+def jiao_yan_xiang_mu(data):
+    return 1, data
+
+# 经度  113.7869444 113.7536111
+def jing_du(data):
+    if data:
+        if 113.7869444 > data > 113.7536111:
+            return 1, data 
+        else:
+            return 2, data
+    else:
+        return 2, data
+
+
+# 纬度  35.0458333 35.0125
+def weidu_du(data):
+    if data:
+        if 35.0458333 > data > 35.0125:
+            return 1, data 
+        else:
+            return 2, data
+    else:
+        return 2, data
+# 固件版本号
+def gu_jian_ban_ben(data):
+    if data[0] == data[1]:
+        return 1, data[0]
+    else:
+        return 2, f"设备{data[0]},输入{data[1]}"
+
+# 电压 合格条件(绿色):\n11~15
+def dian_ya(data):
+    if data:
+        min_num = min(data)
+        max_num = max(data)
+        if 11.0 < min_num and max_num < 15.0:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# 信号 合格条件(绿色):\n>14
+def xin_hao(data):
+    if data:
+        min_num = min(data)
+        max_num = max(data)
+        if 14.0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+# sim卡信息 大于等于180天单元格显示绿色\n2、小于180天大于等于30天单元格显示黄色、\n3、小于30天单元格显示为红色
+def sim(data):
+    if 180 <= data:
+        return 1, f"有效期剩余{data}天" 
+    elif 30 <= data < 180:
+        return 3, f"有效期剩余{data}天" 
+    elif  data < 30:
+        return 2, f"有效期剩余{data}天" 
+
+def wei_zhi(data):
+    if data == "河南省新乡市原阳县":
+        return 1, data
+    else:
+        return 2, data
+
+
+# 上传数据条数 合格条件(绿色):\n1、大于7条\n2、两条数据时间间隔小于20分钟的出现频次2次以内、两条数据间隔大于40分钟出现频率2次以内
+def shu_ju_tiao_shu(data):
+    if data:
+        if len(data) > 7:
+            # 计算数据间隔
+            interval = []
+            for k in range(len(data) - 1):
+                interval.append(data[k+1] - data[k])
+            lte_20 = []
+            gte_40 = []
+            for i in interval:
+                if i < 120:
+                    lte_20.append(i)
+                if i > 240:
+                    gte_40.append(i)
+            if len(lte_20) < 2 and len(gte_40) < 2:
+                return 1,  f"数据量:{len(data)},间隔<20分钟:{len(lte_20)},间隔>40分钟:{len(gte_40)}"
+            else:
+                return 2, f"数据量:{len(data)},间隔<20分钟:{len(lte_20)},间隔>40分钟:{len(gte_40)}"
+        else:
+            return 2, f"数据量:{len(data)}"
+    else:
+        return 2, "无数据"
+
+
+
+# "风速": "合格条件(绿色):\n1、0<示值<10\n2、有1条合格 即可",
+def feng_su(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num and max_num < 10:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "风向": "合格条件(绿色):\n1、0<示值<360\n2、有1条合格即可"
+def feng_xiang(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num and max_num < 360:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+    
+# "降雨量累计": "合格条件(绿色):\n1、0<示值\n2、00:00示值归零\n3、有1条合格即可"
+def jiang_yu(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0.1 < min_num :
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+
+# "土壤含水率": "合格条件(绿色):\n1、0<示值<=100\n2、有1条合格即可
+def tu_rang_han_shui(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num and max_num <= 100:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "土壤温度": "合格条件(绿色):\n1.≠0且在-5~35°C之间\n2、有1条合格即可"
+def tu_rang_wen_du(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if -5 < min_num and max_num < 35:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+# "盐分": "合格条件(绿色):\n1、0<示值<1000#2、有1条合格即可",
+def yan_fen(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num and max_num < 1000:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+# "电导率": "合格条件(绿色):\n1、0<示值\n2、有1条合格即"
+def dian_dao_lv(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+# "氮": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
+def dan(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num :
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+# "磷": "合格条件(绿色):\n1、0<示值且不能为负值\n2、有1条合格即可",
+def lin(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "光合有效辐射": "合格条件(绿色):\n1、0<示值且不能为负值\n2、有1条合格即可",
+def guang_he_fu_she(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "日照时数": "合格条件(绿色):\n1、0.1≤示值\n2、有1条合格即可",
+def ri_zhao(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0.1 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "PM2.5": "合格条件(绿色):\n1、0<示值且不能为负值\n2、有1条合格即可",
+def pm25(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "PM10": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
+def pm10(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "负氧离子": "合格条件(绿色):\n1、0<示值<1000\n2、有1条合格即可",
+def fu_li_zi(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num and max_num < 1000:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+
+# "总辐射": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
+def zong_fu_she(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "二氧化碳": "合格条件(绿色):\n1、400<示值<1500\n2、有1条合格即可",
+def er_yang_hua_tan(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 400 < min_num and max_num < 1500:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "蒸发量": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
+def zheng_fa(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "土壤PH": "合格条件(绿色):\n1、6~8\n2、有1条合格即可",
+def tu_rang_ph(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 6 < min_num and max_num < 8:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+
+# "钾": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
+def jia(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "紫外辐射": "合格条件(绿色):\n1、0<示 值\n2、有1条合格即可",
+def zi_wai_fu_she(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "空气温度": "合格条件(绿色):\n1.-10~35°C,但不允许为0°C\n2、有1条合格即可",
+def keong_qi_wen_du(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if -10 < min_num and max_num < 35 and 0.0 not in data:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "空气湿度": "合格条件(绿色):\n1、0<示值<100\n2、有1条合格即可",
+def keong_qi_shi_du(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num and max_num < 100:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "水质pH": "合格条件(绿色):\n1、6≤示值≤8\n2、有1条合格即可",
+def shui_zhi_ph(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 6 < min_num and max_num < 8:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "水位": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
+def shui_wei(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "水质电导率": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
+def shui_zhi_dao_dian(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+# "气压": "合格条件(绿色):\n1、900<示值<1150\n2、有1条合格即可",
+def qi_ya(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 900 < min_num and max_num < 1150:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "光照度": "合格条件(绿色):\n1、0<示值<200000\n2、有1条合格即可",
+def guang_zhao_du(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num and max_num < 200000:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "硫化氢": "合格条件(绿色):\n1、示值=0\n2、有1条合格即可",
+def liu_hua_qing(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        data = list(set(data))
+        if len(data) == 1 and data[0] == 0:
+            return 1, 0
+        else:
+            return 2, 0
+    else:
+        return 2, 0
+
+
+# "水温": "合格条件(绿色):\n1.0~30°C,但不允许为0°C\n2、 有1条合格即可",
+def shui_wen(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 1.0 < min_num and max_num < 30:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "溶解氧": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
+def rong_jie_yang(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+# "浊度": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
+def zhuo_du(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+# "氨气": "合格条件(绿色):\n1、示值=0\n2、有1条合格即可",
+def an_qi(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        data = list(set(data))
+        if len(data) == 1 and data[0] == 0:
+            return 1, 0
+        else:
+            return 2, 0
+    else:
+        return 2, "没有数据"
+
+
+# "氧气": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
+def yang_qi(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "PM100": "合格条件(绿色):\n1、0<示值\n2 、有1条合格即可",
+def pm100(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if 0 < min_num:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+
+# "露点温度": "合格条件(绿色):\n1.-10~35°C,但不允许为0°C\n2、有1条合格即可",
+def lou_dian_wen_du(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if -10 < min_num and max_num < 35 and 0.0 not in data:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+# 热通量  上传条数的数据在均在±500内(但不能为0),即判定合格,否则不合格
+def re_tong_liang(data):
+    if data:
+        # 去除字段中 -99.99 数据
+        data = [i for i in data if i != -99.99]
+        min_num = min(data)
+        max_num = max(data)
+        if -500 < min_num and max_num < 500 and 0.0 not in data:
+            return 1, f"最小值{min_num},最大值{max_num}"
+        else:
+            return 2, f"最小值{min_num},最大值{max_num}"
+    else:
+        return 2, "没有数据"
+
+# 合格数量
+def he_ge_shu(data):
+    return data[0], data[1]

+ 262 - 15
bigdata_django/zhijian/qxz/utils.py

@@ -1,12 +1,67 @@
 import json
+from operator import delitem
 import requests
 import datetime
+import re
+import pymongo
+from xlrd import open_workbook
+import openpyxl
+from special import (
+    check_id,
+    jiao_yan_xiang_mu,
+    jing_du,
+    weidu_du,
+    gu_jian_ban_ben,
+    dian_ya,
+    xin_hao,
+    sim,
+    wei_zhi,
+    shu_ju_tiao_shu,
+    feng_su,
+    feng_xiang,
+    jiang_yu,
+    tu_rang_han_shui,
+    tu_rang_wen_du,
+    yan_fen,
+    dian_dao_lv,
+    dan,
+    lin,
+    guang_he_fu_she,
+    ri_zhao,
+    pm25,
+    pm10,
+    fu_li_zi,
+    zong_fu_she,
+    er_yang_hua_tan,
+    zheng_fa,
+    tu_rang_ph,
+    jia,
+    zi_wai_fu_she,
+    keong_qi_wen_du,
+    keong_qi_shi_du,
+    shui_zhi_ph,
+    shui_wei,
+    shui_zhi_dao_dian,
+    qi_ya,
+    guang_zhao_du,
+    liu_hua_qing,
+    shui_wen,
+    rong_jie_yang,
+    zhuo_du,
+    an_qi,
+    yang_qi,
+    pm100,
+    lou_dian_wen_du,
+    re_tong_liang,
+    he_ge_shu
+)
 
 
-def time_dif(self,checkdatetime):
+def time_dif(checkdatetime):
     """计算时间差"""
     nowdatetime = datetime.datetime.now()
-    checkdatetime = datetime.datetime.strptime(checkdatetime, "%Y-%m-%d %H:%M:%S")
+    checkdatetime = datetime.datetime.strptime(
+        checkdatetime, "%Y-%m-%d %H:%M:%S")
     timedif = checkdatetime - nowdatetime
     return timedif.days
 
@@ -23,31 +78,223 @@ def sim_info(iccid):
         if res_data["msg"] == "success" and res_data["data"]:
             expiry_date = res_data["data"]["expiry_date"]
             if expiry_date == "未知":
-                return [0, "未查询到卡信息"]
+                return -1
             else:
                 time_difference = time_dif(expiry_date)
-                if time_difference >= 180:
-                    return [1, "有效期剩余{}天".format(time_difference)]
-                elif 30 <= time_difference < 180:
-                    return [1, "有效期剩余{}天".format(time_difference)]
-                else:
-                    return [1, "有效期剩余{}天".format(time_difference)]
+                return time_difference
         else:
-            return [1, "查询无结果"]
-        
+            return -1
+
 
 def get_position(lng, lat):
     """使用经纬度获取位置信息"""
     if lng and lat:
         try:
-            ret = requests.post("http://api.map.baidu.com/geocoder?location=%s,%s&coord_type=gcj02&output=json"%(lat,lng))
+            ret = requests.post(
+                "http://api.map.baidu.com/geocoder?location=%s,%s&coord_type=gcj02&output=json" % (lat, lng))
             ret_json = json.loads(ret.text)
             province, city, district = ret_json["result"]["addressComponent"]["province"], \
-                                    ret_json["result"]["addressComponent"]["city"], \
-                                    ret_json["result"]["addressComponent"]["district"]
-            
+                ret_json["result"]["addressComponent"]["city"], \
+                ret_json["result"]["addressComponent"]["district"]
+
             return province + city + district
         except Exception as e:
             return False
     else:
         return False
+
+
+def get_excel_content(file_path):
+    read_dict = {}
+    if file_path.split(".")[-1] == "xlsx":
+        wb = openpyxl.load_workbook(file_path)
+        sheet = wb[wb.sheetnames[0]]
+        row_num = sheet.max_row
+        d_list = []
+        for row in range(2, row_num + 1):
+            cell = sheet.cell(row, 1)
+            try:
+                cell_value = str(cell.value).strip()
+                if cell_value:
+                    d_list.append(cell.value)
+            except Exception as e:
+                continue
+
+        read_dict["设备ID"] = d_list
+    else:
+        xls = open_workbook(file_path)
+        sheet_object = xls.sheets()[0]
+        ncols = sheet_object.ncols
+        d_list = []
+        col_value = sheet_object.col_values(0)
+        for d_i in col_value[1:]:
+            try:
+                d_i_v = str(d_i).strip()
+                d_list.append(d_i_v)
+            except Exception as e:
+                continue
+        read_dict["设备ID"] = d_list
+    device_list = read_dict.get("设备ID")
+    return device_list
+
+
+head_dict = {
+    "ID": ["/        ", check_id],
+    "检验项目": ["判定标准        ", jiao_yan_xiang_mu],
+    "经度": ["合格条件(绿色):\n113°46′13″±30″范围内", jing_du],
+    "纬度": ["合格条件(绿色):\n35°1′45″±30″范围内", weidu_du],
+    "固件版本号": ["合格条件(绿色):\n用检验时的输入作为导入的标准.\n/ 无法显示,替换为 -", gu_jian_ban_ben],
+    "电压": ["合格条件(绿色):\n11~15", dian_ya],
+    "信号强度": ["合格条件(绿色):\n>14", xin_hao],
+    "sim卡信息": ["合格条件(绿色):\n1、大于等于180天单元格显示绿色\n2、小于180天大于等于30天单元格显示黄色、\n3、小于30天单元格显示为红色", sim],
+    "位置信息": ["合格条件(绿色):显示河南省新乡市原阳县为合格,否则不合格", wei_zhi],
+    "上传数据条数": ["合格条件(绿色):\n1、大于7条\n2、两条数据时间间隔小于20分钟的出现频次2次以内、两条数据间隔大于40分钟出现频率2次以内", shu_ju_tiao_shu],
+    "风速": ["合格条件(绿色):\n1、0<示值<10\n2、有1条合格 即可", feng_su],
+    "风向": ["合格条件(绿色):\n1、0<示值<360\n2、有1条合格即可", feng_xiang],
+    "降雨量累计": ["合格条件(绿色):\n1、0<示值\n2、00:00示值归零\n3、有1条合格即可", jiang_yu],
+    "土壤含水率": ["合格条件(绿色):\n1、0<示值<=100\n2、有1条合格即可", tu_rang_han_shui],
+    "土壤温度": ["合格条件(绿色):\n1.≠0且在-5~35°C之间\n2、有1条合格即可", tu_rang_wen_du],
+    "盐分": ["合格条件(绿色):\n1、0<示值<1000#2、有1条合格即可", yan_fen],
+    "电导率": ["合格条件(绿色):\n1、0<示值\n2、有1条合格即", dian_dao_lv],
+    "氮": ["合格条件(绿色):\n1、0<示值\n2、有1条合格即可", dan],
+    "磷": ["合格条件(绿色):\n1、0<示值且不能为负值\n2、有1条合格即可", lin],
+    "光合有效辐射": ["合格条件(绿色):\n1、0<示值且不能为负值\n2、有1条合格即可", guang_he_fu_she],
+    "日照时数": ["合格条件(绿色):\n1、0.1≤示值\n2、有1条合格即可", ri_zhao],
+    "PM2.5": ["合格条件(绿色):\n1、0<示值且不能为负值\n2、有1条合格即可", pm25],
+    "PM10": ["合格条件(绿色):\n1、0<示值\n2、有1条合格即可", pm10],
+    "负氧离子": ["合格条件(绿色):\n1、0<示值<1000\n2、有1条合格即可", fu_li_zi],
+    "总辐射": ["合格条件(绿色):\n1、0<示值\n2、有1条合格即可", zong_fu_she],
+    "二氧化碳": ["合格条件(绿色):\n1、400<示值<1500\n2、有1条合格即可", er_yang_hua_tan],
+    "蒸发量": ["合格条件(绿色):\n1、0<示值\n2、有1条合格即可", zheng_fa],
+    "土壤PH": ["合格条件(绿色):\n1、6~8\n2、有1条合格即可", tu_rang_ph],
+    "钾": ["合格条件(绿色):\n1、0<示值\n2、有1条合格即可", jia],
+    "紫外辐射": ["合格条件(绿色):\n1、0<示 值\n2、有1条合格即可", zi_wai_fu_she],
+    "空气温度": ["合格条件(绿色):\n1.-10~35°C,但不允许为0°C\n2、有1条合格即可", keong_qi_wen_du],
+    "空气湿度": ["合格条件(绿色):\n1、0<示值<100\n2、有1条合格即可", keong_qi_shi_du],
+    "水质pH": ["合格条件(绿色):\n1、6≤示值≤8\n2、有1条合格即可", shui_zhi_ph],
+    "水位": ["合格条件(绿色):\n1、0<示值\n2、有1条合格即可", shui_wei],
+    "水质电导率": ["合格条件(绿色):\n1、0<示值\n2、有1条合格即可", shui_zhi_dao_dian],
+    "气压": ["合格条件(绿色):\n1、900<示值<1150\n2、有1条合格即可", qi_ya],
+    "光照度": ["合格条件(绿色):\n1、0<示值<200000\n2、有1条合格即可", guang_zhao_du],
+    "硫化氢": ["合格条件(绿色):\n1、示值=0\n2、有1条合格即可", liu_hua_qing],
+    "水温": ["合格条件(绿色):\n1.0~30°C,但不允许为0°C\n2、 有1条合格即可", shui_wen],
+    "溶解氧": ["合格条件(绿色):\n1、0<示值\n2、有1条合格即可", rong_jie_yang],
+    "浊度": ["合格条件(绿色):\n1、0<示值\n2、有1条合格即可", zhuo_du],
+    "氨气": ["合格条件(绿色):\n1、示值=0\n2、有1条合格即可", an_qi],
+    "氧气": ["合格条件(绿色):\n1、0<示值\n2、有1条合格即可", yang_qi],
+    "PM100": ["合格条件(绿色):\n1、0<示值\n2 、有1条合格即可", pm100],
+    "露点温度": ["合格条件(绿色):\n1.-10~35°C,但不允许为0°C\n2、有1条合格即可", lou_dian_wen_du],
+    "热通量": ["合格条件(绿色):上传条数的数据在均在±500内(但不能为0),即判定合格,否则不合格", re_tong_liang],
+    "单台合格数": ["合格条件(绿色):\n所有显示数值全部在合格范围内,则判定为合格,", he_ge_shu]
+}
+
+
+toji_format = {
+    'font_name': '宋体',
+    'font_size': 14,
+    'font_color': 'black',
+    'text_wrap': True,
+    'bold': False,
+    'fg_color': '92D050',
+    'align': 'center',
+    'valign': 'vcenter',
+    'border': 1,
+    'top': 1,
+    'left': 1,
+    'right': 1,
+    'bottom': 1
+}
+title_format = {
+    'font_name': '宋体',
+    'font_size': 12,
+    'bold': True,
+    'align': 'center',
+    'valign': 'vcenter',
+    'border': 1,
+    'top': 1,
+    'left': 1,
+    'right': 1,
+    'bottom': 1
+}
+merge_title_format = {
+    'font_name': '宋体',
+    'font_size': 26,
+    'bold': True,
+    'align': 'center',
+    'valign': 'vcenter',
+    "fg_color": "8DB4E2",
+    'border': 1,
+    'top': 1,
+    'left': 1,
+    'right': 1,
+    'bottom': 1
+}
+explain_formal = {
+    'font_name': '宋体',
+    'font_size': 11,
+    'font_color': 'black',
+    'text_wrap': True,
+    'align': 'justify',
+    'valign': 'vcenter',
+    'border': 1,
+    'top': 1,
+    'left': 1,
+    'right': 1,
+    'bottom': 1
+}
+formal_format = {
+    'font_name': '宋体',
+    'font_size': 11,
+    'font_color': 'black',
+    'fg_color': '77E88C',
+    'text_wrap': True,
+    'align': 'center',
+    'valign': 'vcenter',
+    'border': 1,
+    'top': 1,
+    'left': 1,
+    'right': 1,
+    'bottom': 1
+}
+common_format = {
+    'font_name': '宋体',
+    'font_size': 11,
+    'font_color': 'black',
+    "fg_color": 'E7EC73',
+    'text_wrap': True,
+    'align': 'center',
+    'valign': 'vcenter',
+    'border': 1,
+    'top': 1,
+    'left': 1,
+    'right': 1,
+    'bottom': 1
+}
+error_format = {
+    'font_name': '宋体',
+    'font_size': 11,
+    'font_color': 'black',
+    "fg_color": 'F4746A',
+    'text_wrap': True,
+    'align': 'center',
+    'valign': 'vcenter',
+    'border': 1,
+    'top': 1,
+    'left': 1,
+    'right': 1,
+    'bottom': 1
+}
+
+default_formal = {
+    'font_name': '宋体',
+    'font_size': 11,
+    'font_color': 'black',
+    'text_wrap': True,
+    'align': 'center',
+    'valign': 'vcenter',
+    'border': 1,
+    'top': 1,
+    'left': 1,
+    'right': 1,
+    'bottom': 1
+}