From fc0ce469e3561b4cfce04d4fb8891a1feef82629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E5=89=8D=E6=98=8E?= <909355014@qq.com> Date: Sat, 2 Jul 2022 10:26:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=98=AF=E5=90=A6=E8=B6=85?= =?UTF-8?q?=E6=97=B6=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/am/views.py | 1 + apps/ecm/demo.py | 11 +++++ .../ecm/migrations/0004_auto_20220702_1025.py | 32 ++++++++++++++ apps/ecm/models.py | 1 + apps/ecm/service.py | 42 ++++++++++++++----- apps/third/models.py | 2 +- apps/third/views.py | 5 +-- apps/utils/mixins.py | 9 ++-- server/settings.py | 2 +- 9 files changed, 83 insertions(+), 22 deletions(-) create mode 100644 apps/ecm/migrations/0004_auto_20220702_1025.py diff --git a/apps/am/views.py b/apps/am/views.py index 297542a9..c1bcf024 100755 --- a/apps/am/views.py +++ b/apps/am/views.py @@ -7,6 +7,7 @@ from rest_framework import serializers from apps.third.clients import xxClient from apps.third.tapis import xxapis from rest_framework.response import Response +from rest_framework.exceptions import ParseError from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin diff --git a/apps/ecm/demo.py b/apps/ecm/demo.py index f3147830..d850bdba 100644 --- a/apps/ecm/demo.py +++ b/apps/ecm/demo.py @@ -60,3 +60,14 @@ xx = {'id': 1656652947266, 'infoArray': None, 'protocol': None} print(json.dumps(xx)) + + +{'id': 1656727743278, +'category': 'alarm', +'method': 'alarm.msg', +'info': +{'orgName': '根节点', +'nodeCode': '1000038$1$0$0', +'deviceCode': '1000038', +'alarmCode': '37f2b363-71aa-49c4-b352-711f4e098f46', +'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220622/1/dsf_453810dc-f202-11ec-bd2d-e4246c7d1635_60524172_60587111.jpg', 'nodeType': 2, 'alarmDate': '1656727743', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220622/1/dsf_453810dc-f202-11ec-bd2d-e4246c7d1635_60524172_60587111.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220622/1/dsf_453810dc-f202-11ec-bd2d-e4246c7d1635_60425203_60524172.jpg', 'eye': 0, 'alarmType': 1001000, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 0, 'szSerialUUID': '', 'channelName': '测试摄像头1', 'beginTime': 1656727739, 'endTime': 1656727739, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001000, 'channelSeq': 0, 'orgCode': '001', 'channelName': '测试摄像头1', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None} \ No newline at end of file diff --git a/apps/ecm/migrations/0004_auto_20220702_1025.py b/apps/ecm/migrations/0004_auto_20220702_1025.py new file mode 100644 index 00000000..0a82088a --- /dev/null +++ b/apps/ecm/migrations/0004_auto_20220702_1025.py @@ -0,0 +1,32 @@ +# Generated by Django 3.2.12 on 2022-07-02 02:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ecm', '0003_alter_algochannel_unique_together'), + ] + + operations = [ + migrations.RemoveField( + model_name='event', + name='imgs', + ), + migrations.AddField( + model_name='event', + name='face_img', + field=models.CharField(blank=True, max_length=1000, null=True, verbose_name='人脸照'), + ), + migrations.AddField( + model_name='event', + name='global_img', + field=models.CharField(blank=True, max_length=1000, null=True, verbose_name='全景照'), + ), + migrations.AddField( + model_name='event', + name='is_timeout', + field=models.BooleanField(default=False, verbose_name='是否超时'), + ), + ] diff --git a/apps/ecm/models.py b/apps/ecm/models.py index dc1fa85e..0ecedb3c 100644 --- a/apps/ecm/models.py +++ b/apps/ecm/models.py @@ -86,6 +86,7 @@ class Event(CommonBModel): on_delete=models.CASCADE, null=True, blank=True) msg = models.TextField('事件文本', null=True, blank=True) voice = models.TextField('语音地址', null=True, blank=True) + is_timeout = models.BooleanField('是否超时', default=False) mark = models.PositiveSmallIntegerField('事件标记', default=10, help_text='10(正常)/20(误报)') handle_time = models.DateTimeField('处理时间', null=True, blank=True) handle_user = models.ForeignKey(User, verbose_name='处理人', diff --git a/apps/ecm/service.py b/apps/ecm/service.py index 466b82f7..ae4915c5 100644 --- a/apps/ecm/service.py +++ b/apps/ecm/service.py @@ -3,7 +3,7 @@ import requests from apps.am.models import Access, Area from apps.am.tasks import cache_areas_info -from apps.ecm.models import EventCate +from apps.ecm.models import Event, EventCate from apps.hrm.models import Employee from apps.system.models import User from apps.third.clients import xxClient @@ -14,6 +14,10 @@ from django.core.cache import cache import time import shapely.geometry from apps.third.clients import dhClient +from django.utils import timezone +from django.conf import settings +import os +requests.packages.urllib3.disable_warnings() def get_area_info_from_cache(target: str, cache: list): @@ -22,13 +26,21 @@ def get_area_info_from_cache(target: str, cache: list): return i return None -# def save_dahua_pic(pic:str): -# """保存大华报警图片到本地 -# 返回本地路径 -# """ -# full_url = dhClient.get_full_pic(pic) -# res = requests.get(url=full_url) -# file_path = idwo + +def save_dahua_pic(pic: str): + """保存大华报警图片到本地 + 返回本地路径 + """ + file_name = pic.split('/')[-1] + full_url = dhClient.get_full_pic(pic) + res = requests.get(url=full_url, verify=False) + path = '/media/' + timezone.now().strftime('%Y/%m/%d/') + full_path = settings.BASE_DIR + path + if not os.path.exists(full_path): + os.makedirs(full_path) + with open(full_path + file_name, 'wb') as f: + f.write(res.content) + return path + file_name class EcmService: @@ -57,15 +69,23 @@ class EcmService: vchannel_code = data['info']['nodeCode'] alarm_type = data['info']['alarmType'] vchannel = TDevice.objects.filter(code=vchannel_code).first() - if alarm_type == 1001003 and vchannel: # 内部人员报警 + print(data) + if alarm_type in [1001003, 1001000] and vchannel: # 内部人员报警 # 加载算法逻辑 # 安全帽检测 - ec = EventCate.objects.filter(code='helmet').first() + ec = EventCate.objects.filter(code='helmet').first() # 模拟发生安全帽事件 # 视频区域 area = vchannel.area if ec and area: # 保存照片 - pass + face_img = save_dahua_pic(data['info']['alarmPicture']) + global_img = save_dahua_pic(data['info']['extend']['globalScenePicUrl']) + event = Event() + event.face_img = face_img + event.global_img = global_img + event.area = area + event.obj_cate = 'people' + event.employee = None @classmethod def dispatch_xunxi_event(cls, data: dict): diff --git a/apps/third/models.py b/apps/third/models.py index 8901f0e1..4c98f6c3 100755 --- a/apps/third/models.py +++ b/apps/third/models.py @@ -25,7 +25,7 @@ class TDevice(BaseModel): (DEVICE_IBEACON, '定位信标'), (DEVICE_BLT, '定位标签'), (DEVICE_AOA, 'aoa引擎'), - (DEVICE_SPEAKER, '音响'), + (DEVICE_SPEAKER, '喇叭'), (DEVICE_VCHANNEL, '视频通道'), (DEVICE_DCHANNEL, '闸机通道'), (DEVICE_PANEL, '面板机') diff --git a/apps/third/views.py b/apps/third/views.py index 7d7055bf..cc25672a 100755 --- a/apps/third/views.py +++ b/apps/third/views.py @@ -246,7 +246,6 @@ class DhCommonViewSet(CreateModelMixin, CustomGenericViewSet): method = data['method'] category = data['category'] subsystem = data.get('subsystem', None) - print(data) # info = data.get('info', {}) if method == 'department.update': pass @@ -257,9 +256,9 @@ class DhCommonViewSet(CreateModelMixin, CustomGenericViewSet): 刷卡事件 """ HrmService.swipe(data=data) - elif category == 'alarm' and subsystem == 'admin': + elif category == 'alarm': """ - 视频报警 + 其他报警转到事件派发 """ EcmService.dispatch_dahua_event(data=data) return Response() diff --git a/apps/utils/mixins.py b/apps/utils/mixins.py index f255da7c..47788f31 100755 --- a/apps/utils/mixins.py +++ b/apps/utils/mixins.py @@ -115,15 +115,13 @@ class MyLoggingMixin(object): response = super().finalize_response( request, response, *args, **kwargs ) - # Ensure backward compatibility for those using _should_log hook should_log = ( self._should_log if hasattr(self, "_should_log") else self.should_log ) - if should_log(request, response): if (connection.settings_dict.get("ATOMIC_REQUESTS") and - getattr(response, "exception", None) and connection.in_atomic_block): + getattr(response, "exception", None) and connection.in_atomic_block): # response with exception (HTTP status like: 401, 404, etc) # pointwise disable atomic block for handle log (TransactionManagementError) connection.set_rollback(True) @@ -238,9 +236,8 @@ class MyLoggingMixin(object): Method that should return a value that evaluated to True if the request should be logged. By default, check if the request method is in logging_methods. """ - return ( - self.logging_methods == "__all__" or request.method in self.logging_methods - ) and (response.status_code not in [401, 403, 404]) + return self.logging_methods == "__all__" or response.status_code > 404 or response.status_code == 400 \ + or (request.method in self.logging_methods and response.status_code not in [401, 403, 404]) def _clean_data(self, data): """ diff --git a/server/settings.py b/server/settings.py index a8abc921..8dd8c60c 100755 --- a/server/settings.py +++ b/server/settings.py @@ -268,7 +268,7 @@ SWAGGER_SETTINGS = { LOG_PATH = os.path.join(BASE_DIR, 'log') # 如果地址不存在,则自动创建log文件夹 if not os.path.exists(os.path.join(LOG_PATH)): - os.mkdir(LOG_PATH) + os.makedirs(LOG_PATH) LOGGING = { 'version': 1,