| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479 |
- # -*- coding: utf-8 -*-
- # Form implementation generated from reading ui file '.\ui文件\气象站质检工具.ui'
- #
- # Created by: PyQt5 UI code generator 5.15.4
- #
- # WARNING: Any manual changes made to this file will be lost when pyuic5 is
- # run again. Do not edit this file unless you know what you are doing.
- # pyinstaller -n "气象站(v3.2)" -D -w f:\image_down_code\qxz_zhijian.py -i .\LOGO.ico
- 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 xlrd import open_workbook
- from xlsxwriter.workbook import Workbook
- import openpyxl
- save_filename = ""
- pwd_str = "yf6021"
- 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
- }
- class QxzCand:
- def __init__(self):
- self.func_dict = {
- "空气温度": self.get_cond_101,
- "空气湿度": self.get_cond_102,
- "土壤温度": self.get_cond_106,
- "土壤含水率": self.get_cond_107,
- "风速": self.get_cond_108,
- "风向": self.get_cond_109,
- "降雨量累计": self.get_cond_115,
- "光合有效辐射": self.get_cond_123,
- "气压": self.get_cond_127,
- "盐分": self.get_cond_154,
- "电导率": self.get_cond_211,
- "磷": self.get_cond_156,
- "日照时数": self.get_cond_113,
- "PM2.5": self.get_cond_145,
- "PM10": self.get_cond_146,
- "总辐射": self.get_cond_105,
- "负氧离子": self.get_cond_162,
- "二氧化碳": self.get_cond_120,
- "蒸发量": self.get_cond_110,
- "土壤PH": self.get_cond_128,
- "紫外辐射": self.get_cond_138,
- "水质pH": self.get_cond_228,
- "水位": self.get_cond_230,
- "水质电导率": self.get_cond_178,
- "光照度": self.get_cond_112,
- "硫化氢": self.get_cond_219,
- "水温": self.get_cond_144,
- "浊度": self.get_cond_151,
- "氨气": self.get_cond_153,
- "氧气": self.get_cond_220,
- "PM100": self.get_cond_203,
- "露点温度": self.get_cond_202,
- "氮": self.get_cond_155,
- "钾": self.get_cond_157,
- "溶解氧": self.get_cond_148,
- }
- self.cond_msg_dict = {}
- for k, v in self.func_dict.items():
- self.cond_msg_dict[k] = self.get_cond_msg
- self.head_dict = {
- "ID": "/",
- "检验项目": "判定标准",
- "经度": "合格条件(绿色):\n113°46′13″±30″范围内",
- "纬度": "合格条件(绿色):\n35°1′45″±30″范围内",
- "固件版本号": "合格条件(绿色):\n用检验时的输入作为导入的标准.\n/ 无法显示,替换为 -",
- "电压": "合格条件(绿色):\n11~15",
- "信号强度": "合格条件(绿色):\n>14",
- "上传数据条数": "合格条件(绿色):\n1、大于7条\n2、两条数据时间间隔小于20分钟的出现频次2次以内、两条数据间隔大于40分钟出现频率2次以内",
- "风速": "合格条件(绿色):\n1、0<示值<10\n2、有1条合格 即可",
- "风向": "合格条件(绿色):\n1、0<示值<360\n2、有1条合格即可",
- "降雨量累计": "合格条件(绿色):\n1、0<示值\n2、00:00示值归零\n3、有1条合格即可",
- "土壤含水率": "合格条件(绿色):\n1、0<示值<=100\n2、有1条合格即可",
- "土壤温度": "合格条件(绿色):\n1.≠0且在-5~35°C之间\n2、有1条合格即可",
- "盐分": "合格条件(绿色):\n1、0<示值<1000#2、有1条合格即可",
- "电导率": "合格条件(绿色):\n1、0<示值\n2、有1条合格即",
- "氮": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
- "磷": "合格条件(绿色):\n1、0<示值且不能为负值\n2、有1条合格即可",
- "光合有效辐射": "合格条件(绿色):\n1、0<示值且不能为负值\n2、有1条合格即可",
- "日照时数": "合格条件(绿色):\n1、0.1≤示值\n2、有1条合格即可",
- "PM2.5": "合格条件(绿色):\n1、0<示值且不能为负值\n2、有1条合格即可",
- "PM10": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
- "负氧离子": "合格条件(绿色):\n1、0<示值<1000\n2、有1条合格即可",
- "总辐射": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
- "二氧化碳": "合格条件(绿色):\n1、400<示值<1500\n2、有1条合格即可",
- "蒸发量": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
- "土壤PH": "合格条件(绿色):\n1、6~8\n2、有1条合格即可",
- "钾": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
- "紫外辐射": "合格条件(绿色):\n1、0<示 值\n2、有1条合格即可",
- "空气温度": "合格条件(绿色):\n1.-10~35°C,但不允许为0°C\n2、有1条合格即可",
- "空气湿度": "合格条件(绿色):\n1、0<示值<100\n2、有1条合格即可",
- "水质pH": "合格条件(绿色):\n1、6≤示值≤8\n2、有1条合格即可",
- "水位": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
- "水质电导率": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
- "气压": "合格条件(绿色):\n1、900<示值<1150\n2、有1条合格即可",
- "光照度": "合格条件(绿色):\n1、0<示值<200000\n2、有1条合格即可",
- "硫化氢": "合格条件(绿色):\n1、示值=0\n2、有1条合格即可",
- "水温": "合格条件(绿色):\n1.0~30°C,但不允许为0°C\n2、 有1条合格即可",
- "溶解氧": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
- "浊度": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
- "氨气": "合格条件(绿色):\n1、示值=0\n2、有1条合格即可",
- "氧气": "合格条件(绿色):\n1、0<示值\n2、有1条合格即可",
- "PM100": "合格条件(绿色):\n1、0<示值\n2 、有1条合格即可",
- "露点温度": "合格条件(绿色):\n1.-10~35°C,但不允许为0°C\n2、有1条合格即可",
- "sim卡信息": "合格条件(绿色):\n1、大于等于180天单元格显示绿色\n2、小于180天大于等于30天单元格显示黄色、\n3、小于30天单元格显示为红色",
- "位置信息": "合格条件(绿色):显示河南省新乡市原阳县为合格,否则不合格",
- "单台合格数": "合格条件(绿色):\n所有显示数值全部在合格范围内,则判定为合格"
- }
- def get_cond_lat_msg(self, info):
- return {
- "status": int(info["status"]),
- "msg": f"纬度为: {info['lat']}"
- }
- def get_cond_lng_msg(self, info):
- return {
- "status": int(info["status"]),
- "msg": f"经度为: {info['lng']}"
- }
- def get_cond_volt_msg(self, info):
- return self.get_cond_msg(info)
- def get_cond_rssi_msg(self, info):
- return self.get_cond_msg(info)
- def get_cond_version_msg(self, info):
- status = info["status"]
- value = info["dver_num"]
- old_value = info["old_value"]
- device_version = value.replace('/', '-')
- old_version = old_value.replace('/', '-')
- return {
- "status": status,
- "msg": f"设备:{device_version}, 输入:{old_version}"
- }
- def get_cond_sim_msg(self, info):
- return info
- def get_time_uptime_msg(self, info):
- total_count = int(info["total_count"])
- uptime_20 = int(info["uptime_20"])
- uptime_40 = int(info["uptime_40"])
- msg = f"数据量:{total_count},间隔<20分钟:{uptime_20},间隔>40分钟:{uptime_40}"
- status = 0
- if total_count > 7 and uptime_20 <= 2 and uptime_40 <= 2:
- status = 1
- return {
- "status": status,
- "msg": msg
- }
- def get_cond_msg(self, info):
- """获取输出结果"""
- max_value = info['max_value']
- min_value = info['min_value']
- status = int(info['status'])
- msg = f"最大值:{max_value},最小值:{min_value}"
- return {"status": status, "msg": msg}
- def template_func(self, ek, cond_str):
- """获取模板函数"""
- cond = {
- "$function": {
- "args": [f"${ek}"],
- "lang": "js",
- "body": f"""
- function(values_list){{
- let max_value = Math.max(...values_list);
- let min_value = Math.min(...values_list);
- let status = 0;
- for (let i = 0; i < values_list.length; i++){{
- let v = values_list[i];
- if ({cond_str}){{
- status = 1;
- break;
- }}
- }}
- return {{"max_value": max_value, "min_value": min_value, "status": status}}
- }}
- """
- }
- }
- return cond
- def get_cond_101(self, ek):
- """获取空气温度条件"""
- cond = self.template_func(ek, "v != 0 && -10 <= v && v <= 35")
- return cond
- def get_cond_102(self, ek):
- """获取空气湿度条件"""
- cond = self.template_func(ek, "0 < v && v < 100")
- return cond
- def get_cond_106(self, ek):
- """获取土壤温度条件"""
- cond = self.template_func(ek, "v != 0 && -5 <= v && v <= 35")
- return cond
- def get_cond_107(self, ek):
- """获取土壤含水率条件"""
- cond = self.template_func(ek, "0 < v && v <= 100")
- return cond
- def get_cond_108(self, ek):
- """获取风速条件"""
- cond = self.template_func(ek, "0 < v && v < 10")
- return cond
- def get_cond_109(self, ek):
- """获取风向条件"""
- cond = self.template_func(ek, "0 < v && v < 360")
- return cond
- def get_cond_115(self, ek):
- """获取降雨量累计条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_123(self, ek):
- """获取光合有效辐射条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_127(self, ek):
- """获取气压条件"""
- cond = self.template_func(ek, "900 < v && v < 1150")
- return cond
- def get_cond_154(self, ek):
- """获取盐分条件"""
- cond = self.template_func(ek, "0 < v && v < 1000")
- return cond
- def get_cond_211(self, ek):
- """获取电导率条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_155(self, ek):
- """获取氮条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_156(self, ek):
- """获取磷条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_113(self, ek):
- """获取日照时数条件"""
- cond = self.template_func(ek, "0.1 <= v")
- return cond
- def get_cond_145(self, ek):
- """获取PM2.5条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_146(self, ek):
- """获取PM10条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_105(self, ek):
- """获取总辐射条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_162(self, ek):
- """获取负氧离子条件"""
- cond = self.template_func(ek, "0 < v && v < 1000")
- return cond
- def get_cond_120(self, ek):
- """获取二氧化碳条件"""
- cond = self.template_func(ek, "400 < v && v < 1500")
- return cond
- def get_cond_110(self, ek):
- """获取蒸发量条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_128(self, ek):
- """获取土壤PH条件"""
- cond = self.template_func(ek, "6 <= v && v <= 8")
- return cond
- def get_cond_157(self, ek):
- """获取钾条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_138(self, ek):
- """获取紫外辐射条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_228(self, ek):
- """获取水质pH条件"""
- cond = self.template_func(ek, "6 <= v && v <= 8")
- return cond
- def get_cond_230(self, ek):
- """获取水位条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_178(self, ek):
- """获取水质电导率条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_112(self, ek):
- """获取光照度条件"""
- cond = self.template_func(ek, "0 < v && v < 200000")
- return cond
- def get_cond_219(self, ek):
- """获取硫化氢条件"""
- cond = self.template_func(ek, "v == 0")
- return cond
- def get_cond_144(self, ek):
- """获取水温条件"""
- cond = self.template_func(ek, "0 < v && v <= 30")
- return cond
- def get_cond_148(self, ek):
- """获取溶解氧条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_151(self, ek):
- """获取浊度条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_153(self, ek):
- """获取氨气条件"""
- cond = self.template_func(ek, "v == 0")
- return cond
- def get_cond_220(self, ek):
- """获取氧气条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_203(self, ek):
- """获取PM100条件"""
- cond = self.template_func(ek, "0 < v")
- return cond
- def get_cond_202(self, ek):
- """获取露点温度条件"""
- cond = self.template_func(ek, "-10 < v && v < 35")
- return cond
- class Ui_MainWindow(object):
- """GUI界面"""
- def setupUi(self, MainWindow):
- MainWindow.setObjectName("MainWindow")
- MainWindow.resize(701, 644)
- font = QtGui.QFont()
- font.setFamily("Arial")
- font.setPointSize(12)
- MainWindow.setFont(font)
- icon = QtGui.QIcon("logo.ico")
- MainWindow.setWindowIcon(icon)
- self.centralwidget = QtWidgets.QWidget(MainWindow)
- self.centralwidget.setObjectName("centralwidget")
- self.pageTitleLabel = QtWidgets.QLabel(self.centralwidget)
- self.pageTitleLabel.setGeometry(QtCore.QRect(139, 50, 429, 42))
- font = QtGui.QFont()
- font.setFamily("楷体")
- font.setPointSize(28)
- self.pageTitleLabel.setFont(font)
- self.pageTitleLabel.setTextFormat(QtCore.Qt.AutoText)
- self.pageTitleLabel.setObjectName("pageTitleLabel")
- self.inputFileLabel = QtWidgets.QLabel(self.centralwidget)
- self.inputFileLabel.setGeometry(QtCore.QRect(180, 130, 121, 21))
- self.inputFileLabel.setObjectName("inputFileLabel")
- self.inputFileEdit = QtWidgets.QLineEdit(self.centralwidget)
- self.inputFileEdit.setGeometry(QtCore.QRect(310, 130, 151, 21))
- self.inputFileEdit.setFocusPolicy(QtCore.Qt.NoFocus)
- font = QtGui.QFont()
- font.setFamily("Arial")
- font.setPointSize(8)
- self.inputFileEdit.setFont(font)
- self.inputFileEdit.setObjectName("inputFileEdit")
- self.inputFileTool = QtWidgets.QToolButton(self.centralwidget)
- self.inputFileTool.setGeometry(QtCore.QRect(470, 130, 71, 21))
- font = QtGui.QFont()
- font.setFamily("Arial")
- font.setPointSize(10)
- self.inputFileTool.setFont(font)
- self.inputFileTool.setObjectName("inputFileTool")
- self.savePathLabel = QtWidgets.QLabel(self.centralwidget)
- self.savePathLabel.setGeometry(QtCore.QRect(180, 170, 121, 21))
- self.savePathLabel.setObjectName("savePathLabel")
- self.savePathEdit = QtWidgets.QLineEdit(self.centralwidget)
- self.savePathEdit.setGeometry(QtCore.QRect(310, 170, 151, 21))
- self.savePathEdit.setFocusPolicy(QtCore.Qt.NoFocus)
- font = QtGui.QFont()
- font.setFamily("Arial")
- font.setPointSize(8)
- self.savePathEdit.setFont(font)
- self.savePathEdit.setObjectName("savePathEdit")
- self.savePathTool = QtWidgets.QToolButton(self.centralwidget)
- self.savePathTool.setGeometry(QtCore.QRect(470, 170, 71, 21))
- font = QtGui.QFont()
- font.setFamily("Arial")
- font.setPointSize(10)
- self.savePathTool.setFont(font)
- self.savePathTool.setObjectName("savePathTool")
- self.startTimeLabel = QtWidgets.QLabel(self.centralwidget)
- self.startTimeLabel.setGeometry(QtCore.QRect(180, 210, 121, 21))
- self.startTimeLabel.setObjectName("startTimeLabel")
- self.startTimeEdit = QtWidgets.QDateTimeEdit(self.centralwidget)
- self.startTimeEdit.setGeometry(QtCore.QRect(310, 210, 151, 21))
- self.startTimeEdit.setMaximumDateTime(QtCore.QDateTime(QtCore.QDate(2025, 12, 31), QtCore.QTime(23, 59, 59)))
- self.startTimeEdit.setMinimumDateTime(QtCore.QDateTime(QtCore.QDate(2023, 8, 29), QtCore.QTime(20, 0, 0)))
- self.startTimeEdit.setObjectName("startTimeEdit")
- self.endTimeLabel = QtWidgets.QLabel(self.centralwidget)
- self.endTimeLabel.setGeometry(QtCore.QRect(180, 250, 121, 21))
- self.endTimeLabel.setObjectName("endTimeLabel")
- self.endTimeEdit = QtWidgets.QDateTimeEdit(self.centralwidget)
- self.endTimeEdit.setGeometry(QtCore.QRect(310, 250, 151, 21))
- self.endTimeEdit.setMaximumDateTime(QtCore.QDateTime(QtCore.QDate(2025, 12, 31), QtCore.QTime(23, 59, 59)))
- self.endTimeEdit.setMinimumDateTime(QtCore.QDateTime(QtCore.QDate(2023, 8, 30), QtCore.QTime(10, 0, 0)))
- self.endTimeEdit.setObjectName("endTimeEdit")
- self.platLabel = QtWidgets.QLabel(self.centralwidget)
- self.platLabel.setGeometry(QtCore.QRect(180, 290, 121, 21))
- self.platLabel.setObjectName("dianjiLabel")
- self.platBox = QtWidgets.QComboBox(self.centralwidget)
- self.platBox.setGeometry(QtCore.QRect(310, 290, 151, 21))
- self.platBox.addItems(['大数据平台','四情平台'])
- font = QtGui.QFont()
- font.setFamily("Arial")
- font.setPointSize(11)
- self.platBox.setFont(font)
- self.platBox.setObjectName("platBox")
- self.stm8vsLabel = QtWidgets.QLabel(self.centralwidget)
- self.stm8vsLabel.setGeometry(QtCore.QRect(180, 330, 121, 21))
- self.stm8vsLabel.setObjectName("stm8vsLabel")
- self.stm8vsEdit = QtWidgets.QLineEdit(self.centralwidget)
- self.stm8vsEdit.setGeometry(QtCore.QRect(310, 330, 151, 21))
- font = QtGui.QFont()
- font.setFamily("Arial")
- font.setPointSize(11)
- self.stm8vsEdit.setFont(font)
- self.stm8vsEdit.setObjectName("stm8vsEdit")
- font = QtGui.QFont()
- font.setFamily("Arial")
- font.setPointSize(11)
- self.orderLabel = QtWidgets.QLabel(self.centralwidget)
- self.orderLabel.setGeometry(QtCore.QRect(180, 370, 121, 21))
- self.orderLabel.setObjectName("dverLabel")
- self.orderEdit = QtWidgets.QLineEdit(self.centralwidget)
- self.orderEdit.setGeometry(QtCore.QRect(310, 370, 151, 21))
- font = QtGui.QFont()
- font.setFamily("Arial")
- font.setPointSize(11)
- self.orderEdit.setFont(font)
- self.orderEdit.setObjectName("dverEdit")
- self.pushButton = QtWidgets.QPushButton(self.centralwidget)
- self.pushButton.setGeometry(QtCore.QRect(300, 410, 111, 41))
- self.pushButton.setObjectName("pushButton")
- self.progressBar = QtWidgets.QProgressBar(self.centralwidget)
- self.progressBar.setGeometry(QtCore.QRect(130, 470, 491, 31))
- self.progressBar.setProperty("value", 0)
- self.progressBar.setVisible(False)
- self.progressBar.setObjectName("progressBar")
- MainWindow.setCentralWidget(self.centralwidget)
- self.retranslateUi(MainWindow)
- self.inputFileTool.clicked.connect(self.input_file_path)
- self.savePathTool.clicked.connect(self.out_save_location)
- self.pushButton.clicked.connect(self.on_click)
- QtCore.QMetaObject.connectSlotsByName(MainWindow)
- def retranslateUi(self, MainWindow):
- _translate = QtCore.QCoreApplication.translate
- MainWindow.setWindowTitle(_translate("MainWindow", "气象站质检工具"))
- self.savePathTool.setText(_translate("MainWindow", "选择文件夹"))
- self.inputFileTool.setText(_translate("MainWindow", "选择文件"))
- self.pageTitleLabel.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-weight:600; color:#3a45aa;\">云飞气象站设备质检工具</span></p></body></html>"))
- self.savePathLabel.setText(_translate("MainWindow", "|输出文件位置:"))
- self.inputFileLabel.setText(_translate("MainWindow", "|输入文件位置:"))
- self.startTimeLabel.setText(_translate("MainWindow", "|开始时间:"))
- self.endTimeLabel.setText(_translate("MainWindow", "|结束时间:"))
- self.platLabel.setText(_translate("MainWindow", "|检验平台:"))
- self.stm8vsLabel.setText(_translate("MainWindow", "|主板版本号:"))
- self.orderLabel.setText(_translate("MainWindow", "|任务单号:"))
- self.pushButton.setText(_translate("MainWindow", "开始导出"))
- def input_file_path(self):
- file_path = QtWidgets.QFileDialog.getOpenFileName(None,"选取文件","./","All Files (*.xlsx;*.xls);;Text Files (*.txt);;ALL(*)")
- self.inputFileEdit.setText(file_path[0])
- self.inputFileEdit.setStyleSheet("color:black;")
- def out_save_location(self):
- fname = QtWidgets.QFileDialog.getExistingDirectory(None, '选取文件夹', './')
- self.savePathEdit.setText(fname)
- self.savePathEdit.setStyleSheet("color:black;")
- def on_click(self):
- file_path = self.inputFileEdit.text()
- save_path = self.savePathEdit.text()
- start_time = self.startTimeEdit.dateTime().toPyDateTime()
- end_time = self.endTimeEdit.dateTime().toPyDateTime()
- set_plat = self.platBox.currentText()
- set_stm8vs = self.stm8vsEdit.text()
- set_order = self.orderEdit.text()
-
- if not all ([file_path,save_path,start_time,end_time,set_stm8vs,set_order]):
- QtWidgets.QMessageBox.information(None, "提示", "选项未填写完整")
- elif end_time < start_time:
- QtWidgets.QMessageBox.information(None, "提示", "结束日期应在开始日期之后")
- else:
- 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")
- if device_list:
- self.inputFileTool.setEnabled(False)
- self.savePathTool.setEnabled(False)
- self.startTimeEdit.setEnabled(False)
- self.endTimeEdit.setEnabled(False)
- self.platBox.setEnabled(False)
- self.stm8vsEdit.setEnabled(False)
- self.orderEdit.setEnabled(False)
- self.pushButton.setEnabled(False)
- self.pushButton.setText("执行中...")
- self.runThread = SCDThread(device_list,save_path,start_time,end_time,set_plat,set_stm8vs,set_order)
- self.runThread.proess_signal.connect(self.set_progressbar_value)
- self.runThread.start()
- self.progressBar.setVisible(True)
- else:
- QtWidgets.QMessageBox.information(None, "提示", "输入文件无'设备ID'列或该列无数据")
- def set_progressbar_value(self, value):
- self.progressBar.setValue(value)
- if value == 100:
- QtWidgets.QMessageBox.information(None, "提示", "文件导出完毕!导出文件名:\n{}".format(save_filename))
- self.inputFileTool.setEnabled(True)
- self.inputFileEdit.setText("")
- self.savePathTool.setEnabled(True)
- self.savePathEdit.setText("")
- self.startTimeEdit.setEnabled(True)
- self.endTimeEdit.setEnabled(True)
- self.platBox.setEnabled(True)
- self.stm8vsEdit.setEnabled(True)
- self.stm8vsEdit.setText("")
- self.orderEdit.setEnabled(True)
- self.orderEdit.setText("")
- self.pushButton.setEnabled(True)
- self.pushButton.setText("开始导出")
- self.progressBar.setVisible(False)
- self.progressBar.setValue(0)
- return
- class SCDThread(QtCore.QThread):
- """涉及进度条需主界面动态执行GUI,线程执行业务逻辑,避免主页面卡死"""
- proess_signal = QtCore.pyqtSignal(int)
- def __init__(self,device_list,save_path,start_time,end_time,set_plat,set_stm8vs,set_order):
- super(SCDThread, self).__init__()
- self.save_path = save_path
- self.start_time = time.mktime(start_time.timetuple())
- self.end_time = time.mktime(end_time.timetuple())
- # self.start_time = 1689993000
- # self.end_time = 1690008000
- self.start_time_str = start_time.strftime("%y-%m-%d %H:%M:%S")
- self.end_time_str = end_time.strftime("%y-%m-%d %H:%M:%S")
- self.set_plat = set_plat
- self.set_stm8vs = set_stm8vs
- self.set_order = set_order
- self.user = parse.quote_plus("root")
- self.passwd = parse.quote_plus("yfkj@6020")
- self.myclient = pymongo.MongoClient("mongodb://{0}:{1}@8.136.98.49:57017/".format(self.user,self.passwd))
- self.db = self.myclient.smartfarming
- self.device_collection = self.db.sa_device
- self.qxz_collection = self.db.sa_device_qxz_data
- self.config = {
- 'host': '120.27.222.26',
- 'port': 3306,
- 'user': 'yfwlw',
- 'password': 'sql_yfkj_6019',
- 'db': 'yfwlw',
- 'charset': 'utf8mb4',
- 'cursorclass': pymysql.cursors.DictCursor,
- }
- self.connection = pymysql.connect(**self.config)
- self.cursor = self.connection.cursor()
- self.cond = QxzCand()
- self.mongo_ping()
- device_list_tp = []
- for d in device_list:
- d_id, device_id, platform = self.device_their_platform(d)
- device_list_tp.append(device_id)
- self.device_list = device_list_tp
-
- def mongo_ping(self):
- """mongo-ping预防连接失效"""
- # try:
- # self.myclient.admin.command('ping')
- # except: # "ConnectionFailure"
- self.myclient = pymongo.MongoClient("mongodb://{0}:{1}@8.136.98.49:57017/".format(self.user,self.passwd))
- self.db = self.myclient.smartfarming
- self.device_collection = self.db.sa_device
- self.qxz_collection = self.db.sa_qxz_data
- self.qxz_info_record_collection = self.db.sa_qxz_info_record
- self.qxz_base_info_collection = self.db.sa_qxz_base_info
- # self.sa_qxz_conf = self.db.
-
- def sql_ping(self):
- """mysql-ping 预防连接失效"""
- try:
- self.connection.ping()
- except:
- self.connection = pymysql.connect(**self.config)
- self.cursor = self.connection.cursor()
- def __time_dif(self,checkdatetime):
- """计算时间差"""
- nowdatetime = datetime.datetime.now()
- checkdatetime = datetime.datetime.strptime(checkdatetime, "%Y-%m-%d %H:%M:%S")
- timedif = checkdatetime - nowdatetime
- return timedif.days
-
- def device_their_platform(self,shortId):
- """确定设备所在平台以及完整设备号"""
- self.mongo_ping()
- self.sql_ping()
- regex = re.compile('.*{}$'.format(shortId))
- bd_device_dict = self.device_collection.find_one(
- filter = {"device_id":regex,"device_type_id":5},
- projection = {'_id': 0},
- sort = [('uptime', pymongo.DESCENDING)]
- )
- device_sql = "SELECT * FROM AppInfoManage_qxzstatus_new WHERE equip_id_id LIKE '%{}' ORDER BY upl_time DESC LIMIT 1;".format(shortId)
- self.cursor.execute(device_sql)
- sq_device_dict = self.cursor.fetchone()
- if bd_device_dict and sq_device_dict:
- bd_upltime = bd_device_dict["uptime"]
- sq_upltime = time.mktime(sq_device_dict["upl_time"].timetuple())
- if bd_upltime >= sq_upltime:
- d_id = bd_device_dict["id"]
- deviceId = bd_device_dict["device_id"]
- platform = "大数据平台"
- else:
- d_id = ""
- deviceId = sq_device_dict["equip_id_id"]
- platform = "四情平台"
- elif bd_device_dict and not sq_device_dict:
- d_id = bd_device_dict["id"]
- deviceId = bd_device_dict["device_id"]
- platform = "大数据平台"
- return d_id,deviceId,platform
- elif not bd_device_dict and sq_device_dict:
- d_id = ""
- deviceId = sq_device_dict["equip_id_id"]
- platform = "四情平台"
- else:
- d_id = ""
- deviceId = "平台无此设备"
- platform = "未知"
- return d_id,deviceId,platform
-
- def sim_info(self, iccid):
- """查询卡信息"""
- url = "http://8.136.98.49:10001/iotcard/platsimview/inquiries/"
- try:
- response = requests.request("POST", url, data={"iccid": iccid})
- except:
- return [0, "查询卡信息异常稍后重试"]
- else:
- res_data = json.loads(response.text)
- if res_data["msg"] == "success" and res_data["data"]:
- expiry_date = res_data["data"]["expiry_date"]
- if expiry_date == "未知":
- return [0, "未查询到卡信息"]
- else:
- time_difference = self.__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)]
- else:
- return [1, "查询无结果"]
- def _get_data_new(self):
- """获取最新设备数据信息"""
- pipeline = [
- {
- "$match": {
- "device_id": {"$in": self.device_list}
- }
- },
- {
- "$group": {
- "_id": {"device_id": "$device_id"},
- "last_msg": {"$last": "$$ROOT"}
- }
- },
- {
- "$replaceRoot": {"newRoot": "$last_msg"}
- }
- ]
- cursor = self.db.sa_qxz_data.aggregate(pipeline, allowDiskUse=True)
- data_dict = {item['device_id']: item for item in cursor}
- return data_dict
- def _get_bigdata_qxz_conf(self):
- data_dict = self._get_data_new()
- cursor = self.db.sa_qxz_conf.find({"device_id": {"$in": self.device_list}})
- title_name_set = set()
- qxz_conf_dict = {}
- for item in cursor:
- device_id = item['device_id']
- qxz_data = data_dict[device_id]
- config_dict = {}
- counter = Counter()
- for k, v in item.items():
- if k.startswith('e') and v and qxz_data.get(k, None):
- t_name = v.split('#')[0]
- t_index = counter.get(t_name, "")
- config_dict[k] = f"{t_name}#{t_index}"
- counter[t_name] += 1
- n_list = list(config_dict.values())
- title_name_set.update(n_list)
- qxz_conf_dict[device_id] = config_dict
- title_name_list = sorted(list(title_name_set))
- return title_name_list, qxz_conf_dict
- def get_qxz_element_data(self, device_id, conf_dict):
- group_dict = {
- "_id": "$device_id",
- "total_count": {"$count": {}},
- "uptime_list": {"$push": "$uptime"}
- }
- project_dict = {
- "_id": 0,
- "device_id": "$_id",
- "total_count": "$total_count",
- "uptime_info": {
- "$function": {
- "args": ["$uptime_list"],
- "lang": "js",
- "body": """
- function(uptime_list){
- let old_uptime = uptime_list[0];
- let uptime_20 = 0;
- let uptime_40 = 0;
- for (let i = 1; i < uptime_list.length; i++) {
- let uptime = uptime_list[i];
- let diff_time = uptime - old_uptime;
- if (diff_time < 1200){
- uptime_20 += 1;
- } else if (diff_time > 2400){
- uptime_40 += 1;
- }
- old_uptime = uptime;
- }
- return {"uptime_20": uptime_20, "uptime_40": uptime_40}
- }
- """
- }
- }
- }
- for ek in conf_dict.keys():
- group_dict[ek] = {"$push": f"${ek}"}
- try:
- k = conf_dict[ek]
- func_name = self.get_conf_key(k)
- project_dict[ek] = self.cond.func_dict[func_name](ek)
- except KeyError as e:
- continue
- pipeline = [
- {
- "$match": {
- "device_id": device_id,
- "uptime": {
- "$gte": self.start_time,
- "$lt": self.end_time
- }
- }
- },
- {
- "$sort": {"uptime": 1}
- },
- {
- "$project": {
- "device_id": "$device_id",
- "uptime": "$uptime",
- "tmp_list": {
- "$filter": {
- "input": {"$objectToArray": "$$ROOT"},
- "as": "item",
- "cond": {
- "$and": [
- {
- "$regexMatch": {
- "input": "$$item.k",
- "regex": "^e\d+",
- "options": "i"
- }
- },
- {
- "$regexMatch": {
- "input": "$$item.v",
- "regex": ".*#.*",
- "options": "i"
- }
- }
- ]
- }
- }
- }
- }
- },
- {
- "$addFields": {
- "tmp_obj": {
- "$arrayToObject": {
- "$map": {
- "input": "$tmp_list",
- "as": "item",
- "in": {
- "k": "$$item.k",
- "v": {
- "$toInt": {
- "$convert": {
- "input": {"$arrayElemAt": [{"$split": ["$$item.v", "#"]}, 0]},
- "to": "int",
- "onError": 0,
- "onNull": 0
- }
- # "$toDouble": {
- # "$arrayElemAt": [{"$split": ["$$item.v", "#"]}, 0]
- # }
- }
- }
- }
- }
- }
- }
- }
- },
- {
- "$replaceRoot": {
- "newRoot": {
- "$mergeObjects": ["$tmp_obj", {"device_id": "$device_id", "uptime": "$uptime"}]
- }
- }
- },
- {
- "$group": group_dict
- },
- {
- "$project": project_dict
- }
- ]
- print("执行之前...")
- cursor = self.db.sa_qxz_data.aggregate(pipeline, allowDiskUse=True)
- result = {k: v for item in cursor for k, v in item.items()}
- return result
- def get_qxz_volt_or_rssi_data(self):
- pipeline = [
- {
- "$match": {
- "device_id": {
- "$in": self.device_list
- },
- 'uptime': {
- '$gte': self.start_time,
- '$lte': self.end_time
- },
- },
- },
- {
- "$project": {
- "device_id": "$device_id",
- "volt": {
- "$toDouble": "$volt"
- },
- "rssi": {
- "$toDouble": "$rssi"
- }
- }
- },
- {
- "$group": {
- "_id": "$device_id",
- "max_volt": {
- "$max": "$volt"
- },
- "min_volt": {
- "$min": "$volt"
- },
- "max_rssi": {
- "$max": "$rssi"
- },
- "min_rssi": {
- "$min": "$rssi"
- }
- }
- },
- {
- "$project": {
- "_id": 0,
- "device_id": "$_id",
- "volt_info": {
- 'max_value': "$max_volt", 'min_value': "$min_volt",
- 'status': {
- "$cond": {
- "if": {
- "$and": [
- {"$lte": ["$max_volt", 15]},
- {"$gte": ["$min_volt", 11]}
- ]
- },
- "then": 1,
- "else": 0
- }
- }
- },
- "rssi_info": {
- 'max_value': "$max_rssi", 'min_value': "$min_rssi",
- 'status': {
- "$cond": {
- "if": {
- "$gte": ["$min_rssi", 14]
- },
- "then": 1,
- "else": 0
- }
- }
- }
- }
- }
- ]
- cursor = self.qxz_info_record_collection.aggregate(pipeline, allowDiskUse=True)
- result = {item['device_id']: item for item in cursor}
- return result
- def get_qxz_device_data(self):
- pipeline = [
- {
- "$match": {
- "device_id": {
- "$in": self.device_list
- }
- },
- },
- {
- "$project": {
- "device_id": "$device_id",
- "dver_num": "$dver_num",
- "lng": {
- "$convert": {
- "input": "$lng",
- "to": "double",
- "onError": 0,
- "onNull": 0
- }
- },
- "lat": {
- "$convert": {
- "input": "$lat",
- "to": "double",
- "onError": 0,
- "onNull": 0
- }
- }
- }
- },
- {
- "$project": {
- "_id": 0,
- "device_id": "$device_id",
- "dver_info": {
- "status": {
- "$cond": {
- "if": {
- "$eq": ["$dver_num", self.set_stm8vs]
- },
- "then": 1,
- "else": 0
- }
- },
- "dver_num": "$dver_num",
- "old_value": self.set_stm8vs
- },
- "lng_info": {
- "status": {
- "$cond": {
- "if": {
- "$and": [
- {"$lte": ["$lng", 113.7869444]},
- {"$gte": ["$lng", 113.7536111]}
- ]
- },
- "then": 1,
- "else": 0
- }
- },
- "lng": "$lng"
- },
- "lat_info": {
- "status": {
- "$cond": {
- "if": {
- "$and": [
- {"$lte": ["$lat", 35.0458333]},
- {"$gte": ["$lat", 35.0125]}
- ]
- },
- "then": 1,
- "else": 0
- }
- },
- "lat": "$lat"
- }
- }
- }
- ]
- cursor = self.device_collection.aggregate(pipeline, allowDiskUse=True)
- result = {item['device_id']: item for item in cursor}
- return result
- def get_sim_data(self):
- pipeline = [
- {
- "$match": {
- "device_id": {
- "$in": self.device_list
- }
- }
- },
- {
- "$project": {
- "_id": 0,
- "device_id": "$device_id",
- "iccid": "$iccid"
- }
- }
- ]
- cursor = self.qxz_base_info_collection.aggregate(pipeline, allowDiskUse=True)
- result = {item['device_id']: item["iccid"] for item in cursor}
- return result
- def parse_data(self, device_id, qxz_conf_dict, vr_dict, device_data_dict, sim_data):
- """解析获取元素数据"""
- element_dict = {}
- element_dict["ID#"] = device_id
- element_dict["检验项目#"] = device_id
- try:
- conf_dict = qxz_conf_dict[device_id]
- device_data = self.get_qxz_element_data(device_id, conf_dict)
- element_dict.update({conf_dict[k]: v for k, v in device_data.items() if k in conf_dict})
- vr_info = vr_dict[device_id]
- dd_info = device_data_dict[device_id]
- element_dict["经度#"] = dd_info["lng_info"]
- element_dict["纬度#"] = dd_info["lat_info"]
- element_dict["固件版本号#"] = dd_info["dver_info"]
- element_dict["电压#"] = vr_info["volt_info"]
- element_dict["信号强度#"] = vr_info["rssi_info"]
- sim_info = self.sim_info(sim_data[device_id])
- element_dict["sim卡信息#"] = {
- "status": sim_info[0],
- "msg": sim_info[1]
- }
- element_dict["上传数据条数#"] = {
- "total_count": device_data['total_count'],
- "uptime_20": device_data["uptime_info"]["uptime_20"],
- "uptime_40": device_data["uptime_info"]["uptime_40"]
- }
- except KeyError as e:
- pass
- return element_dict
- def get_conf_key(self, k):
- key = k.split('#')[0]
- if "土壤含水率" in key:
- key = "土壤含水率"
- if "土壤温度" in key:
- key = "土壤温度"
- return key
- def get_position(self, 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_json = json.loads(ret.text)
- province, city, district = ret_json["result"]["addressComponent"]["province"], \
- ret_json["result"]["addressComponent"]["city"], \
- ret_json["result"]["addressComponent"]["district"]
-
- return province + city + district
- except Exception as e:
- return False
- else:
- return False
-
- def run(self):
- """主业务逻辑,涉及进度条不能模块化,慢慢捋"""
- title_name_list = ["ID#", "检验项目#", "电压#", "信号强度#", "经度#", "纬度#", "固件版本号#", "sim卡信息#",
- "上传数据条数#"]
- default_func_dict = {
- "电压": self.cond.get_cond_volt_msg,
- "信号强度": self.cond.get_cond_rssi_msg,
- "经度": self.cond.get_cond_lng_msg,
- "纬度": self.cond.get_cond_lat_msg,
- "固件版本号": self.cond.get_cond_version_msg,
- "上传数据条数": self.cond.get_time_uptime_msg,
- "sim卡信息": self.cond.get_cond_sim_msg
- }
- head_name_list, qxz_conf_dict = self._get_bigdata_qxz_conf()
- for n in head_name_list:
- if n not in title_name_list:
- title_name_list.append(n)
- title_name_list.append("位置信息#")
- # title_name_list.append("热通量#")
- title_name_list.append("单台合格数#")
- device_data_dict = self.get_qxz_device_data()
- vr_dict = self.get_qxz_volt_or_rssi_data()
- sim_data = self.get_sim_data()
- proess = 0
- now_time = datetime.datetime.now()
- global save_filename
- save_filename = self.set_order + "_" + now_time.strftime("%m%d") + ".xlsx"
- save_path = os.path.join(self.save_path,save_filename)
- workbook = Workbook(save_path)
- 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 = {
- 0: red_style,
- 1: green_style,
- 2: yellow_style,
- 3: default_style
- }
- head_list = [i.split("#")[0] for i in title_name_list]
- worksheet.merge_range(0, 0, 0, len(head_list) - 1, "物联网气象站设备质检表格", merge_title_style)
- for index, k in enumerate(title_name_list):
- value = k.split('#')[0]
- worksheet.write(2, index, value, default_style)
- for index, k in enumerate(title_name_list):
- key = self.get_conf_key(k)
- try:
- value = self.cond.head_dict[key]
- except KeyError as e:
- value = "无判定条件"
- worksheet.write(3, index, value, default_style)
- row_index = 4
- qualified = 0
- for device_id in self.device_list:
- self.mongo_ping()
- element_dict = self.parse_data(device_id, qxz_conf_dict, vr_dict, device_data_dict, sim_data)
- device_config = self.db.sa_qxz_conf.find_one({"device_id": device_id}, {'_id':0,'id':0})
- device_data = self.db.sa_qxz_data.find({"device_id": device_id, "uptime": {"$gte": self.start_time, "$lte": self.end_time}})
-
- # device_machine = self.db.sa_device.find_one({"device_id": device_id})
- not_qualified = 0
- lng = 0
- lat = 0
- for index, k in enumerate(title_name_list):
- status, msg = 3, "无数据"
- try:
- value = element_dict[k]
- key = self.get_conf_key(k)
- if key in ["ID", "检验项目"]:
- rt = {"status": 1, "msg": value}
- elif key in default_func_dict:
- rt = default_func_dict[key](value)
- if key == "经度":
- lng = value.get("lng")
- if key == "纬度":
- lat = value.get("lat")
- else:
- if key == "日照时数":
- idevice_key_sun = ""
- device_config = dict(device_config)
- for iname, ivalue in device_config.items():
- if ivalue and isinstance(ivalue, str):
- if "日照时数" in ivalue:
- idevice_key_sun = iname
- idevice_data = []
- for d in device_data:
- idevice_data.append(float((d.get(idevice_key_sun)).split("#")[0]))
- if max(idevice_data) > 0.1:
- rt = {'status': 1, 'msg': f'最大值:{str(max(idevice_data))},最小值:{str(min(idevice_data))}'}
- else:
- rt = {'status': 0, 'msg': f'最大值:{str(max(idevice_data))},最小值:{str(min(idevice_data))}'}
- elif key == "降雨量累计":
- idevice_key_rain = ""
- device_config = dict(device_config)
- for iname, ivalue in device_config.items():
- if ivalue and isinstance(ivalue, str):
- if "降雨量累计" in ivalue:
- idevice_key_rain = iname
- idevice_data = []
- for d in device_data:
- idevice_data.append(float((d.get(idevice_key_rain)).split("#")[0]))
- if max(idevice_data) > 0.1:
- rt = {'status': 1, 'msg': f'最大值:{str(max(idevice_data))},最小值:{str(min(idevice_data))}'}
- else:
- rt = {'status': 0, 'msg': f'最大值:{str(max(idevice_data))},最小值:{str(min(idevice_data))}'}
- else:
- rt = self.cond.cond_msg_dict[key](value)
- status, msg = rt['status'], rt['msg']
- except Exception as e:
- pass
- if status == 0:
- not_qualified += 1
- if k == "位置信息#":
- # 使用经纬度获取地理
- result = self.get_position(lng, lat)
- if not result:
- device_tp = self.device_collection.find_one({"device_id": device_id})
- if device_tp:
- result = device_tp.get("province") + device_tp.get("city") + device_tp.get("district")
- else:
- result = ""
- if result and result == "河南省新乡市原阳县":
- status = 1
- msg = result
- else:
- status = 0
- msg = result
- if k == "单台合格数#":
- status, msg = 0, f"不合格: {not_qualified}"
- if not_qualified == 0:
- status, msg = 1, "合格"
- column_style = style_dict[status]
- worksheet.write(row_index, index, str(msg), column_style)
- proess = (index + 1) / len(self.device_list) * 100
- if int(proess) == 100:
- self.proess_signal.emit(99)
- else:
- self.proess_signal.emit(int(proess))
- if not_qualified == 0:
- qualified += 1
- row_index += 1
- toji_data = [
- "任务单号", self.set_order, "检验时间", self.start_time_str, self.end_time_str,
- "报告日期", now_time.strftime("%y-%m-%d %H:%M:%S"), "合格数", qualified
- ]
- for i in range(len(head_list) - len(toji_data)):
- toji_data.append(" ")
- for index, k in enumerate(toji_data):
- value = str(k)
- worksheet.write(1, index, value, toji_style)
- c_n = len(value) + 15
- worksheet.set_column(index, index, c_n)
- worksheet.protect(pwd_str)
- workbook.close()
- self.cursor.close()
- self.connection.close()
- self.myclient.close()
- self.proess_signal.emit(100)
- if __name__== "__main__":
- QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
- QtGui.QGuiApplication.setAttribute(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
- app = QtWidgets.QApplication(sys.argv)
- MainWindow = QtWidgets.QMainWindow()
- ui = Ui_MainWindow()
- ui.setupUi(MainWindow)
- MainWindow.show()
- sys.exit(app.exec_())
|