From 5cb1331000f931333ac8c0f90f229ddf09dbde31 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 10 Mar 2023 14:53:11 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=91=8A=E8=AD=A6=E9=97=B4=E9=9A=94?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E5=86=85=E4=B8=8D=E8=A7=A6=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/ecm/service.py | 61 +++++++++++++++++++++++++-------------------- apps/ecm/tasks.py | 6 +++++ apps/ecm/views.py | 2 +- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/apps/ecm/service.py b/apps/ecm/service.py index 559d0e49..106a01c9 100644 --- a/apps/ecm/service.py +++ b/apps/ecm/service.py @@ -250,6 +250,7 @@ def check_not_in_place(opl: Opl): for i in tds: if i.code not in macs: # 触发作业人员未就位事件 + cate = EventCate.objects.get(code='not_in_place') event = Event() event.area = area event.obj_cate = 'opl' @@ -257,7 +258,6 @@ def check_not_in_place(opl: Opl): event.opl = opl event.happen_time = timezone.now() event.save() - cate = EventCate.objects.get(code='not_in_place') Eventdo.objects.get_or_create(cate=cate, event=event, defaults={ 'cate': cate, 'event': event @@ -434,13 +434,8 @@ def loc_change(data): if area_fix['stay_minute_max'] > 0 and area_fix['stay_minute_max'] < stay_minute: # 触发超时滞留事件 code_name = 'stand_area' - if code_name: # 2分钟不再次触发 - last_event = Event.objects.filter( - cates__code=code_name, employee=blts.employee).order_by('-create_time').first() - if last_event and last_event.create_time + timedelta(minutes=2) > timezone.now(): - pass - else: - handle_xx_event_2(code_name, ep=blts.employee, area=Area.objects.get(id=area_fix['id'])) + if code_name: + 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 @@ -458,7 +453,8 @@ def handle_xx_event(name: str, data: dict): # 找到最近未处理同一人发生的事件 if cate: # 5分钟内不再次触发 last_event = Event.objects.filter(cates__code=name, employee=blts.employee).order_by('-create_time').first() - if last_event and last_event.create_time + timedelta(minutes=5) > timezone.now(): + 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(): return event = Event() # 查询定位信息 @@ -485,26 +481,27 @@ def handle_xx_event(name: str, data: dict): def handle_xx_event_2(name: str, ep: Employee, area: Area): # 违规进入事件特殊处理 # 找寻该区域下审批和进行的作业, 本厂或相关方人员, 如是就不触发 - 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() - if last_event and last_event.create_time + timedelta(minutes=2) > timezone.now(): # 2分钟不再次触发 - return - 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 - elif ops.filter(coordinator__employee=ep).exists(): - # 如果是协调员 - return - elif Opl.objects.filter(operation__in=ops, charger__employee=ep).exists(): - # 如果是作业负责人 - return - elif Opl.objects.filter(operation__in=ops, monitor__employee=ep).exists(): - # 如果是作业监护人 - return 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分钟不再次触发 + return + 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 + elif ops.filter(coordinator__employee=ep).exists(): + # 如果是协调员 + return + elif Opl.objects.filter(operation__in=ops, charger__employee=ep).exists(): + # 如果是作业负责人 + return + elif Opl.objects.filter(operation__in=ops, monitor__employee=ep).exists(): + # 如果是作业监护人 + return event = Event() event.area = area # 查询定位信息 @@ -605,10 +602,14 @@ def get_area_from_point(x: int, y: int, floorNo: str, area_fix_id): def snap_and_analyse(vchannel: TDevice, algo_codes: list, opl: Opl = None): global_img_o = dhClient.snap(vchannel.code) happen_time = timezone.now() + if global_img_o is None: + return ec_codes = ai_analyse_2(algo_codes, global_img=global_img_o) # 算法处理返回的事件结果 if ec_codes: # 获取本次所有发生事件种类 ecs = EventCate.objects.filter(code__in=ec_codes.keys()) + if not ecs.exists(): + return obj_cate = 'opl' if opl else 'other' ep = None if 'helmet' in ec_codes or 'helmet2' in ec_codes and obj_cate == 'other': @@ -619,6 +620,12 @@ def snap_and_analyse(vchannel: TDevice, algo_codes: list, opl: Opl = None): # if res and res[0]: # 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 + event = Event() event.global_img = ec_codes['global_img'] if ec_codes.get('global_img', None) else save_dahua_pic(global_img_o) event.vchannel = vchannel diff --git a/apps/ecm/tasks.py b/apps/ecm/tasks.py index b5312c02..698e167b 100644 --- a/apps/ecm/tasks.py +++ b/apps/ecm/tasks.py @@ -19,6 +19,7 @@ import time from django.core.cache import cache from django.conf import settings from apps.utils.tasks import CustomTask +from datetime import timedelta @shared_task(base=CustomTask) @@ -61,6 +62,11 @@ def update_count_people(i: Area): 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(): + return event = Event() event.area = area event.obj_cate = 'area' diff --git a/apps/ecm/views.py b/apps/ecm/views.py index d3023c59..e2907a13 100644 --- a/apps/ecm/views.py +++ b/apps/ecm/views.py @@ -39,7 +39,7 @@ class EventCateViewSet(CreateModelMixin, UpdateModelMixin, ListModelMixin, Custo create_serializer_class = EventCateCreateUpdateSerializer update_serializer_class = EventCateCreateUpdateSerializer serializer_class = EventCateListSerializer - filterset_fields = ['self_algo'] + filterset_fields = ['self_algo', 'trigger'] ordering = ['priority', 'create_time'] From 830dee33588d46fd33f40130b18e781b5b013fd9 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 10 Mar 2023 14:53:39 +0800 Subject: [PATCH 2/4] =?UTF-8?q?dhclient=20snap=20=E6=9C=89=E5=8F=AF?= =?UTF-8?q?=E8=83=BD=E5=A4=B1=E8=B4=A5=E8=BF=9B=E8=A1=8C=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/third/dahua.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/third/dahua.py b/apps/third/dahua.py index f8f69400..6f4a0ab1 100644 --- a/apps/third/dahua.py +++ b/apps/third/dahua.py @@ -135,9 +135,11 @@ class DhClient: json_data['deviceCode'] = d_code json_data['params'] = '{\"method\":\"dev.snap\",\"id\":123,\"params\":{\"DevID\":\"' + \ str(d_code) + '\",\"DevChannel\":' + str(num) + ',\"PicNum\":1,\"SnapType\":1,\"CmdSrc\":0}}' - _, res = self.request(**dhapis['dev_snap'], json=json_data) - res = json.loads(res) - return self.get_full_pic(res['params']['PicInfo']) + is_ok, res = self.request(**dhapis['dev_snap'], json=json_data) + if is_ok == 'success': + res = json.loads(res) + return self.get_full_pic(res['params']['PicInfo']) + return None def get_password_token(self): _, res = self.request(**dhapis['oauth_key']) From 367d9b31ddb2812688fcc366fb7cdb2c863439f9 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 10 Mar 2023 16:07:59 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=89=93=E5=8D=A1=E6=97=B6=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E5=BC=82=E5=B8=B8=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0008_clockrecord_exception_type.py | 18 ++++++++++++++++++ apps/hrm/models.py | 7 +++++++ apps/hrm/services.py | 11 ++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 apps/hrm/migrations/0008_clockrecord_exception_type.py diff --git a/apps/hrm/migrations/0008_clockrecord_exception_type.py b/apps/hrm/migrations/0008_clockrecord_exception_type.py new file mode 100644 index 00000000..ba6d844b --- /dev/null +++ b/apps/hrm/migrations/0008_clockrecord_exception_type.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.12 on 2023-03-10 07:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('hrm', '0007_alter_employee_job_state'), + ] + + operations = [ + migrations.AddField( + model_name='clockrecord', + name='exception_type', + field=models.PositiveSmallIntegerField(blank=True, choices=[(10, '在岗时间短'), (20, '在岗时间长')], null=True, verbose_name='异常类型'), + ), + ] diff --git a/apps/hrm/models.py b/apps/hrm/models.py index 0b5e3e05..dd4ad618 100755 --- a/apps/hrm/models.py +++ b/apps/hrm/models.py @@ -83,10 +83,17 @@ class ClockRecord(BaseModel): (ClOCK_ON, '上班打卡'), (CLOCK_OFF, '下班打卡'), ) + E_TYPE_LESS = 10 + E_TYPE_MORE = 20 + E_TYPE_CHOISE = ( + (E_TYPE_LESS, '在岗时间短'), + (E_TYPE_MORE, '在岗时间长') + ) type = models.PositiveSmallIntegerField('打卡类型', choices=type_choice, default=ClOCK_ON) employee = models.ForeignKey(Employee, verbose_name='对应人员', on_delete=models.CASCADE) trigger = models.CharField('触发', max_length=20) detail = models.JSONField('相关记录', default=dict, null=False, blank=True) + exception_type = models.PositiveSmallIntegerField('异常类型', choices=E_TYPE_CHOISE, null=True, blank=True) class Certificate(CommonAModel): diff --git a/apps/hrm/services.py b/apps/hrm/services.py index af1259af..2f6a7455 100755 --- a/apps/hrm/services.py +++ b/apps/hrm/services.py @@ -332,6 +332,15 @@ class HrmService: ep.is_atwork = False ep.last_check_time = s_time_f ep.save() + # 判断是否有异常 + cr_e = ClockRecord.objects.filter(create_time__lte=cr_20.create_time).exclude(id=cr_20.id).order_by('-create_time').first() + time_d = cr_20.create_time - cr_e.create_time + if time_d < timedelta(hours=7): + cr_20.exception_type = ClockRecord.E_TYPE_LESS + cr_20.save() + elif time_d > timedelta(hours=14): + cr_20.exception_type = ClockRecord.E_TYPE_MORE + cr_20.save() # 进行相关方/访客项目更新 Visit.objects.filter(state=Visit.V_ENTER, visitors__employee__id_number=id_number).update( @@ -339,4 +348,4 @@ class HrmService: Rpj.objects.filter(state=Rpj.RPJ_ENTER, remployees__employee__id_number=id_number).update( state=Rpj.RPJ_WORKING) - # 此处可触发安全帽事件逻辑 + # 此处可触发安全帽事件逻辑 \ No newline at end of file From f54cd0028fbc10ab10253093e4e9726eb059aeba Mon Sep 17 00:00:00 2001 From: caoqianming Date: Fri, 10 Mar 2023 17:08:03 +0800 Subject: [PATCH 4/4] =?UTF-8?q?tdevice=20=E5=A2=9E=E5=8A=A0mtask=5Fuid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../third/migrations/0007_tdevice_mtask_uid.py | 18 ++++++++++++++++++ apps/third/models.py | 1 + 2 files changed, 19 insertions(+) create mode 100644 apps/third/migrations/0007_tdevice_mtask_uid.py diff --git a/apps/third/migrations/0007_tdevice_mtask_uid.py b/apps/third/migrations/0007_tdevice_mtask_uid.py new file mode 100644 index 00000000..b39cb342 --- /dev/null +++ b/apps/third/migrations/0007_tdevice_mtask_uid.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.12 on 2023-03-10 09:06 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('third', '0006_tlog_headers'), + ] + + operations = [ + migrations.AddField( + model_name='tdevice', + name='mtask_uid', + field=models.CharField(blank=True, max_length=100, null=True, verbose_name='监控任务ID'), + ), + ] diff --git a/apps/third/models.py b/apps/third/models.py index 5f558757..6b339138 100755 --- a/apps/third/models.py +++ b/apps/third/models.py @@ -45,6 +45,7 @@ class TDevice(BaseModel): is_clock = models.BooleanField('是否打卡设备', default=False) access_list = models.JSONField('自动下发人员类型', default=list, null=False, blank=True, help_text='employee/remployee/visitor/driver') + mtask_uid = models.CharField('监控任务ID', max_length=100, null=True, blank=True) # algos = models.ManyToManyField('ecm.eventcate', through='ecm.algochannel', blank=True) third_info = models.JSONField('三方信息', default=dict, null=False, blank=True)