优化quart接口。优化添加设备逻辑。

This commit is contained in:
2025-11-26 16:18:02 +08:00
parent 0a200cfc6f
commit 648f6cdfee
2 changed files with 77 additions and 92 deletions

View File

@@ -4,12 +4,10 @@ import socket
import threading
import time
import subprocess
from typing import Dict, Optional
from typing import Dict
import tidevice
import wda
from tidevice import Usbmux, ConnectionType
from Entity.DeviceModel import DeviceModel
from Entity.Variables import WdaAppBundleId, wdaFunctionPort
from Module.FlaskSubprocessManager import FlaskSubprocessManager
@@ -71,31 +69,33 @@ class DeviceInfo:
LogManager.method_info("进入主循环", "listen", udid="system")
print("[Listen] 开始监听设备上下线...")
last_broadcast = 0.0 # 用来做“心跳全量同步”的时间戳
while True:
try:
usb = Usbmux().device_list()
online = {d.udid for d in usb if d.conn_type == ConnectionType.USB}
except Exception as e:
LogManager.warning(f"[device_list] 异常:{e}", udid="system")
time.sleep(1)
continue
print("[Listen] device_list 出错,本轮视为无设备,防止状态脏死")
usb = []
online = set()
with self._lock:
known = set(self._models.keys())
# 1. 新设备
# ---------- 1. 新设备 ----------
now = time.time()
for udid in online:
self._last_seen[udid] = time.time()
self._last_seen[udid] = now
if udid not in known:
try:
self._add_device(udid)
except Exception as e:
# 单设备异常不能干掉整个循环
LogManager.warning(f"[Add] 处理设备 {udid} 异常: {e}", udid=udid)
print(f"[Add] 处理设备 {udid} 异常: {e}")
# 2. 可能离线设备
now = time.time()
# ---------- 2. 可能离线设备 ----------
for udid in list(known):
if udid not in online:
last = self._last_seen.get(udid, 0)
@@ -106,6 +106,15 @@ class DeviceInfo:
LogManager.method_error(f"移除失败:{e}", "listen", udid=udid)
print(f"[Remove] 移除失败 {udid}: {e}")
# ---------- 3. 心跳:每 5 秒强制同步一次到 Flask ----------
if now - last_broadcast > 5.0:
try:
self._manager_send()
except Exception as e:
print(f"[Listen] 周期同步到 Flask 失败: {e}")
else:
last_broadcast = now
time.sleep(1)
# ==========================
@@ -216,7 +225,6 @@ class DeviceInfo:
# 给 WDA 一点启动缓冲时间
time.sleep(2.0)
for _ in range(max_retry):
# 设备已移除就不再尝试
with self._lock:

View File

@@ -469,20 +469,38 @@ async def passAnchorData():
needReply = data.get("needReply", False)
# 获取打招呼数据
ev.prologueList = data.get("prologueList", [])
needTranslate = data.get("needTranslate", False)
# 添加主播数据
addModelToAnchorList(acList)
# 启动线程,执行脚本
failed_ids = []
# 启动线程,执行脚本(单个设备异常不影响其它设备)
for udid in idList:
manager = ScriptManager()
event = threading.Event()
# 启动脚本
thread = threading.Thread(target=manager.safe_greetNewFollowers,
args=(udid, needReply, isComment, needTranslate, event,))
# 添加到线程管理
ThreadManager.add(udid, thread, event)
try:
manager = ScriptManager()
event = threading.Event()
thread = threading.Thread(
target=manager.safe_greetNewFollowers,
args=(udid, needReply, isComment, needTranslate, event,),
)
ThreadManager.add(udid, thread, event)
except Exception as e:
failed_ids.append(udid)
LogManager.error(f"[passAnchorData] 设备 {udid} 启动脚本失败: {e}")
# 如果所有设备都失败,可以考虑返回错误码
if failed_ids and len(failed_ids) == len(idList):
return ResultData(
data="",
code=1001,
message=f"所有设备启动失败: {failed_ids}"
).toJson()
# 部分失败也算整体成功,只是记录一下
if failed_ids:
LogManager.warning(f"[passAnchorData] 部分设备启动失败: {failed_ids}")
return ResultData(data="").toJson()
except Exception as e:
LogManager.error(e)
@@ -493,6 +511,7 @@ async def followAndGreetUnion():
try:
LogManager.method_info("关注打招呼", "关注打招呼(联盟号)")
data: Dict[str, Any] = await request.get_json()
# 设备列表
idList = data.get("deviceList", [])
# 主播列表
@@ -503,29 +522,45 @@ async def followAndGreetUnion():
# 是否需要回复
needReply = data.get("needReply", True)
needTranslate = data.get("needTranslate", False)
# 获取打招呼数据
ev.prologueList = data.get("prologueList", [])
# 添加主播数据
addModelToAnchorList(acList)
# 启动线程,执行脚本
failed_ids = []
# 启动线程,执行脚本(单个设备异常不影响其它设备)
for udid in idList:
manager = ScriptManager()
event = threading.Event()
# 启动脚本
thread = threading.Thread(target=manager.safe_followAndGreetUnion,
args=(udid, needReply, needTranslate, event))
# 添加到线程管理
ThreadManager.add(udid, thread, event)
try:
manager = ScriptManager()
event = threading.Event()
thread = threading.Thread(
target=manager.safe_followAndGreetUnion,
args=(udid, needReply, needTranslate, event),
)
ThreadManager.add(udid, thread, event)
except Exception as e:
failed_ids.append(udid)
LogManager.error(f"[followAndGreetUnion] 设备 {udid} 启动脚本失败: {e}")
# 如果所有设备都失败,可以返回错误码
if failed_ids and len(failed_ids) == len(idList):
return ResultData(
data="",
code=1001,
message=f"所有设备启动失败: {failed_ids}",
).toJson()
# 部分失败也算整体成功,只是记录一下
if failed_ids:
LogManager.warning(f"[followAndGreetUnion] 部分设备启动失败: {failed_ids}")
return ResultData(data="").toJson()
except Exception as e:
LogManager.error(e)
LogManager.error(f"[followAndGreetUnion] 接口级异常: {e}")
return ResultData(data="", code=1001).toJson()
# 获取私信数据
@@ -824,64 +859,6 @@ async def getDeviceNetStatus():
return ResultData(data=value, code=200).toJson()
@app.route('/test', methods=['POST'])
def test():
import wda
import cv2
import numpy as np
# 设备的UDID
udid = "00008110-000120603C13801E"
# 连接到设备
client = wda.USBClient(udid)
session = client.session()
# 设置Appium的截图深度
session.appium_settings({"snapshotMaxDepth": 15})
# 获取当前屏幕截图
screenshot = session.screenshot()
screenshot = cv2.imdecode(np.frombuffer(screenshot, np.uint8), cv2.IMREAD_COLOR)
# 读取大图和小图
large_image = screenshot # 这里使用截图作为大图
template = cv2.imread(r'E:\python\Scrcpy_test\open-cv-tk\insert_comment.png', 0) # 0 表示以灰度模式读取
# 检查图像是否成功加载
if template is None:
print("小图加载失败,请检查路径")
exit()
# 获取模板的宽度和高度
w, h = template.shape[::-1]
# 使用模板匹配方法
result = cv2.matchTemplate(large_image, template, cv2.TM_CCOEFF_NORMED)
# 设定阈值
threshold = 0.8
loc = np.where(result >= threshold)
# 遍历所有匹配点
if loc[0].size > 0: # 检查是否有匹配点
for pt in zip(*loc[::-1]): # 将坐标转换为 (x, y) 格式
cv2.rectangle(large_image, pt, (pt[0] + w, pt[1] + h), (0, 255, 0), 2)
print(f"找到匹配区域,坐标:{pt},尺寸:{(w, h)}")
else:
print("未找到匹配区域,请检查模板和大图的内容,或调整阈值")
# 保存结果
cv2.imwrite('matched_result.png', large_image)
# 显示结果
cv2.imshow('Matched Result', large_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 关闭会话
session.close()
# 获取ai配置
@app.route("/getAiConfig", methods=['GET'])
def getAiConfig():