cbd_zhijian_beidahuang.py 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516
  1. from asyncio import ensure_future, shield
  2. from concurrent.futures import process
  3. from platform import python_build
  4. import traceback
  5. from tracemalloc import start
  6. from turtle import st
  7. from PyQt5 import QtCore, QtGui, QtWidgets
  8. import shutil
  9. import os
  10. import sys
  11. import re
  12. import ast
  13. from urllib import parse
  14. import json
  15. import time
  16. import datetime
  17. import requests
  18. import pymongo
  19. import pymysql
  20. from xlrd import open_workbook
  21. from xlsxwriter.workbook import Workbook
  22. import numpy as np
  23. import cv2
  24. from aliyunsdkcore.vendored.requests.auth import HTTPBasicAuth
  25. import requests
  26. import datetime
  27. import time
  28. import hashlib
  29. from skimage import filters
  30. save_filename = ""
  31. pwd_str = "yf6021"
  32. toji_format = {
  33. 'font_name' : '宋体',
  34. 'font_size': 12,
  35. 'font_color': 'black',
  36. 'text_wrap': True,
  37. 'bold': False,
  38. 'fg_color': '92D050',
  39. 'align': 'center',
  40. 'valign': 'vcenter',
  41. 'border': 1,
  42. 'top': 1,
  43. 'left': 1,
  44. 'right': 1,
  45. 'bottom': 1
  46. }
  47. title_format = {
  48. 'font_name' : '宋体',
  49. 'font_size': 10,
  50. 'bold': True,
  51. 'align': 'center',
  52. 'valign': 'vcenter',
  53. "text_wrap": True,
  54. 'border': 1,
  55. 'top': 1,
  56. 'left': 1,
  57. 'right': 1,
  58. 'bottom': 1
  59. }
  60. merge_title_format = {
  61. 'font_name' : '宋体',
  62. 'font_size': 22,
  63. 'bold': True,
  64. 'align': 'center',
  65. 'valign': 'vcenter',
  66. "fg_color": "8DB4E2",
  67. 'border': 1,
  68. 'top': 1,
  69. 'left': 1,
  70. 'right': 1,
  71. 'bottom': 1
  72. }
  73. explain_formal = {
  74. 'font_name' : '宋体',
  75. 'font_size': 9,
  76. 'font_color': 'black',
  77. 'text_wrap': True,
  78. 'align': 'justify',
  79. 'valign': 'vcenter',
  80. 'border': 1,
  81. 'top': 1,
  82. 'left': 1,
  83. 'right': 1,
  84. 'bottom': 1
  85. }
  86. formal_format = {
  87. 'font_name' : '宋体',
  88. 'font_size': 9,
  89. 'font_color': 'black',
  90. 'fg_color': '77E88C',
  91. 'text_wrap': True,
  92. 'align': 'center',
  93. 'valign': 'vcenter',
  94. 'border': 1,
  95. 'top': 1,
  96. 'left': 1,
  97. 'right': 1,
  98. 'bottom': 1
  99. }
  100. common_format = {
  101. 'font_name' : '宋体',
  102. 'font_size': 9,
  103. 'font_color': 'black',
  104. "fg_color": 'E7EC73',
  105. 'text_wrap': True,
  106. 'align': 'center',
  107. 'valign': 'vcenter',
  108. 'border': 1,
  109. 'top': 1,
  110. 'left': 1,
  111. 'right': 1,
  112. 'bottom': 1
  113. }
  114. error_format = {
  115. 'font_name' : '宋体',
  116. 'font_size': 9,
  117. 'font_color': 'black',
  118. "fg_color": 'F4746A',
  119. 'text_wrap': True,
  120. 'align': 'center',
  121. 'valign': 'vcenter',
  122. 'border': 1,
  123. 'top': 1,
  124. 'left': 1,
  125. 'right': 1,
  126. 'bottom': 1
  127. }
  128. class Ui_MainWindow(object):
  129. """GUI界面"""
  130. def setupUi(self, MainWindow):
  131. MainWindow.setObjectName("MainWindow")
  132. MainWindow.resize(701, 644)
  133. font = QtGui.QFont()
  134. font.setFamily("Arial")
  135. font.setPointSize(12)
  136. MainWindow.setFont(font)
  137. icon = QtGui.QIcon("logo.ico")
  138. MainWindow.setWindowIcon(icon)
  139. self.centralwidget = QtWidgets.QWidget(MainWindow)
  140. self.centralwidget.setObjectName("centralwidget")
  141. self.pageTitleLabel = QtWidgets.QLabel(self.centralwidget)
  142. self.pageTitleLabel.setGeometry(QtCore.QRect(139, 50, 429, 42))
  143. font = QtGui.QFont()
  144. font.setFamily("楷体")
  145. font.setPointSize(28)
  146. self.pageTitleLabel.setFont(font)
  147. self.pageTitleLabel.setTextFormat(QtCore.Qt.AutoText)
  148. self.pageTitleLabel.setObjectName("pageTitleLabel")
  149. self.inputFileLabel = QtWidgets.QLabel(self.centralwidget)
  150. self.inputFileLabel.setGeometry(QtCore.QRect(180, 130, 121, 21))
  151. self.inputFileLabel.setObjectName("inputFileLabel")
  152. self.inputFileEdit = QtWidgets.QLineEdit(self.centralwidget)
  153. self.inputFileEdit.setGeometry(QtCore.QRect(310, 130, 151, 21))
  154. self.inputFileEdit.setFocusPolicy(QtCore.Qt.NoFocus)
  155. font = QtGui.QFont()
  156. font.setFamily("Arial")
  157. font.setPointSize(8)
  158. self.inputFileEdit.setFont(font)
  159. self.inputFileEdit.setObjectName("inputFileEdit")
  160. self.inputFileTool = QtWidgets.QToolButton(self.centralwidget)
  161. self.inputFileTool.setGeometry(QtCore.QRect(470, 130, 71, 21))
  162. font = QtGui.QFont()
  163. font.setFamily("Arial")
  164. font.setPointSize(10)
  165. self.inputFileTool.setFont(font)
  166. self.inputFileTool.setObjectName("inputFileTool")
  167. self.savePathLabel = QtWidgets.QLabel(self.centralwidget)
  168. self.savePathLabel.setGeometry(QtCore.QRect(180, 170, 121, 21))
  169. self.savePathLabel.setObjectName("savePathLabel")
  170. self.savePathEdit = QtWidgets.QLineEdit(self.centralwidget)
  171. self.savePathEdit.setGeometry(QtCore.QRect(310, 170, 151, 21))
  172. self.savePathEdit.setFocusPolicy(QtCore.Qt.NoFocus)
  173. font = QtGui.QFont()
  174. font.setFamily("Arial")
  175. font.setPointSize(8)
  176. self.savePathEdit.setFont(font)
  177. self.savePathEdit.setObjectName("savePathEdit")
  178. self.savePathTool = QtWidgets.QToolButton(self.centralwidget)
  179. self.savePathTool.setGeometry(QtCore.QRect(470, 170, 71, 21))
  180. font = QtGui.QFont()
  181. font.setFamily("Arial")
  182. font.setPointSize(10)
  183. self.savePathTool.setFont(font)
  184. self.savePathTool.setObjectName("savePathTool")
  185. self.startTimeLabel = QtWidgets.QLabel(self.centralwidget)
  186. self.startTimeLabel.setGeometry(QtCore.QRect(180, 210, 121, 21))
  187. self.startTimeLabel.setObjectName("startTimeLabel")
  188. self.startTimeEdit = QtWidgets.QDateTimeEdit(self.centralwidget)
  189. self.startTimeEdit.setGeometry(QtCore.QRect(310, 210, 151, 21))
  190. self.startTimeEdit.setMaximumDateTime(QtCore.QDateTime(QtCore.QDate(2028, 12, 31), QtCore.QTime(23, 59, 59)))
  191. self.startTimeEdit.setMinimumDateTime(QtCore.QDateTime(QtCore.QDate(2024, 6, 1), QtCore.QTime(8, 0, 0)))
  192. self.startTimeEdit.setObjectName("startTimeEdit")
  193. self.endTimeLabel = QtWidgets.QLabel(self.centralwidget)
  194. self.endTimeLabel.setGeometry(QtCore.QRect(180, 250, 121, 21))
  195. self.endTimeLabel.setObjectName("endTimeLabel")
  196. self.endTimeEdit = QtWidgets.QDateTimeEdit(self.centralwidget)
  197. self.endTimeEdit.setGeometry(QtCore.QRect(310, 250, 151, 21))
  198. self.endTimeEdit.setMaximumDateTime(QtCore.QDateTime(QtCore.QDate(2028, 12, 31), QtCore.QTime(23, 59, 59)))
  199. self.endTimeEdit.setMinimumDateTime(QtCore.QDateTime(QtCore.QDate(2024, 6, 1), QtCore.QTime(12, 0, 0)))
  200. self.endTimeEdit.setObjectName("endTimeEdit")
  201. self.platLabel = QtWidgets.QLabel(self.centralwidget)
  202. self.platLabel.setGeometry(QtCore.QRect(180, 290, 121, 21))
  203. self.platLabel.setObjectName("dianjiLabel")
  204. self.platBox = QtWidgets.QComboBox(self.centralwidget)
  205. self.platBox.setGeometry(QtCore.QRect(310, 290, 151, 21))
  206. self.platBox.addItems(['大数据平台','四情平台'])
  207. # 产品名称
  208. self.productLabel = QtWidgets.QLabel(self.centralwidget)
  209. self.productLabel.setGeometry(QtCore.QRect(180, 440, 121, 21))
  210. self.productLabel.setObjectName("productLabel")
  211. self.productBox = QtWidgets.QComboBox(self.centralwidget)
  212. self.productBox.setGeometry(QtCore.QRect(310, 440, 151, 21))
  213. self.productBox.addItems(['1.0测报灯','4.0测报灯', "水稻测报灯"])
  214. # 供电选择
  215. self.powerSupplyLabel = QtWidgets.QLabel(self.centralwidget)
  216. self.powerSupplyLabel.setGeometry(QtCore.QRect(180, 470, 121, 21))
  217. self.powerSupplyLabel.setObjectName("powerSupplyLabel")
  218. self.powerSupplyBox = QtWidgets.QComboBox(self.centralwidget)
  219. self.powerSupplyBox.setGeometry(QtCore.QRect(310, 470, 151, 21))
  220. self.powerSupplyBox.addItems(['AC','DC'])
  221. font = QtGui.QFont()
  222. font.setFamily("Arial")
  223. font.setPointSize(11)
  224. self.platBox.setFont(font)
  225. self.platBox.setObjectName("platBox")
  226. self.stm8vsLabel = QtWidgets.QLabel(self.centralwidget)
  227. self.stm8vsLabel.setGeometry(QtCore.QRect(180, 330, 121, 21))
  228. self.stm8vsLabel.setObjectName("stm8vsLabel")
  229. self.stm8vsEdit = QtWidgets.QLineEdit(self.centralwidget)
  230. self.stm8vsEdit.setGeometry(QtCore.QRect(310, 330, 151, 21))
  231. font = QtGui.QFont()
  232. font.setFamily("Arial")
  233. font.setPointSize(11)
  234. self.stm8vsEdit.setFont(font)
  235. self.stm8vsEdit.setObjectName("stm8vsEdit")
  236. self.dverLabel = QtWidgets.QLabel(self.centralwidget)
  237. self.dverLabel.setGeometry(QtCore.QRect(180, 370, 121, 21))
  238. self.dverLabel.setObjectName("dverLabel")
  239. self.dverEdit = QtWidgets.QLineEdit(self.centralwidget)
  240. self.dverEdit.setGeometry(QtCore.QRect(310, 370, 151, 21))
  241. font = QtGui.QFont()
  242. font.setFamily("Arial")
  243. font.setPointSize(11)
  244. self.dverEdit.setFont(font)
  245. self.dverEdit.setObjectName("dverEdit")
  246. self.orderLabel = QtWidgets.QLabel(self.centralwidget)
  247. self.orderLabel.setGeometry(QtCore.QRect(180, 410, 121, 21))
  248. self.orderLabel.setObjectName("dverLabel")
  249. self.orderEdit = QtWidgets.QLineEdit(self.centralwidget)
  250. self.orderEdit.setGeometry(QtCore.QRect(310, 410, 151, 21))
  251. # 进度条与按钮
  252. font = QtGui.QFont()
  253. font.setFamily("Arial")
  254. font.setPointSize(11)
  255. self.orderEdit.setFont(font)
  256. self.orderEdit.setObjectName("dverEdit")
  257. self.pushButton = QtWidgets.QPushButton(self.centralwidget)
  258. self.pushButton.setGeometry(QtCore.QRect(300, 520, 111, 41))
  259. self.pushButton.setObjectName("pushButton")
  260. self.progressBar = QtWidgets.QProgressBar(self.centralwidget)
  261. self.progressBar.setGeometry(QtCore.QRect(130, 540, 491, 31))
  262. self.progressBar.setProperty("value", 0)
  263. self.progressBar.setVisible(False)
  264. self.progressBar.setObjectName("progressBar")
  265. MainWindow.setCentralWidget(self.centralwidget)
  266. self.retranslateUi(MainWindow)
  267. self.inputFileTool.clicked.connect(self.input_file_path)
  268. self.savePathTool.clicked.connect(self.out_save_location)
  269. self.pushButton.clicked.connect(self.on_click)
  270. QtCore.QMetaObject.connectSlotsByName(MainWindow)
  271. def retranslateUi(self, MainWindow):
  272. _translate = QtCore.QCoreApplication.translate
  273. MainWindow.setWindowTitle(_translate("MainWindow", "杀虫灯质检工具"))
  274. self.savePathTool.setText(_translate("MainWindow", "选择文件夹"))
  275. self.inputFileTool.setText(_translate("MainWindow", "选择文件"))
  276. self.pageTitleLabel.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-weight:600; color:#3a45aa;\">北大荒测报灯质检工具</span></p></body></html>"))
  277. self.savePathLabel.setText(_translate("MainWindow", "|输出文件位置:"))
  278. self.inputFileLabel.setText(_translate("MainWindow", "|输入文件位置:"))
  279. self.startTimeLabel.setText(_translate("MainWindow", "|开始时间:"))
  280. self.endTimeLabel.setText(_translate("MainWindow", "|结束时间:"))
  281. self.platLabel.setText(_translate("MainWindow", "|检验平台:"))
  282. self.productLabel.setText(_translate("MainWindow", "|产品名称:"))
  283. self.powerSupplyLabel.setText(_translate("MainWindow", "|供电选择:"))
  284. self.stm8vsLabel.setText(_translate("MainWindow", "|系统固件版本号:"))
  285. self.dverLabel.setText(_translate("MainWindow", "|RTU固件版本号: "))
  286. self.orderLabel.setText(_translate("MainWindow", "|任务单号:"))
  287. self.pushButton.setText(_translate("MainWindow", "开始导出"))
  288. def input_file_path(self):
  289. file_path = QtWidgets.QFileDialog.getOpenFileName(None,"选取文件","./","All Files (*.xlsx;*.xls);;Text Files (*.txt)")
  290. self.inputFileEdit.setText(file_path[0])
  291. self.inputFileEdit.setStyleSheet("color:black;")
  292. def out_save_location(self):
  293. fname = QtWidgets.QFileDialog.getExistingDirectory(None, '选取文件夹', './')
  294. self.savePathEdit.setText(fname)
  295. self.savePathEdit.setStyleSheet("color:black;")
  296. def on_click(self):
  297. file_path = self.inputFileEdit.text()
  298. save_path = self.savePathEdit.text()
  299. start_time = self.startTimeEdit.dateTime().toPyDateTime()
  300. end_time = self.endTimeEdit.dateTime().toPyDateTime()
  301. set_plat = self.platBox.currentText()
  302. set_stm8vs = self.stm8vsEdit.text()
  303. set_dver = self.dverEdit.text()
  304. set_order = self.orderEdit.text()
  305. set_product = self.productBox.currentText()
  306. set_power = self.powerSupplyBox.currentText()
  307. if not all ([file_path,save_path,start_time,end_time,set_stm8vs,set_dver,set_order]):
  308. QtWidgets.QMessageBox.information(None, "提示", "选项未填写完整")
  309. elif end_time < start_time:
  310. QtWidgets.QMessageBox.information(None, "提示", "结束日期应在开始日期之后")
  311. else:
  312. xls = open_workbook(file_path)
  313. sheet_object = xls.sheets()[0]
  314. ncols = sheet_object.ncols
  315. read_dict = {}
  316. for i in range(ncols):
  317. col_value = sheet_object.col_values(i)
  318. read_dict[col_value[0]] = col_value[1:]
  319. device_list = read_dict.get("设备ID")
  320. if device_list:
  321. self.inputFileTool.setEnabled(False)
  322. self.savePathTool.setEnabled(False)
  323. self.startTimeEdit.setEnabled(False)
  324. self.endTimeEdit.setEnabled(False)
  325. self.platBox.setEnabled(False)
  326. self.productBox.setEnabled(False)
  327. self.powerSupplyBox.setEnabled(False)
  328. self.stm8vsEdit.setEnabled(False)
  329. self.dverEdit.setEnabled(False)
  330. self.orderEdit.setEnabled(False)
  331. self.pushButton.setEnabled(False)
  332. self.pushButton.setText("执行中...")
  333. self.runThread = CBDThread(device_list,save_path,start_time,end_time,set_plat,set_stm8vs,set_dver,set_order, set_product, set_power)
  334. self.runThread.proess_signal.connect(self.set_progressbar_value)
  335. self.runThread.start()
  336. self.progressBar.setVisible(True)
  337. else:
  338. QtWidgets.QMessageBox.information(None, "提示", "输入文件无'设备ID'列或该列无数据")
  339. def set_progressbar_value(self, value):
  340. self.progressBar.setValue(value)
  341. if value == 100:
  342. QtWidgets.QMessageBox.information(None, "提示", "文件导出完毕!导出文件名:\n{}".format(save_filename))
  343. self.inputFileTool.setEnabled(True)
  344. self.inputFileEdit.setText("")
  345. self.savePathTool.setEnabled(True)
  346. self.savePathEdit.setText("")
  347. self.startTimeEdit.setEnabled(True)
  348. self.endTimeEdit.setEnabled(True)
  349. self.platBox.setEnabled(True)
  350. self.productBox.setEnabled(True)
  351. self.powerSupplyBox.setEnabled(True)
  352. self.stm8vsEdit.setEnabled(True)
  353. # self.stm8vsEdit.setText("")
  354. self.dverEdit.setEnabled(True)
  355. # self.dverEdit.setText("")
  356. self.orderEdit.setEnabled(True)
  357. self.orderEdit.setText("")
  358. self.pushButton.setEnabled(True)
  359. self.pushButton.setText("开始导出")
  360. self.progressBar.setVisible(False)
  361. self.progressBar.setValue(0)
  362. return
  363. class CBDThread(QtCore.QThread):
  364. """涉及进度条需主界面动态执行GUI,线程执行业务逻辑,避免主页面卡死"""
  365. proess_signal = QtCore.pyqtSignal(int)
  366. def __init__(self,device_list,save_path,start_time,end_time,set_plat,set_stm8vs,set_dver,set_order, set_product, set_power):
  367. super(CBDThread, self).__init__()
  368. self.device_list = device_list
  369. self.save_path = save_path
  370. self.start_time = time.mktime(start_time.timetuple())
  371. self.end_time = time.mktime(end_time.timetuple())
  372. # self.start_time = 1689737400
  373. # self.end_time = 1689753600
  374. self.start_time_str = start_time.strftime("%y-%m-%d %H:%M:%S")
  375. self.end_time_str = end_time.strftime("%y-%m-%d %H:%M:%S")
  376. self.set_plat = set_plat
  377. self.set_stm8vs = set_stm8vs
  378. self.set_dver = set_dver
  379. self.set_order = set_order
  380. self.set_product = set_product
  381. self.set_power = set_power
  382. self.user = parse.quote_plus("root")
  383. self.passwd = parse.quote_plus("yfkj@6020")
  384. self.myclient = pymongo.MongoClient("mongodb://{0}:{1}@8.136.98.49:57017/".format(self.user,self.passwd))
  385. self.db = self.myclient.smartfarming
  386. self.device_collection = self.db.sa_device
  387. self.cbd_collection = self.db.sa_device_cbd_data
  388. self.cbd_photo = self.db.sa_device_cbdphoto
  389. self.cbd_alerm = self.db.sa_alarm_record
  390. self.device_config = self.db.sa_device_config
  391. self.sa_device_config = self.db.sa_device_config
  392. self.config = {
  393. 'host': '120.27.222.26',
  394. 'port': 3306,
  395. 'user': 'yfwlw',
  396. 'password': 'sql_yfkj_6019',
  397. 'db': 'yfwlw',
  398. 'charset': 'utf8mb4',
  399. 'cursorclass': pymysql.cursors.DictCursor,
  400. }
  401. self.connection = pymysql.connect(**self.config)
  402. self.cursor = self.connection.cursor()
  403. def get_position(self, device_id):
  404. device = self.device_collection.find_one({"device_id": device_id})
  405. province, city, district = device.get("province"), device.get("city"), device.get("district")
  406. position_device = f"{province}{city}{district}"
  407. if position_device:
  408. return position_device
  409. lng, lat = device.get("lng"), device.get("lat")
  410. if lng and lat:
  411. try:
  412. ret = requests.post("http://api.map.baidu.com/geocoder?location=%s,%s&coord_type=gcj02&output=json"%(lat,lng))
  413. ret_json = json.loads(ret.text)
  414. province, city, district = ret_json["result"]["addressComponent"]["province"], \
  415. ret_json["result"]["addressComponent"]["city"], \
  416. ret_json["result"]["addressComponent"]["district"]
  417. return province + city + district
  418. except Exception as e:
  419. return False
  420. else:
  421. return False
  422. def sim_info(self,iccid):
  423. # 时间戳 用于获取sign
  424. timestamp = int(time.time())
  425. current_milli_time = lambda: int(round(time.time() * 1000))
  426. data_1 = "appid=%s&iccid=%s&timestamp=%s%s"%("102420177762",iccid,current_milli_time(),"6397d7e6a56589f1d93284e9800493e1")
  427. sign = hashlib.sha256(data_1.encode('utf-8')).hexdigest()
  428. data = {"appid": "102420177762", "iccid": iccid, "timestamp":current_milli_time(),"sign":sign}
  429. url = "https://api.simboss.com/2.0/device/detail"
  430. try:
  431. status = 1
  432. ret = requests.post(url, data=data)
  433. code = json.loads(ret.text)["code"]
  434. if code == "0":
  435. status = 1
  436. else:
  437. url = 'http://sim.brlink.cn/api/open/iotcard/card'
  438. appkey = "iaO2DKgS8KdlnVgU"
  439. appsecret = "qzKgO4sBdzMrjRwv9H22S9ufepNv8Hl5ehPqkYVD31DCICjyKwqUdj7zihQQKfgx"
  440. status = 2
  441. ret = requests.post(url,json={'iccid':iccid},auth=HTTPBasicAuth(appkey,appsecret),timeout=(5,10))
  442. codes = json.loads(ret.text)["code"]
  443. if codes == 0:
  444. status = 2
  445. else:
  446. url = "https://jsnl.xmnengjia.com/open/api/module/cards"
  447. data = {"iccids":[iccid]}
  448. data = json.dumps(data)
  449. ret = requests.post(url,data=data,timeout=(10,30))
  450. status = 3
  451. except:
  452. status = 0
  453. ret = 0
  454. day = 0
  455. if ret:
  456. try:
  457. result = json.loads(ret.text)
  458. expiry_date = result.get("data", {}).get("expiry_date")
  459. now_date = int(time.time())
  460. time_difference = int((expiry_date - now_date) / 3600 / 24)
  461. if time_difference < 30:
  462. return [1,"有效期剩余{}天".format(time_difference)]
  463. elif time_difference >= 181:
  464. return [1,"有效期剩余{}天".format(time_difference)]
  465. else:
  466. return [1,"有效期剩余{}天".format(time_difference)]
  467. except:
  468. return [1, "查询无结果"]
  469. else:
  470. return [1, "查询无结果"]
  471. def _imageToMatrix(self, image):
  472. """
  473. 根据名称读取图片对象转化矩阵
  474. :param strName:
  475. :return: 返回矩阵
  476. """
  477. imgMat = np.matrix(image)
  478. return imgMat
  479. def preImgOps(self, img):
  480. """
  481. 图像的预处理操作
  482. :param img: 图像的而明朝
  483. :return: 灰度化和resize之后的图片对象
  484. """
  485. # 预处理操作
  486. try:
  487. reImg = cv2.resize(img, (300, 400), interpolation=cv2.INTER_CUBIC) #
  488. img2gray = cv2.cvtColor(reImg, cv2.COLOR_BGR2GRAY) # 将图片压缩为单通道的灰度图
  489. return reImg,img2gray, True
  490. except Exception as e:
  491. return None, None, False
  492. def ReadImage(self, im_file):
  493. """
  494. 读取图片
  495. :param im_file: 图像的路径
  496. :return: 利用opencv读取的完整图像img 托虫板内接四边形图像cutimg 内接四边形的坐标c[xmin,ymin,xmax,ymax]
  497. """
  498. try:
  499. img = cv2.imdecode(np.fromfile(im_file, dtype=np.uint8), cv2.IMREAD_COLOR)
  500. ImgShape = img.shape
  501. center = [ImgShape[1]/2,ImgShape[0]/2] #圆盘中心
  502. radius = int(ImgShape[0]/2) #圆盘半径
  503. length = pow(2,0.5)*radius #圆的内接正方形边长
  504. Size = int(length/2)
  505. xmin = int(center[0] - Size)
  506. xmax = int(center[0] + Size)
  507. ymin = int((center[1] - Size)*1.1)
  508. ymax = int(center[1] + Size)
  509. c = [xmin,ymin,xmax,ymax]
  510. cutimg = img[ymin:ymax,xmin:xmax]
  511. return img,cutimg,c, True
  512. except Exception as e:
  513. return None, None, None, False
  514. def getFileName(self, imageFile):
  515. url, FileName = os.path.split(imageFile)
  516. tamp = []
  517. tamp.append(FileName)
  518. return tamp
  519. #图像清晰度检测
  520. def predict(self, imageFile):
  521. """
  522. 图像清晰度检测
  523. Args:
  524. imageFile(dir or file):单张图片或者存放图片的文件夹
  525. """
  526. result = [] #存放清晰度评分
  527. imgList = [] #存放识别后图片
  528. if os.path.isdir(imageFile):
  529. imageFileList = [os.path.join(imageFile,x) for x in os.listdir(imageFile)]
  530. for image in imageFileList:
  531. img,cutimg,c, is_get = self.ReadImage(image)
  532. if is_get:
  533. reImg, img2gray, is_imgs= self.preImgOps(cutimg)
  534. if is_imgs:
  535. f = self._imageToMatrix(img2gray)
  536. tmp = filters.sobel(f)
  537. source=np.sum(tmp**2)
  538. source=np.sqrt(source)
  539. result.append(source)
  540. imgList.append(img)
  541. elif os.path.isfile(imageFile):
  542. img,cutimg,c, is_get = self.ReadImage(imageFile)
  543. if is_get:
  544. reImg, img2gray, is_imgs= self.preImgOps(cutimg)
  545. if is_imgs:
  546. f = self._imageToMatrix(img2gray)
  547. tmp = filters.sobel(f)
  548. source=np.sum(tmp**2)
  549. source=np.sqrt(source)
  550. result.append(source)
  551. imgList.append(img)
  552. return result
  553. def __bigdata_iamge_verify(self, device_id):
  554. # 对图片质量进行打分并求平均值
  555. scores_time = {}
  556. photo_obj = self.cbd_photo.find({"device_id":str(device_id), 'addtime': {"$gte": int(self.start_time) - 3600 * 4,"$lte":self.start_time}})
  557. for p in photo_obj:
  558. photo_addr = p.get("addr")
  559. addtime = p.get("addtime")
  560. # 把图片下载到本地
  561. local_dir = "org_image"
  562. file_name = photo_addr.split("/")[-1]
  563. file_name = file_name.replace("?", "")
  564. os.makedirs(local_dir) if not os.path.exists(local_dir) else None
  565. # response = requests.get(f"https://bigdata-image.oss-cn-hangzhou.aliyuncs.com/Basics/cbd/{photo_addr}")
  566. if "ftp" in photo_addr:
  567. response = requests.get(photo_addr)
  568. else:
  569. response = requests.get(f"http://8.136.98.49:8003/Basics/cbd/{photo_addr}")
  570. with open(os.path.join(local_dir, file_name), 'wb') as f:
  571. f.write(response.content)
  572. result_score = self.predict(os.path.join(local_dir, file_name))
  573. if result_score:
  574. avg_score = sum(result_score)/len(result_score)
  575. scores_time[str(addtime)] = avg_score
  576. try:
  577. os.remove(os.path.join(local_dir, file_name))
  578. except:
  579. pass
  580. try:
  581. shutil.rmtree(local_dir)
  582. except:
  583. pass
  584. print(scores_time, "----------------------")
  585. return scores_time
  586. def __siqing_image_verify(self, device_id):
  587. # 对图片质量进行打分并求平均值
  588. scores_time = {}
  589. sql = "SELECT * FROM AppInfoManage_cbdphoto WHERE equip_id_id='{}' AND upl_time BETWEEN '{}' AND '{}' order by 'alarm_time';".format(device_id,self.start_time_str,self.end_time_str)
  590. self.cursor.execute(sql)
  591. photo_obj = self.cursor.fetchall()
  592. for p in photo_obj:
  593. photo_addr = p.get("addr")
  594. addtime = p.get("addtime")
  595. # 把图片下载到本地
  596. local_dir = "org_image"
  597. file_name = photo_addr.split("/")[-1]
  598. os.makedirs(local_dir) if not os.path.exists(local_dir) else None
  599. response = requests.get(photo_addr)
  600. with open(os.path.join(local_dir, file_name), 'wb') as f:
  601. f.write(response.content)
  602. result_score = self.predict(os.path.join(local_dir, file_name))
  603. avg_score = sum(result_score)/len(result_score)
  604. scores_time[str(addtime)] = avg_score
  605. try:
  606. os.remove(os.path.join(local_dir, file_name))
  607. except:
  608. pass
  609. return scores_time
  610. def mongo_ping(self):
  611. """mongo-ping预防连接失效"""
  612. try:
  613. self.myclient.admin.command('ping')
  614. except: # "ConnectionFailure"
  615. self.myclient = pymongo.MongoClient("mongodb://{0}:{1}@8.136.98.49:57017/".format(self.user,self.passwd))
  616. self.db = self.myclient.smartfarming
  617. self.device_collection = self.db.sa_device
  618. self.cbd_collection = self.db.sa_device_cbd_data
  619. self.cbd_photo = self.db.sa_device_cbdphoto
  620. self.cbd_alerm = self.db.sa_alarm_record
  621. def sql_ping(self):
  622. """mysql-ping 预防连接失效"""
  623. try:
  624. self.connection.ping()
  625. except:
  626. self.connection = pymysql.connect(**self.config)
  627. self.cursor = self.connection.cursor()
  628. def __time_dif(self,checkdatetime):
  629. """计算时间差"""
  630. nowdatetime = datetime.datetime.now()
  631. checkdatetime = datetime.datetime.strptime(checkdatetime, "%Y-%m-%d %H:%M:%S")
  632. timedif = checkdatetime - nowdatetime
  633. return timedif.days
  634. def device_their_platform(self,shortId):
  635. """确定设备所在平台已经完整设备号"""
  636. self.mongo_ping()
  637. self.sql_ping()
  638. regex = re.compile('.*{}$'.format(shortId))
  639. bd_device_dict = self.device_collection.find_one(
  640. filter = {"device_id":regex,"device_type_id":3},
  641. projection = {'_id': 0},
  642. sort = [('uptime', pymongo.DESCENDING)]
  643. )
  644. device_sql = "SELECT * FROM AppInfoManage_cbdstatus WHERE equip_id_id LIKE '%{}' ORDER BY upl_time DESC LIMIT 1;".format(shortId)
  645. self.cursor.execute(device_sql)
  646. sq_device_dict = self.cursor.fetchone()
  647. if bd_device_dict and sq_device_dict:
  648. bd_upltime = bd_device_dict["uptime"]
  649. sq_upltime = time.mktime(sq_device_dict["upl_time"].timetuple())
  650. if bd_upltime >= sq_upltime:
  651. d_id = bd_device_dict["id"]
  652. deviceId = bd_device_dict["device_id"]
  653. platform = "大数据平台"
  654. else:
  655. d_id = ""
  656. deviceId = sq_device_dict["equip_id_id"]
  657. platform = "四情平台"
  658. elif bd_device_dict and not sq_device_dict:
  659. d_id = bd_device_dict["id"]
  660. deviceId = bd_device_dict["device_id"]
  661. platform = "大数据平台"
  662. return d_id,deviceId,platform
  663. elif not bd_device_dict and sq_device_dict:
  664. d_id = ""
  665. deviceId = sq_device_dict["equip_id_id"]
  666. platform = "四情平台"
  667. else:
  668. d_id = ""
  669. deviceId = "平台无此设备"
  670. platform = "未知"
  671. return d_id,deviceId,platform
  672. def eliminate_adjacent_duplicates(self, string):
  673. result = ''
  674. prev_char = None
  675. for char in string:
  676. if char != prev_char:
  677. result += char
  678. prev_char = char
  679. return result
  680. def __bigdata_verify(self,data_cursor,data_status,device_id_info, image_score, proess, data_temps, position, tt, device_id):
  681. """
  682. 获取大数据平台查询结果
  683. 1. 合格
  684. 2. 不合格
  685. """
  686. current_jg = [1,""] # 振动电机工作状态下电流匹配度
  687. up_jg = [1,"无电流不足信息"] # 上仓门电机电机工作状态
  688. down_jg = [1,"无电流不足信息"] # 下仓门电机电机工作状态
  689. lig_jg = [1,"无电流不足信息"] # 灯管工作状态下
  690. machine_jg = [1, "无电流不足信息"]# 清扫/转盘电机工作状态
  691. camera_jg = [1, "无电流不足信息"] # 相机工作状态
  692. current_jg_ct, up_jg_ct, down_jg_ct, lig_jg_ct, camera_jg_ct, machine_ct = 0,0,0,0,0,0
  693. for alerm in data_status:
  694. alarm_time = datetime.datetime.fromtimestamp(alerm.get("alarm_time")).strftime("%Y-%m-%d %H:%M:%S")
  695. a = alerm.get("alarm_desc", "")
  696. if a:
  697. a = json.loads(a)
  698. if a.get("type", "") == "震动电机":
  699. if "电流不足" in a.get("status"):
  700. current_jg_ct += 1
  701. elif a.get("type", "") == "上仓门电机":
  702. if "电流不足" in a.get("status"):
  703. up_jg_ct += 1
  704. elif a.get("type", "") == "下仓门电机":
  705. if "电流不足" in a.get("status"):
  706. down_jg_ct += 1
  707. elif a.get("type", "") == "灯管":
  708. if "电流不足" in a.get("status"):
  709. lig_jg_ct += 1
  710. elif a.get("type", "") in ["清扫电机", "转盘电机"]:
  711. if "电流不足" in a.get("status"):
  712. machine_ct += 1
  713. elif a.get("type", "") == "相机":
  714. print(a, "电流不足", alarm_time)
  715. if "电流不足" in a.get("status"):
  716. camera_jg_ct += 1
  717. iccid = ""
  718. lng_lst = []
  719. lat_lst = []
  720. work_status = [] # 工作状态切换
  721. elec_vs_lst = [] # 电路板固件版本号
  722. v_vs_lst = [] # 电压
  723. tr_k_jg_lst = [] # 温控
  724. rain_k_jg_lst = []# 雨控
  725. infor_jg_count = 0 # 上报信息条数
  726. heat_temp_lst = []# 加热仓温度
  727. temp_hum = [] # 环境温度 环境湿度
  728. total_time = [] # 总时长
  729. start_time = 0
  730. information_count = [] # 上报时间
  731. infor_lamp = {}
  732. dver_lst = []
  733. for c in data_temps:
  734. device_c = c.get("device_data", "")
  735. if device_c:
  736. device_c = ast.literal_eval(device_c)
  737. tp = device_c.get("tps", "")
  738. if tp == "1":
  739. tr_k_jg_lst.append(tp)
  740. for index, cur in enumerate(data_cursor):
  741. start_time = int(cur.get("addtime", 0))
  742. device_data = cur.get("device_data", "")
  743. if device_data:
  744. device_data = ast.literal_eval(device_data)
  745. iccid = device_data.get("iccid", "")
  746. lamp = device_data.get("lamp")
  747. if lamp == "0":
  748. infor_lamp[str(start_time)] = lamp
  749. information_count.append(start_time)
  750. lng = device_data.get("lng", "")
  751. lat = device_data.get("lat", "")
  752. try:
  753. lng_lst.append(float(lng))
  754. lat_lst.append(float(lat))
  755. except Exception as e:
  756. lng_lst.append(0)
  757. lat_lst.append(0)
  758. work_status.append(device_data.get("ws", ""))
  759. elec_vs_lst.append(device_data.get("dver", ""))
  760. v_vs_lst.append(float(device_data.get("vbat", 0)))
  761. rain_k_jg_lst.append(device_data.get("rps", ""))
  762. infor_jg_count += 1
  763. heat_temp_lst.append(float(device_data.get("hrt", 0)))
  764. temp_hum.append({"at": device_data.get("at", ""), "ah": device_data.get("ah", "")})
  765. if self.set_power == "AC":
  766. total_time.append(int(device_data.get("tt")))
  767. elif self.set_power == "DC":
  768. st = device_data.get("st") # 19:00
  769. et = device_data.get("et") # 08:00
  770. st = int(st.split(":")[0])
  771. et = int(et.split(":")[0])
  772. if st > et:
  773. total = 24 - st + et
  774. else:
  775. total = et - st
  776. total_time.append(total)
  777. dver = device_data.get("dver", "")
  778. if dver:
  779. dver_lst.append(dver)
  780. # 检查卡号及有效期
  781. if self.set_product != "水稻测报灯":
  782. card_jg = self.sim_info(iccid)
  783. else:
  784. card_jg = [1, "合格"]
  785. # 经度
  786. lng_pass = [i for i in lng_lst if 113.76194444 >= i or i >= 113.77861111]
  787. if len(lng_pass):
  788. lng_jg = [4,f"{str(min(lng_lst))}~{str(max(lng_lst))},不符合条件的数据有{str(len(lng_pass))}条"]
  789. else:
  790. lng_jg = [1, f"{str(min(lng_lst))}~{str(max(lng_lst))}"]
  791. # 纬度 35°2'57″±30″ 35.040776 35.057442
  792. lat_pass = [i for i in lat_lst if 35.040776 >=i or i >= 35.057442]
  793. if len(lat_pass):
  794. lat_jg = [4,f"{str(min(lat_lst))}~{str(max(lat_lst))},不符合条件的数据有{str(len(lat_pass))}条"]
  795. else:
  796. lat_jg = [1, f"{str(min(lat_lst))}~{str(max(lat_lst))}"]
  797. # 工作状态切换
  798. work_status_str = "".join(work_status)
  799. result = self.eliminate_adjacent_duplicates(work_status_str)
  800. count_01 = result.count("01")
  801. count_10 = result.count("10")
  802. ww = min([count_01, count_10])
  803. if ww >= 1:
  804. work_jg = [1, f"待机/工作转换{str(ww)}次"]
  805. else:
  806. work_jg = [0, f"无待机/工作转换"]
  807. # 电路板输入电压
  808. v_vs_pass = [i for i in v_vs_lst if 22 > i or i > 30]
  809. if len(v_vs_pass):
  810. v_vs = [0, f"{str(min(v_vs_lst))}~{str(max(v_vs_lst))},不合格数据3条"]
  811. else:
  812. v_vs = [1, f"{str(min(v_vs_lst))}~{str(max(v_vs_lst))}"]
  813. # 温控
  814. if "1" in tr_k_jg_lst:
  815. tr_k_jg = [1, f"上报被温控数据{str(tr_k_jg_lst.count('1'))}条"]
  816. else:
  817. tr_k_jg = [0, f"无数据上报"]
  818. # 雨控
  819. if self.set_product != "水稻测报灯":
  820. if "1" in rain_k_jg_lst:
  821. rain_k_jg = [1, f"被雨控有{str(rain_k_jg_lst.count('1'))}条数据"]
  822. else:
  823. rain_k_jg = [0, "无被雨控数据上报"]
  824. else:
  825. rain_k_jg = [1, "合格"]
  826. # 加热仓温度
  827. heat_temp = []
  828. for h in heat_temp_lst:
  829. if 85 <= h <= 105:
  830. heat_temp = [1, f"{str(min(heat_temp_lst))}~{str(max(heat_temp_lst))}"]
  831. break
  832. if not heat_temp:
  833. heat_temp = [0, f"{str(min(heat_temp_lst))}~{str(max(heat_temp_lst))}"]
  834. # 环境温度
  835. if {"at": "25", "ah": "35"} in temp_hum:
  836. en_temp = [0,"35且环境湿度显示25"]
  837. else:
  838. temp = [float(k.get("at", 0)) for k in temp_hum]
  839. en_temp = [1,f"{str(min(temp))}~{str(max(temp))}"]
  840. # 环境湿度
  841. if {"at": "35", "ah": "25"} in temp_hum:
  842. en_hum = [0,"25且环境温度显示35"]
  843. else:
  844. temp = [float(k.get("ah", 0)) for k in temp_hum]
  845. en_hum = [1,f"{str(min(temp))}~{str(max(temp))}"]
  846. # 图片质量
  847. if self.set_product == "4.0测报灯" or self.set_product == "水稻测报灯":
  848. sorted_dict = sorted(image_score.items(), key=lambda x: x[1], reverse=True)
  849. sorted_dict = sorted_dict[:3]
  850. lte = []
  851. score = []
  852. print(sorted_dict, "----------------")
  853. for v in sorted_dict:
  854. rank = 55 if self.set_product == "水稻测报灯" else 68
  855. if v[1] < rank:
  856. lte.append(str(v[1]))
  857. score.append(str(round(v[1], 3)))
  858. else:
  859. score.append(str(round(v[1], 3)))
  860. if sorted_dict:
  861. if lte:
  862. img_jg = [0, ",".join(score)]
  863. else:
  864. img_jg = [1, ",".join(score)]
  865. else:
  866. img_jg = [0, "输入开始时间前4h内无图片"]
  867. else:
  868. img_jg = [1, ""]
  869. # 上报信息条数
  870. interval = [abs(information_count[i+1] - information_count[i]) for i in range(len(information_count) - 1)]
  871. k = 0
  872. for i in interval:
  873. if i < 5 * 60:
  874. k += 1
  875. if len(information_count) >= 22 and k <= 3:
  876. infor_jg_count = [1, f"数据条数为{str(len(information_count))},其中有小于5分钟的数据间隔{str(k)}条"]
  877. elif len(information_count) >= 22 and k >=4:
  878. infor_jg_count = [0, f"数据条数{str(len(information_count))},其中有小于5分钟的数据间隔{str(k)}条"]
  879. else:
  880. infor_jg_count = [0, f"数据条数{str(len(information_count))},其中有小于5分钟的数据间隔{str(k)}条"]
  881. # 图片数量统计
  882. try:
  883. print(device_id, "device 设备_id")
  884. device_config = self.sa_device_config.find_one({"d_id": int(device_id), "cmd": "paramconf"}, {"device_config": 1, "_id": 0})
  885. d_config = device_config.get("device_config")
  886. print(d_config, "++++++++++++++++")
  887. d_config = eval(d_config)
  888. print(d_config, 'json')
  889. collt = int(d_config.get('ext').get("collt"))
  890. htim = int(d_config.get('ext').get("htim"))
  891. if collt > 0 and htim >0:
  892. if int(d_config.get('ext').get("ts")) == 1: # 时控
  893. photo_obj = self.cbd_photo.find({"device_id":str(device_id), 'addtime': {"$gte": self.start_time,"$lte":self.end_time}}, {"addtime": 1, "_id": 0}).sort("addtime", 1)
  894. addtime_lst = [i.get("addtime") for i in list(photo_obj)]
  895. # print(self.start_time, self.end_time, [datetime.datetime.fromtimestamp(i).strftime("%Y-%m-%d %H:%M:%S") for i in addtime_lst], "-----------------------")
  896. # 总图片数量
  897. count_photo = len(addtime_lst)
  898. # 应该出现的图片数量
  899. print(collt, htim, "落虫时间与加热时间")
  900. photo_deal_interval = collt + htim
  901. # 时控时间
  902. st = d_config.get('ext').get("st")
  903. et = d_config.get('ext').get("et")
  904. if int(et) == 0:
  905. et = 24
  906. device_interval = int(et) - int(st)
  907. print("开始时间,结束时间", f"{et, st}")
  908. should_count_photo = (device_interval * 60) / photo_deal_interval
  909. print(et, st, "开始与结束时间")
  910. if abs(should_count_photo - count_photo) <= 1:
  911. count_message = [1, "上报图片数量正常"]
  912. else:
  913. count_message = [0, f"上报图片数量{count_photo}张,应上报图片{abs(int(should_count_photo))}张"]
  914. else:
  915. count_message = [0, "设备处于光控模式"]
  916. else:
  917. count_message = [0, f"落虫或加热时间有误,落虫时间{collt},加热时间{htim}"]
  918. except Exception as e:
  919. traceback.print_exc()
  920. print(e, "------------工作时间检测---------")
  921. count_message = [0, "无上报数据"]
  922. # 电路板固件版本号 RTU固件版本号
  923. rtus = []
  924. gujians = []
  925. for d in dver_lst:
  926. rtu = d.split("-")[-1]
  927. gujian = d.replace(rtu, "").replace("-", "")
  928. gujians.append(gujian)
  929. rtus.append(rtu)
  930. rtus = list(set(rtus))
  931. gujians = list(set(gujians))
  932. if len(gujians) == 1 and gujians[0] == self.set_stm8vs:
  933. gujian_num = [1, self.set_stm8vs]
  934. else:
  935. if len(gujians) == 1:
  936. gujian_num = [0, gujians[0]]
  937. else:
  938. gujian_num = [0, ",".join(gujians)]
  939. if len(rtus) == 1 and rtus[0] == self.set_dver:
  940. rtu_num = [1, self.set_dver]
  941. else:
  942. if len(rtus) == 1:
  943. rtu_num = [0, rtus[0]]
  944. else:
  945. rtu_num = [0, ",".join(rtus)]
  946. # 工作时长 判定
  947. # 数据超过8小时判断
  948. try:
  949. if information_count:
  950. print("上报数据", information_count)
  951. eight_check_start = information_count[0]
  952. eight_check_end = information_count[-1]
  953. if abs((eight_check_end - eight_check_start)) > 3600 * 8:
  954. time_jg = [1, f'正常工作时间为{abs(int((eight_check_end - eight_check_start)) / 3600)}h']
  955. else:
  956. time_jg = [0, f'正常工作时间为{abs(int((eight_check_end - eight_check_start) / 3600))}h,小于8小时']
  957. else:
  958. time_jg = [0, '检测时间段内无数据上报']
  959. except Exception as e:
  960. time_jg = [0, '检测时间段内无数据上报']
  961. traceback.print_exc()
  962. if position == "河南省新乡市原阳县":
  963. position_cg = [1, position]
  964. else:
  965. position_cg = [0, position]
  966. # 记录开始时间与结束时间及时间段内的记录数量
  967. return [
  968. device_id_info,
  969. [1, self.set_order],
  970. card_jg,
  971. lng_jg,
  972. lat_jg,
  973. gujian_num,
  974. rtu_num,
  975. v_vs,
  976. tr_k_jg,
  977. rain_k_jg,
  978. infor_jg_count,
  979. heat_temp,
  980. en_temp,
  981. en_hum,
  982. img_jg,
  983. count_message,
  984. time_jg,
  985. position_cg
  986. ]
  987. def __siqing_verify(self, data_result,status_result, status_all_result, alarm_result, device_id_info, image_score, process):
  988. """获取四情平台查询结果"""
  989. current_jg = [1,""] # 振动电机工作状态下电流匹配度
  990. up_jg = [1,"无电流不足信息"] # 上仓门电机电机工作状态
  991. down_jg = [1,"无电流不足信息"] # 下仓门电机电机工作状态
  992. lig_jg = [1,"无电流不足信息"] # 灯管工作状态下
  993. machine_jg = [1, "无电流不足信息"]# 电机工作状态
  994. camera_jg = [1, "无电流不足信息"] # 相机工作状态
  995. time_jg = [1, "合格"] # 工作时长
  996. current_jg_ct, up_jg_ct, down_jg_ct, lig_jg_ct, camera_jg_ct = 0,0,0,0,0
  997. if alarm_result:
  998. for alerm in alarm_result:
  999. a = alerm.get("alarm_desc", "")
  1000. if a:
  1001. try:
  1002. a = eval(a)
  1003. except Exception as e:
  1004. a = json.loads(a)
  1005. if a.get("type", "") == "震动电机":
  1006. if a.get("status") == "电流不足":
  1007. current_jg_ct += 1
  1008. elif a.get("type", "") == "上仓门电机":
  1009. if "电流不足" in a.get("status"):
  1010. up_jg_ct += 1
  1011. elif a.get("type", "") == "下仓门电机":
  1012. if "电流不足" in a.get("status"):
  1013. down_jg_ct += 1
  1014. elif a.get("type", "") == "灯管":
  1015. if a.get("status") == "电流不足":
  1016. lig_jg_ct += 1
  1017. elif a.get("type", "") == "相机":
  1018. if a.get("status") == "电流不足":
  1019. camera_jg_ct += 1
  1020. if current_jg_ct:
  1021. current_jg = [1,""]
  1022. if up_jg_ct:
  1023. up_jg = [0,f"有电流不足信息{str(up_jg_ct)}条"]
  1024. if down_jg_ct:
  1025. down_jg = [0,f"有电流不足信息{str(down_jg_ct)}条"]
  1026. if lig_jg_ct:
  1027. lig_jg = [0,f"有电流不足信息{str(lig_jg_ct)}条"]
  1028. if camera_jg_ct:
  1029. camera_jg = [0,f"有电流不足信息{str(camera_jg_ct)}条"]
  1030. lng_lst = [] # 经度
  1031. lat_lst = [] # 纬度
  1032. tr_k_jg_lst = [] # 温控
  1033. rain_k_jg_lst = []# 雨控
  1034. infor_jg_count = 0 # 上报信息条数
  1035. heat_temp_lst = []# 加热仓温度
  1036. temp_hum = [] # 环境温度 环境湿度
  1037. total_time = [] # 总时长
  1038. information_count = [] # 上报时间
  1039. v_vs_lst = [] # 电压
  1040. for index, cur in enumerate(data_result):
  1041. upl_time_str = cur.get("upl_time", "0")
  1042. upl_time_int = int(time.mktime(upl_time_str.timetuple()))
  1043. information_count.append(upl_time_int)
  1044. device_data = cur.get("cbd_data", "")
  1045. if device_data:
  1046. device_data = ast.literal_eval(device_data)
  1047. lng = device_data.get("lng", "")
  1048. lng_lst.append(float(lng))
  1049. lat = device_data.get("lat", "")
  1050. lat_lst.append(float(lat))
  1051. v_vs_lst.append(float(device_data.get("vbat", "0")))
  1052. tr_k_jg_lst.append(device_data.get("tps", ""))
  1053. rain_k_jg_lst.append(device_data.get("rps", ""))
  1054. infor_jg_count += 1
  1055. heat_temp_lst.append(float(device_data.get("hrt", 0)))
  1056. temp_hum.append({"at": device_data.get("at", ""), "ah": device_data.get("ah", "")})
  1057. if self.set_power == "AC":
  1058. total_time.append(device_data.get("tt"))
  1059. elif self.set_power == "DC":
  1060. st = device_data.get("st", "00:00")
  1061. et = device_data.get("et", "00:00")
  1062. st = int(st.split(":")[0])
  1063. et = int(et.split(":")[0])
  1064. if st > et:
  1065. total = 24 - st + et
  1066. else:
  1067. total = et - st
  1068. total_time.append(total)
  1069. # 经度
  1070. lng_pass = [i for i in lng_lst if 113.76194444 >= i or i >= 113.77861111]
  1071. if len(lng_pass):
  1072. lng_jg = [0,f"{str(min(lng_lst))}~{str(max(lng_lst))},不符合条件的数据有{str(len(lng_pass))}条"]
  1073. else:
  1074. lng_jg = [1, f"{str(min(lng_lst))}~{str(max(lng_lst))}"]
  1075. # 纬度 35.02083333,35.0375
  1076. lat_pass = [i for i in lat_lst if 35.02083333 >=i or i >= 35.0375]
  1077. if len(lat_pass):
  1078. lat_jg = [0,f"{str(min(lat_lst))}~{str(max(lat_lst))},不符合条件的数据有{str(len(lat_pass))}条"]
  1079. else:
  1080. lat_jg = [1, f"{str(min(lat_lst))}~{str(max(lat_lst))}"]
  1081. # 电路板输入电压
  1082. v_vs_pass = [i for i in v_vs_lst if 22 >= i or i >= 30]
  1083. if len(v_vs_pass):
  1084. v_vs = [0, f"{str(min(v_vs_lst))}~{str(max(v_vs_lst))},不合格数据3条"]
  1085. else:
  1086. v_vs = [1, f"{str(min(v_vs_lst))}~{str(max(v_vs_lst))}"]
  1087. # 温控
  1088. if "1" in tr_k_jg_lst:
  1089. tr_k_jg = [1, f"上报被温控数据{str(tr_k_jg_lst.count('1'))}条"]
  1090. else:
  1091. tr_k_jg = [0, f"无数据上报"]
  1092. # 雨控
  1093. if self.set_product == "水稻测报灯":
  1094. rain_k_jg = [1, "合格"]
  1095. else:
  1096. if "1" in rain_k_jg_lst:
  1097. rain_k_jg = [1, f"被雨控有{str(rain_k_jg_lst.count('1'))}条数据"]
  1098. else:
  1099. rain_k_jg = [0, "无被雨控数据上报"]
  1100. # 加热仓温度
  1101. heat_temp = []
  1102. for h in heat_temp_lst:
  1103. if 85 <= h <= 105:
  1104. heat_temp = [1, f"{str(min(heat_temp_lst))}~{str(max(heat_temp_lst))}"]
  1105. break
  1106. if not heat_temp:
  1107. heat_temp = [0, f"{str(min(heat_temp_lst))}~{str(max(heat_temp_lst))}"]
  1108. # 环境温度
  1109. if {"at": "25", "ah": "35"} in temp_hum:
  1110. en_temp = [0,"35且环境湿度显示25"]
  1111. else:
  1112. temp = [float(k.get("at", 0)) for k in temp_hum]
  1113. en_temp = [1,f"{str(min(temp))}~{str(max(temp))}"]
  1114. # 环境湿度
  1115. if {"at": "35", "ah": "25"} in temp_hum:
  1116. en_hum = [0,"25且环境温度显示35"]
  1117. else:
  1118. temp = [float(k.get("ah", 0)) for k in temp_hum]
  1119. en_hum = [1,f"{str(min(temp))}~{str(max(temp))}"]
  1120. # 图片质量
  1121. img_pass = []
  1122. img_score = []
  1123. for k, v in image_score.items():
  1124. if v > 50:
  1125. img_score.append(v)
  1126. if v < 68:
  1127. img_pass.append((datetime.datetime.fromtimestamp(int(k))).strftime("%Y-%m-%d %H:%M:%S"))
  1128. if img_score:
  1129. if img_pass:
  1130. img_jg = [0, f"{str(min(img_score))}~{str(max(img_score))}, 不合格图片{str(len(img_pass))}幅, 上报时间为{','.join(img_pass)}"]
  1131. else:
  1132. img_jg = [1, f"{str(min(img_score))}~{str(max(img_score))}"]
  1133. else:
  1134. img_jg = [0, "图片得分均在50以下"]
  1135. # 上报信息条数
  1136. interval = [abs(information_count[i+1] - information_count[i]) for i in range(len(information_count) - 1)]
  1137. k = 0
  1138. for i in interval:
  1139. if i < 5 * 60:
  1140. k += 1
  1141. if len(information_count) >= 22 and k == 0:
  1142. infor_jg_count = [1, f"数据条数为{str(len(information_count))},无小于5分钟的数据间隔"]
  1143. elif len(information_count) >= 22 and k:
  1144. infor_jg_count = [0, f"数据条数{str(len(information_count))},其中有小于5分钟的数据间隔{str(k)}条"]
  1145. else:
  1146. infor_jg_count = [0, f"数据条数{str(len(information_count))}"]
  1147. iccid = ""
  1148. work_status = [] # 工作状态切换
  1149. elec_vs_lst = [] # 电路板固件版本号
  1150. for index, cur in enumerate(status_all_result):
  1151. device_data = cur.get("cbd_status", "")
  1152. if device_data:
  1153. device_data = ast.literal_eval(device_data)
  1154. iccid = device_data.get("iccid", "")
  1155. work_status.append(str(device_data.get("ws", "")))
  1156. elec_vs_lst.append(device_data.get("dver", ""))
  1157. # 检查卡号及有效期
  1158. card_jg = self.sim_info(iccid)
  1159. # 工作状态切换
  1160. work_status_str = "".join(work_status)
  1161. wr = work_status_str.count("01")
  1162. if wr > 4:
  1163. work_jg = [1, f"待机/工作转换{str(wr)}次"]
  1164. else:
  1165. work_jg = [0, f"待机/工作转换{str(wr)}次"]
  1166. # 电路板固件版本号 RTU固件版本号
  1167. rtus = []
  1168. gujians = []
  1169. for d in elec_vs_lst:
  1170. rtu = d.split("-")[-1]
  1171. gujian = d.replace(rtu, "").replace("-", "")
  1172. # if gujian == self.set_stm8vs:
  1173. gujians.append(gujian)
  1174. # if rtu == self.set_dver:
  1175. rtus.append(rtu)
  1176. rtus = list(set(rtus))
  1177. gujians = list(set(gujians))
  1178. if len(gujians) == 1 and gujians[0] == self.set_stm8vs:
  1179. gujian_num = [1, self.set_stm8vs]
  1180. else:
  1181. if len(gujians) == 1:
  1182. gujian_num = [0, gujians[0]]
  1183. else:
  1184. gujian_num = [0, ",".join(gujians)]
  1185. if len(rtus) == 1 and rtus[0] == self.set_dver:
  1186. rtu_num = [1, self.set_dver]
  1187. else:
  1188. if len(rtus) == 1:
  1189. rtu_num = [0, rtus[0]]
  1190. else:
  1191. rtu_num = [0, ",".join(rtus)]
  1192. # 工作时长 判定
  1193. if self.set_power == "DC":
  1194. power_pass = []
  1195. for i in total_time:
  1196. if i not in power_pass:
  1197. power_pass.append(i)
  1198. if len(power_pass) == 1 and power_pass[0] == 4:
  1199. time_jg = [1, "4"]
  1200. else:
  1201. time_jg = [0, ",".join([str(i) for i in power_pass])]
  1202. if self.set_power == "AC":
  1203. power_pass = []
  1204. for i in total_time:
  1205. if i not in power_pass:
  1206. power_pass.append(i)
  1207. if len(power_pass) == 1 and power_pass[0] == 9:
  1208. time_jg = [1, "9"]
  1209. else:
  1210. time_jg = [0, ",".join([str(i) for i in power_pass])]
  1211. return [
  1212. device_id_info,
  1213. [1, self.set_order],
  1214. card_jg,
  1215. lng_jg,
  1216. lat_jg,
  1217. work_jg,
  1218. gujian_num,
  1219. rtu_num,
  1220. v_vs,
  1221. tr_k_jg,
  1222. rain_k_jg,
  1223. infor_jg_count,
  1224. heat_temp,
  1225. en_temp,
  1226. en_hum,
  1227. current_jg,
  1228. up_jg,
  1229. down_jg,
  1230. lig_jg,
  1231. img_jg,
  1232. machine_jg,
  1233. camera_jg,
  1234. time_jg
  1235. ]
  1236. def run(self):
  1237. """主业务逻辑,涉及进度条不能模块化,慢慢捋"""
  1238. proess = 0
  1239. now_time = datetime.datetime.now()
  1240. time_stamp = str(int(datetime.datetime.timestamp(now_time)))
  1241. global save_filename
  1242. save_filename = self.set_order + "_" + now_time.strftime("%m%d") + f"测报灯检验-{time_stamp}.xlsx"
  1243. save_path = os.path.join(self.save_path,save_filename)
  1244. workbook = Workbook(save_path)
  1245. worksheet = workbook.add_worksheet()
  1246. worksheet.set_row(0, 30)
  1247. worksheet.set_row(1, 35)
  1248. worksheet.set_row(2, 50)
  1249. worksheet.set_row(3, 80)
  1250. for i in range(len(self.device_list)):
  1251. worksheet.set_row(i+4, 15)
  1252. worksheet.set_column(0, 26, 12)
  1253. toji_style = workbook.add_format(toji_format)
  1254. title_style = workbook.add_format(title_format)
  1255. explain_style = workbook.add_format(explain_formal)
  1256. formal_style = workbook.add_format(formal_format)
  1257. error_style = workbook.add_format(error_format)
  1258. common_style = workbook.add_format(common_format)
  1259. merge_title_style = workbook.add_format(merge_title_format)
  1260. worksheet.merge_range('A1:Y1',"物联网测报灯在线检验原始表格",merge_title_style)
  1261. # "振动电机工作状态下\n电流匹配度",
  1262. # "上仓门电机电机工作状态下 \n 电流匹配度","下仓门电机工作状态下 \n电流匹配度","灯管工作状态下 \n电流匹配度","清扫电机/转盘电机工作状态下的 \n 最大电流","相机工作状态下 \n电流匹配度",
  1263. title_data = [
  1264. "文档ID","设备ID", "任务单号", "卡号及有效期","经度","纬度","电路板固件版本号","RTU固件版本号",
  1265. "电路板输入电压","温控","雨控","上报信息条数","加热仓温度","环境温度","环境湿度","图片质量","工作模式与时间检测",
  1266. "图片数量", "位置", "综合判定"
  1267. ]
  1268. worksheet.write_row(row = 2 ,col = 0, data = title_data,cell_format=title_style) # 35.040776 35.057442
  1269. explain_data = [
  1270. "/",
  1271. "后台显示与输入一致为合格,否则为不合格",
  1272. "按照输入文件的任务单为依据复制到此列",
  1273. "有显示卡号及有效期即为合格,否则为不合格",
  1274. "合格条件(绿色):\n113°46′13″±30″范围内,转为十进度为:(113.76194444,113.77861111)区间内",
  1275. "合格条件(绿色):\n35°2'57″±30″范围内,转为十进度为:(35.040776,35.057442)区间内",
  1276. "合格条件(绿色):\n后台上报结果与输入标准对照,相符则合格,其余则不合格",
  1277. "合格条件(绿色):\n后台上报结果与输入标准对照,相符则合格,其余则不合格",
  1278. "合格条件(绿色):\n电路板输入电压:22~30V",
  1279. "合格条件(绿色):\n测试时间段之前至少有一条被温控数据上报",
  1280. "合格条件(绿色):\n测试时间段内至少有一条被雨控数据上报",
  1281. "合格条件(绿色):\n1、“工作”的条数大于22条,2、在“工作”的前提下,两条数据间隔小于等于5分钟的次数不能高于3条,两项全部符合为合格,否则不合格",
  1282. "合格条件(绿色):\n上传的加热温度包含但不局限于85~105°之间的值",
  1283. "合格条件(绿色):\n等于35且环境温度等于25的前提下为不合格,其余显示的任何值为合格",
  1284. "合格条件(绿色):\n等于25度且环境湿度等于35的前提下为不合格,其余显示的任何值为合格",
  1285. "合格条件(绿色):\n对自动检查前上传的图片质量进行打分,取前三个图片分数,如果有一个小于68为不合格,否则合格",
  1286. "合格条件(绿色):\n在工作时间超过8h为合格,否则不合格",
  1287. "合格条件(绿色):\n工作时间内应上传图片数量在±1张之内合格,否则不",
  1288. "位置信息(绿色): \n合格条件(绿色), 显示河南省新乡市原阳县为合格,否则不合格",
  1289. "合格条件(绿色):\nd:r列全部合格为合格,否则为不合格",
  1290. ""
  1291. ]
  1292. worksheet.write_row(row = 3 ,col = 0, data = explain_data,cell_format=explain_style)
  1293. formal_counts = 0
  1294. verify_list = []
  1295. for index, short_id in enumerate(self.device_list):
  1296. short_id = str(int(short_id)).strip() # 把device_id转换成字符串并去除空格
  1297. d_id,deviceId,platform = self.device_their_platform(short_id)
  1298. # if short_id != deviceId:
  1299. # device_id_info = [0, "不合格"]
  1300. # else:
  1301. device_id_info = [1, deviceId]
  1302. worksheet.write(index+4,0,short_id,formal_style)
  1303. if platform == "大数据平台":
  1304. try:
  1305. worksheet.write(index+4,1,deviceId,formal_style)
  1306. self.mongo_ping()
  1307. data_status = self.cbd_alerm.find({"equip_id": deviceId, "alarm_time": {"$gte":self.start_time ,"$lte":self.end_time}}).sort([('alarm_time', pymongo.DESCENDING)])
  1308. data_cursor = self.cbd_collection.find({"device_id":d_id,'addtime': {"$gte":self.start_time ,"$lte":self.end_time}}).sort([('addtime', pymongo.DESCENDING)])
  1309. data_temps = self.cbd_collection.find({"device_id":d_id,'addtime': {"$gte":self.start_time - 3600 * 24 ,"$lte":self.start_time}}).sort([('addtime', pymongo.DESCENDING)])
  1310. data_counts = data_cursor.count()
  1311. # 配置
  1312. de = self.device_collection.find_one({"device_id":deviceId})
  1313. device_config = self.device_config.find_one({"d_id":de.get("id")})
  1314. tt = 0
  1315. if device_config:
  1316. device_config_temp = device_config.get("device_config")
  1317. device_config_temp = eval(device_config_temp)
  1318. device_config_temp_ext = device_config_temp.get("ext")
  1319. tt = device_config_temp_ext.get("tt")
  1320. image_score = self.__bigdata_iamge_verify(d_id)
  1321. # print(data_counts)
  1322. if data_counts == 0:
  1323. for i in range(1,19):
  1324. worksheet.write(index+4,i,"搜索时间内无数据",error_style)
  1325. worksheet.write(index+4,20,"不合格",error_style)
  1326. danji_verify = []
  1327. for i in range(19):
  1328. danji_verify.append(0)
  1329. verify_list.append(danji_verify)
  1330. else:
  1331. danji_verify = []
  1332. result = self.get_position(deviceId)
  1333. # print(result, "地址")
  1334. verify_data = self.__bigdata_verify(data_cursor,data_status, device_id_info, image_score, proess, data_temps, result, tt, d_id)
  1335. print("\n", verify_data, "\n")
  1336. for clo_index, verify_ in enumerate(verify_data):
  1337. danji_verify.append(verify_[0])
  1338. if verify_[0] == 0:
  1339. worksheet.write(index+4,clo_index+1,verify_[1],error_style)
  1340. elif verify_[0] == 1:
  1341. worksheet.write(index+4,clo_index+1,verify_[1],formal_style)
  1342. else:
  1343. worksheet.write(index+4,clo_index+1,verify_[1],common_style)
  1344. if 4 in danji_verify and (0 not in danji_verify):
  1345. worksheet.write(index+4,19,"可接受", formal_style)
  1346. elif 0 in danji_verify:
  1347. worksheet.write(index+4,19,"不合格", error_style)
  1348. else:
  1349. formal_counts += 1
  1350. worksheet.write(index+4,19,"合格",formal_style)
  1351. verify_list.append(danji_verify)
  1352. except Exception as e:
  1353. print(e)
  1354. elif platform == "四情平台":
  1355. try:
  1356. worksheet.write(index+4,1,deviceId,formal_style)
  1357. self.sql_ping()
  1358. data_sql = "SELECT * FROM AppInfoManage_cbddata WHERE equip_id_id='{}' AND upl_time BETWEEN '{}' AND '{}' order by upl_time;".format(deviceId,self.start_time_str,self.end_time_str)
  1359. alarm_sql = "SELECT * FROM AppInfoManage_cbd_alarm_record WHERE equip_id_id='{}' AND alarm_time BETWEEN '{}' AND '{}' order by alarm_time;".format(deviceId,self.start_time_str,self.end_time_str)
  1360. self.cursor.execute(data_sql)
  1361. data_result = self.cursor.fetchall()
  1362. self.cursor.execute(alarm_sql)
  1363. alarm_result = self.cursor.fetchall()
  1364. status_sql = "SELECT * FROM AppInfoManage_cbdstatus WHERE equip_id_id='{}' AND upl_time BETWEEN '{}' AND '{}' order by upl_time;".format(deviceId,self.start_time_str,self.end_time_str)
  1365. self.cursor.execute(status_sql)
  1366. status_result = self.cursor.fetchall()
  1367. status_all_sql = "SELECT * FROM AppInfoManage_cbdstatus_all WHERE equip_id_id='{}' AND upl_time BETWEEN '{}' AND '{}' order by upl_time;".format(deviceId,self.start_time_str,self.end_time_str)
  1368. self.cursor.execute(status_all_sql)
  1369. status_all_result = self.cursor.fetchall()
  1370. if len(data_result) == 0:
  1371. # 空白数据填充
  1372. for i in range(1,19):
  1373. worksheet.write(index+4,i,"搜索时间内无数据",error_style)
  1374. worksheet.write(index+4,19,"不合格",error_style)
  1375. danji_verify = []
  1376. for i in range(19):
  1377. danji_verify.append(0)
  1378. verify_list.append(danji_verify)
  1379. else:
  1380. image_score = self.__siqing_image_verify(deviceId)
  1381. verify_data = self.__siqing_verify(data_result,status_result, status_all_result, alarm_result, device_id_info, image_score, process)
  1382. danji_verify = []
  1383. for clo_index, verify_ in enumerate(verify_data):
  1384. danji_verify.append(verify_[0])
  1385. if verify_[0] == 0:
  1386. worksheet.write(index+4,clo_index+1,verify_[1],error_style)
  1387. elif verify_[0] == 1:
  1388. worksheet.write(index+4,clo_index+1,verify_[1],formal_style)
  1389. else:
  1390. worksheet.write(index+4,clo_index+1,verify_[1],common_style)
  1391. if 0 in danji_verify:
  1392. worksheet.write(index+4,19,"不合格",error_style)
  1393. else:
  1394. formal_counts += 1
  1395. worksheet.write(index+4,19,"合格",formal_style)
  1396. verify_list.append(danji_verify)
  1397. except Exception as e:
  1398. print(e)
  1399. pass
  1400. proess = (index+1)/len(self.device_list) * 100
  1401. if int(proess) == 100:
  1402. self.proess_signal.emit(99)
  1403. else:
  1404. self.proess_signal.emit(int(proess))
  1405. toji_data = [
  1406. "任务单号",self.set_order,
  1407. "检验时间",'{}\n{}'.format(self.start_time_str,self.end_time_str),
  1408. "检验数量",len(self.device_list),
  1409. "合格数",formal_counts,
  1410. "检验平台",self.set_plat,
  1411. "主板版本",self.set_stm8vs,
  1412. "联网版本",self.set_dver,
  1413. "产品名称", self.set_product,
  1414. "供电选择", self.set_power,
  1415. "报告日期",now_time.strftime("%y-%m-%d %H:%M:%S")
  1416. ]
  1417. worksheet.write_row(row = 1 ,col = 0, data = toji_data,cell_format=toji_style)
  1418. worksheet.protect(pwd_str) # 保护视图,不允许修改
  1419. workbook.close()
  1420. self.cursor.close()
  1421. self.connection.close()
  1422. self.myclient.close()
  1423. self.proess_signal.emit(100)
  1424. if __name__== "__main__":
  1425. QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
  1426. QtGui.QGuiApplication.setAttribute(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
  1427. app = QtWidgets.QApplication(sys.argv)
  1428. MainWindow = QtWidgets.QMainWindow()
  1429. ui = Ui_MainWindow()
  1430. ui.setupUi(MainWindow)
  1431. MainWindow.show()
  1432. sys.exit(app.exec_())