event serializer

This commit is contained in:
曹前明 2022-07-04 08:51:56 +08:00
parent 6231e09a30
commit ffa48f8031
9 changed files with 315 additions and 223 deletions

2
apps/ecm/algo.py Normal file
View File

@ -0,0 +1,2 @@
def helmet_test():
return True

View File

@ -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='固定喇叭'),
),
]

View File

@ -21,10 +21,10 @@ class EventCate(CommonAModel):
name = models.CharField('名称', max_length=20, unique=True) name = models.CharField('名称', max_length=20, unique=True)
trigger = models.PositiveSmallIntegerField('触发方式', default=10, choices=EVENT_TRIGGER_CHOICES) trigger = models.PositiveSmallIntegerField('触发方式', default=10, choices=EVENT_TRIGGER_CHOICES)
self_algo = models.BooleanField('识别算法', default=False) 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男声') voice_person = models.PositiveSmallIntegerField('声音选择', default=0, help_text='0女声3男声')
speakers = models.ManyToManyField(TDevice, verbose_name='固定音响', blank=True) speakers = models.ManyToManyField(TDevice, verbose_name='固定喇叭', blank=True, related_name='ec_speakers')
filter_area_level = models.PositiveSmallIntegerField('固定音响区域级别过滤', choices=Area.AREA_LEVEL_CHOICES, filter_area_level = models.PositiveSmallIntegerField('固定喇叭区域级别过滤', choices=Area.AREA_LEVEL_CHOICES,
default=Area.AREA_1) default=Area.AREA_1)
hanle_minute = models.PositiveSmallIntegerField('处理时间', default=0, help_text='超过处理时间事件状态变为超时未处理,0代表未配置') 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) face_img = models.CharField('人脸照', max_length=1000, null=True, blank=True)
global_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) 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) location = models.JSONField('事件点位坐标', default=dict, null=False, blank=True)
obj_cate = models.CharField('发生对象', max_length=20, help_text='people(人员)/...') obj_cate = models.CharField('发生对象', max_length=20, help_text='people(人员)/...')
employee = models.ForeignKey(Employee, verbose_name='当事人', employee = models.ForeignKey(Employee, verbose_name='当事人',

View File

@ -74,7 +74,7 @@ class NotifySettingsSerializer(CustomModelSerializer):
class EventSerializer(serializers.ModelSerializer): class EventSerializer(serializers.ModelSerializer):
area_ = AreaSerializer(source='area', read_only=True) 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) employee_ = EmployeeSerializer(source='employee', read_only=True)
handle_user_name = serializers.CharField(source='handle_user.name', read_only=True) handle_user_name = serializers.CharField(source='handle_user.name', read_only=True)

View File

@ -1,10 +1,11 @@
from apps.ecm.algo import helmet_test
from apps.utils.sms import send_sms from apps.utils.sms import send_sms
import requests import requests
from apps.am.models import Access, Area from apps.am.models import Access, Area
from apps.am.tasks import cache_areas_info 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.hrm.models import Employee
from apps.system.models import User from apps.system.models import User
from apps.third.clients import xxClient 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): def get_area_info_from_cache(target: str, cache: list):
"""从区域信息缓存里匹配到所在区域
Args:
target (str): 区域ID
cache (list):
Returns:
_type_: _description_
"""
for i in cache: for i in cache:
if i['id'] == target: if i['id'] == target:
return i return i
return None return None
def save_dahua_pic(pic: str): def save_dahua_pic(pic_url: str):
"""保存大华报警图片到本地 """保存大华报警图片到本地
返回本地路径 返回本地路径
""" """
file_name = pic.split('/')[-1] file_name = pic_url.split('/')[-1].split('?')[-1]
full_url = dhClient.get_full_pic(pic) res = requests.get(url=pic_url, verify=False)
res = requests.get(url=full_url, verify=False)
path = '/media/' + timezone.now().strftime('%Y/%m/%d/') path = '/media/' + timezone.now().strftime('%Y/%m/%d/')
full_path = settings.BASE_DIR + path full_path = settings.BASE_DIR + path
if not os.path.exists(full_path): if not os.path.exists(full_path):
@ -46,242 +55,274 @@ def save_dahua_pic(pic: str):
return path + file_name 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 algo_handle(codes: list, data: dict):
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()
@classmethod Args:
def dispatch_dahua_event(cls, data: dict): code (str): 算法标识列表
"""分发大华事件进行处理 data (dict): 需要处理的内容
""" """
vchannel_code = data['info']['nodeCode'] return ['helmet']
alarm_type = data['info']['alarmType']
vchannel = TDevice.objects.filter(code=vchannel_code).first()
print(data) def save_voice_and_speak(event: Event):
if alarm_type in [1001003, 1001000] and vchannel: # 内部人员/或陌生人报警 """生成并保存语音地址并喇叭播放
# 加载算法逻辑
# 安全帽检测 Args:
ec = EventCate.objects.filter(code='helmet').first() # 模拟发生安全帽事件 event (Event): _description_
# 视频区域 """
area = vchannel.area _, event.voice, _ = generate_voice(event.voice_msg, event.cates[0].voice_person)
if ec and area: event.save()
# 保存照片 sps = list(TDevice.objects.filter(area=event.area, type=TDevice.DEVICE_SPEAKER).values_list('code', flat=True))
face_img = save_dahua_pic(data['info']['alarmPicture']) if len(sps) == 0: # 如果当前区域没有喇叭就找覆盖区的喇叭
global_img = save_dahua_pic(data['info']['extend']['globalScenePicUrl']) 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 = Event()
event.face_img = face_img event.face_img = save_dahua_pic(face_img_o)
event.global_img = global_img event.global_img = save_dahua_pic(global_img_o)
event.area = area event.area = area
event.obj_cate = 'people' event.obj_cate = obj_cate
ep = None # 找到人员 event.vchannel = vchannel
if alarm_type == 1001003: voice_msg = ''
ep = Employee.objects.filter(id_number=data['info']['extend']['candidateInfo'][0]['id']).first()
if ep: if ep:
voice_msg = '位于{}{}{},您未佩戴安全帽,请及时处理'
ep_name = ep.name ep_name = ep.name
ep_type = '员工' ep_type = '员工'
if ep.type == 'rempoyee': if ep.type == 'rempoyee':
ep_type = '相关方人员' ep_type = '相关方人员'
elif ep.type == 'visitor': elif ep.type == 'visitor':
ep_type = '访客' ep_type = '访客'
event.voice_msg = voice_msg.format(area.name, ep_type, ep_name) voice_msg = '位于{}{}{},'.format(area.name, ep_type, ep_name)
else: 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.employee = ep
_, event.voice, _ = generate_voice(event.voice_msg, ec.voice_person)
event.save() event.save()
Eventdo.objects.get_or_create(cate=ec, event=event, defaults={ for i in ecs:
'cate': ec, Eventdo.objects.get_or_create(cate=i, event=event, defaults={
'event': event 'cate': i,
}) 'event': event
cls.create_remind_and_speak(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 dispatch_xunxi_event(data: dict):
def rail_in(cls, data): """分发寻息事件进行处理
"""围栏进入事件 """
""" if data.type == 'rail':
# 找到所在围栏 if data.data.type == 1:
area = Area.objects.filter(third_info__xx_rail__id=data['railId']).first() # 围栏进入
# 找到进入对象 rail_in(data=data.data)
blts = TDevice.objects.filter(code=data['userId']).first() elif data.data.type == 2:
if area and blts and blts.employee: # 如果是人 # 围栏离开
if area.type == Area.AREA_TYPE_FIX: rail_out(data=data.data)
# 更新人员位置信息缓存 elif data.type == 'onKeyAlarm':
key_str = 'ep_{}'.format(blts.employee.id) # 一键呼救
ep_loc_dict = cache.get_or_set( one_key_alarm(data=data)
key_str, cls.get_ep_default(), timeout=None elif data.type == 'location':
) # 定位信息
if ep_loc_dict['area_fix_id'] != area.id: # 如果区域未变化则不动 loc_change(data=data)
ep_loc_dict['time1'] = ep_loc_dict['time2'] elif data.type == 'onOffLine':
ep_loc_dict['area_fix_id'] = area.id if data.data.online:
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):
# 触发未知标签进入事件
pass pass
else:
@classmethod # 标签定位离线
def rail_out(cls, data):
pass
@classmethod
def low_power(cls, data):
# 有绑定对象再提示低电量
blts = TDevice.objects.filter(code=data['userId']).first()
if blts.employee:
# 触发低电量提醒事件
pass 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 rail_in(data):
def loc_change(cls, data): """围栏进入事件
blts = TDevice.objects.filter(code=data['userId']).first() """
if blts.employee: # 找到所在围栏
# 从缓存查询人员位置信息 area = Area.objects.filter(third_info__xx_rail__id=data['railId']).first()
time2 = int(time.time()) # 找到进入对象
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) key_str = 'ep_{}'.format(blts.employee.id)
ep_loc_dict = cache.get_or_set( 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 if ep_loc_dict['area_fix_id'] != area.id: # 如果区域未变化则不动
# 从缓存里获取固定区域列表信息 ep_loc_dict['time1'] = ep_loc_dict['time2']
area_fix_list = cache.get('area_fix_list', None) ep_loc_dict['area_fix_id'] = area.id
if not area_fix_list: cache.set(key_str, ep_loc_dict)
area_fix_list = cache_areas_info() ep_blt = blts.employee # 标签绑定人员
if ep_loc_dict.get('area_fix_id', None): if ep_blt:
# 如果存在所在固定区域 for i in Access.objects.filter(area=area).order_by('sort'):
area_info = get_area_info_from_cache(ep_loc_dict['area_fix_id'], area_fix_list) # 优先自定义权限过滤
if area_info: if i.post: # 如果是按岗位设定的
# 在该固定区域停留时间(分钟) eps_access = Employee.objects.filter(user__posts=i.post)
stay_minute = int((ep_loc_dict['time2']-ep_loc_dict['time1'])/60) if ep_blt in eps_access and i.type == Access.ACCESS_IN_YES:
# 判断停留时间是否合理
# 先通过自定义权限过滤(暂未做)
# 再经过通用设置过滤
if 0 < stay_minute < area_info['stay_minute_min']:
# 触发离岗事件
return 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 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: else:
for i in area_fix_list: # 触发非法进入事件
if data['floorNo'] == i['floor_no']: pass
point = shapely.geometry.Point(data['xMillimeter'], data['yMillimeter']) elif area and (not blts):
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 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 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

View File

@ -1,7 +1,8 @@
from email.mime import base
from django.urls import path, include from django.urls import path, include
from rest_framework import routers from rest_framework import routers
from apps.third.views import DahuaTestView, DhCommonViewSet, SpTestView, XxCommonViewSet, XxTestView 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/' API_BASE_URL = 'api/third/'
HTML_BASE_URL = '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('dahua', DhCommonViewSet, basename='api_dahua')
router.register('tdevice', TDeviceViewSet, basename='tdevice') router.register('tdevice', TDeviceViewSet, basename='tdevice')
router.register('tlog', TlogViewSet, basename='tlog') router.register('tlog', TlogViewSet, basename='tlog')
router.register('tdevice/blt', BltViewSet, basename='blt')
urlpatterns = [ urlpatterns = [
path(API_BASE_URL, include(router.urls)), path(API_BASE_URL, include(router.urls)),
path(API_BASE_URL + 'dahua/test/', DahuaTestView.as_view()), path(API_BASE_URL + 'dahua/test/', DahuaTestView.as_view()),

View File

@ -1,6 +1,6 @@
import json import json
from rest_framework.exceptions import ParseError, APIException 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.hrm.services import HrmService
from apps.third.tapis import dhapis, xxapis, spapis from apps.third.tapis import dhapis, xxapis, spapis
from apps.third.errors import TAPI_CODE_WRONG from apps.third.errors import TAPI_CODE_WRONG
@ -75,7 +75,7 @@ class XxListener(stomp.ConnectionListener):
def on_message(self, frame): def on_message(self, frame):
data = json.loads(frame.body) data = json.loads(frame.body)
EcmService.dispatch_xunxi_event(data) dispatch_xunxi_event(data)
print('received a message "%s"' % frame.body) 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() return Response()

View File

@ -1,7 +1,7 @@
from apps.third.models import TDevice, Tlog from apps.third.models import TDevice, Tlog
from apps.third.serializers import BindAreaSerializer, LabelLocationSerializer, TDeviceSerializer, TlogSerializer from apps.third.serializers import BindAreaSerializer, LabelLocationSerializer, TDeviceSerializer, TlogSerializer
from apps.utils.viewsets import CustomGenericViewSet 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.clients import xxClient, dhClient, spClient
from apps.third.tapis import xxapis, dhapis, spapis from apps.third.tapis import xxapis, dhapis, spapis
from rest_framework.response import Response from rest_framework.response import Response
@ -11,6 +11,17 @@ from apps.am.models import Area
from rest_framework.views import APIView 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): class TDeviceViewSet(ListModelMixin, CustomGenericViewSet):
""" """
三方设备接口 三方设备接口

View File

@ -29,7 +29,7 @@ def send_sms(phone: str, template_code: str, template_param: dict):
request.add_query_param('TemplateParam', json.dumps(template_param)) request.add_query_param('TemplateParam', json.dumps(template_param))
res = client.do_action(request) res = client.do_action(request)
res_dict = json.loads(str(res, encoding='utf-8')) 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: if res_dict['result'] == 0:
return True, res_dict return True, res_dict