from __future__ import absolute_import, unicode_literals import os from threading import Thread from channels.layers import get_channel_layer from asgiref.sync import async_to_sync from celery import shared_task import requests from apps.am.models import Area from apps.ecm.models import EventCate, Event from apps.opm.models import Opl from apps.third.dahua import dhClient from apps.third.xunxi import xxClient from apps.third.models import TDevice from apps.third.tapis import xxapis from django.utils import timezone import time from django.core.cache import cache from django.conf import settings from apps.utils.tasks import CustomTask from apps.ecm.models import AlgoChannel from datetime import timedelta from apps.ai.main import algo_dict from datetime import datetime import uuid from apps.ecm.serializers import EventSerializer from django.utils import timezone from django.core.exceptions import ObjectDoesNotExist @shared_task(base=CustomTask) def store_img(code: str, duration: int): while True: global_img = dhClient.snap(code) file_name = global_img.split('/')[-1].split('?')[0] res = requests.get(url=global_img, verify=False) path = '/media/temp/store_img/' 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) time.sleep(duration) def update_count_people(i: Area): from apps.ecm.service import handle_xx_event_3 if i.third_info.get('xx_rail', None): railId = i.third_info['xx_rail']['id'] json = {"railId": railId, "type": ""} _, res = xxClient.request(**xxapis['rail_ibeacon_list'], json=json) blt_list = res['recordList'] macs = [] for m in blt_list: macs.append(m['userId']) count_people = TDevice.objects.filter( type=TDevice.DEVICE_BLT, obj_cate='people', code__in=macs).exclude(employee=None).count() i.count_people = count_people i.save() if count_people >= i.count_people_max: # 触发超员事件 handle_xx_event_3('over_man', i) elif count_people < i.count_people_min: # 触发缺员事件 handle_xx_event_3('lack_man', i) return {'count': count_people} @shared_task def cal_area_count(): """ 计算区域内人员数量 """ areas = Area.objects.filter(type=Area.AREA_TYPE_FIX) for i in areas: update_count_people(i) @shared_task def check_event_timeout(): """判断事件处理是否超期 """ for i in Event.objects.filter(handle_user=None, is_timeout=False): cate = i.cates.all().order_by('priority', 'create_time').first() if cate and cate.handle_minute > 0 and (timezone.now()-i.create_time).seconds > cate.handle_minute * 60: i.is_timeout = True i.save() @shared_task def opl_task(vc_codes: list, opl_id: str): """作业监控任务(废弃) """ from apps.ecm.service import snap_and_analyse start_time = time.time() opl_cate = Opl.objects.get(id=opl_id).cate # 找到作业需要加载的算法 algo_codes = list(EventCate.objects.filter(opl_cates=opl_cate).values_list('code', flat=True)) vchannels = TDevice.objects.filter(code__in=vc_codes) opl = Opl.objects.get(id=opl_id) while time.time()-start_time < 10800: # 一次任务不手动关闭最多持续3小时 for i in vchannels: Thread(target=snap_and_analyse, args=(i, algo_codes, opl), daemon=True).start() time.sleep(10) opl.mtask_uid = None opl.save() @shared_task(base=CustomTask) def monitor_check(vc_ids = []): """ 监控任务监控重启/可每隔一段时间执行一次 """ if vc_ids: vcs = TDevice.objects.filter(id__in=vc_ids, type=TDevice.DEVICE_VCHANNEL) else: vcs = TDevice.objects.filter(ac_vchannel__always_on=True, type=TDevice.DEVICE_VCHANNEL) for vc in vcs: # 获取每一个要开启的视频通道 algo_codes = AlgoChannel.objects.filter(vchannel=vc, always_on=True).values_list('algo__code', flat=True) ckey = 'vchannel_' + vc.id if algo_codes: tid = str(uuid.uuid4()) cache.set(ckey, {'id': tid, 'algo_codes': algo_codes, 'start_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S")}, timeout=60) Thread(target=loop_and_analyse, args=(vc, tid), daemon=True).start() else: cache.delete(ckey) @shared_task(base=CustomTask) def loop_and_analyse(vc: TDevice, tid: str): from apps.ecm.service import snap_and_analyse ckey = 'vchannel_' + vc.id while cache.get(ckey, {}).get('id', None) == tid: vc_dict = cache.get(ckey, {}) if 'algo_codes' in vc_dict: intersection = list(set(vc_dict['algo_codes']) & set(algo_dict.keys())) # 取布设与算法的交集 if intersection: Thread(target=snap_and_analyse, args=(vc, intersection), daemon=True).start() time.sleep(10) @shared_task(base=CustomTask) def monitor_and_analyse(vchannel_code: str, algo_codes: list): """rtsp流监控进行算法识别 Args: vchannel_code (str): 视频通道编号 algo_codes (list): 算法代号 """ # cates = EventCate.objects.filter(loop_on=True, self_algo=True) # AlgoChannel.objects.filter(algo__loop_on=True, algo__self_algo=True).values('algo__code', 'vchannel') import cv2 # RTSP URL rtsp_url = dhClient.get_rtsp(vchannel_code) # 打开RTSP流 cap = cv2.VideoCapture(rtsp_url) # 检查是否成功打开 if not cap.isOpened(): print("Error opening video stream or file") # 循环读取帧 while cap.isOpened(): ret, frame = cap.read() if not ret: break # 在这里可以对每一帧进行处理 # 显示帧 cv2.namedWindow("Frame", 0) cv2.resizeWindow("Frame", 1600, 900) cv2.imshow("Frame", frame) # 按 'q' 键退出 if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放资源 cap.release() cv2.destroyAllWindows() @shared_task(base=CustomTask) def compressed_all_ecm_image(): from apps.ecm.service import compress_global_img events = Event.objects.exclude(global_img=None) for event in events: if event.global_img and event.global_img_compressed is None: event.global_img_compressed = compress_global_img(event.global_img) event.save() @shared_task(base=CustomTask) def remind_push(remindId: str): from apps.ecm.models import Remind from apps.ecm.serializers import RemindSerializer remind = Remind.objects.get(id=remindId) channel_layer = get_channel_layer() data = { 'type': 'remind', 'remind': RemindSerializer(instance=remind).data, 'msg': '' } async_to_sync(channel_layer.group_send)(f"user_{remind.recipient.id}", data) @shared_task(base=CustomTask) def event_push(eventId: str): try: event = Event.objects.get(id=eventId) except ObjectDoesNotExist: return if event.handle_time is None: now = timezone.now() channel_layer = get_channel_layer() data = { 'type': 'event', 'event': EventSerializer(instance=event).data, 'msg': '' } async_to_sync(channel_layer.group_send)('event', data) event.last_ws_pushtime = timezone.now() event.save() main_cate = event.cates.all().order_by('priority', 'create_time').first() unhandled_push_interval = main_cate.unhandled_push_interval event_push.apply_async(args=[eventId], eta=now + timedelta(seconds=unhandled_push_interval))