libushang 5 mesiacov pred
rodič
commit
eb269d6add

+ 324 - 0
common/AvconMiniAPI.py

@@ -0,0 +1,324 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import requests
+import string
+import random
+import json
+from utils import *
+from utils.redis_util import *
+
+app_id = "820e2aa3903e46939abde098409319e1"
+secret= "92659e6e0dd3c550952df7c95a483d56"
+
+'''
+融合通信Mini客户端对接
+U8 OpenAPI使用说明书
+'''
+
+API_ROOT = "http://19.152.196.106:12030/avcon-api"
+
+def get_nonce(length: int = 10) -> str:
+    characters = string.ascii_letters + string.digits
+    # 随机选择字符集的长度个字符
+    random_string = ''.join(random.choice(characters) for _ in range(length))
+    return random_string
+
+
+def get_sign_data(nonce: str, timestamp: str, uri: str, query: str = None, body: dict = None) -> str:
+    data = nonce + str(timestamp) + str(uri)
+    if query is not None:
+        data = data + query
+    if body is not None:
+        data = data + json.dumps(body, ensure_ascii=False)
+    
+    sign_data = md5(data)
+    
+    print('data:', data)
+    print('sign_data:', sign_data)
+    return sign_data
+
+# 3.1 获得Token
+def get_auth_token():
+    nonce = get_nonce()
+    timestamp = str(unixstamp())
+    uri = "/oauth/token"
+    query = "app_id="+app_id+"&secret="+secret
+
+    sign_data = get_sign_data(nonce, timestamp, uri, query)
+    headers = {
+        "Content-Type": 'application/json',
+        "X-Nonce": nonce,
+        "X-Timestamp": timestamp,
+        "X-Signature": sign_data
+    }
+    response = requests.get(API_ROOT + uri + "?" + query, headers=headers, timeout=15)
+    print(response.text)
+    if response.status_code == 200:
+        result = response.json()
+        if result['code'] == 0:
+            data = result['data']
+            return data['token']
+        
+def get_redis_token():
+    redis_key = "avcon_mini_api_token"
+    token_val = redis_get(redis_key)
+    if token_val is None:
+        token_val = get_auth_token()
+        if token_val is not None:
+            redis_set_with_time(redis_key, token_val, 300)
+
+    print('auth_token:', token_val)
+    return token_val
+
+# 4.1 查询配置项
+def get_config(name: str):
+    token = get_redis_token()
+    nonce = get_nonce()
+    timestamp = str(unixstamp())
+    uri = "/open/api/v1/config/" + name
+
+    sign_data = get_sign_data(nonce, timestamp, uri)
+    headers = {
+        "Content-Type": 'application/json',
+        "Authorization": token,
+        "X-Nonce": nonce,
+        "X-Timestamp": timestamp,
+        "X-Signature": sign_data
+    }
+    response = requests.get(API_ROOT + uri, headers=headers, timeout=15)
+    
+    if response.status_code == 200:
+        result = response.json()
+        if result['code'] == 0:
+            data = result['data']
+            return data
+    else:
+        print(response.text)   
+
+# 5.1 查询区域
+def get_group(group_id: str = 'G1@mm.zw.yj'):
+    token = get_redis_token()
+    nonce = get_nonce()
+    timestamp = str(unixstamp())
+    uri = "/open/api/v1/monitor-room-group/" + group_id
+
+    sign_data = get_sign_data(nonce, timestamp, uri)
+    headers = {
+        "Content-Type": 'application/json',
+        "Authorization": token,
+        "X-Nonce": nonce,
+        "X-Timestamp": timestamp,
+        "X-Signature": sign_data
+    }
+    response = requests.get(API_ROOT + uri, headers=headers, timeout=15)
+    
+    if response.status_code == 200:
+        result = response.json()
+        if result['code'] == 0:
+            data = result['data']
+            return data
+    else:
+        print(response.text)   
+
+# 5.2 查询区域分页
+def get_group_page():
+    token = get_redis_token()
+    nonce = get_nonce()
+    timestamp = str(unixstamp())
+    uri = "/open/api/v1/monitor-room-group/page"
+    query = "page_num=1&page_size=100"
+
+    sign_data = get_sign_data(nonce, timestamp, uri, query)
+    headers = {
+        "Content-Type": 'application/json',
+        "Authorization": token,
+        "X-Nonce": nonce,
+        "X-Timestamp": timestamp,
+        "X-Signature": sign_data
+    }
+    response = requests.get(API_ROOT + uri + "?" + query, headers=headers, timeout=15)
+    
+    if response.status_code == 200:
+        result = response.json()
+        if result['code'] == 0:
+            data = result['data']
+            return data
+    else:
+        print(response.text)
+
+# 5.3 查询区域的设备分页
+def get_group_device(group_id: str):
+    token = get_redis_token()
+    nonce = get_nonce()
+    timestamp = str(unixstamp())
+    uri = "/open/api/v1/monitor-room-group/" + group_id + "/device/page"
+    query = "page_num=1&page_size=100"
+
+    sign_data = get_sign_data(nonce, timestamp, uri, query)
+    headers = {
+        "Content-Type": 'application/json',
+        "Authorization": token,
+        "X-Nonce": nonce,
+        "X-Timestamp": timestamp,
+        "X-Signature": sign_data
+    }
+    response = requests.get(API_ROOT + uri + "?" + query, headers=headers, timeout=15)
+    
+    if response.status_code == 200:
+        result = response.json()
+        if result['code'] == 0:
+            data = result['data']
+            return data
+    else:
+        print(response.text)
+
+
+# 6.1 查询设备
+def get_device_info(dev_id: str):
+    token = get_redis_token()
+    nonce = get_nonce()
+    timestamp = str(unixstamp())
+    uri = "/open/api/v1/device/" + dev_id
+
+    sign_data = get_sign_data(nonce, timestamp, uri)
+    headers = {
+        "Content-Type": 'application/json',
+        "Authorization": token,
+        "X-Nonce": nonce,
+        "X-Timestamp": timestamp,
+        "X-Signature": sign_data
+    }
+    response = requests.get(API_ROOT + uri, headers=headers, timeout=15)
+    
+    if response.status_code == 200:
+        result = response.json()
+        if result['code'] == 0:
+            data = result['data']
+            return data
+    else:
+        print(response.text)
+
+
+# 6.2 查询设备分页
+def get_device_all():
+    token = get_redis_token()
+    nonce = get_nonce()
+    timestamp = str(unixstamp())
+    uri = "/open/api/v1/device/page"
+
+    json_data = {
+        "domain": "mm.zw.yj"
+    }
+    query = "json="+json.dumps(json_data, ensure_ascii=False) + "&page_num=1&page_size=1000"
+
+    sign_data = get_sign_data(nonce, timestamp, uri, query)
+    headers = {
+        "Content-Type": 'application/json',
+        "Authorization": token,
+        "X-Nonce": nonce,
+        "X-Timestamp": timestamp,
+        "X-Signature": sign_data
+    }
+    response = requests.get(API_ROOT + uri + "?" + query, headers=headers, timeout=15)
+    
+    if response.status_code == 200:
+        result = response.json()
+        if result['code'] == 0:
+            data = result['data']
+            return data
+    else:
+        print(response.text)
+
+
+# 6.3 查询设备的通道分页
+def get_device_channel(dev_id: str):
+    token = get_redis_token()
+    nonce = get_nonce()
+    timestamp = str(unixstamp())
+    uri = "/open/api/v1/device/" + dev_id + "/channel/page"
+
+    json_data = {
+        "domain": "mm.zw.yj"
+    }
+    query = "json="+json.dumps(json_data, ensure_ascii=False) + "&page_num=1&page_size=1000"
+
+    sign_data = get_sign_data(nonce, timestamp, uri, query)
+    headers = {
+        "Content-Type": 'application/json',
+        "Authorization": token,
+        "X-Nonce": nonce,
+        "X-Timestamp": timestamp,
+        "X-Signature": sign_data
+    }
+    response = requests.get(API_ROOT + uri + "?" + query, headers=headers, timeout=15)
+    
+    if response.status_code == 200:
+        result = response.json()
+        if result['code'] == 0:
+            data = result['data']
+            return data
+    else:
+        print(response.text)
+
+
+# 6.4 查询设备的通道GPS位置分页
+def get_device_channel_gps(dev_id: str):
+    token = get_redis_token()
+    nonce = get_nonce()
+    timestamp = str(unixstamp())
+    uri = "/open/api/v1/device/" + dev_id + "/channel-gps-point"
+
+    sign_data = get_sign_data(nonce, timestamp, uri)
+    headers = {
+        "Content-Type": 'application/json',
+        "Authorization": token,
+        "X-Nonce": nonce,
+        "X-Timestamp": timestamp,
+        "X-Signature": sign_data
+    }
+    response = requests.get(API_ROOT + uri, headers=headers, timeout=15)
+
+    if response.status_code == 200:
+        result = response.json()
+        if result['code'] == 0:
+            data = result['data']
+            return data
+        else:
+            print(response.text)
+    else:
+        print(response.text)
+
+
+# 7.1 查询通道
+
+# 7.2 查询通道分页
+def get_channel_all():
+    token = get_redis_token()
+    nonce = get_nonce()
+    timestamp = str(unixstamp())
+    uri = "/open/api/v1/device-channel/page"
+
+    json_data = {
+        "domain": "mm.zw.yj"
+    }
+    query = "json="+json.dumps(json_data, ensure_ascii=False) + "&page_num=1&page_size=1000"
+
+    sign_data = get_sign_data(nonce, timestamp, uri, query)
+    headers = {
+        "Content-Type": 'application/json',
+        "Authorization": token,
+        "X-Nonce": nonce,
+        "X-Timestamp": timestamp,
+        "X-Signature": sign_data
+    }
+    response = requests.get(API_ROOT + uri + "?" + query, headers=headers, timeout=15)
+    
+    if response.status_code == 200:
+        result = response.json()
+        if result['code'] == 0:
+            data = result['data']
+            return data
+    else:
+        print(response.text)
+
+# 7.3 查询通道GPS位置

+ 1 - 0
common/AvconWebService.py

@@ -9,6 +9,7 @@ from pprint import pprint
 
 '''
 融合通信WEB服务对接
+废弃 2024-12-10**************
 '''
 
 def get_aws_service():

+ 1 - 1
jobs/__init__.py

@@ -22,7 +22,7 @@ def register_jobs(scheduler: BaseScheduler):
     # scheduler.add_job(wdgh_proc, next_run_time=(datetime.now() + timedelta(seconds=13)))
     # scheduler.add_job(wdyy_proc, CronTrigger.from_crontab('0 * * * *'))
 
-    scheduler.add_job(avcon_proc, next_run_time=(datetime.now() + timedelta(seconds=15)))
+    # scheduler.add_job(avcon_proc, next_run_time=(datetime.now() + timedelta(seconds=15)))
     scheduler.add_job(avcon_proc, CronTrigger.from_crontab('0 0 * * *'))
 
 def tick():

+ 78 - 51
routers/api/videoResource/avcon.py

@@ -11,8 +11,9 @@ from utils.video_util import *
 from common.security import valid_access_token
 from fastapi.responses import JSONResponse
 import traceback
+import base64
 from datetime import datetime
-from common import AvconH5API
+from common import AvconH5API, AvconMiniAPI
 from models import *
 
 '''
@@ -25,60 +26,86 @@ router = APIRouter()
 async def get_video_list(
     db: Session = Depends(get_db)
 ):
-    '''
-    rows = db.query(AvconDevice).all()
-    dev_list = []
-    for row in rows:
-        dev_list.append(get_model_dict(row))
-    return dev_list
-    '''
     return AvconH5API.get_channel_all()
 
-    '''
-    以下代码已迁移到job里面,每1个小时刷新一次,仅供API接口调用参考,可以删除
-    dev_list = []
-    region_list = AvconH5API.get_region()
-    if region_list is not None:
-        for region_item in region_list:
-
-            region_id = region_item['region_id']
-            region_name = region_item['region_name']
-            region_group_list = AvconH5API.get_group(region_id)
-            
-            if region_group_list is not None:                
-                for region_group_item in region_group_list:
-
-                    group_id = region_group_item['group_id']
-                    group_name = region_group_item['group_name']
-
-                    # 子节点下面才有事业部
-                    child_count = region_group_item['child_count']
-                    if child_count > 0:
-                        child_region_group_list = AvconH5API.get_group(region_id, group_id)
-                        if child_region_group_list is not None:                
-                            for child_region_group_item in child_region_group_list:
-                                child_group_id = child_region_group_item['group_id']
-                                child_group_name = child_region_group_item['group_name']
-
-                                device_list = AvconH5API.get_group_device(child_group_id)
-                                if device_list is not None:
-                                    for device_item in device_list:
-                                        dev_id = device_item['dev_id']
-                                        dev_name = device_item['dev_name']
-                                        device_item['parent_group_id'] = group_id
-                                        dev_list.append(device_item)
+@router.get('/get_mini_video_list')
+async def get_mini_video_list(
+    db: Session = Depends(get_db)
+):
+    # domain = AvconMiniAPI.get_config("DOMAIN")
+    # rsa_public_key = AvconMiniAPI.get_config("RSA_PUBLIC_KEY")
+    # return domain + " / " + rsa_public_key
 
-    
-    if len(dev_list) > 0:
-        db.query(AvconDevice).delete()
-        db.commit()
+    # return AvconMiniAPI.get_group_page()
+
+    # return AvconMiniAPI.get_group_device("G6@mm.zw.yj")
+
+    # return AvconMiniAPI.get_device_info("19.152.196.150@mm.zw.yj")
+
+    # return AvconMiniAPI.get_device_all()
+
+    # return AvconMiniAPI.get_device_channel("19.152.196.150@mm.zw.yj")
+
+    # return AvconMiniAPI.get_device_channel_gps("19.152.196.150@mm.zw.yj")
 
-        for n in dev_list:
-            new_dev = AvconDevice(**n)
-            db.add(new_dev)
-        db.commit()
+    return AvconMiniAPI.get_channel_all()
 
-    return dev_list
-    '''
 
+@router.post("/get_start_mini_param")
+async def get_start_mini_param(
+    body = Depends(remove_xss_json),
+    db: Session = Depends(get_db)
+):
+    userid = get_req_param(body, "userid")
+    password = "123"
+
+    # 自动入会时的会议ID,若不传roomid或roomid为空,则程序会自动召开一个会议,并将dev-list对应的人员拉入会议中
+    roomid = get_req_param_optional(body, "roomid")
+
+    # 进入会议后需要广播的人员列表
+    dev_list = get_req_param(body, "dev-list")
+
+    params = {
+        "mode": "mini",
+        "cmd": "enterroom",
+        "serverip": "19.152.196.106",
+        "userid": userid,
+        "password": password,
+        "roomid": roomid,
+        "windowpos": {"x": 0,"y": 0,"width": 1000,"height": 700,"top": True},
+        "members": {
+            "num": 10,
+            "dev-list": [
+                {
+                    "id": "cs0030@xf"
+                },
+                {
+                    "id": "cs0028@xf",
+                    "avtype": "a"
+                }
+            ],
+            "sip-list": [
+                {
+                    "id": "60002"
+                },
+                {
+                    "id": "60008",
+                    "avtype": "a"
+                }
+            ]
+        }
+    }
+
+    params['members']['num'] = len(dev_list)
+    params['members']['dev-list'] = dev_list
+    
+    logger.info("发起融合通信mini客户端: {}", params)
+
+    json_str = json.dumps(params, ensure_ascii=False)
+    base64_str = base64.b64encode(json_str.encode('utf-8')).decode('utf-8')
 
+    return {
+        "code": 0,
+        "msg": "success",
+        "data": "" + "avcon6://" + base64_str
+    }