# -*- encoding: utf-8 -*- """ @File : EquipmentInfoService.py @Time : 2022/4/14 17:28 @Author : stephen @Email : zhangdongming@asj6.wecom.work @Software: PyCharm """ import itertools from django.db.models import Value, CharField, Q from Model.models import EquipmentInfo1, EquipmentInfo2, EquipmentInfo3, EquipmentInfo4, EquipmentInfo5, \ EquipmentInfo6, EquipmentInfo7, EquipmentInfo8, EquipmentInfo9, EquipmentInfo10, \ EquipmentInfo11, EquipmentInfo12, EquipmentInfo13, EquipmentInfo14, EquipmentInfo15, EquipmentInfo16, \ EquipmentInfo17, EquipmentInfo18, EquipmentInfo19, EquipmentInfo20 EQUIPMENT_INFO_MODEL_LIST = [EquipmentInfo1, EquipmentInfo2, EquipmentInfo3, EquipmentInfo4, EquipmentInfo5, EquipmentInfo6, EquipmentInfo7, EquipmentInfo8, EquipmentInfo9, EquipmentInfo10, EquipmentInfo11, EquipmentInfo12, EquipmentInfo13, EquipmentInfo14, EquipmentInfo15, EquipmentInfo16, EquipmentInfo17, EquipmentInfo18, EquipmentInfo19, EquipmentInfo20] class EquipmentInfoService: """ 推送数据分表,封装常用函数 """ @classmethod def get_comb_event_type(cls, event_type): """ 重新组合ai消息类型查询,使其支持ai多标签查询 @param event_type: 消息类型 @return: event_type_list 消息类型数组 """ if ',' in event_type: event_type_list = event_type.split(',') event_type_list = [int(i.strip()) for i in event_type_list] else: event_type_list = [int(event_type)] ai_event_type_list = [] normal_event_type_list = [] a_type = [60, 61, 62, 63, 64, 65, 66] for val in event_type_list: if val <= 4: # 分离出ai类型,以便后续组合ai标签,目前只存在4个ai类型1,2,3,4 ai_event_type_list.append(val) else: if val not in a_type: normal_event_type_list.append(val) if len(ai_event_type_list) < 1: return normal_event_type_list ai_event_type_list.sort() ai_type = [1, 2, 3, 4] # AI目前所有的标签,1人,2车,3宠物,4包裹,后续有新类型需要这里加, 后续会优化,存在表里,包裹存对应的aws标签 comb_ai_event_type = [] seen = set() for i in range(1, len(ai_type) + 1): # 计算所有组合,如[1, 2, 3, 4], 4取1,4取2,4取3,4取4 for s in itertools.combinations(ai_type, i): if s not in seen: # 去除重复项, 如a=[1,2,3,4,4],会有两个[1,2,3,4,4],[1,2,3,4,4]的组合 seen.add(s) s_list = list(s) for ai_event_type in ai_event_type_list: if ai_event_type in s_list: # 排除没有选择的标签组合 if s_list not in comb_ai_event_type: s_list = [str(v) for v in s_list] comb_ai_event_type.append(s_list) regroup_list = [] for val in comb_ai_event_type: # 组合ai类型组合,如[[2,3],[1,3]] -> [23, 13] val = ''.join(val) regroup_list.append(int(val)) group_list = regroup_list + normal_event_type_list # 加上普通移动消息类型 return group_list @classmethod def get_all_comb_event_type(cls): """ 计算ai消息类型全组合 @return: event_type_list ai所有消息类型数组 """ ai_type = [1, 2, 3, 4] # AI目前所有的标签,1人,2车,3宠物,4包裹,后续有新类型需要这里加, 后续会优化,存在表里,包裹存对应的aws标签 comb_ai_event_type = [] for i in range(1, len(ai_type) + 1): # 计算所有组合,如[1, 2, 3, 4], 4取1,4取2,4取3,4取4 for s in itertools.combinations(ai_type, i): s_list = list(s) s_list = [str(v) for v in s_list] comb_ai_event_type.append(s_list) regroup_list = [] for val in comb_ai_event_type: # 组合ai类型组合,如[[2,3],[1,3]] -> [23, 13] val = ''.join(val) regroup_list.append(int(val)) return regroup_list @classmethod def get_combo_types(cls, event_type, event_tag): """ 获取设备算法组合类型 51:移动侦测,52:传感器报警,53:影像遗失,54:PIR,55:门磁报警,56:外部发报,57:人型报警(提示:有人出现),58:车型,59:宠物,60:人脸,61:异响, 62:区域闯入,63:区域闯出,64:长时间无人检测,65:长时间无人检测 0:代表空字符,702:摄像头休眠,703:摄像头唤醒,704:电量过低 AWS AI识别 1:人形,2:车型,3:宠物,4:包裹。云端AI类型 @param event_tag: @param event_type: @return: """ try: types = [] if event_tag: res = event_tag.split(',') types = [int(var) for var in res if var] return types res_type = cls.is_type_exist(event_type) if res_type == 0: return types combo_types = [51, 57, 58, 60, 59, 61, 62, 63, 64, 65] event_type = str(event_type) len_type = len(event_type) for i in range(0, len_type): e_type = int(event_type[len_type - 1 - i]) if e_type == 1: types.append(combo_types[i]) return types except Exception as e: print('推送错误异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e))) return event_type @staticmethod def is_combo_tag(event_type, event_tag): """ 是否为多标签 """ if not event_tag: return False res = event_tag.split(',') types = [int(var) for var in res if var] if event_type in types and len(types) == 1: return False return True @classmethod def is_type_exist(cls, event_type): """ 判断类型是否存在列表 @param event_type: @return: 0 or event_type """ combo_types = cls.combo_type_all() if not combo_types: return 0 if event_type in combo_types: return event_type return 0 @staticmethod def combo_type_all(): """ 获取所有组合类型 @return: """ arr_list = [] event_arr = [] resource_list = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512] for i in range(2, len(resource_list) + 1): arr_list += list(itertools.combinations(resource_list, i)) # 表示从 [1,2,3,4] 中选出 3个元素的组合情况 for i in arr_list: val = 0 for item in i: val += item event_arr.append(int(EquipmentInfoService.dec_to_bin(val))) return event_arr @staticmethod def dec_to_bin(num): """ 十进制转二进制 @param num: @return: """ result = "" while num != 0: ret = num % 2 num //= 2 result = str(ret) + result return result @staticmethod def get_combo_type_bins(event_type): """ 获取组合类型二进制列表 @param event_type: 标签类型 @return: """ res_list = [] try: if ',' in event_type: res_list = event_type.split(',') res_list = [int(i.strip()) for i in res_list] else: res_list = [int(event_type)] combo_types = [51, 57, 58, 60, 59, 61] for e_item in res_list: bins = EquipmentInfoService.combo_type_all() if e_item in combo_types: event_label = combo_types.index(e_item) + 1 for item in bins: val = str(item) val_len = len(val) if val_len >= event_label and int(val[val_len - event_label]) == 1: res_list.append(int(item)) return res_list except Exception as e: print('推送错误异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e))) return res_list @staticmethod def get_event_tag(event_type): """ 获取标签用于筛选推送消息 """ if ',' in event_type: tags = '' res_list = event_type.split(',') tag_size = len(res_list) for i, item in enumerate(res_list): tags += ',' + str(item) + ',' if i < (tag_size - 1): tags += '|' return tags else: return ',' + str(event_type) + ',' @classmethod def union_equipment_info(cls, user_id, uid_list, event_type, start_time, end_time, page, line): """ 联表查询推送数据 @param user_id: @param uid_list: @param event_type: @param start_time: @param end_time: @param page: @param line: @return: """ try: kwargs = { 'device_user_id': user_id, 'event_time__range': (start_time, end_time), } event_type_kwargs = { 'device_user_id': user_id, 'event_time__range': (start_time, end_time), } if uid_list: kwargs['device_uid__in'] = uid_list event_type_kwargs['device_uid__in'] = uid_list event_type_list = [] if event_type: # 多类型查询 event_type_list = cls.get_comb_event_type(event_type) event_type_list = list(set(event_type_list)) tags = cls.get_event_tag(event_type) if event_type_list: event_type_kwargs['event_type__in'] = event_type_list event_type_kwargs['event_tag'] = '' kwargs['event_tag__regex'] = tags elif tags: kwargs['event_tag__regex'] = tags if not event_type_list: # 新增tab_val字段记录表的标识:表编号+10 equipment_info_1 = EquipmentInfo1.objects.filter(**kwargs).annotate(tab_val=Value('11', output_field=CharField())) equipment_info_2 = EquipmentInfo2.objects.filter(**kwargs).annotate(tab_val=Value('12', output_field=CharField())) equipment_info_3 = EquipmentInfo3.objects.filter(**kwargs).annotate(tab_val=Value('13', output_field=CharField())) equipment_info_4 = EquipmentInfo4.objects.filter(**kwargs).annotate(tab_val=Value('14', output_field=CharField())) equipment_info_5 = EquipmentInfo5.objects.filter(**kwargs).annotate(tab_val=Value('15', output_field=CharField())) equipment_info_6 = EquipmentInfo6.objects.filter(**kwargs).annotate(tab_val=Value('16', output_field=CharField())) equipment_info_7 = EquipmentInfo7.objects.filter(**kwargs).annotate(tab_val=Value('17', output_field=CharField())) equipment_info_8 = EquipmentInfo8.objects.filter(**kwargs).annotate(tab_val=Value('18', output_field=CharField())) equipment_info_9 = EquipmentInfo9.objects.filter(**kwargs).annotate(tab_val=Value('19', output_field=CharField())) equipment_info_10 = EquipmentInfo10.objects.filter(**kwargs).annotate(tab_val=Value('20', output_field=CharField())) equipment_info_11 = EquipmentInfo11.objects.filter(**kwargs).annotate(tab_val=Value('21', output_field=CharField())) equipment_info_12 = EquipmentInfo12.objects.filter(**kwargs).annotate(tab_val=Value('22', output_field=CharField())) equipment_info_13 = EquipmentInfo13.objects.filter(**kwargs).annotate(tab_val=Value('23', output_field=CharField())) equipment_info_14 = EquipmentInfo14.objects.filter(**kwargs).annotate(tab_val=Value('24', output_field=CharField())) equipment_info_15 = EquipmentInfo15.objects.filter(**kwargs).annotate(tab_val=Value('25', output_field=CharField())) equipment_info_16 = EquipmentInfo16.objects.filter(**kwargs).annotate(tab_val=Value('26', output_field=CharField())) equipment_info_17 = EquipmentInfo17.objects.filter(**kwargs).annotate(tab_val=Value('27', output_field=CharField())) equipment_info_18 = EquipmentInfo18.objects.filter(**kwargs).annotate(tab_val=Value('28', output_field=CharField())) equipment_info_19 = EquipmentInfo19.objects.filter(**kwargs).annotate(tab_val=Value('29', output_field=CharField())) equipment_info_20 = EquipmentInfo20.objects.filter(**kwargs).annotate(tab_val=Value('30', output_field=CharField())) else: equipment_info_1 = EquipmentInfo1.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('11', output_field=CharField())) equipment_info_2 = EquipmentInfo2.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('12', output_field=CharField())) equipment_info_3 = EquipmentInfo3.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('13', output_field=CharField())) equipment_info_4 = EquipmentInfo4.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('14', output_field=CharField())) equipment_info_5 = EquipmentInfo5.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('15', output_field=CharField())) equipment_info_6 = EquipmentInfo6.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('16', output_field=CharField())) equipment_info_7 = EquipmentInfo7.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('17', output_field=CharField())) equipment_info_8 = EquipmentInfo8.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('18', output_field=CharField())) equipment_info_9 = EquipmentInfo9.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('19', output_field=CharField())) equipment_info_10 = EquipmentInfo10.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('20', output_field=CharField())) equipment_info_11 = EquipmentInfo11.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('21', output_field=CharField())) equipment_info_12 = EquipmentInfo12.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('22', output_field=CharField())) equipment_info_13 = EquipmentInfo13.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('23', output_field=CharField())) equipment_info_14 = EquipmentInfo14.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('24', output_field=CharField())) equipment_info_15 = EquipmentInfo15.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('25', output_field=CharField())) equipment_info_16 = EquipmentInfo16.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('26', output_field=CharField())) equipment_info_17 = EquipmentInfo17.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('27', output_field=CharField())) equipment_info_18 = EquipmentInfo18.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('28', output_field=CharField())) equipment_info_19 = EquipmentInfo19.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('29', output_field=CharField())) equipment_info_20 = EquipmentInfo20.objects.filter(Q(**kwargs) | Q(**event_type_kwargs)).annotate(tab_val=Value('30', output_field=CharField())) equipment_info_union = equipment_info_1.union( equipment_info_2, equipment_info_3, equipment_info_4, equipment_info_5, equipment_info_6, equipment_info_7, equipment_info_8, equipment_info_9, equipment_info_10, equipment_info_11, equipment_info_12, equipment_info_13, equipment_info_14, equipment_info_15, equipment_info_16, equipment_info_17, equipment_info_18, equipment_info_19, equipment_info_20) count = equipment_info_union.count() if count == 0: return None, 0 equipment_info_union = cls.get_equipment_info_union_page(equipment_info_union, page, line) return equipment_info_union, count except Exception as e: print('error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) @staticmethod def get_equipment_info_union_page(equipment_info_union, page, line): """ 获取查询结果集进行排序、分页,遍历重命名字典key(主要针对原函数返回结果集) @param equipment_info_union: 设备信息结果集 @param page: 页数 @param line: 分页大小 @return: qs_page 遍历后的设备信息结果集 """ equipment_info_qs = equipment_info_union.values('id', 'device_uid', 'device_nick_name', 'channel', 'event_type', 'status', 'answer_status', 'alarm', 'event_time', 'is_st', 'add_time', 'storage_location', 'border_coords', 'tab_val', 'event_tag') equipment_info_qs = equipment_info_qs.order_by('-event_time') equipment_info_qs = equipment_info_qs[(page - 1) * line:page * line] for equipment_info in equipment_info_qs: # id: 表标识+id equipment_info['id'] = equipment_info['tab_val'] + str(equipment_info['id']) equipment_info['devUid'] = equipment_info['device_uid'] equipment_info['devNickName'] = equipment_info['device_nick_name'] equipment_info['Channel'] = equipment_info['channel'] equipment_info['eventType'] = equipment_info['event_type'] equipment_info['eventTime'] = equipment_info['event_time'] equipment_info['receiveTime'] = equipment_info['event_time'] equipment_info['addTime'] = equipment_info['add_time'] equipment_info['borderCoords'] = equipment_info['border_coords'] equipment_info['eventTag'] = equipment_info['event_tag'] equipment_info.pop('device_uid') equipment_info.pop('device_nick_name') equipment_info.pop('channel') equipment_info.pop('event_type') equipment_info.pop('event_time') equipment_info.pop('add_time') equipment_info.pop('border_coords') equipment_info.pop('tab_val') equipment_info.pop('event_tag') return equipment_info_qs @staticmethod def all_read_equipment_info(**kwargs): """ 全部已读推送消息 @param kwargs: @return: """ for equipment_info_model in EQUIPMENT_INFO_MODEL_LIST: equipment_info_model.objects.filter(**kwargs).update(status=1) @staticmethod def update_equipment_info_answer_status(**kwargs): """ 已接听一键通话消息 @param kwargs: @return: """ for equipment_info_model in EQUIPMENT_INFO_MODEL_LIST: equipment_info_model.objects.filter(**kwargs).update(answer_status=1) @staticmethod def delete_all_equipment_info(**kwargs): """ 删除全部推送消息 @param kwargs: @return: """ for equipment_info_model in EQUIPMENT_INFO_MODEL_LIST: equipment_info_model.objects.filter(**kwargs).delete() @staticmethod def get_equipment_info_model_with_full_id(full_id): """ 根据拼接id获取推送表 @param full_id: 拼接id,表标识+id @return: """ tab_val = int(full_id[:2]) - 10 if tab_val > 20: return None tab_index = tab_val - 1 return EQUIPMENT_INFO_MODEL_LIST[tab_index] @staticmethod def count_equipment_info(**kwargs): """ 查询推送数据数量 @param kwargs: @return: count """ count = 0 for equipment_info_model in EQUIPMENT_INFO_MODEL_LIST: count += equipment_info_model.objects.filter(**kwargs).count() return count