feat: ecm提出check_same_allow_minute_and_raise_event方法

This commit is contained in:
caoqianming 2024-03-01 18:49:40 +08:00
parent f51075e1ef
commit 61c8e6ab98
1 changed files with 82 additions and 45 deletions

View File

@ -62,6 +62,7 @@ def save_dahua_pic(pic_url: str, save_path: str = '/media/'):
f.write(res.content)
return path + file_name
def compress_global_img(path_file):
full_path_file = settings.BASE_DIR + path_file
try:
@ -71,12 +72,13 @@ def compress_global_img(path_file):
myLogger.error(f'图片压缩失败-{full_path_file}-{traceback.format_exc()}')
return None
def get_ep_default():
"""返回人员默认位置信息
"""
return {
'area_fix_id': None, # 当前所在固定区域ID
'area_fix_name': None, # 当前所在固定区域Name
'area_fix_name': None, # 当前所在固定区域Name
'area_temp_id': None, # 当前所在临时区域ID
'xx_detail': {}, # 寻息定位的详细信息
'time0': None, # 定位首次出现时间戳
@ -84,6 +86,7 @@ def get_ep_default():
"time2": int(time.time()), # 当前时间戳
}
def gen_params(event: Event):
"""
生成短信模板发送参数
@ -112,7 +115,7 @@ def gen_params(event: Event):
cats_list.append(i.name)
params['event'] = ','.join(cats_list)
return params
def notify_event(event: Event):
"""事件后续处理:
@ -127,9 +130,11 @@ def notify_event(event: Event):
else:
params = gen_params(event)
if params['employee']:
event.voice_msg = '位于{}{},{},请及时处理'.format(params['area'], params['employee'], params['event'])
event.voice_msg = '位于{}{},{},请及时处理'.format(
params['area'], params['employee'], params['event'])
else:
event.voice_msg = '{}下,发生{},请及时处理'.format(params['area'], params['event'])
event.voice_msg = '{}下,发生{},请及时处理'.format(
params['area'], params['event'])
event.save()
# 喇叭播放(任何情况下)
Thread(target=save_voice_and_speak, args=(event,), daemon=True).start()
@ -165,7 +170,8 @@ def save_voice_and_speak(event: Event):
sps = list(TDevice.objects.filter(areas=event.area,
type=TDevice.DEVICE_SPEAKER).values_list('code', flat=True))
# 查找固定喇叭
sps2 = list(TDevice.objects.filter(ec_speakers__event_cates=event).values_list('code', flat=True))
sps2 = list(TDevice.objects.filter(
ec_speakers__event_cates=event).values_list('code', flat=True))
for i in sps2:
if i not in sps:
sps.append(i)
@ -186,7 +192,8 @@ def create_remind(event: Event, params: dict):
# t_sms = Thread(target=send_sms, args=(event.employee.phone, '1001', {'code': '5678'}), daemon=True)
# t_sms.start()
# 查找所有提醒配置
n_s = NotifySetting.objects.filter(event_cate__in=event.cates.all()).order_by('sort')
n_s = NotifySetting.objects.filter(
event_cate__in=event.cates.all()).order_by('sort')
area_level = event.area.level if event.area else Area.AREA_4
for i in n_s:
if i.user and area_level >= i.filter_area_level:
@ -200,11 +207,13 @@ def create_remind(event: Event, params: dict):
elif i.post and area_level >= i.filter_area_level:
qs = User.objects.filter(posts=i.post)
if i.filter_recipient == 20 and event.employee and event.employee.user:
qs = qs.filter(depts__in=get_parent_queryset(event.employee.user.belong_dept))
qs = qs.filter(depts__in=get_parent_queryset(
event.employee.user.belong_dept))
elif i.filter_recipient == 10 and event.employee and event.employee.user:
qs = qs.filter(depts=event.employee.user.belong_dept)
elif i.filter_recipient == 40 and event.area.belong_dept:
qs = qs.filter(depts__in=get_parent_queryset(event.area.belong_dept))
qs = qs.filter(depts__in=get_parent_queryset(
event.area.belong_dept))
elif i.filter_recipient == 30 and event.area.belong_dept:
qs = qs.filter(depts=event.area.belong_dept)
else:
@ -238,7 +247,8 @@ def create_remind(event: Event, params: dict):
})
elif i.variable == 'visit_receptionist':
if event.employee and event.employee.type == 'visitor': # 确定是访客
visit = Visit.objects.filter(visitors__employee=event.employee, state=Visit.V_WORKING).first()
visit = Visit.objects.filter(
visitors__employee=event.employee, state=Visit.V_WORKING).first()
if visit:
Remind.objects.get_or_create(event=event, recipient=visit.receptionist,
defaults={
@ -272,13 +282,15 @@ def check_not_in_place(opl: Opl):
"railId": railId,
"type": ""
}
is_ok, res = xxClient.request(**xxapis['rail_ibeacon_list'], json=json, raise_exception=False)
is_ok, res = xxClient.request(
**xxapis['rail_ibeacon_list'], json=json, raise_exception=False)
if is_ok == 'success':
blt_list = res['recordList']
macs = [] # 所有该区域在线标签
for i in blt_list:
macs.append(i['userId'])
tds = TDevice.objects.filter(type=TDevice.DEVICE_BLT, employee__user__opl_worker__opl=opl) # 所有工作人员的定位标签
tds = TDevice.objects.filter(
type=TDevice.DEVICE_BLT, employee__user__opl_worker__opl=opl) # 所有工作人员的定位标签
for i in tds:
if i.code not in macs:
# 触发作业人员未就位事件
@ -306,13 +318,15 @@ def check_miss_lcard(ep: Employee, area: Area):
"railId": railId,
"type": ""
}
is_ok, res = xxClient.request(**xxapis['rail_ibeacon_list'], json=json, raise_exception=False)
is_ok, res = xxClient.request(
**xxapis['rail_ibeacon_list'], json=json, raise_exception=False)
if is_ok == 'success':
blt_list = res['recordList']
macs = [] # 所有该区域在线标签
for i in blt_list:
macs.append(i['userId'])
td = TDevice.objects.filter(type=TDevice.DEVICE_BLT, employee=ep).first()
td = TDevice.objects.filter(
type=TDevice.DEVICE_BLT, employee=ep).first()
if td and td.code in macs:
return False
return True
@ -335,7 +349,8 @@ def dispatch_dahua_event(data: dict):
if alarm_type in [1001003, 1001000]:
obj_cate = 'people'
face_img_o = dhClient.get_full_pic(data['info']['alarmPicture'])
global_img_o = dhClient.get_full_pic(data['info']['extend']['globalScenePicUrl'])
global_img_o = dhClient.get_full_pic(
data['info']['extend']['globalScenePicUrl'])
else:
global_img_o = dhClient.get_full_pic(data['info']['alarmPicture'])
happen_time = timestamp_to_time(int(data['info']['alarmDate']))
@ -350,21 +365,26 @@ def dispatch_dahua_event(data: dict):
else:
algo_codes.append(i['algo__code'])
if algo_codes:
ec_codes = ai_analyse_2(algo_codes, global_img=global_img_o, face_img=face_img_o) # 算法处理
ec_codes = ai_analyse_2(
algo_codes, global_img=global_img_o, face_img=face_img_o) # 算法处理
for m in ec_codes.keys():
for n in algo_channels:
if m == n['algo__code']:
cates.append(n['algo'])
if alarm_type == 1001003 and area: # 内部人员需要执行未带定位卡算法
ep = Employee.objects.filter(id_number=data['info']['extend']['candidateInfo'][0]['id']).first()
ep = Employee.objects.filter(
id_number=data['info']['extend']['candidateInfo'][0]['id']).first()
# 检查是否携带定位卡只针对内部员工和相关方
if 'miss_lcard' in algo_codes and ep:
is_happend = check_miss_lcard(ep=ep, area=area)
if is_happend:
cates.append(EventCate.objects.filter(code='miss_lcard').first().id)
cate_obj = EventCate.objects.filter(code='miss_lcard').first()
if cate_obj and check_same_allow_minute_and_raise_event(cate_obj, ep):
cates.append(cate_obj.id)
if cates:
event = Event()
event.global_img = ec_codes['global_img'] if ec_codes.get('global_img', None) else save_dahua_pic(global_img_o)
event.global_img = ec_codes['global_img'] if ec_codes.get(
'global_img', None) else save_dahua_pic(global_img_o)
event.global_img_compressed = compress_global_img(event.global_img)
if face_img_o:
event.face_img = save_dahua_pic(face_img_o)
@ -377,7 +397,7 @@ def dispatch_dahua_event(data: dict):
current_level = 10
for i in cates:
cate = EventCate.objects.get(id=i)
if cate.origin_level>current_level:
if cate.origin_level > current_level:
event.current_level = current_level
Eventdo.objects.get_or_create(cate=cate, event=event, defaults={
'cate': cate,
@ -452,12 +472,14 @@ def loc_change(data):
ep_loc_dict['time2'] = int(time.time())
ep_loc_dict['xx_detail'] = data
area_fix, area_temp = get_area_from_point(data['longitude'], data['latitude'], data['floorNo'], ep_loc_dict['area_fix_id'])
area_fix, area_temp = get_area_from_point(
data['longitude'], data['latitude'], data['floorNo'], ep_loc_dict['area_fix_id'])
time2 = int(time.time())
ep_loc_dict['area_temp_id'] = area_temp['id'] if area_temp else None
ep_loc_dict['time2'] = time2
if area_fix and ep_loc_dict['area_fix_id'] == area_fix['id']:
ep_loc_dict['area_fix_name'] = area_fix.get('name', None) # 兼容性处理,后续可去除
ep_loc_dict['area_fix_name'] = area_fix.get(
'name', None) # 兼容性处理,后续可去除
# 如果停留在该区域
cache.set(key_str, ep_loc_dict, timeout=None)
# 在该固定区域停留时间(分钟)
@ -473,15 +495,36 @@ def loc_change(data):
# 触发超时滞留事件
code_name = 'stand_area'
if code_name:
handle_xx_event_2(code_name, ep=blts.employee, area=Area.objects.get(id=area_fix['id']))
handle_xx_event_2(code_name, ep=blts.employee,
area=Area.objects.get(id=area_fix['id']))
else:
ep_loc_dict['time1'] = time2
ep_loc_dict['area_fix_id'] = area_fix['id'] if area_fix else None
ep_loc_dict['area_fix_name'] = area_fix.get('name', None) if area_fix else None
ep_loc_dict['area_fix_name'] = area_fix.get(
'name', None) if area_fix else None
cache.set(key_str, ep_loc_dict, timeout=None)
return ep_loc_dict
def check_same_allow_minute_and_raise_event(cate: EventCate, employee: Employee = None, area: Area = None, obj_cate: str = None):
"""
根据配置告警间隔判断是否需要报出事件
"""
filters = {'cate': cate}
if employee:
filters['employee'] = employee
if area:
filters['area'] = area
if obj_cate:
filters['obj_cate'] = obj_cate
last_event = Event.objects.filter(
**filters).order_by('-create_time').first()
minutes = cate.same_allow_minute
if minutes > 0 and last_event and last_event.create_time + timedelta(minutes=minutes) > timezone.now():
return True
return False
def handle_xx_event(name: str, data: dict):
# 有绑定对象再提示事件(包括一键报警事件/低电量)
blts = TDevice.objects.filter(code=data['mac']).first()
@ -491,9 +534,7 @@ def handle_xx_event(name: str, data: dict):
cate = EventCate.objects.filter(code=name).first()
# 找到最近未处理同一人发生的事件
if cate: # 5分钟内不再次触发
last_event = Event.objects.filter(cates__code=name, employee=blts.employee).order_by('-create_time').first()
same_allow_minute = cate.same_allow_minute
if same_allow_minute >0 and last_event and last_event.create_time + timedelta(minutes=cate.same_allow_minute) > timezone.now():
if check_same_allow_minute_and_raise_event(cate, blts.employee) is False:
return
event = Event()
# 查询定位信息
@ -523,12 +564,10 @@ def handle_xx_event_2(name: str, ep: Employee, area: Area):
cate = EventCate.objects.filter(code=name).first()
if cate:
if name == 'i_enter' and ep.type in ['employee', 'remployee']:
last_event = Event.objects.filter(
cates__code='i_enter', employee=ep, area=area).order_by('-create_time').first()
same_allow_minute = cate.same_allow_minute
if same_allow_minute>0 and last_event and last_event.create_time + timedelta(minutes=same_allow_minute) > timezone.now(): # 2分钟不再次触发
if check_same_allow_minute_and_raise_event(cate, ep, area) is False:
return
ops = Operation.objects.filter(area=area, state__in=[Operation.OP_AUDIT, Operation.OP_WAIT, Operation.OP_WORK])
ops = Operation.objects.filter(area=area, state__in=[
Operation.OP_AUDIT, Operation.OP_WAIT, Operation.OP_WORK])
if OplWorker.objects.filter(opl__operation__in=ops, worker__employee=ep).exists():
# 如果是作业人员
return
@ -646,7 +685,8 @@ def snap_and_analyse(vchannel: TDevice, algo_codes: list, opl: Opl = None):
if global_img_o is None: # 说明视频抓拍失败
if cvalue:
try:
cvalue.update({'snap': 'fail', 'snap_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S")})
cvalue.update(
{'snap': 'fail', 'snap_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S")})
cache.set(ckey, cvalue, timeout=60)
except:
pass
@ -654,7 +694,8 @@ def snap_and_analyse(vchannel: TDevice, algo_codes: list, opl: Opl = None):
else:
if cvalue:
try:
cvalue.update({'snap': 'success', 'snap_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S")})
cvalue.update(
{'snap': 'success', 'snap_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S")})
cache.set(ckey, cvalue, timeout=60)
except:
pass
@ -675,13 +716,11 @@ def snap_and_analyse(vchannel: TDevice, algo_codes: list, opl: Opl = None):
# ep = Employee.objects.filter(id_number=res[0]['identity']).first()
pass
last_event = Event.objects.filter(cates__in=ecs, employee=ep, obj_cate=obj_cate).order_by('-create_time').first()
same_allow_minute = ecs.order_by('same_allow_minute').first().same_allow_minute
if same_allow_minute>0 and last_event and last_event.create_time + timedelta(minutes=same_allow_minute) > timezone.now(): # 告警间隔范围内不再次触发
return
ecs = [cate for cate in ecs if check_same_allow_minute_and_raise_event(
cate, ep, None, obj_cate) is True]
event = Event()
event.global_img = ec_codes['global_img'] if ec_codes.get('global_img', None) else save_dahua_pic(global_img_o)
event.global_img = ec_codes['global_img'] if ec_codes.get(
'global_img', None) else save_dahua_pic(global_img_o)
event.global_img_compressed = compress_global_img(event.global_img)
event.vchannel = vchannel
event.area = vchannel.area
@ -702,10 +741,7 @@ def snap_and_analyse(vchannel: TDevice, algo_codes: list, opl: Opl = None):
def handle_xx_event_3(name: str, area: Area):
cate = EventCate.objects.filter(code=name).first()
if cate:
# 告警间隔内不触发
last_event = Event.objects.filter(cates=cate, area=area, obj_cate='area').order_by('-create_time').first()
same_allow_minute = cate.same_allow_minute
if same_allow_minute >0 and last_event and last_event.create_time + timedelta(minutes=cate.same_allow_minute) > timezone.now():
if check_same_allow_minute_and_raise_event(cate, None, area) is False:
return
event = Event()
event.area = area
@ -716,5 +752,6 @@ def handle_xx_event_3(name: str, area: Area):
'cate': cate,
'event': event
})
voice_msg = area.name + '下有' + str(area.count_people) + '人,' + cate.name + ',请及时处理'
notify_event(event, voice_msg=voice_msg)
voice_msg = area.name + '下有' + \
str(area.count_people) + '人,' + cate.name + ',请及时处理'
notify_event(event, voice_msg=voice_msg)