diff --git a/apps/ecm/algo.py b/apps/ecm/algo.py new file mode 100644 index 00000000..75339aa4 --- /dev/null +++ b/apps/ecm/algo.py @@ -0,0 +1,2 @@ +def helmet_test(): + return True diff --git a/apps/ecm/migrations/0008_auto_20220704_0841.py b/apps/ecm/migrations/0008_auto_20220704_0841.py new file mode 100644 index 00000000..8b3caf31 --- /dev/null +++ b/apps/ecm/migrations/0008_auto_20220704_0841.py @@ -0,0 +1,35 @@ +# Generated by Django 3.2.12 on 2022-07-04 00:41 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('third', '0003_alter_tdevice_type'), + ('ecm', '0007_auto_20220702_1327'), + ] + + operations = [ + migrations.AddField( + model_name='event', + name='vchannel', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='third.tdevice', verbose_name='抓拍设备'), + ), + migrations.AlterField( + model_name='eventcate', + name='filter_area_level', + field=models.PositiveSmallIntegerField(choices=[(10, '办公'), (20, '生产一般'), (30, '生产重点'), (40, '四级')], default=10, verbose_name='固定喇叭区域级别过滤'), + ), + migrations.AlterField( + model_name='eventcate', + name='speaker_on', + field=models.BooleanField(default=True, verbose_name='开启喇叭报警'), + ), + migrations.AlterField( + model_name='eventcate', + name='speakers', + field=models.ManyToManyField(blank=True, related_name='ec_speakers', to='third.TDevice', verbose_name='固定喇叭'), + ), + ] diff --git a/apps/ecm/models.py b/apps/ecm/models.py index 141f2f0b..8672be8b 100644 --- a/apps/ecm/models.py +++ b/apps/ecm/models.py @@ -21,10 +21,10 @@ class EventCate(CommonAModel): name = models.CharField('名称', max_length=20, unique=True) trigger = models.PositiveSmallIntegerField('触发方式', default=10, choices=EVENT_TRIGGER_CHOICES) self_algo = models.BooleanField('识别算法', default=False) - speaker_on = models.BooleanField('开启音响报警', default=True) + speaker_on = models.BooleanField('开启喇叭报警', default=True) voice_person = models.PositiveSmallIntegerField('声音选择', default=0, help_text='0女声3男声') - speakers = models.ManyToManyField(TDevice, verbose_name='固定音响', blank=True) - filter_area_level = models.PositiveSmallIntegerField('固定音响区域级别过滤', choices=Area.AREA_LEVEL_CHOICES, + speakers = models.ManyToManyField(TDevice, verbose_name='固定喇叭', blank=True, related_name='ec_speakers') + filter_area_level = models.PositiveSmallIntegerField('固定喇叭区域级别过滤', choices=Area.AREA_LEVEL_CHOICES, default=Area.AREA_1) hanle_minute = models.PositiveSmallIntegerField('处理时间', default=0, help_text='超过处理时间事件状态变为超时未处理,0代表未配置') @@ -80,6 +80,7 @@ class Event(CommonBModel): face_img = models.CharField('人脸照', max_length=1000, null=True, blank=True) global_img = models.CharField('全景照', max_length=1000, null=True, blank=True) area = models.ForeignKey(Area, verbose_name='发生区域', on_delete=models.CASCADE) + vchannel = models.ForeignKey(TDevice, verbose_name='抓拍设备', on_delete=models.CASCADE, null=True, blank=True) location = models.JSONField('事件点位坐标', default=dict, null=False, blank=True) obj_cate = models.CharField('发生对象', max_length=20, help_text='people(人员)/...') employee = models.ForeignKey(Employee, verbose_name='当事人', diff --git a/apps/ecm/serializers.py b/apps/ecm/serializers.py index b708df6b..278fb465 100644 --- a/apps/ecm/serializers.py +++ b/apps/ecm/serializers.py @@ -74,7 +74,7 @@ class NotifySettingsSerializer(CustomModelSerializer): class EventSerializer(serializers.ModelSerializer): area_ = AreaSerializer(source='area', read_only=True) - cate_ = EventCateSimpleSerializer(source='cate', read_only=True, many=True) + cates_ = EventCateSimpleSerializer(source='cate', read_only=True, many=True) employee_ = EmployeeSerializer(source='employee', read_only=True) handle_user_name = serializers.CharField(source='handle_user.name', read_only=True) diff --git a/apps/ecm/service.py b/apps/ecm/service.py index 4c461694..10f53ee8 100644 --- a/apps/ecm/service.py +++ b/apps/ecm/service.py @@ -1,10 +1,11 @@ +from apps.ecm.algo import helmet_test from apps.utils.sms import send_sms import requests from apps.am.models import Access, Area from apps.am.tasks import cache_areas_info -from apps.ecm.models import Event, EventCate, Eventdo +from apps.ecm.models import AlgoChannel, Event, EventCate, Eventdo from apps.hrm.models import Employee from apps.system.models import User from apps.third.clients import xxClient @@ -24,19 +25,27 @@ requests.packages.urllib3.disable_warnings() def get_area_info_from_cache(target: str, cache: list): + """从区域信息缓存里匹配到所在区域 + + Args: + target (str): 区域ID + cache (list): + + Returns: + _type_: _description_ + """ for i in cache: if i['id'] == target: return i return None -def save_dahua_pic(pic: str): +def save_dahua_pic(pic_url: str): """保存大华报警图片到本地 返回本地路径 """ - file_name = pic.split('/')[-1] - full_url = dhClient.get_full_pic(pic) - res = requests.get(url=full_url, verify=False) + file_name = pic_url.split('/')[-1].split('?')[-1] + res = requests.get(url=pic_url, verify=False) path = '/media/' + timezone.now().strftime('%Y/%m/%d/') full_path = settings.BASE_DIR + path if not os.path.exists(full_path): @@ -46,242 +55,274 @@ def save_dahua_pic(pic: str): return path + file_name -class EcmService: - """事件处理服务 +def get_ep_default(): + """返回人员默认位置信息 """ + return { + 'area_fix_id': None, # 当前所在固定区域ID + 'time0': None, # 定位首次出现时间戳 + "time1": None, # 首次在该区域时间戳 + "time2": int(time.time()), # 当前时间戳 + } - @classmethod - def get_ep_default(cls): - return { - 'area_fix_id': None, # 当前所在固定区域ID - 'time0': None, # 定位首次出现时间戳 - "time1": None, # 首次在该区域时间戳 - "time2": int(time.time()), # 当前时间戳 - } - @classmethod - def create_remind_and_speak(cls, event: Event): - """ - 创建事件提醒并发送短信/微信/喇叭 - """ - # 喇叭提醒 - if event.voice: - sps = list(TDevice.objects.filter(area=event.area, type=TDevice.DEVICE_SPEAKER).values_list('code', flat=True)) - if len(sps) == 0: # 找覆盖区的音响 - sps = list(TDevice.objects.filter(areas=event.area, - type=TDevice.DEVICE_SPEAKER).values_list('code', flat=True)) - if sps: - t = Thread(target=spClient.speak, args=(event.voice, sps), daemon=True) - t.start() - if event.employee and event.employee.phone: - t = Thread(target=send_sms, args=(event.employee.phone, '1001', {'code': '5678'}), daemon=True) - t.start() +def algo_handle(codes: list, data: dict): + """算法 - @classmethod - def dispatch_dahua_event(cls, data: dict): - """分发大华事件进行处理 - """ - vchannel_code = data['info']['nodeCode'] - alarm_type = data['info']['alarmType'] - vchannel = TDevice.objects.filter(code=vchannel_code).first() - print(data) - if alarm_type in [1001003, 1001000] and vchannel: # 内部人员/或陌生人报警 - # 加载算法逻辑 - # 安全帽检测 - ec = EventCate.objects.filter(code='helmet').first() # 模拟发生安全帽事件 - # 视频区域 - area = vchannel.area - if ec and area: - # 保存照片 - face_img = save_dahua_pic(data['info']['alarmPicture']) - global_img = save_dahua_pic(data['info']['extend']['globalScenePicUrl']) + Args: + code (str): 算法标识列表 + data (dict): 需要处理的内容 + """ + return ['helmet'] + + +def save_voice_and_speak(event: Event): + """生成并保存语音地址并喇叭播放 + + Args: + event (Event): _description_ + """ + _, event.voice, _ = generate_voice(event.voice_msg, event.cates[0].voice_person) + event.save() + sps = list(TDevice.objects.filter(area=event.area, type=TDevice.DEVICE_SPEAKER).values_list('code', flat=True)) + if len(sps) == 0: # 如果当前区域没有喇叭就找覆盖区的喇叭 + sps = list(TDevice.objects.filter(areas=event.area, + type=TDevice.DEVICE_SPEAKER).values_list('code', flat=True)) + # 固定喇叭 + sps2 = list(TDevice.objects.filter(ec_speakers__in=event.cates).values_list('code', flat=True)) + for i in sps2: + if i not in sps: + sps.append(i) + if sps: + spClient.speak(event.voice, sps) + + +def create_remind(event: Event): + """ + 创建事件提醒并发送短信 + """ + if event.employee and event.employee.phone: + t_sms = Thread(target=send_sms, args=(event.employee.phone, '1001', {'code': '5678'}), daemon=True) + t_sms.start() + + +def dispatch_dahua_event(data: dict): + """分发大华事件进行处理 + """ + vchannel_code = data['info']['nodeCode'] + alarm_type = data['info']['alarmType'] + vchannel = TDevice.objects.filter(code=vchannel_code).first() + event = None + print(data) + if alarm_type in [1001003, 1001000] and vchannel: # 内部人员/或陌生人报警 + # 查看加载的算法 + algo_codes = list(AlgoChannel.objects.filter(vchannel=vchannel).exclude( + algo__code=None).values_list('algo__code', flat=True)) + area = vchannel.area # 视频所在区域 + if algo_codes and area: # 如果加载了算法且视频通道绑定区域才继续 + face_img_o = dhClient.get_full_pic(data['info']['alarmPicture']) + global_img_o = dhClient.get_full_pic(data['info']['extend']['globalScenePicUrl']) + obj_cate = 'people' + ep = None # 对应人员 + if alarm_type == 1001003: # 内部人员 + ep = Employee.objects.filter(id_number=data['info']['extend']['candidateInfo'][0]['id']).first() + ec_codes = algo_handle(algo_codes, data={}) # 算法处理 + if ec_codes: # 如果触发事件 + # 获取本次所有发生事件种类 + ecs = EventCate.objects.filter(code__in=ec_codes) + # 创建事件 event = Event() - event.face_img = face_img - event.global_img = global_img + event.face_img = save_dahua_pic(face_img_o) + event.global_img = save_dahua_pic(global_img_o) event.area = area - event.obj_cate = 'people' - ep = None # 找到人员 - if alarm_type == 1001003: - ep = Employee.objects.filter(id_number=data['info']['extend']['candidateInfo'][0]['id']).first() + event.obj_cate = obj_cate + event.vchannel = vchannel + voice_msg = '' if ep: - voice_msg = '位于{}的{}{},您未佩戴安全帽,请及时处理' ep_name = ep.name ep_type = '员工' if ep.type == 'rempoyee': ep_type = '相关方人员' elif ep.type == 'visitor': ep_type = '访客' - event.voice_msg = voice_msg.format(area.name, ep_type, ep_name) + voice_msg = '位于{}的{}{},'.format(area.name, ep_type, ep_name) else: - event.voice_msg = '位于{}的未知人员,您未佩戴安全帽,请及时处理'.format(area.name) + voice_msg = '位于{}的未知人员,'.format(area.name) + for i in ecs: + voice_msg = voice_msg + i.name + ',' + event.voice_msg = voice_msg + ',请及时处理' event.employee = ep - _, event.voice, _ = generate_voice(event.voice_msg, ec.voice_person) event.save() - Eventdo.objects.get_or_create(cate=ec, event=event, defaults={ - 'cate': ec, - 'event': event - }) - cls.create_remind_and_speak(event=event) + for i in ecs: + Eventdo.objects.get_or_create(cate=i, event=event, defaults={ + 'cate': i, + 'event': event + }) + if event: + t_v = Thread(target=save_voice_and_speak, args=(event,), daemon=True) + t_v.start() + t_r = Thread(target=create_remind, args=(event,), daemon=True) + t_r.start() - @classmethod - def dispatch_xunxi_event(cls, data: dict): - """分发寻息事件进行处理 - """ - if data.type == 'rail': - if data.data.type == 1: - # 围栏进入 - cls.rail_in(data=data.data) - elif data.data.type == 2: - # 围栏离开 - cls.rail_out(data=data.data) - elif data.type == 'onKeyAlarm': - # 一键呼救 - cls.one_key_alarm(data=data) - elif data.type == 'location': - # 定位信息 - cls.loc_change(data=data) - elif data.type == 'onOffLine': - if data.data.online: - # 标签定位在线 - pass - else: - # 标签定位离线 - pass - elif data.type == 'lowpower': - # 低电量 - cls.low_power(data=data.data) - elif data.type == 'bltOnOffLineV2': - if data.data.online: - # 标签通信在线 - cls.blt_online(data=data.data) - else: - # 标签通信离线 - cls.blt_offline(data=data.data) - @classmethod - def rail_in(cls, data): - """围栏进入事件 - """ - # 找到所在围栏 - area = Area.objects.filter(third_info__xx_rail__id=data['railId']).first() - # 找到进入对象 - blts = TDevice.objects.filter(code=data['userId']).first() - if area and blts and blts.employee: # 如果是人 - if area.type == Area.AREA_TYPE_FIX: - # 更新人员位置信息缓存 - key_str = 'ep_{}'.format(blts.employee.id) - ep_loc_dict = cache.get_or_set( - key_str, cls.get_ep_default(), timeout=None - ) - if ep_loc_dict['area_fix_id'] != area.id: # 如果区域未变化则不动 - ep_loc_dict['time1'] = ep_loc_dict['time2'] - ep_loc_dict['area_fix_id'] = area.id - cache.set(key_str, ep_loc_dict) - ep_blt = blts.employee # 标签绑定人员 - if ep_blt: - for i in Access.objects.filter(area=area).order_by('sort'): - # 优先自定义权限过滤 - if i.post: # 如果是按岗位设定的 - eps_access = Employee.objects.filter(user__posts=i.post) - if ep_blt in eps_access and i.type == Access.ACCESS_IN_YES: - return - elif ep_blt in eps_access and i.type == Access.ACCESS_IN_NO: - # 触发非法进入事件 - pass - elif i.dept: # 如果是按部门设定的 - if i.dept.type == 'dept': # 如果是内部部门 - depts = get_child_queryset2(i.dept) - if ep_blt.belong_dept in depts and i.type == Access.ACCESS_IN_YES: - return - elif ep_blt.belong_dept in depts and i.type == Access.ACCESS_IN_NO: - # 触发非法进入事件 - pass - elif i.dept.type == 'rparty': # 如果是相关方 - if ep_blt.belong_dept == i.dept and i.type == Access.ACCESS_IN_YES: - return - elif ep_blt.belong_dept == i.dept and i.type == Access.ACCESS_IN_NO: - # 触发非法进入事件 - pass - elif i.employee: # 如果是按人设定的 - if ep_blt == i.employee and i.type == Access.ACCESS_IN_YES: - return - elif ep_blt == i.employee and i.type == Access.ACCESS_IN_NO: - # 触发非法进入事件 - pass - # 通用权限设置过滤 - if ep_blt.type == 'employee' and area.employee_yes: - return - elif ep_blt.type == 'remployee' and area.remployee_yes: - return - elif ep_blt.type == 'visitor' and area.visitor_yes: - return - else: - # 触发非法进入事件 - pass - elif area and (not blts): - # 触发未知标签进入事件 +def dispatch_xunxi_event(data: dict): + """分发寻息事件进行处理 + """ + if data.type == 'rail': + if data.data.type == 1: + # 围栏进入 + rail_in(data=data.data) + elif data.data.type == 2: + # 围栏离开 + rail_out(data=data.data) + elif data.type == 'onKeyAlarm': + # 一键呼救 + one_key_alarm(data=data) + elif data.type == 'location': + # 定位信息 + loc_change(data=data) + elif data.type == 'onOffLine': + if data.data.online: + # 标签定位在线 pass - - @classmethod - def rail_out(cls, data): - pass - - @classmethod - def low_power(cls, data): - # 有绑定对象再提示低电量 - blts = TDevice.objects.filter(code=data['userId']).first() - if blts.employee: - # 触发低电量提醒事件 + else: + # 标签定位离线 pass + elif data.type == 'lowpower': + # 低电量 + low_power(data=data.data) + elif data.type == 'bltOnOffLineV2': + if data.data.online: + # 标签通信在线 + blt_online(data=data.data) + else: + # 标签通信离线 + blt_offline(data=data.data) - @classmethod - def one_key_alarm(cls, data): - pass - @classmethod - def loc_change(cls, data): - blts = TDevice.objects.filter(code=data['userId']).first() - if blts.employee: - # 从缓存查询人员位置信息 - time2 = int(time.time()) +def rail_in(data): + """围栏进入事件 + """ + # 找到所在围栏 + area = Area.objects.filter(third_info__xx_rail__id=data['railId']).first() + # 找到进入对象 + blts = TDevice.objects.filter(code=data['userId']).first() + if area and blts and blts.employee: # 如果是人 + if area.type == Area.AREA_TYPE_FIX: # 如果是固定区域 + # 更新人员位置信息缓存 key_str = 'ep_{}'.format(blts.employee.id) ep_loc_dict = cache.get_or_set( - key_str, cls.get_ep_default(), timeout=None + key_str, get_ep_default(), timeout=None ) - ep_loc_dict['time2'] = time2 - # 从缓存里获取固定区域列表信息 - area_fix_list = cache.get('area_fix_list', None) - if not area_fix_list: - area_fix_list = cache_areas_info() - if ep_loc_dict.get('area_fix_id', None): - # 如果存在所在固定区域 - area_info = get_area_info_from_cache(ep_loc_dict['area_fix_id'], area_fix_list) - if area_info: - # 在该固定区域停留时间(分钟) - stay_minute = int((ep_loc_dict['time2']-ep_loc_dict['time1'])/60) - # 判断停留时间是否合理 - # 先通过自定义权限过滤(暂未做) - # 再经过通用设置过滤 - if 0 < stay_minute < area_info['stay_minute_min']: - # 触发离岗事件 + if ep_loc_dict['area_fix_id'] != area.id: # 如果区域未变化则不动 + ep_loc_dict['time1'] = ep_loc_dict['time2'] + ep_loc_dict['area_fix_id'] = area.id + cache.set(key_str, ep_loc_dict) + ep_blt = blts.employee # 标签绑定人员 + if ep_blt: + for i in Access.objects.filter(area=area).order_by('sort'): + # 优先自定义权限过滤 + if i.post: # 如果是按岗位设定的 + eps_access = Employee.objects.filter(user__posts=i.post) + if ep_blt in eps_access and i.type == Access.ACCESS_IN_YES: return - elif area_info['stay_minute_max'] < stay_minute: - # 触发超时滞留事件 + elif ep_blt in eps_access and i.type == Access.ACCESS_IN_NO: + # 触发非法进入事件 + pass + elif i.dept: # 如果是按部门设定的 + if i.dept.type == 'dept': # 如果是内部部门 + depts = get_child_queryset2(i.dept) + if ep_blt.belong_dept in depts and i.type == Access.ACCESS_IN_YES: + return + elif ep_blt.belong_dept in depts and i.type == Access.ACCESS_IN_NO: + # 触发非法进入事件 + pass + elif i.dept.type == 'rparty': # 如果是相关方 + if ep_blt.belong_dept == i.dept and i.type == Access.ACCESS_IN_YES: + return + elif ep_blt.belong_dept == i.dept and i.type == Access.ACCESS_IN_NO: + # 触发非法进入事件 + pass + elif i.employee: # 如果是按人设定的 + if ep_blt == i.employee and i.type == Access.ACCESS_IN_YES: return + elif ep_blt == i.employee and i.type == Access.ACCESS_IN_NO: + # 触发非法进入事件 + pass + # 通用权限设置过滤 + if ep_blt.type == 'employee' and area.employee_yes: + return + elif ep_blt.type == 'remployee' and area.remployee_yes: + return + elif ep_blt.type == 'visitor' and area.visitor_yes: + return else: - for i in area_fix_list: - if data['floorNo'] == i['floor_no']: - point = shapely.geometry.Point(data['xMillimeter'], data['yMillimeter']) - if i['poly_shape'].intersects(point): # 如果点在多边形中 - ep_loc_dict['time1'] = time2 - ep_loc_dict['are_id'] = i['area_fix_id'] - ep_loc_dict['time2'] = time2 - cache.set(key_str, ep_loc_dict) - - @classmethod - def blt_online(cls, data): + # 触发非法进入事件 + pass + elif area and (not blts): + # 触发未知标签进入事件 pass - @classmethod - def blt_offline(cls, data): + +def rail_out(data): + pass + + +def low_power(data): + # 有绑定对象再提示低电量 + blts = TDevice.objects.filter(code=data['userId']).first() + if blts.employee: + # 触发低电量提醒事件 pass + + +def one_key_alarm(data): + pass + + +def loc_change(data): + blts = TDevice.objects.filter(code=data['userId']).first() + if blts.employee: + # 从缓存查询人员位置信息 + time2 = int(time.time()) + key_str = 'ep_{}'.format(blts.employee.id) + ep_loc_dict = cache.get_or_set( + key_str, get_ep_default(), timeout=None + ) + ep_loc_dict['time2'] = time2 + # 从缓存里获取固定区域列表信息 + area_fix_list = cache.get('area_fix_list', None) + if not area_fix_list: + area_fix_list = cache_areas_info() + if ep_loc_dict.get('area_fix_id', None): + # 如果存在所在固定区域 + area_info = get_area_info_from_cache(ep_loc_dict['area_fix_id'], area_fix_list) + if area_info: + # 在该固定区域停留时间(分钟) + stay_minute = int((ep_loc_dict['time2']-ep_loc_dict['time1'])/60) + # 判断停留时间是否合理 + # 先通过自定义权限过滤(暂未做) + # 再经过通用设置过滤 + if 0 < stay_minute < area_info['stay_minute_min']: + # 触发离岗事件 + return + elif area_info['stay_minute_max'] < stay_minute: + # 触发超时滞留事件 + return + else: + for i in area_fix_list: + if data['floorNo'] == i['floor_no']: + point = shapely.geometry.Point(data['xMillimeter'], data['yMillimeter']) + if i['poly_shape'].intersects(point): # 如果点在多边形中 + ep_loc_dict['time1'] = time2 + ep_loc_dict['are_id'] = i['area_fix_id'] + ep_loc_dict['time2'] = time2 + cache.set(key_str, ep_loc_dict) + + +def blt_online(data): + pass + + +def blt_offline(data): + pass diff --git a/apps/third/urls.py b/apps/third/urls.py index 9ff8e873..b1c5c934 100755 --- a/apps/third/urls.py +++ b/apps/third/urls.py @@ -1,7 +1,8 @@ +from email.mime import base from django.urls import path, include from rest_framework import routers from apps.third.views import DahuaTestView, DhCommonViewSet, SpTestView, XxCommonViewSet, XxTestView -from apps.third.views_d import TDeviceViewSet, TlogViewSet +from apps.third.views_d import BltViewSet, TDeviceViewSet, TlogViewSet API_BASE_URL = 'api/third/' HTML_BASE_URL = 'third/' @@ -11,6 +12,7 @@ router.register('xunxi', XxCommonViewSet, basename='api_xunxi') router.register('dahua', DhCommonViewSet, basename='api_dahua') router.register('tdevice', TDeviceViewSet, basename='tdevice') router.register('tlog', TlogViewSet, basename='tlog') +router.register('tdevice/blt', BltViewSet, basename='blt') urlpatterns = [ path(API_BASE_URL, include(router.urls)), path(API_BASE_URL + 'dahua/test/', DahuaTestView.as_view()), diff --git a/apps/third/views.py b/apps/third/views.py index cc25672a..02d7613f 100755 --- a/apps/third/views.py +++ b/apps/third/views.py @@ -1,6 +1,6 @@ import json from rest_framework.exceptions import ParseError, APIException -from apps.ecm.service import EcmService +from apps.ecm.service import dispatch_dahua_event, dispatch_xunxi_event from apps.hrm.services import HrmService from apps.third.tapis import dhapis, xxapis, spapis from apps.third.errors import TAPI_CODE_WRONG @@ -75,7 +75,7 @@ class XxListener(stomp.ConnectionListener): def on_message(self, frame): data = json.loads(frame.body) - EcmService.dispatch_xunxi_event(data) + dispatch_xunxi_event(data) print('received a message "%s"' % frame.body) @@ -260,5 +260,5 @@ class DhCommonViewSet(CreateModelMixin, CustomGenericViewSet): """ 其他报警转到事件派发 """ - EcmService.dispatch_dahua_event(data=data) + dispatch_dahua_event(data=data) return Response() diff --git a/apps/third/views_d.py b/apps/third/views_d.py index 28c0dfa7..488864fb 100644 --- a/apps/third/views_d.py +++ b/apps/third/views_d.py @@ -1,7 +1,7 @@ from apps.third.models import TDevice, Tlog from apps.third.serializers import BindAreaSerializer, LabelLocationSerializer, TDeviceSerializer, TlogSerializer from apps.utils.viewsets import CustomGenericViewSet -from rest_framework.mixins import ListModelMixin +from rest_framework.mixins import ListModelMixin, CreateModelMixin from apps.third.clients import xxClient, dhClient, spClient from apps.third.tapis import xxapis, dhapis, spapis from rest_framework.response import Response @@ -11,6 +11,17 @@ from apps.am.models import Area from rest_framework.views import APIView +class BltViewSet(CreateModelMixin, CustomGenericViewSet): + """定位标签列表 + + 定位标签列表 + """ + queryset = TDevice.objects.filter(type=TDevice.DEVICE_BLT) + serializer_class = TDeviceSerializer + select_related_fields = ['employee'] + ordering = ['-create_time'] + + class TDeviceViewSet(ListModelMixin, CustomGenericViewSet): """ 三方设备接口 diff --git a/apps/utils/sms.py b/apps/utils/sms.py index 54b791e3..7863f3b1 100644 --- a/apps/utils/sms.py +++ b/apps/utils/sms.py @@ -29,7 +29,7 @@ def send_sms(phone: str, template_code: str, template_param: dict): request.add_query_param('TemplateParam', json.dumps(template_param)) res = client.do_action(request) res_dict = json.loads(str(res, encoding='utf-8')) - print(phone, template_code, template_param, res_dict) + # print(phone, template_code, template_param, res_dict) if res_dict['result'] == 0: return True, res_dict