Sfoglia il codice sorgente

增加请求MQTT下发快照指令

zhuo 3 settimane fa
parent
commit
ca3ce2182b
1 ha cambiato i file con 104 aggiunte e 2 eliminazioni
  1. 104 2
      controller/index.py

+ 104 - 2
controller/index.py

@@ -5,10 +5,10 @@ import threading
 import time
 from collections import OrderedDict
 from datetime import datetime
-
 import requests
 from django.http import JsonResponse
 from django.shortcuts import render
+from django.views import View
 from django.views.generic import TemplateView
 
 from azoauth.config import *
@@ -18,7 +18,7 @@ from object.ResObject import ResObject
 from object.ResponseObject import ResponseObject
 from object.tkObject import tkObject
 from service.CommonService import CommonService
-
+import uuid
 
 class authView(TemplateView):
     def post(self, request, *args, **kwargs):
@@ -979,3 +979,105 @@ class VesseTest(TemplateView):
         except Exception as e:
             print(e)
             return response.json(500, repr(e))
+
+def get_domain_by_region(region):
+    if region == 'EU':
+        return SERVER_PREFIX_EU
+    if region == 'CN':
+        return SERVER_PREFIX_TEST
+    return SERVER_PREFIX
+
+def get_uuid():
+    return str(uuid.uuid4())
+
+class GetSnapshotView(View):
+    def post(self, request):
+        logger = logging.getLogger('django')
+        try:
+            data = json.loads(request.body)
+            endpoint_id = data['endpoint_id']
+            access_token = data['access_token']
+            correlation_token = data.get('correlation_token', '')
+            region = data.get('region', 'US')
+            if not endpoint_id or not access_token:
+                raise ValueError("endpoint_id 或 access_token 为空")
+
+        except Exception as e:
+            logger.error(f"参数解析/校验失败: {e}")
+            return JsonResponse({'error': 'BAD_REQUEST'}, status=400)
+
+        try:
+            user = UserModel.objects.get(access_token=access_token)
+        except UserModel.DoesNotExist:
+            return JsonResponse({'error': 'INVALID_TOKEN'}, status=401)
+
+        # 验证设备归属
+        if not user.uid_rtsp.filter(uid=endpoint_id).exists():
+            return JsonResponse({'error': 'NO_SUCH_DEVICE'}, status=403)
+
+        # 获取设备信息
+        device = user.uid_rtsp.get(uid=endpoint_id)
+        password = device.password or ''
+        region = getattr(device, 'region', region)
+        rtsp_path = device.rtsp_url
+
+        rtsp_domain = get_domain_by_region(region).split('//')[-1]
+        rtsp_url = f'rtsp://{rtsp_domain}:8554/{rtsp_path}'
+
+        if '_' in endpoint_id:
+            uid_base, channel = endpoint_id.rsplit('_', 1)
+        else:
+            uid_base = endpoint_id
+            channel  = '0'
+
+        logger.info(f"[GetSnapshot] uid={uid_base}, channel={channel}, region={region}")
+
+        domain_name = get_domain_by_region(region)
+
+        # 启动线程异步下发快照指令
+        threading.Thread(
+            target=self.send_snapshot_command,
+            args=(domain_name, uid_base, password, rtsp_url, channel, logger),
+            daemon=True
+        ).start()
+        logger.info(f"[GetSnapshot] 已启动快照指令线程 → domain={domain_name}, UID={uid_base}")
+
+        #  返回 DeferredResponse
+        return JsonResponse({
+            "event": {
+                "header": {
+                    "namespace": "Alexa",
+                    "name": "DeferredResponse",
+                    "messageId": get_uuid(),
+                    "correlationToken": correlation_token,
+                    "payloadVersion": "3"
+                },
+                "endpoint": {
+                    "endpointId": endpoint_id
+                },
+                "payload": {
+                    "estimatedDeferralInSeconds": 7
+                }
+            }
+        })
+
+    def send_snapshot_command(self, domain_name, uid, password, rtsp_url, channel, logger):
+
+        url = f'{domain_name}/iot/requestPublishMessage'
+        payload = {
+            'UID': uid,
+            'rtsp': rtsp_url,
+            'enable': '1',
+            'channel': channel
+        }
+        try:
+            resp = requests.post(url, data=payload, timeout=10)
+            if resp.status_code != 200:
+                logger.error(f"[send_snapshot] {url} 返回 HTTP {resp.status_code}")
+                return
+            data = resp.json()
+            logger.info(f"[send_snapshot] 响应({url}): {data}")
+            if data.get('result_code') != 0:
+                logger.error(f"[send_snapshot] 下发失败, result_code={data.get('result_code')}")
+        except Exception as ex:
+            logger.error(f"[send_snapshot] 请求异常: {ex}")