qxz_zhijian_debug.py 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  1. from cgi import print_arguments
  2. from unittest import result
  3. from PyQt5 import QtCore, QtGui, QtWidgets
  4. import os
  5. import sys
  6. import re
  7. import ast
  8. from urllib import parse
  9. import json
  10. import time
  11. import datetime
  12. import requests
  13. import uuid
  14. import pymongo
  15. import pymysql
  16. from collections import defaultdict, Counter
  17. from xlrd import open_workbook
  18. from xlsxwriter.workbook import Workbook
  19. import openpyxl
  20. save_filename = ""
  21. pwd_str = "yf6021"
  22. toji_format = {
  23. 'font_name' : '宋体',
  24. 'font_size': 14,
  25. 'font_color': 'black',
  26. 'text_wrap': True,
  27. 'bold': False,
  28. 'fg_color': '92D050',
  29. 'align': 'center',
  30. 'valign': 'vcenter',
  31. 'border': 1,
  32. 'top': 1,
  33. 'left': 1,
  34. 'right': 1,
  35. 'bottom': 1
  36. }
  37. title_format = {
  38. 'font_name' : '宋体',
  39. 'font_size': 12,
  40. 'bold': True,
  41. 'align': 'center',
  42. 'valign': 'vcenter',
  43. 'border': 1,
  44. 'top': 1,
  45. 'left': 1,
  46. 'right': 1,
  47. 'bottom': 1
  48. }
  49. merge_title_format = {
  50. 'font_name' : '宋体',
  51. 'font_size': 26,
  52. 'bold': True,
  53. 'align': 'center',
  54. 'valign': 'vcenter',
  55. "fg_color": "8DB4E2",
  56. 'border': 1,
  57. 'top': 1,
  58. 'left': 1,
  59. 'right': 1,
  60. 'bottom': 1
  61. }
  62. explain_formal = {
  63. 'font_name' : '宋体',
  64. 'font_size': 11,
  65. 'font_color': 'black',
  66. 'text_wrap': True,
  67. 'align': 'justify',
  68. 'valign': 'vcenter',
  69. 'border': 1,
  70. 'top': 1,
  71. 'left': 1,
  72. 'right': 1,
  73. 'bottom': 1
  74. }
  75. formal_format = {
  76. 'font_name' : '宋体',
  77. 'font_size': 11,
  78. 'font_color': 'black',
  79. 'fg_color': '77E88C',
  80. 'text_wrap': True,
  81. 'align': 'center',
  82. 'valign': 'vcenter',
  83. 'border': 1,
  84. 'top': 1,
  85. 'left': 1,
  86. 'right': 1,
  87. 'bottom': 1
  88. }
  89. common_format = {
  90. 'font_name' : '宋体',
  91. 'font_size': 11,
  92. 'font_color': 'black',
  93. "fg_color": 'E7EC73',
  94. 'text_wrap': True,
  95. 'align': 'center',
  96. 'valign': 'vcenter',
  97. 'border': 1,
  98. 'top': 1,
  99. 'left': 1,
  100. 'right': 1,
  101. 'bottom': 1
  102. }
  103. error_format = {
  104. 'font_name' : '宋体',
  105. 'font_size': 11,
  106. 'font_color': 'black',
  107. "fg_color": 'F4746A',
  108. 'text_wrap': True,
  109. 'align': 'center',
  110. 'valign': 'vcenter',
  111. 'border': 1,
  112. 'top': 1,
  113. 'left': 1,
  114. 'right': 1,
  115. 'bottom': 1
  116. }
  117. default_formal = {
  118. 'font_name': '宋体',
  119. 'font_size': 11,
  120. 'font_color': 'black',
  121. 'text_wrap': True,
  122. 'align': 'center',
  123. 'valign': 'vcenter',
  124. 'border': 1,
  125. 'top': 1,
  126. 'left': 1,
  127. 'right': 1,
  128. 'bottom': 1
  129. }
  130. class SCDThread(object):
  131. """涉及进度条需主界面动态执行GUI,线程执行业务逻辑,避免主页面卡死"""
  132. def __init__(self,device_list,save_path,start_time,end_time,set_plat,set_stm8vs,set_order):
  133. self.device_list = device_list
  134. self.save_path = save_path
  135. self.start_time = start_time
  136. self.end_time = end_time
  137. self.start_time_str = start_time.strftime("%y-%m-%d %H:%M:%S")
  138. self.end_time_str = end_time.strftime("%y-%m-%d %H:%M:%S")
  139. self.set_plat = set_plat
  140. self.set_stm8vs = set_stm8vs
  141. self.set_order = set_order
  142. self.user = parse.quote_plus("root")
  143. self.passwd = parse.quote_plus("yfkj@6020")
  144. self.myclient = pymongo.MongoClient("mongodb://{0}:{1}@8.136.98.49:57017/".format(self.user,self.passwd))
  145. self.db = self.myclient.smartfarming
  146. self.device_collection = self.db.sa_device
  147. self.qxz_collection = self.db.sa_device_qxz_data
  148. self.config = {
  149. 'host': '120.27.222.26',
  150. 'port': 3306,
  151. 'user': 'yfwlw',
  152. 'password': 'sql_yfkj_6019',
  153. 'db': 'yfwlw',
  154. 'charset': 'utf8mb4',
  155. 'cursorclass': pymysql.cursors.DictCursor,
  156. }
  157. self.connection = pymysql.connect(**self.config)
  158. self.cursor = self.connection.cursor()
  159. self.mongo_ping()
  160. def mongo_ping(self):
  161. """mongo-ping预防连接失效"""
  162. # try:
  163. # self.myclient.admin.command('ping')
  164. # except: # "ConnectionFailure"
  165. self.myclient = pymongo.MongoClient("mongodb://{0}:{1}@8.136.98.49:57017/".format(self.user,self.passwd))
  166. self.db = self.myclient.smartfarming
  167. self.device_collection = self.db.sa_device
  168. self.qxz_collection = self.db.sa_qxz_data
  169. self.qxz_info_record_collection = self.db.sa_qxz_info_record
  170. self.qxz_base_info_collection = self.db.sa_qxz_base_info
  171. # self.sa_qxz_conf = self.db.
  172. def sql_ping(self):
  173. """mysql-ping 预防连接失效"""
  174. try:
  175. self.connection.ping()
  176. except:
  177. self.connection = pymysql.connect(**self.config)
  178. self.cursor = self.connection.cursor()
  179. def __time_dif(self,checkdatetime):
  180. """计算时间差"""
  181. nowdatetime = datetime.datetime.now()
  182. checkdatetime = datetime.datetime.strptime(checkdatetime, "%Y-%m-%d %H:%M:%S")
  183. timedif = checkdatetime - nowdatetime
  184. return timedif.days
  185. def device_their_platform(self,shortId):
  186. """确定设备所在平台以及完整设备号"""
  187. self.mongo_ping()
  188. self.sql_ping()
  189. regex = re.compile('.*{}$'.format(shortId))
  190. bd_device_dict = self.device_collection.find_one(
  191. filter = {"device_id":regex,"device_type_id":5},
  192. projection = {'_id': 0},
  193. sort = [('uptime', pymongo.DESCENDING)]
  194. )
  195. device_sql = "SELECT * FROM AppInfoManage_qxzstatus_new WHERE equip_id_id LIKE '%{}' ORDER BY upl_time DESC LIMIT 1;".format(shortId)
  196. self.cursor.execute(device_sql)
  197. sq_device_dict = self.cursor.fetchone()
  198. if bd_device_dict and sq_device_dict:
  199. bd_upltime = bd_device_dict["uptime"]
  200. sq_upltime = time.mktime(sq_device_dict["upl_time"].timetuple())
  201. if bd_upltime >= sq_upltime:
  202. d_id = bd_device_dict["id"]
  203. deviceId = bd_device_dict["device_id"]
  204. platform = "大数据平台"
  205. else:
  206. d_id = ""
  207. deviceId = sq_device_dict["equip_id_id"]
  208. platform = "四情平台"
  209. elif bd_device_dict and not sq_device_dict:
  210. d_id = bd_device_dict["id"]
  211. deviceId = bd_device_dict["device_id"]
  212. platform = "大数据平台"
  213. return d_id,deviceId,platform
  214. elif not bd_device_dict and sq_device_dict:
  215. d_id = ""
  216. deviceId = sq_device_dict["equip_id_id"]
  217. platform = "四情平台"
  218. else:
  219. d_id = ""
  220. deviceId = "平台无此设备"
  221. platform = "未知"
  222. print("deviceId:",deviceId)
  223. return d_id,deviceId,platform
  224. def sim_info(self, iccid):
  225. """查询卡信息"""
  226. url = "http://8.136.98.49:10001/iotcard/platsimview/inquiries/"
  227. try:
  228. response = requests.request("POST", url, data={"iccid": iccid})
  229. except:
  230. return [0, "查询卡信息异常稍后重试"]
  231. else:
  232. res_data = json.loads(response.text)
  233. if res_data["msg"] == "success" and res_data["data"]:
  234. expiry_date = res_data["data"]["expiry_date"]
  235. if expiry_date == "未知":
  236. return [0, "未查询到卡信息"]
  237. else:
  238. time_difference = self.__time_dif(expiry_date)
  239. if time_difference >= 180:
  240. return [1, "有效期剩余{}天".format(time_difference)]
  241. elif 30 <= time_difference < 180:
  242. return [2, "有效期剩余{}天".format(time_difference)]
  243. else:
  244. return [0, "有效期剩余{}天".format(time_difference)]
  245. else:
  246. return [0, "查询无结果"]
  247. def _get_data_new(self):
  248. """获取最新设备数据信息"""
  249. pipeline = [
  250. {
  251. "$match": {
  252. "device_id": {"$in": self.device_list}
  253. }
  254. },
  255. {
  256. "$group": {
  257. "_id": {"device_id": "$device_id"},
  258. "last_msg": {"$last": "$$ROOT"}
  259. }
  260. },
  261. {
  262. "$replaceRoot": {"newRoot": "$last_msg"}
  263. }
  264. ]
  265. cursor = self.db.sa_qxz_data.aggregate(pipeline, allowDiskUse=True)
  266. data_dict = {item['device_id']: item for item in cursor}
  267. return data_dict
  268. def _get_bigdata_qxz_conf(self):
  269. data_dict = self._get_data_new()
  270. cursor = self.db.sa_qxz_conf.find({"device_id": {"$in": self.device_list}})
  271. title_name_set = set()
  272. qxz_conf_dict = {}
  273. for item in cursor:
  274. device_id = item['device_id']
  275. qxz_data = data_dict[device_id]
  276. config_dict = {}
  277. counter = Counter()
  278. for k, v in item.items():
  279. if k.startswith('e') and v and qxz_data.get(k, None):
  280. t_name = v.split('#')[0]
  281. t_index = counter.get(t_name, "")
  282. config_dict[k] = f"{t_name}#{t_index}"
  283. counter[t_name] += 1
  284. n_list = list(config_dict.values())
  285. title_name_set.update(n_list)
  286. qxz_conf_dict[device_id] = config_dict
  287. title_name_list = sorted(list(title_name_set))
  288. for i in title_name_list:
  289. print(i)
  290. for k, v in qxz_conf_dict.items():
  291. print(k, v)
  292. return title_name_list, qxz_conf_dict
  293. def get_qxz_element_data(self, device_id, conf_dict):
  294. group_dict = {
  295. "_id": "$device_id",
  296. "total_count": {"$count": {}},
  297. "uptime_list": {"$push": "$uptime"}
  298. }
  299. project_dict = {
  300. "_id": 0,
  301. "device_id": "$_id",
  302. "total_count": "$total_count",
  303. "uptime_info": {
  304. "$function": {
  305. "args": ["$uptime_list"],
  306. "lang": "js",
  307. "body": """
  308. function(uptime_list){
  309. let old_uptime = uptime_list[0];
  310. let uptime_20 = 0;
  311. let uptime_40 = 0;
  312. for (let i = 1; i < uptime_list.length; i++) {
  313. let uptime = uptime_list[i];
  314. let diff_time = uptime - old_uptime;
  315. if (diff_time < 1200){
  316. uptime_20 += 1;
  317. } else if (diff_time > 2400){
  318. uptime_40 += 1;
  319. }
  320. old_uptime = uptime;
  321. }
  322. return {"uptime_20": uptime_20, "uptime_40": uptime_40}
  323. }
  324. """
  325. }
  326. }
  327. }
  328. for ek in conf_dict.keys():
  329. group_dict[ek] = {"$push": f"${ek}"}
  330. try:
  331. k = conf_dict[ek]
  332. func_name = self.get_conf_key(k)
  333. project_dict[ek] = self.cond.func_dict[func_name](ek)
  334. except KeyError as e:
  335. continue
  336. pipeline = [
  337. {
  338. "$match": {
  339. "device_id": device_id,
  340. "uptime": {
  341. "$gte": self.start_time,
  342. "$lt": self.end_time
  343. }
  344. }
  345. },
  346. {
  347. "$sort": {"uptime": 1}
  348. },
  349. {
  350. "$project": {
  351. "device_id": "$device_id",
  352. "uptime": "$uptime",
  353. "tmp_list": {
  354. "$filter": {
  355. "input": {"$objectToArray": "$$ROOT"},
  356. "as": "item",
  357. "cond": {
  358. "$and": [
  359. {
  360. "$regexMatch": {
  361. "input": "$$item.k",
  362. "regex": "^e\d+",
  363. "options": "i"
  364. }
  365. },
  366. {
  367. "$regexMatch": {
  368. "input": "$$item.v",
  369. "regex": ".*#.*",
  370. "options": "i"
  371. }
  372. }
  373. ]
  374. }
  375. }
  376. }
  377. }
  378. },
  379. {
  380. "$addFields": {
  381. "tmp_obj": {
  382. "$arrayToObject": {
  383. "$map": {
  384. "input": "$tmp_list",
  385. "as": "item",
  386. "in": {
  387. "k": "$$item.k",
  388. "v": {
  389. "$toInt": {
  390. "$toDouble": {"$arrayElemAt": [{"$split": ["$$item.v", "#"]}, 0]}
  391. }
  392. }
  393. }
  394. }
  395. }
  396. }
  397. }
  398. },
  399. {
  400. "$replaceRoot": {
  401. "newRoot": {
  402. "$mergeObjects": ["$tmp_obj", {"device_id": "$device_id", "uptime": "$uptime"}]
  403. }
  404. }
  405. },
  406. {
  407. "$group": group_dict
  408. },
  409. {
  410. "$project": project_dict
  411. }
  412. ]
  413. cursor = self.db.sa_qxz_data.aggregate(pipeline, allowDiskUse=True)
  414. result = {k: v for item in cursor for k, v in item.items()}
  415. return result
  416. def get_qxz_volt_or_rssi_data(self):
  417. pipeline = [
  418. {
  419. "$match": {
  420. "device_id": {
  421. "$in": self.device_list
  422. }
  423. },
  424. },
  425. {
  426. "$project": {
  427. "device_id": "$device_id",
  428. "volt": {
  429. "$toDouble": "$volt"
  430. },
  431. "rssi": {
  432. "$toDouble": "$rssi"
  433. }
  434. }
  435. },
  436. {
  437. "$group": {
  438. "_id": "$device_id",
  439. "max_volt": {
  440. "$max": "$volt"
  441. },
  442. "min_volt": {
  443. "$min": "$volt"
  444. },
  445. "max_rssi": {
  446. "$max": "$rssi"
  447. },
  448. "min_rssi": {
  449. "$min": "$rssi"
  450. }
  451. }
  452. },
  453. {
  454. "$project": {
  455. "_id": 0,
  456. "device_id": "$_id",
  457. "volt_info": {
  458. 'max_value': "$max_volt", 'min_value': "$min_volt",
  459. 'status': {
  460. "$cond": {
  461. "if": {
  462. "$and": [
  463. {"$lte": ["$max_volt", 15]},
  464. {"$gte": ["$min_volt", 11]}
  465. ]
  466. },
  467. "then": 1,
  468. "else": 0
  469. }
  470. }
  471. },
  472. "rssi_info": {
  473. 'max_value': "$max_rssi", 'min_value': "$min_rssi",
  474. 'status': {
  475. "$cond": {
  476. "if": {
  477. "$gte": ["$min_rssi", 14]
  478. },
  479. "then": 1,
  480. "else": 0
  481. }
  482. }
  483. }
  484. }
  485. }
  486. ]
  487. cursor = self.qxz_info_record_collection.aggregate(pipeline, allowDiskUse=True)
  488. result = {item['device_id']: item for item in cursor}
  489. return result
  490. def get_qxz_device_data(self):
  491. pipeline = [
  492. {
  493. "$match": {
  494. "device_id": {
  495. "$in": self.device_list
  496. }
  497. },
  498. },
  499. {
  500. "$project": {
  501. "device_id": "$device_id",
  502. "dver_num": "$dver_num",
  503. "lng": {
  504. "$convert": {
  505. "input": "$lng",
  506. "to": "double",
  507. "onError": 0,
  508. "onNull": 0
  509. }
  510. },
  511. "lat": {
  512. "$convert": {
  513. "input": "$lat",
  514. "to": "double",
  515. "onError": 0,
  516. "onNull": 0
  517. }
  518. }
  519. }
  520. },
  521. {
  522. "$project": {
  523. "_id": 0,
  524. "device_id": "$device_id",
  525. "dver_info": {
  526. "status": {
  527. "$cond": {
  528. "if": {
  529. "$eq": ["$dver_num", self.set_stm8vs]
  530. },
  531. "then": 1,
  532. "else": 0
  533. }
  534. },
  535. "dver_num": "$dver_num",
  536. "old_value": self.set_stm8vs
  537. },
  538. "lng_info": {
  539. "status": {
  540. "$cond": {
  541. "if": {
  542. "$and": [
  543. {"$lte": ["$lng", 113.7869444]},
  544. {"$gte": ["$lng", 113.7536111]}
  545. ]
  546. },
  547. "then": 1,
  548. "else": 0
  549. }
  550. },
  551. "lng": "$lng"
  552. },
  553. "lat_info": {
  554. "status": {
  555. "$cond": {
  556. "if": {
  557. "$and": [
  558. {"$lte": ["$lat", 35.0458333]},
  559. {"$gte": ["$lat", 35.0125]}
  560. ]
  561. },
  562. "then": 1,
  563. "else": 0
  564. }
  565. },
  566. "lat": "$lat"
  567. }
  568. }
  569. }
  570. ]
  571. cursor = self.device_collection.aggregate(pipeline, allowDiskUse=True)
  572. result = {item['device_id']: item for item in cursor}
  573. return result
  574. def get_sim_data(self):
  575. pipeline = [
  576. {
  577. "$match": {
  578. "device_id": {
  579. "$in": self.device_list
  580. }
  581. }
  582. },
  583. {
  584. "$project": {
  585. "_id": 0,
  586. "device_id": "$device_id",
  587. "iccid": "$iccid"
  588. }
  589. }
  590. ]
  591. cursor = self.qxz_base_info_collection.aggregate(pipeline, allowDiskUse=True)
  592. result = {item['device_id']: item["iccid"] for item in cursor}
  593. return result
  594. def parse_data(self, device_id, qxz_conf_dict, vr_dict, device_data_dict, sim_data):
  595. """解析获取元素数据"""
  596. element_dict = {}
  597. element_dict["ID#"] = device_id
  598. element_dict["检验项目#"] = device_id
  599. try:
  600. conf_dict = qxz_conf_dict[device_id]
  601. device_data = self.get_qxz_element_data(device_id, conf_dict)
  602. element_dict.update({conf_dict[k]: v for k, v in device_data.items() if k in conf_dict})
  603. vr_info = vr_dict[device_id]
  604. dd_info = device_data_dict[device_id]
  605. element_dict["经度#"] = dd_info["lng_info"]
  606. element_dict["纬度#"] = dd_info["lat_info"]
  607. element_dict["固件版本号#"] = dd_info["dver_info"]
  608. element_dict["电压#"] = vr_info["volt_info"]
  609. element_dict["信号强度#"] = vr_info["rssi_info"]
  610. sim_info = self.sim_info(sim_data[device_id])
  611. element_dict["sim卡信息#"] = {
  612. "status": sim_info[0],
  613. "msg": sim_info[1]
  614. }
  615. element_dict["上传数据条数#"] = {
  616. "total_count": device_data['total_count'],
  617. "uptime_20": device_data["uptime_info"]["uptime_20"],
  618. "uptime_40": device_data["uptime_info"]["uptime_40"]
  619. }
  620. except KeyError as e:
  621. pass
  622. return element_dict
  623. def get_conf_key(self, k):
  624. key = k.split('#')[0]
  625. if "土壤含水率" in key:
  626. key = "土壤含水率"
  627. if "土壤温度" in key:
  628. key = "土壤温度"
  629. return key
  630. def get_position(self, lng, lat):
  631. if lng and lat:
  632. try:
  633. ret = requests.post("http://api.map.baidu.com/geocoder?location=%s,%s&coord_type=gcj02&output=json"%(lat,lng))
  634. ret_json = json.loads(ret.text)
  635. province, city, district = ret_json["result"]["addressComponent"]["province"], \
  636. ret_json["result"]["addressComponent"]["city"], \
  637. ret_json["result"]["addressComponent"]["district"]
  638. return province + city + district
  639. except Exception as e:
  640. return False
  641. else:
  642. return False
  643. def get_conf_data(self, device_config, device_data, keys):
  644. device_config = dict(device_config)
  645. for iname, ivalue in device_config.items():
  646. if ivalue and isinstance(ivalue, str):
  647. if keys in ivalue:
  648. idevice_key_sun = iname
  649. idevice_data = []
  650. for d in device_data:
  651. print(d, "++")
  652. idevice_data.append(float((d.get(idevice_key_sun)).split("#")[0]))
  653. return idevice_data
  654. def run(self):
  655. """主业务逻辑,涉及进度条不能模块化,慢慢捋"""
  656. title_name_list = ["ID#", "检验项目#", "电压#", "信号强度#", "经度#", "纬度#", "固件版本号#", "sim卡信息#",
  657. "上传数据条数#"]
  658. default_func_dict = {
  659. "电压": self.cond.get_cond_volt_msg,
  660. "信号强度": self.cond.get_cond_rssi_msg,
  661. "经度": self.cond.get_cond_lng_msg,
  662. "纬度": self.cond.get_cond_lat_msg,
  663. "固件版本号": self.cond.get_cond_version_msg,
  664. "上传数据条数": self.cond.get_time_uptime_msg,
  665. "sim卡信息": self.cond.get_cond_sim_msg
  666. }
  667. head_name_list, qxz_conf_dict = self._get_bigdata_qxz_conf()
  668. for n in head_name_list:
  669. if n not in title_name_list:
  670. title_name_list.append(n)
  671. title_name_list.append("位置信息#")
  672. title_name_list.append("单台合格数#")
  673. device_data_dict = self.get_qxz_device_data()
  674. vr_dict = self.get_qxz_volt_or_rssi_data()
  675. sim_data = self.get_sim_data()
  676. proess = 0
  677. now_time = datetime.datetime.now()
  678. global save_filename
  679. save_filename = self.set_order + "_" + now_time.strftime("%m%d") + ".xlsx"
  680. save_path = os.path.join(self.save_path,save_filename)
  681. workbook = Workbook(save_path)
  682. worksheet = workbook.add_worksheet()
  683. merge_title_style = workbook.add_format(merge_title_format)
  684. toji_style = workbook.add_format(toji_format)
  685. default_style = workbook.add_format(default_formal)
  686. red_style = workbook.add_format(error_format)
  687. green_style = workbook.add_format(formal_format)
  688. yellow_style = workbook.add_format(common_format)
  689. style_dict = {
  690. 0: red_style,
  691. 1: green_style,
  692. 2: yellow_style,
  693. 3: default_style
  694. }
  695. head_list = [i.split("#")[0] for i in title_name_list]
  696. worksheet.merge_range(0, 0, 0, len(head_list) - 1, "物联网气象站设备质检表格", merge_title_style)
  697. for index, k in enumerate(title_name_list):
  698. value = k.split('#')[0]
  699. worksheet.write(2, index, value, default_style)
  700. for index, k in enumerate(title_name_list):
  701. key = self.get_conf_key(k)
  702. try:
  703. value = self.cond.head_dict[key]
  704. except KeyError as e:
  705. value = "无判定条件"
  706. worksheet.write(3, index, value, default_style)
  707. row_index = 4
  708. qualified = 0
  709. for device_id in self.device_list:
  710. self.mongo_ping()
  711. element_dict = self.parse_data(device_id, qxz_conf_dict, vr_dict, device_data_dict, sim_data)
  712. device_config = self.db.sa_qxz_conf.find_one({"device_id": device_id}, {'_id':0,'id':0})
  713. device_data = self.db.sa_qxz_data.find({"device_id": device_id, "uptime": {"$gte": self.start_time, "$lte": self.end_time}})
  714. # device_machine = self.db.sa_device.find_one({"device_id": device_id})
  715. not_qualified = 0
  716. lng = 0
  717. lat = 0
  718. for index, k in enumerate(title_name_list):
  719. status, msg = 3, "无数据"
  720. try:
  721. value = element_dict[k]
  722. key = self.get_conf_key(k)
  723. if key in ["ID", "检验项目"]:
  724. rt = {"status": 1, "msg": value}
  725. elif key in default_func_dict:
  726. print(key, "-----------------")
  727. if key == "电压":
  728. print("----", device_data.count())
  729. result = self.get_conf_data(device_config, device_data, "电压")
  730. print(result, "************")
  731. rt = default_func_dict[key](value)
  732. if key == "经度":
  733. lng = value.get("lng")
  734. if key == "纬度":
  735. lat = value.get("lat")
  736. else:
  737. if key == "日照时数":
  738. idevice_key_sun = ""
  739. device_config = dict(device_config)
  740. for iname, ivalue in device_config.items():
  741. if ivalue and isinstance(ivalue, str):
  742. if "日照时数" in ivalue:
  743. idevice_key_sun = iname
  744. idevice_data = []
  745. for d in device_data:
  746. idevice_data.append(float((d.get(idevice_key_sun)).split("#")[0]))
  747. if max(idevice_data) > 0.1:
  748. rt = {'status': 1, 'msg': f'最大值:{str(max(idevice_data))},最小值:{str(min(idevice_data))}'}
  749. else:
  750. rt = {'status': 0, 'msg': f'最大值:{str(max(idevice_data))},最小值:{str(min(idevice_data))}'}
  751. elif key == "降雨量累计":
  752. idevice_key_rain = ""
  753. device_config = dict(device_config)
  754. for iname, ivalue in device_config.items():
  755. if ivalue and isinstance(ivalue, str):
  756. if "降雨量累计" in ivalue:
  757. idevice_key_rain = iname
  758. idevice_data = []
  759. for d in device_data:
  760. idevice_data.append(float((d.get(idevice_key_rain)).split("#")[0]))
  761. if max(idevice_data) > 0.1:
  762. rt = {'status': 1, 'msg': f'最大值:{str(max(idevice_data))},最小值:{str(min(idevice_data))}'}
  763. else:
  764. rt = {'status': 0, 'msg': f'最大值:{str(max(idevice_data))},最小值:{str(min(idevice_data))}'}
  765. else:
  766. rt = self.cond.cond_msg_dict[key](value)
  767. status, msg = rt['status'], rt['msg']
  768. except Exception as e:
  769. pass
  770. if status == 0:
  771. not_qualified += 1
  772. if k == "位置信息#":
  773. # 使用经纬度获取地理
  774. result = self.get_position(lng, lat)
  775. if result and result == "河南省新乡市原阳县":
  776. status = 1
  777. msg = result
  778. else:
  779. status = 0
  780. msg = result
  781. if k == "单台合格数#":
  782. status, msg = 0, f"不合格: {not_qualified}"
  783. if not_qualified == 0:
  784. status, msg = 1, "合格"
  785. column_style = style_dict[status]
  786. worksheet.write(row_index, index, str(msg), column_style)
  787. proess = (index + 1) / len(self.device_list) * 100
  788. if int(proess) == 100:
  789. self.proess_signal.emit(99)
  790. else:
  791. self.proess_signal.emit(int(proess))
  792. if not_qualified == 0:
  793. qualified += 1
  794. row_index += 1
  795. toji_data = [
  796. "任务单号", self.set_order, "检验时间", self.start_time_str, self.end_time_str,
  797. "报告日期", now_time.strftime("%y-%m-%d %H:%M:%S"), "合格数", qualified
  798. ]
  799. for i in range(len(head_list) - len(toji_data)):
  800. toji_data.append(" ")
  801. for index, k in enumerate(toji_data):
  802. value = str(k)
  803. worksheet.write(1, index, value, toji_style)
  804. c_n = len(value) + 15
  805. worksheet.set_column(index, index, c_n)
  806. worksheet.protect(pwd_str)
  807. workbook.close()
  808. self.cursor.close()
  809. self.connection.close()
  810. self.myclient.close()
  811. if __name__ == "__main__":
  812. device_list,save_path,start_time,end_time,set_plat,set_stm8vs,set_order = [""]
  813. SCDThread().run()