EquipmentInfoService.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. # -*- encoding: utf-8 -*-
  2. """
  3. @File : EquipmentInfoService.py
  4. @Time : 2022/4/14 17:28
  5. @Author : stephen
  6. @Email : zhangdongming@asj6.wecom.work
  7. @Software: PyCharm
  8. """
  9. import itertools
  10. from django.db.models import Value, CharField, Q
  11. from Model.models import EquipmentInfo1, EquipmentInfo2, EquipmentInfo3, EquipmentInfo4, EquipmentInfo5, \
  12. EquipmentInfo6, EquipmentInfo7, EquipmentInfo8, EquipmentInfo9, EquipmentInfo10, \
  13. EquipmentInfo11, EquipmentInfo12, EquipmentInfo13, EquipmentInfo14, EquipmentInfo15, EquipmentInfo16, \
  14. EquipmentInfo17, EquipmentInfo18, EquipmentInfo19, EquipmentInfo20
  15. EQUIPMENT_INFO_MODEL_LIST = [EquipmentInfo1, EquipmentInfo2, EquipmentInfo3, EquipmentInfo4, EquipmentInfo5,
  16. EquipmentInfo6, EquipmentInfo7, EquipmentInfo8, EquipmentInfo9, EquipmentInfo10,
  17. EquipmentInfo11, EquipmentInfo12, EquipmentInfo13, EquipmentInfo14, EquipmentInfo15,
  18. EquipmentInfo16, EquipmentInfo17, EquipmentInfo18, EquipmentInfo19, EquipmentInfo20]
  19. class EquipmentInfoService:
  20. """
  21. 推送数据分表,封装常用函数
  22. """
  23. @classmethod
  24. def get_comb_event_type(cls, event_type):
  25. """
  26. 重新组合ai消息类型查询,使其支持ai多标签查询
  27. @param event_type: 消息类型
  28. @return: event_type_list 消息类型数组
  29. """
  30. if ',' in event_type:
  31. event_type_list = event_type.split(',')
  32. event_type_list = [int(i.strip()) for i in event_type_list]
  33. else:
  34. event_type_list = [int(event_type)]
  35. ai_event_type_list = []
  36. normal_event_type_list = []
  37. a_type = [60, 61, 62, 63, 64, 65, 66]
  38. for val in event_type_list:
  39. if val <= 4: # 分离出ai类型,以便后续组合ai标签,目前只存在4个ai类型1,2,3,4
  40. ai_event_type_list.append(val)
  41. else:
  42. if val not in a_type:
  43. normal_event_type_list.append(val)
  44. if len(ai_event_type_list) < 1:
  45. return normal_event_type_list
  46. ai_event_type_list.sort()
  47. ai_type = [1, 2, 3, 4] # AI目前所有的标签,1人,2车,3宠物,4包裹,后续有新类型需要这里加, 后续会优化,存在表里,包裹存对应的aws标签
  48. comb_ai_event_type = []
  49. seen = set()
  50. for i in range(1, len(ai_type) + 1): # 计算所有组合,如[1, 2, 3, 4], 4取1,4取2,4取3,4取4
  51. for s in itertools.combinations(ai_type, i):
  52. if s not in seen: # 去除重复项, 如a=[1,2,3,4,4],会有两个[1,2,3,4,4],[1,2,3,4,4]的组合
  53. seen.add(s)
  54. s_list = list(s)
  55. for ai_event_type in ai_event_type_list:
  56. if ai_event_type in s_list: # 排除没有选择的标签组合
  57. if s_list not in comb_ai_event_type:
  58. s_list = [str(v) for v in s_list]
  59. comb_ai_event_type.append(s_list)
  60. regroup_list = []
  61. for val in comb_ai_event_type: # 组合ai类型组合,如[[2,3],[1,3]] -> [23, 13]
  62. val = ''.join(val)
  63. regroup_list.append(int(val))
  64. group_list = regroup_list + normal_event_type_list # 加上普通移动消息类型
  65. return group_list
  66. @classmethod
  67. def get_all_comb_event_type(cls):
  68. """
  69. 计算ai消息类型全组合
  70. @return: event_type_list ai所有消息类型数组
  71. """
  72. ai_type = [1, 2, 3, 4] # AI目前所有的标签,1人,2车,3宠物,4包裹,后续有新类型需要这里加, 后续会优化,存在表里,包裹存对应的aws标签
  73. comb_ai_event_type = []
  74. for i in range(1, len(ai_type) + 1): # 计算所有组合,如[1, 2, 3, 4], 4取1,4取2,4取3,4取4
  75. for s in itertools.combinations(ai_type, i):
  76. s_list = list(s)
  77. s_list = [str(v) for v in s_list]
  78. comb_ai_event_type.append(s_list)
  79. regroup_list = []
  80. for val in comb_ai_event_type: # 组合ai类型组合,如[[2,3],[1,3]] -> [23, 13]
  81. val = ''.join(val)
  82. regroup_list.append(int(val))
  83. return regroup_list
  84. @classmethod
  85. def get_combo_types(cls, event_type, event_tag):
  86. """
  87. 获取设备算法组合类型
  88. 51:移动侦测,52:传感器报警,53:影像遗失,54:PIR,55:门磁报警,56:外部发报,57:人型报警(提示:有人出现),58:车型,59:宠物,60:人脸,61:异响,
  89. 62:区域闯入,63:区域闯出,64:长时间无人检测,65:长时间无人检测
  90. 0:代表空字符,702:摄像头休眠,703:摄像头唤醒,704:电量过低
  91. AWS AI识别 1:人形,2:车型,3:宠物,4:包裹。云端AI类型
  92. @param event_tag:
  93. @param event_type:
  94. @return:
  95. """
  96. try:
  97. types = []
  98. if event_tag:
  99. res = event_tag.split(',')
  100. types = [int(var) for var in res if var]
  101. return types
  102. res_type = cls.is_type_exist(event_type)
  103. if res_type == 0:
  104. return types
  105. combo_types = [51, 57, 58, 60, 59, 61, 62, 63, 64, 65]
  106. event_type = str(event_type)
  107. len_type = len(event_type)
  108. for i in range(0, len_type):
  109. e_type = int(event_type[len_type - 1 - i])
  110. if e_type == 1:
  111. types.append(combo_types[i])
  112. return types
  113. except Exception as e:
  114. print('推送错误异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  115. return event_type
  116. @staticmethod
  117. def is_combo_tag(event_type, event_tag):
  118. """
  119. 是否为多标签
  120. """
  121. if not event_tag:
  122. return False
  123. res = event_tag.split(',')
  124. types = [int(var) for var in res if var]
  125. if event_type in types and len(types) == 1:
  126. return False
  127. return True
  128. @classmethod
  129. def is_type_exist(cls, event_type):
  130. """
  131. 判断类型是否存在列表
  132. @param event_type:
  133. @return: 0 or event_type
  134. """
  135. combo_types = cls.combo_type_all()
  136. if not combo_types:
  137. return 0
  138. if event_type in combo_types:
  139. return event_type
  140. return 0
  141. @staticmethod
  142. def combo_type_all():
  143. """
  144. 获取所有组合类型
  145. @return:
  146. """
  147. arr_list = []
  148. event_arr = []
  149. resource_list = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
  150. for i in range(2, len(resource_list) + 1):
  151. arr_list += list(itertools.combinations(resource_list, i)) # 表示从 [1,2,3,4] 中选出 3个元素的组合情况
  152. for i in arr_list:
  153. val = 0
  154. for item in i:
  155. val += item
  156. event_arr.append(int(EquipmentInfoService.dec_to_bin(val)))
  157. return event_arr
  158. @staticmethod
  159. def dec_to_bin(num):
  160. """
  161. 十进制转二进制
  162. @param num:
  163. @return:
  164. """
  165. result = ""
  166. while num != 0:
  167. ret = num % 2
  168. num //= 2
  169. result = str(ret) + result
  170. return result
  171. @staticmethod
  172. def get_combo_type_bins(event_type):
  173. """
  174. 获取组合类型二进制列表
  175. @param event_type: 标签类型
  176. @return:
  177. """
  178. res_list = []
  179. try:
  180. if ',' in event_type:
  181. res_list = event_type.split(',')
  182. res_list = [int(i.strip()) for i in res_list]
  183. else:
  184. res_list = [int(event_type)]
  185. combo_types = [51, 57, 58, 60, 59, 61]
  186. for e_item in res_list:
  187. bins = EquipmentInfoService.combo_type_all()
  188. if e_item in combo_types:
  189. event_label = combo_types.index(e_item) + 1
  190. for item in bins:
  191. val = str(item)
  192. val_len = len(val)
  193. if val_len >= event_label and int(val[val_len - event_label]) == 1:
  194. res_list.append(int(item))
  195. return res_list
  196. except Exception as e:
  197. print('推送错误异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  198. return res_list
  199. @staticmethod
  200. def get_event_tag(event_type):
  201. """
  202. 获取标签用于筛选推送消息
  203. """
  204. if ',' in event_type:
  205. tags = ''
  206. res_list = event_type.split(',')
  207. tag_size = len(res_list)
  208. for i, item in enumerate(res_list):
  209. tags += ',' + str(item) + ','
  210. if i < (tag_size - 1):
  211. tags += '|'
  212. return tags
  213. else:
  214. return ',' + str(event_type) + ','
  215. @classmethod
  216. def union_equipment_info(cls, user_id, uid_list, event_type, start_time, end_time, page, line):
  217. """
  218. 联表查询推送数据
  219. @param user_id:
  220. @param uid_list:
  221. @param event_type:
  222. @param start_time:
  223. @param end_time:
  224. @param page:
  225. @param line:
  226. @return:
  227. """
  228. try:
  229. kwargs = {
  230. 'device_user_id': user_id,
  231. 'event_time__range': (start_time, end_time),
  232. }
  233. event_type_kwargs = {
  234. 'device_user_id': user_id,
  235. 'event_time__range': (start_time, end_time),
  236. }
  237. if uid_list:
  238. kwargs['device_uid__in'] = uid_list
  239. event_type_kwargs['device_uid__in'] = uid_list
  240. event_type_list = []
  241. if event_type:
  242. # 多类型查询
  243. event_type_list = cls.get_comb_event_type(event_type)
  244. event_type_list = list(set(event_type_list))
  245. tags = cls.get_event_tag(event_type)
  246. if event_type_list:
  247. event_type_kwargs['event_type__in'] = event_type_list
  248. event_type_kwargs['event_tag'] = ''
  249. kwargs['event_tag__regex'] = tags
  250. elif tags:
  251. kwargs['event_tag__regex'] = tags
  252. if not event_type_list:
  253. # 新增tab_val字段记录表的标识:表编号+10
  254. equipment_info_1 = EquipmentInfo1.objects.filter(**kwargs).annotate(tab_val=Value('11', output_field=CharField()))
  255. equipment_info_2 = EquipmentInfo2.objects.filter(**kwargs).annotate(tab_val=Value('12', output_field=CharField()))
  256. equipment_info_3 = EquipmentInfo3.objects.filter(**kwargs).annotate(tab_val=Value('13', output_field=CharField()))
  257. equipment_info_4 = EquipmentInfo4.objects.filter(**kwargs).annotate(tab_val=Value('14', output_field=CharField()))
  258. equipment_info_5 = EquipmentInfo5.objects.filter(**kwargs).annotate(tab_val=Value('15', output_field=CharField()))
  259. equipment_info_6 = EquipmentInfo6.objects.filter(**kwargs).annotate(tab_val=Value('16', output_field=CharField()))
  260. equipment_info_7 = EquipmentInfo7.objects.filter(**kwargs).annotate(tab_val=Value('17', output_field=CharField()))
  261. equipment_info_8 = EquipmentInfo8.objects.filter(**kwargs).annotate(tab_val=Value('18', output_field=CharField()))
  262. equipment_info_9 = EquipmentInfo9.objects.filter(**kwargs).annotate(tab_val=Value('19', output_field=CharField()))
  263. equipment_info_10 = EquipmentInfo10.objects.filter(**kwargs).annotate(tab_val=Value('20', output_field=CharField()))
  264. equipment_info_11 = EquipmentInfo11.objects.filter(**kwargs).annotate(tab_val=Value('21', output_field=CharField()))
  265. equipment_info_12 = EquipmentInfo12.objects.filter(**kwargs).annotate(tab_val=Value('22', output_field=CharField()))
  266. equipment_info_13 = EquipmentInfo13.objects.filter(**kwargs).annotate(tab_val=Value('23', output_field=CharField()))
  267. equipment_info_14 = EquipmentInfo14.objects.filter(**kwargs).annotate(tab_val=Value('24', output_field=CharField()))
  268. equipment_info_15 = EquipmentInfo15.objects.filter(**kwargs).annotate(tab_val=Value('25', output_field=CharField()))
  269. equipment_info_16 = EquipmentInfo16.objects.filter(**kwargs).annotate(tab_val=Value('26', output_field=CharField()))
  270. equipment_info_17 = EquipmentInfo17.objects.filter(**kwargs).annotate(tab_val=Value('27', output_field=CharField()))
  271. equipment_info_18 = EquipmentInfo18.objects.filter(**kwargs).annotate(tab_val=Value('28', output_field=CharField()))
  272. equipment_info_19 = EquipmentInfo19.objects.filter(**kwargs).annotate(tab_val=Value('29', output_field=CharField()))
  273. equipment_info_20 = EquipmentInfo20.objects.filter(**kwargs).annotate(tab_val=Value('30', output_field=CharField()))
  274. else:
  275. equipment_info_1 = EquipmentInfo1.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('11', output_field=CharField()))
  276. equipment_info_2 = EquipmentInfo2.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('12', output_field=CharField()))
  277. equipment_info_3 = EquipmentInfo3.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('13', output_field=CharField()))
  278. equipment_info_4 = EquipmentInfo4.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('14', output_field=CharField()))
  279. equipment_info_5 = EquipmentInfo5.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('15', output_field=CharField()))
  280. equipment_info_6 = EquipmentInfo6.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('16', output_field=CharField()))
  281. equipment_info_7 = EquipmentInfo7.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('17', output_field=CharField()))
  282. equipment_info_8 = EquipmentInfo8.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('18', output_field=CharField()))
  283. equipment_info_9 = EquipmentInfo9.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('19', output_field=CharField()))
  284. equipment_info_10 = EquipmentInfo10.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('20', output_field=CharField()))
  285. equipment_info_11 = EquipmentInfo11.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('21', output_field=CharField()))
  286. equipment_info_12 = EquipmentInfo12.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('22', output_field=CharField()))
  287. equipment_info_13 = EquipmentInfo13.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('23', output_field=CharField()))
  288. equipment_info_14 = EquipmentInfo14.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('24', output_field=CharField()))
  289. equipment_info_15 = EquipmentInfo15.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('25', output_field=CharField()))
  290. equipment_info_16 = EquipmentInfo16.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('26', output_field=CharField()))
  291. equipment_info_17 = EquipmentInfo17.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('27', output_field=CharField()))
  292. equipment_info_18 = EquipmentInfo18.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('28', output_field=CharField()))
  293. equipment_info_19 = EquipmentInfo19.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('29', output_field=CharField()))
  294. equipment_info_20 = EquipmentInfo20.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('30', output_field=CharField()))
  295. equipment_info_union = equipment_info_1.union(
  296. equipment_info_2, equipment_info_3, equipment_info_4, equipment_info_5, equipment_info_6, equipment_info_7,
  297. equipment_info_8, equipment_info_9, equipment_info_10,
  298. equipment_info_11, equipment_info_12, equipment_info_13, equipment_info_14, equipment_info_15,
  299. equipment_info_16, equipment_info_17, equipment_info_18, equipment_info_19, equipment_info_20)
  300. count = equipment_info_union.count()
  301. if count == 0:
  302. return None, 0
  303. equipment_info_union = cls.get_equipment_info_union_page(equipment_info_union, page, line)
  304. return equipment_info_union, count
  305. except Exception as e:
  306. print('error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  307. @staticmethod
  308. def get_equipment_info_union_page(equipment_info_union, page, line):
  309. """
  310. 获取查询结果集进行排序、分页,遍历重命名字典key(主要针对原函数返回结果集)
  311. @param equipment_info_union: 设备信息结果集
  312. @param page: 页数
  313. @param line: 分页大小
  314. @return: qs_page 遍历后的设备信息结果集
  315. """
  316. equipment_info_qs = equipment_info_union.values('id', 'device_uid', 'device_nick_name', 'channel', 'event_type',
  317. 'status', 'answer_status', 'alarm', 'event_time', 'is_st',
  318. 'add_time', 'storage_location', 'border_coords', 'tab_val',
  319. 'event_tag')
  320. equipment_info_qs = equipment_info_qs.order_by('-event_time')
  321. equipment_info_qs = equipment_info_qs[(page - 1) * line:page * line]
  322. for equipment_info in equipment_info_qs:
  323. # id: 表标识+id
  324. equipment_info['id'] = equipment_info['tab_val'] + str(equipment_info['id'])
  325. equipment_info['devUid'] = equipment_info['device_uid']
  326. equipment_info['devNickName'] = equipment_info['device_nick_name']
  327. equipment_info['Channel'] = equipment_info['channel']
  328. equipment_info['eventType'] = equipment_info['event_type']
  329. equipment_info['eventTime'] = equipment_info['event_time']
  330. equipment_info['receiveTime'] = equipment_info['event_time']
  331. equipment_info['addTime'] = equipment_info['add_time']
  332. equipment_info['borderCoords'] = equipment_info['border_coords']
  333. equipment_info['eventTag'] = equipment_info['event_tag']
  334. equipment_info.pop('device_uid')
  335. equipment_info.pop('device_nick_name')
  336. equipment_info.pop('channel')
  337. equipment_info.pop('event_type')
  338. equipment_info.pop('event_time')
  339. equipment_info.pop('add_time')
  340. equipment_info.pop('border_coords')
  341. equipment_info.pop('tab_val')
  342. equipment_info.pop('event_tag')
  343. return equipment_info_qs
  344. @staticmethod
  345. def all_read_equipment_info(**kwargs):
  346. """
  347. 全部已读推送消息
  348. @param kwargs:
  349. @return:
  350. """
  351. for equipment_info_model in EQUIPMENT_INFO_MODEL_LIST:
  352. equipment_info_model.objects.filter(**kwargs).update(status=1)
  353. @staticmethod
  354. def update_equipment_info_answer_status(**kwargs):
  355. """
  356. 已接听一键通话消息
  357. @param kwargs:
  358. @return:
  359. """
  360. for equipment_info_model in EQUIPMENT_INFO_MODEL_LIST:
  361. equipment_info_model.objects.filter(**kwargs).update(answer_status=1)
  362. @staticmethod
  363. def delete_all_equipment_info(**kwargs):
  364. """
  365. 删除全部推送消息
  366. @param kwargs:
  367. @return:
  368. """
  369. for equipment_info_model in EQUIPMENT_INFO_MODEL_LIST:
  370. equipment_info_model.objects.filter(**kwargs).delete()
  371. @staticmethod
  372. def get_equipment_info_model_with_full_id(full_id):
  373. """
  374. 根据拼接id获取推送表
  375. @param full_id: 拼接id,表标识+id
  376. @return:
  377. """
  378. tab_val = int(full_id[:2]) - 10
  379. if tab_val > 20:
  380. return None
  381. tab_index = tab_val - 1
  382. return EQUIPMENT_INFO_MODEL_LIST[tab_index]
  383. @staticmethod
  384. def count_equipment_info(**kwargs):
  385. """
  386. 查询推送数据数量
  387. @param kwargs:
  388. @return: count
  389. """
  390. count = 0
  391. for equipment_info_model in EQUIPMENT_INFO_MODEL_LIST:
  392. count += equipment_info_model.objects.filter(**kwargs).count()
  393. return count