| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503 | 
							- # -*- encoding: utf-8 -*-
 
- """
 
- @File    : EquipmentInfoService.py
 
- @Time    : 2022/4/14 17:28
 
- @Author  : stephen
 
- @Email   : zhangdongming@asj6.wecom.work
 
- @Software: PyCharm
 
- """
 
- import datetime
 
- import itertools
 
- import logging
 
- import time
 
- from django.db.models import Value, CharField, Q
 
- from Model.models import EquipmentInfoMonday, EquipmentInfoTuesday, EquipmentInfoWednesday, EquipmentInfoThursday, \
 
-     EquipmentInfoFriday, EquipmentInfoSaturday, EquipmentInfoSunday
 
- from Object.utils import LocalDateTimeUtil
 
- """
 
- 设备分表查询Service    
 
- 因数据量不断增加,单表保留近七天数据进行分表优化设计
 
- 进行拆分为七张表星期一至星期天进行分表存储。分担单表存储读写压力。
 
- """
 
- class EquipmentInfoService:
 
-     @staticmethod
 
-     def get_equipment_info_model(dt, val=0):
 
-         """
 
-         根据日期判断是星期几,返回相应的Model对象
 
-         @param val: 1-7代表week
 
-         @param dt: 日期 例:2022-03-03
 
-         @return: 星期一至星期天equipment_info对象实例
 
-         """
 
-         week = 1
 
-         if dt:
 
-             week = LocalDateTimeUtil.date_to_week(dt)
 
-         if 0 < val < 8:
 
-             week = val
 
-         equipment_info = None
 
-         if week == 1:
 
-             equipment_info = EquipmentInfoMonday.objects.all().annotate(tab_val=Value('1', output_field=CharField()))
 
-         elif week == 2:
 
-             equipment_info = EquipmentInfoTuesday.objects.all().annotate(tab_val=Value('2', output_field=CharField()))
 
-         elif week == 3:
 
-             equipment_info = EquipmentInfoWednesday.objects.all().annotate(tab_val=Value('3', output_field=CharField()))
 
-         elif week == 4:
 
-             equipment_info = EquipmentInfoThursday.objects.all().annotate(tab_val=Value('4', output_field=CharField()))
 
-         elif week == 5:
 
-             equipment_info = EquipmentInfoFriday.objects.all().annotate(tab_val=Value('5', output_field=CharField()))
 
-         elif week == 6:
 
-             equipment_info = EquipmentInfoSaturday.objects.all().annotate(tab_val=Value('6', output_field=CharField()))
 
-         elif week == 7:
 
-             equipment_info = EquipmentInfoSunday.objects.all().annotate(tab_val=Value('7', output_field=CharField()))
 
-         return equipment_info
 
-     @classmethod
 
-     def find_by_start_time_equipment_info(cls, page, size, user_id, start_time, end_time, event_type,
 
-                                           uid_list):
 
-         """
 
-         通过start_time查找指定日期当天设备消息推送
 
-         @param page: 页数
 
-         @param size: 每页条数
 
-         @param user_id: 设备用户id
 
-         @param start_time: 开始时间
 
-         @param end_time: 结束时间
 
-         @param event_type: 事件类型
 
-         @param uid_list: 设备uid列表
 
-         @return: result 查询结果
 
-         """
 
-         if start_time and end_time:
 
-             start_date = datetime.datetime.fromtimestamp(int(start_time))
 
-             # 根据开始日期,获取设备信息查询对象
 
-             qs = EquipmentInfoService.get_equipment_info_model(str(start_date.date()), 0)
 
-             # 调用查询方法
 
-             qs = cls.query_equipment_info(qs, user_id, start_time, end_time, event_type,
 
-                                           uid_list)
 
-             # 时区问题
 
-             week = LocalDateTimeUtil.date_to_week(str(start_date.date()))
 
-             if week > 0:
 
-                 # 根据筛选日期 查找昨天数据
 
-                 yesterday = 7 if week == 1 else week - 1
 
-                 yesterday_info = EquipmentInfoService.get_equipment_info_model('', yesterday)
 
-                 yesterday_info = cls.query_equipment_info(yesterday_info, user_id, start_time, end_time, event_type,
 
-                                                           uid_list)
 
-                 # 根据筛选日期 查找明天数据
 
-                 tomorrow = 1 if week == 7 else week + 1
 
-                 tomorrow_info = EquipmentInfoService.get_equipment_info_model('', tomorrow)
 
-                 tomorrow_info = cls.query_equipment_info(tomorrow_info, user_id, start_time, end_time, event_type,
 
-                                                          uid_list)
 
-                 qs = qs.union(yesterday_info, tomorrow_info, all=True)
 
-             if qs.exists():
 
-                 count = qs.count()
 
-                 qs_page = cls.get_equipment_info_page(qs, page, size)
 
-                 return qs_page, count
 
-         return None, 0
 
-     @classmethod
 
-     def get_equipment_info_week_all(cls, page, size, user_id, start_time, end_time, event_type,
 
-                                     uid_list):
 
-         """
 
-         分表查询近七天设备消息推送
 
-         @param page: 页数
 
-         @param size: 分页大小
 
-         @param user_id: 设备用户id
 
-         @param start_time: 事件开始时间
 
-         @param end_time: 事件结束时间
 
-         @param event_type: 事件类型
 
-         @param uid_list: uid列表
 
-         @return: qs_page, count 结果集
 
-         """
 
-         # 星期一设备信息查询
 
-         monday_qs = EquipmentInfoService.get_equipment_info_model('', 1)
 
-         monday_qs = cls.query_equipment_info(monday_qs, user_id, start_time, end_time, event_type,
 
-                                              uid_list)
 
-         # 星期二设备信息查询
 
-         tuesday_qs = EquipmentInfoService.get_equipment_info_model('', 2)
 
-         tuesday_qs = cls.query_equipment_info(tuesday_qs, user_id, start_time, end_time, event_type,
 
-                                               uid_list)
 
-         # 星期三设备信息查询
 
-         wednesday_qs = EquipmentInfoService.get_equipment_info_model('', 3)
 
-         wednesday_qs = cls.query_equipment_info(wednesday_qs, user_id, start_time, end_time, event_type,
 
-                                                 uid_list)
 
-         # 星期四设备信息查询
 
-         thursday_qs = EquipmentInfoService.get_equipment_info_model('', 4)
 
-         thursday_qs = cls.query_equipment_info(thursday_qs, user_id, start_time, end_time, event_type,
 
-                                                uid_list)
 
-         # 星期五设备信息查询
 
-         friday_qs = EquipmentInfoService.get_equipment_info_model('', 5)
 
-         friday_qs = cls.query_equipment_info(friday_qs, user_id, start_time, end_time, event_type,
 
-                                              uid_list)
 
-         # 星期六设备信息查询
 
-         saturday_qs = EquipmentInfoService.get_equipment_info_model('', 6)
 
-         saturday_qs = cls.query_equipment_info(saturday_qs, user_id, start_time, end_time, event_type,
 
-                                                uid_list)
 
-         # 星期天设备信息查询
 
-         sunday_qs = EquipmentInfoService.get_equipment_info_model('', 7)
 
-         sunday_qs = cls.query_equipment_info(sunday_qs, user_id, start_time, end_time, event_type,
 
-                                              uid_list)
 
-         result = monday_qs.union(tuesday_qs, wednesday_qs, thursday_qs, friday_qs, saturday_qs, sunday_qs, all=True)
 
-         count = result.count()
 
-         qs_page = cls.get_equipment_info_page(result, page, size)
 
-         return qs_page, count
 
-     @classmethod
 
-     def query_equipment_info(cls, qs, user_id, start_time, end_time, event_type,
 
-                              uid_list):
 
-         """
 
-         设备信息条件查询,根据分表设计,默认条件event_time大于七天前时间
 
-         @param qs: 设备信息查询对象
 
-         @param user_id: 设备用户id
 
-         @param start_time: 开始时间
 
-         @param end_time: 结束时间
 
-         @param event_type: 事件类型
 
-         @param uid_list: 设备uid列表
 
-         @return: result 设备信息结果集
 
-         """
 
-         now_time = int(time.time())
 
-         # 获取七天前时间戳
 
-         seven_days_before_time = LocalDateTimeUtil.get_before_days_timestamp(now_time, 7)
 
-         # 默认查询当前表event_time大于七天前时间
 
-         qs = qs.filter(event_time__gt=seven_days_before_time)
 
-         if user_id:
 
-             qs = qs.filter(device_user_id=user_id)
 
-         if event_type:
 
-             # 多类型查询
 
-             eventTypeList = cls.get_comb_event_type(event_type)
 
-             # eventTypeList += cls.get_combo_type_bins(event_type)
 
-             eventTypeList = list(set(eventTypeList))
 
-             tags = cls.get_event_tag(event_type)
 
-             if eventTypeList:
 
-                 qs = qs.filter(Q(event_type__in=eventTypeList, event_tag='') | Q(event_tag__regex=tags))
 
-             elif tags:
 
-                 qs = qs.filter(event_tag__regex=tags)
 
-         if start_time and end_time:
 
-             qs = qs.filter(event_time__range=(start_time, end_time))
 
-         else:
 
-             qs = qs.filter(event_time__range=(start_time, now_time))
 
-         if uid_list:
 
-             uid_list = uid_list.split(',')
 
-             qs = qs.filter(device_uid__in=uid_list)
 
-         return qs
 
-     @classmethod
 
-     def get_equipment_info_page(cls, equipment_info_qs, page, size):
 
-         """
 
-         获取查询结果集进行排序、分页,遍历重命名字典key(主要针对原函数返回结果集)
 
-         @param equipment_info_qs: 设备信息结果集
 
-         @param page: 页数
 
-         @param size: 分页大小
 
-         @return: qs_page 遍历后的设备信息结果集
 
-         """
 
-         equipment_info_qs = equipment_info_qs.values('id', 'device_uid', 'device_nick_name', 'channel', 'event_type',
 
-                                                      'status', 'answer_status', 'alarm',
 
-                                                      'event_time', 'receive_time', 'is_st', 'add_time',
 
-                                                      'storage_location', 'border_coords', 'tab_val', 'event_tag')
 
-         equipment_info_qs = equipment_info_qs.order_by('-event_time')
 
-         qs_page = equipment_info_qs[(page - 1) * size:page * size]
 
-         if not qs_page or not qs_page.exists() or qs_page.count == 0:
 
-             return qs_page
 
-         for item in qs_page:
 
-             # 星期表值
 
-             tab_val = item['tab_val']
 
-             # id = 星期表值+id
 
-             item['id'] = int(tab_val + str(item['id']))
 
-             item['devUid'] = item['device_uid']
 
-             item['devNickName'] = item['device_nick_name']
 
-             item['Channel'] = item['channel']
 
-             item['eventType'] = item['event_type']
 
-             item['eventTime'] = item['event_time']
 
-             item['receiveTime'] = item['receive_time']
 
-             item['addTime'] = item['add_time']
 
-             item['borderCoords'] = item['border_coords']
 
-             item['eventTag'] = item['event_tag']
 
-             item.pop('device_uid')
 
-             item.pop('device_nick_name')
 
-             item.pop('channel')
 
-             item.pop('event_type')
 
-             item.pop('event_time')
 
-             item.pop('receive_time')
 
-             item.pop('add_time')
 
-             item.pop('border_coords')
 
-             item.pop('tab_val')
 
-             item.pop('event_tag')
 
-         return qs_page
 
-     @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
 
-     @staticmethod
 
-     def get_equipment_info_obj(dt, **kwargs):
 
-         """
 
-         根据日期判断是星期几,返回相应的对象实例
 
-         @param dt: 日期 例:2022-03-03
 
-         @param kwargs: 设备信息属性值
 
-         @return: 星期一至星期天equipment_info对象实例
 
-         """
 
-         logger = logging.getLogger('info')
 
-         week = LocalDateTimeUtil.date_to_week(dt)
 
-         logger.info('本周{}'.format(str(week)))
 
-         equipment_info = None
 
-         if week == 1:
 
-             equipment_info = EquipmentInfoMonday(**kwargs)
 
-         elif week == 2:
 
-             equipment_info = EquipmentInfoTuesday(**kwargs)
 
-         elif week == 3:
 
-             equipment_info = EquipmentInfoWednesday(**kwargs)
 
-         elif week == 4:
 
-             equipment_info = EquipmentInfoThursday(**kwargs)
 
-         elif week == 5:
 
-             equipment_info = EquipmentInfoFriday(**kwargs)
 
-         elif week == 6:
 
-             equipment_info = EquipmentInfoSaturday(**kwargs)
 
-         elif week == 7:
 
-             equipment_info = EquipmentInfoSunday(**kwargs)
 
-         logger.info(type(equipment_info))
 
-         logger.info(equipment_info)
 
-         return equipment_info
 
-     @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) + ','
 
-     @staticmethod
 
-     def update_equipment_answer_status(user_id, uid, event_time):
 
-         """
 
-         更新一键通话消息状态
 
-         @param user_id: 用户id
 
-         @param uid: uid
 
-         @param event_time: 事件时间
 
-         @return updated_flag: bool
 
-         """
 
-         updated_flag = False
 
-         updated = EquipmentInfoMonday.objects.filter(device_user_id=user_id, device_uid=uid, event_time=event_time,
 
-                                                      event_type=606).update(answer_status=1)
 
-         if updated:
 
-             updated_flag = True
 
-         updated = EquipmentInfoTuesday.objects.filter(device_user_id=user_id, device_uid=uid, event_time=event_time,
 
-                                                       event_type=606).update(answer_status=1)
 
-         if updated:
 
-             updated_flag = True
 
-         updated = EquipmentInfoWednesday.objects.filter(device_user_id=user_id, device_uid=uid, event_time=event_time,
 
-                                                         event_type=606).update(answer_status=1)
 
-         if updated:
 
-             updated_flag = True
 
-         updated = EquipmentInfoThursday.objects.filter(device_user_id=user_id, device_uid=uid, event_time=event_time,
 
-                                                        event_type=606).update(answer_status=1)
 
-         if updated:
 
-             updated_flag = True
 
-         updated = EquipmentInfoFriday.objects.filter(device_user_id=user_id, device_uid=uid, event_time=event_time,
 
-                                                      event_type=606).update(answer_status=1)
 
-         if updated:
 
-             updated_flag = True
 
-         updated = EquipmentInfoSaturday.objects.filter(device_user_id=user_id, device_uid=uid, event_time=event_time,
 
-                                                        event_type=606).update(answer_status=1)
 
-         if updated:
 
-             updated_flag = True
 
-         updated = EquipmentInfoSunday.objects.filter(device_user_id=user_id, device_uid=uid, event_time=event_time,
 
-                                                      event_type=606).update(answer_status=1)
 
-         if updated:
 
-             updated_flag = True
 
-         return updated_flag
 
 
  |