pest_image.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. from io import BytesIO
  2. import json
  3. import time
  4. import pandas as pd
  5. import datetime
  6. import xlwt
  7. from django.views.generic import ListView
  8. from django.http import HttpResponse
  9. from django.utils.encoding import escape_uri_path
  10. from django.conf import settings
  11. from django.db.models import Q
  12. from smartfarming.models.worm_forecast import MongoCBDphoto
  13. from smartfarming.models.device import MongoDevice, MongoXYCBData, MongoSCDData
  14. from smartfarming.models.weather import QXZdata_New, MongoQXZ_Conf
  15. from smartfarming.api.views.forecast.all_dict import insect_dict
  16. from kedong.decoration import kedong_deco, PortError
  17. config_dict = settings.CONFIG
  18. class PestImageSourceExport(ListView):
  19. def get(self, request, *args, **kwargs):
  20. # 测报灯害虫图像信息溯源数据导出
  21. parameters = request.GET
  22. d_ids = parameters.get("d_ids")
  23. start_time = int(parameters.get("start_time"))
  24. end_time = int(parameters.get("end_time"))
  25. select_name = parameters.get("pest_name")
  26. filename = parameters.get("filename")
  27. page = int(parameters.get("page","1"))
  28. page_size = 9999999
  29. amend = parameters.get("amend","0")
  30. # 获取统计设备列表
  31. if d_ids:
  32. d_id_list = [int(d_id) for d_id in d_ids.split(",")]
  33. d_id_dicts = {}
  34. device_queryset = MongoDevice.objects.filter(id__in=d_id_list)
  35. for device_object in device_queryset:
  36. d_id_dicts[device_object.id] = {"location":device_object.province+device_object.city+device_object.district,
  37. "device_id":device_object.device_id,
  38. "device_code":device_object.device_code,
  39. "device_name":device_object.device_name if device_object.device_name else "测报灯"
  40. }
  41. else:
  42. raise PortError("d_ids","参数缺失")
  43. # 统计
  44. photo_queryset = MongoCBDphoto.objects.filter(device_id__in=list(d_id_dicts.keys()),photo_status=1,addtime__range=(start_time,end_time))
  45. if amend == "0":
  46. photo_queryset = photo_queryset.filter(~Q(indentify_result="")).order_by("-addtime")
  47. else:
  48. photo_queryset = photo_queryset.filter(~Q(indentify_result="") | ~Q(mark="")).order_by("-addtime")
  49. pest_image_data = []
  50. for photo_object in photo_queryset:
  51. # 单张照片结果
  52. indentify_result = photo_object.indentify_result
  53. mark = photo_object.mark
  54. pest_string = ""
  55. pest_dict = {}
  56. if amend == "1" and mark:
  57. if mark == "[]":
  58. continue
  59. else:
  60. mark = json.loads(mark)
  61. for index,label in enumerate(mark):
  62. pest_name = label.get("text")
  63. pest_num = 1
  64. if pest_name not in pest_string:
  65. if index != 0:
  66. pest_string += "、"
  67. pest_string += pest_name
  68. if pest_name in pest_dict:
  69. pest_dict[pest_name] += pest_num
  70. else:
  71. pest_dict[pest_name] = 1
  72. else:
  73. if indentify_result != "0":
  74. for index,result in enumerate(indentify_result.split("#")) :
  75. if index != 0:
  76. pest_string += "、"
  77. tuple_result = result.split(",")
  78. pest_name = insect_dict.get(tuple_result[0],"未命名")
  79. pest_string+=pest_name
  80. try:
  81. pest_dict[pest_name] = int(tuple_result[1])
  82. except:
  83. pass
  84. if select_name and select_name not in pest_string:
  85. continue
  86. addtime = photo_object.addtime
  87. __d_id = int(photo_object.device_id)
  88. pest_image_data.append({"deviceId":d_id_dicts[__d_id]["device_id"],
  89. "deviceName":d_id_dicts[__d_id]["device_name"],
  90. "pestName":pest_string,
  91. "addtime":addtime,
  92. "location":d_id_dicts[__d_id]["location"],
  93. "img_url":photo_object.addr,
  94. "indentify_photo":photo_object.indentify_photo,
  95. "pest_dict":pest_dict
  96. })
  97. return_data = pest_image_data[(page-1)*page_size:page*page_size]
  98. save_data = dict(设备ID=[],设备名称=[],害虫名称=[],上报时间=[],设备位置=[],图像=[])
  99. for data in return_data:
  100. save_data["设备ID"].append(data.get("deviceId"))
  101. save_data["设备名称"].append(data.get("deviceName"))
  102. save_data["害虫名称"].append(data.get("pestName"))
  103. uptime = datetime.datetime.fromtimestamp(data.get("addtime")).strftime("%Y-%m-%d %H:%M:%S")
  104. save_data["上报时间"].append(uptime)
  105. save_data["设备位置"].append(data.get("location"))
  106. ind_url = data.get("indentify_photo")
  107. if ind_url:
  108. if ind_url.startswith("http"):
  109. save_data["图像"].append(ind_url)
  110. else:
  111. save_data["图像"].append(config_dict["image_url"]["discern"] + ind_url)
  112. else:
  113. save_data["图像"].append("")
  114. df = pd.DataFrame(data=save_data)
  115. output = BytesIO()
  116. df.to_excel(output,index=False)
  117. output.seek(0)
  118. response = HttpResponse(content_type='application/vnd.ms-excel')
  119. response['Content-Disposition'] = 'attachment;filename={}.xls'.format(escape_uri_path(filename))
  120. response.write(output.getvalue())
  121. return response
  122. class PestBaseDataExport(ListView):
  123. # 虫害基础数据
  124. def get(self, request, *args, **kwargs):
  125. '''
  126. 测报灯害虫基础数据导出
  127. '''
  128. parameters = request.GET
  129. d_ids = parameters.get("d_ids")
  130. start_time = int(parameters.get("start_time"))
  131. end_time = int(parameters.get("end_time"))
  132. select_name = parameters.get("pest_name")
  133. page = int(parameters.get("page","1"))
  134. page_size = int(parameters.get("page_size",999999))
  135. amend = parameters.get("amend","0")
  136. filename = parameters.get("filename")
  137. # 获取统计设备列表
  138. if d_ids:
  139. d_id_list = [int(d_id) for d_id in d_ids.split(",")]
  140. else:
  141. raise PortError("d_ids","参数缺失")
  142. # 统计
  143. photo_queryset = MongoCBDphoto.objects.filter(device_id__in=d_id_list,photo_status=1,addtime__range=(start_time,end_time))
  144. if amend == "0":
  145. photo_queryset = photo_queryset.filter(~Q(indentify_result="")).order_by("-addtime")
  146. else:
  147. photo_queryset = photo_queryset.filter(~Q(indentify_result="") | ~Q(mark="")).order_by("-addtime")
  148. pest_base_data = []
  149. for photo_object in photo_queryset:
  150. # 单张照片结果
  151. indentify_result = photo_object.indentify_result
  152. mark = photo_object.mark
  153. addtime = photo_object.addtime
  154. pest_dict = {}
  155. if amend == "1" and mark:
  156. mark = json.loads(mark)
  157. for label in mark:
  158. pest_name = label.get("text")
  159. pest_num = 1
  160. if select_name and select_name not in pest_name:
  161. continue
  162. if pest_name in pest_dict:
  163. pest_dict[pest_name] += pest_num
  164. else:
  165. pest_dict[pest_name] = pest_num
  166. for label_key,label_value in pest_dict.items():
  167. pest_base_data.append(dict(pest_name=label_key,pest_num=label_value,addtime=addtime))
  168. else:
  169. for result in indentify_result.split("#"):
  170. tuple_result = result.split(",")
  171. pest_name = insect_dict.get(tuple_result[0],"未命名")
  172. if select_name and select_name not in pest_name:
  173. continue
  174. try:
  175. pest_num = int(tuple_result[1])
  176. pest_dict=dict(pest_name=pest_name,pest_num=pest_num,addtime=addtime)
  177. pest_base_data.append(pest_dict)
  178. except:
  179. pass
  180. return_data = pest_base_data[(page-1)*page_size:page*page_size]
  181. save_data = dict(害虫名称=[],害虫数量=[],上报时间=[])
  182. for data in return_data:
  183. save_data["害虫名称"].append(data.get("pest_name"))
  184. save_data["害虫数量"].append(data.get("pest_num"))
  185. uptime = datetime.datetime.fromtimestamp(data.get("addtime")).strftime("%Y-%m-%d %H:%M:%S")
  186. save_data["上报时间"].append(uptime)
  187. df = pd.DataFrame(data=save_data)
  188. output = BytesIO()
  189. df.to_excel(output,index=False)
  190. output.seek(0)
  191. response = HttpResponse(content_type='application/vnd.ms-excel')
  192. response['Content-Disposition'] = 'attachment;filename={}.xls'.format(escape_uri_path(filename))
  193. response.write(output.getvalue())
  194. return response
  195. # 气象站数据导出接口
  196. class QxzDataExport(ListView):
  197. """
  198. 气象站数据导出接口
  199. 参数说明:
  200. device_id 必传 设备号
  201. begin 非必传 开始时间
  202. end 非必传 结束时间
  203. filename 必传 文件名称
  204. """
  205. def get(self,request):
  206. device_id = request.GET.get('device_id')
  207. f_tbegin = request.GET.get('begin')
  208. f_tend = request.GET.get('end')
  209. filename = request.GET.get('filename')
  210. device_data = QXZdata_New.objects.filter(device_id=device_id).order_by("id")
  211. if f_tbegin:
  212. device_data = device_data.filter(uptime__gte=f_tbegin)
  213. if f_tend:
  214. device_data = device_data.filter(uptime__lte=f_tend)
  215. book = xlwt.Workbook() # 创建一个excel对象
  216. sheet = book.add_sheet('Sheet1',cell_overwrite_ok=True) # 添加一个sheet页
  217. tes = []
  218. if device_data:
  219. try:
  220. for x in device_data:
  221. otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(x.uptime))
  222. te = []
  223. data = [x.e1,x.e2,x.e3,x.e4,x.e5,
  224. x.e6,x.e7,x.e8,x.e9,x.e10,
  225. x.e11,x.e12,x.e13,x.e14,
  226. x.e15,x.e16,x.e17,x.e18,
  227. x.e19,x.e20,x.e21,x.e22,
  228. x.e23,x.e24,x.e25,x.e26,
  229. x.e27,x.e28,x.e29,x.e30,otherStyleTime]
  230. conf_list = [i for i in data if i !='' and i != None ]
  231. for y in conf_list:
  232. if y:
  233. num = str(y.split("#")[0])
  234. te.append(num)
  235. tes.append(te)
  236. x = MongoQXZ_Conf.objects.get(device_id=device_id)
  237. conf = [x.e1,x.e2,x.e3,x.e4,x.e5,
  238. x.e6,x.e7,x.e8,x.e9,x.e10,
  239. x.e11,x.e12,x.e13,x.e14,
  240. x.e15,x.e16,x.e17,x.e18,
  241. x.e19,x.e20,x.e21,x.e22,
  242. x.e23,x.e24,x.e25,x.e26,
  243. x.e27,x.e28,x.e29,x.e30]
  244. conf_list = [i for i in conf if i !='' ]
  245. tep = []
  246. for x in conf_list:
  247. if x:
  248. tite = x.replace('#', '')
  249. tep.append(tite)
  250. tep.append("采集时间")
  251. for i in range(len(tep)): # 遍历列
  252. sheet.write(0,i,tep[i]) # 将title数组中的字段写入到0行i列中
  253. for y in range(len(tes)):
  254. for i in range(len(tes[y])):
  255. sheet.write(y+1,i,tes[y][i])
  256. except:
  257. sheet.write(0,0,"错误的时间段")
  258. else:
  259. sheet.write(0,0,"该时间段内没数据清重新设置时间段") # 将title数组中的字段写入到0行i列中
  260. #写出到IO
  261. output = BytesIO()
  262. book.save(output)
  263. # 重新定位到开始
  264. output.seek(0)
  265. response = HttpResponse(content_type='application/vnd.ms-excel')
  266. response['Content-Disposition'] = 'attachment;filename={}.xls'.format(escape_uri_path(filename))
  267. response.write(output.getvalue())
  268. return response
  269. class CbdExport(ListView):
  270. """
  271. 设备数据导出接口
  272. device_id 设备号(str)
  273. start_time 开始时间(时间戳)
  274. end_time 结束时间(时间戳)
  275. filename 导出的文件名(str)
  276. device_type 设备类型
  277. """
  278. def get(self,request):
  279. device_id = request.GET.get("device_id")
  280. start_time = request.GET.get("start_time")
  281. end_time = request.GET.get("end_time")
  282. filename = request.GET.get("filename")
  283. device_type = request.GET.get("device_type")
  284. # username = request.GET.get("username")
  285. book = xlwt.Workbook()
  286. sheet = book.add_sheet('Sheet1',cell_overwrite_ok=True) # 添加一个sheet页
  287. try:
  288. devices = MongoDevice.objects.get(id=device_id)
  289. except:
  290. data = {"code":"401","type":"未找到该设备"}
  291. data = json.dumps(data,ensure_ascii=False)
  292. return HttpResponse(data)
  293. if device_type == "4":
  294. models = MongoXYCBData
  295. elif device_type == "2":
  296. models = MongoSCDData
  297. else:
  298. data = {"code":"403","type":"暂不支持该设备类型"}
  299. data = json.dumps(data,ensure_ascii=False)
  300. return HttpResponse(data)
  301. if device_id:
  302. device_data = models.objects.filter(device_id=device_id).order_by("-id")
  303. else:
  304. data = {"code":"400","type":"参数为空"}
  305. data = json.dumps(data,ensure_ascii=False)
  306. return HttpResponse(data)
  307. if start_time:
  308. device_data = device_data.filter(addtime__range=(int(start_time), int(end_time)))
  309. sta2 = []
  310. if device_data:
  311. for x in device_data:
  312. times = time.localtime(x.addtime)
  313. times = time.strftime("%Y-%m-%d %H:%M:%S",times)
  314. sta2.append({"data": eval(x.device_data),
  315. "upl_time":times})
  316. else:
  317. sheet.write(1+1,0,"暂无数据")
  318. # 性诱性诱测报
  319. if device_type == "4":
  320. title = [
  321. "设备ID", "设备开关", "工作状态", "环境温度(℃)", "环境湿度(%)",
  322. "充电电压(V)", "电池电压(V)", "充电状态", "电池状态", "诱虫次数",
  323. "信号强度", "上报时间"
  324. ]
  325. for i in range(len(title)): # 遍历列
  326. sheet.write(0, i, title[i]) # 将title数组中的字段写入到0行i列中
  327. for x in range(len(sta2)): # 遍历列表
  328. try:
  329. x_d = sta2[x]["data"]
  330. ds = "关机" if x_d["ds"] == 0 else "开机"
  331. ws = "待机" if x_d["ws"] == 0 else "工作"
  332. try:
  333. at = x_d["at"]
  334. except Exception as e:
  335. at = "0"
  336. try:
  337. ah = x_d["ah"]
  338. except Exception as e:
  339. ah = "0"
  340. infr_ct = x_d["infr_ct"]
  341. volt_ct = x_d["volt_ct"]
  342. try:
  343. cv = x_d["cv"]
  344. except Exception as e:
  345. cv = "0"
  346. try:
  347. bv = x_d["bv"]
  348. except Exception as e:
  349. bv = "0"
  350. cs = "非充电" if x_d["cs"] == "0" else "充电"
  351. if x_d["bs"] == "0":
  352. bs = "正常"
  353. elif x_d["bs"] == "1":
  354. bs = "欠压"
  355. else:
  356. bs = "过压"
  357. csq = str(x_d["csq"])
  358. dver = x_d["dver"]
  359. try:
  360. lat = x_d["lat"]
  361. lng = x_d["lng"]
  362. except Exception as e:
  363. lat = "0"
  364. lng = "0"
  365. table_value = {
  366. "设备ID": devices.device_id,
  367. "设备开关": ds,
  368. "工作状态": ws,
  369. "环境温度(℃)": at,
  370. "环境湿度(%)": ah,
  371. "充电电压(V)": cv,
  372. "电池电压(V)": bv,
  373. "充电状态": cs,
  374. "电池状态": bs,
  375. "诱虫次数": infr_ct,
  376. "信号强度": csq,
  377. "上报时间": sta2[x]["upl_time"]
  378. }
  379. for i, v in enumerate(title):
  380. sheet.write(x + 1, i, table_value.get(v))
  381. except:
  382. continue
  383. # 杀虫灯
  384. elif device_type == "2":
  385. title = ["设备ID", "设备开关", "工作状态", "雨控状态", "温控状态", "倾倒状态", "电击次数", "定时时长(h)",
  386. "环境温度(℃)", "环境湿度(%)", "充电电压(V)", "电池电压(V)","信号强度", "上报时间", "经度", "纬度"]
  387. for i in range(len(title)): # 遍历列
  388. sheet.write(0, i, title[i]) # 将title数组中的字段写入到0行i列中
  389. for x in range(len(sta2)): # 遍历列表
  390. try:
  391. if int(sta2[x]["data"]["ds"]) == 0:
  392. ds = "关机"
  393. else:
  394. ds = "开机"
  395. if int(sta2[x]["data"]["ws"]) == 0:
  396. ws = "待机"
  397. elif int(sta2[x]["data"]["ws"]) == 2:
  398. ws = "充电"
  399. else:
  400. ws = "工作"
  401. if int(sta2[x]["data"]["rps"]) == 0:
  402. rps = "正常"
  403. else:
  404. rps = "雨控"
  405. if int(sta2[x]["data"]["tps"]) == 0:
  406. tps = "正常"
  407. else:
  408. tps = "温控"
  409. if int(sta2[x]["data"]["dps"]) == 0:
  410. dps = "正常"
  411. else:
  412. dps = "保护"
  413. try:
  414. lat = sta2[x]["data"]["lat"]
  415. lng = sta2[x]["data"]["lng"]
  416. except:
  417. lat = 0
  418. lng = 0
  419. sheet.write(x + 1, 0, devices.device_id) # 将equip_id写入到第x+1行,第0列中
  420. sheet.write(x + 1, 1, ds) # 设备开关
  421. sheet.write(x + 1, 2, ws) # 工作状态
  422. sheet.write(x + 1, 3, rps) # 雨控状态
  423. sheet.write(x + 1, 4, tps) # 温控状态
  424. sheet.write(x + 1, 5, dps) # 倾倒状态
  425. sheet.write(x + 1, 6, sta2[x]["data"]["ct"]) # 电击次数
  426. sheet.write(x + 1, 7, sta2[x]["data"]["tt"]) # 定时时长
  427. sheet.write(x + 1, 8, sta2[x]["data"]["at"]) # 环境温度
  428. sheet.write(x + 1, 9, sta2[x]["data"]["ah"]) # 环境湿度
  429. sheet.write(x + 1, 10, sta2[x]["data"]["cv"]) # 充电电压
  430. sheet.write(x + 1, 11, sta2[x]["data"]["bv"]) # 电池电压
  431. sheet.write(x + 1, 12, sta2[x]["data"]["csq"]) # 信号强度
  432. sheet.write(x + 1, 13, sta2[x]["upl_time"]) # 上报时间
  433. sheet.write(x + 1, 14, lng) # 经度
  434. sheet.write(x + 1, 15, lat) # 纬度
  435. except:
  436. continue
  437. sheet.col(0).width = 256 * 18
  438. sheet.col(2).width = 256 * 11
  439. sheet.col(3).width = 256 * 11
  440. sheet.col(4).width = 256 * 13
  441. sheet.col(8).width = 256 * 11
  442. sheet.col(9).width = 256 * 11
  443. sheet.col(10).width = 256 * 20
  444. # 写出到IO
  445. output = BytesIO()
  446. book.save(output)
  447. # 重新定位到开始
  448. output.seek(0)
  449. response = HttpResponse(content_type='application/vnd.ms-excel')
  450. response['Content-Disposition'] = 'attachment;filename={}.xls'.format(escape_uri_path(filename))
  451. response.write(output.getvalue())
  452. return response