pc2_requests.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. """
  2. Author: zhaoyong 77912776@qq.com
  3. Date: 2025-08-23 14:37:39
  4. LastEditTime: 2025-08-23 20:43:45
  5. LastEditors: zhaoyong 77912776@qq.com
  6. FilePath: robot_ai/utils/pc2_requests.py
  7. Description: PC2网络请求模块 - 异步版本
  8. """
  9. import time
  10. import aiohttp
  11. import asyncio
  12. import threading
  13. from utils.logger import logger
  14. # 延迟加载配置,避免循环导入
  15. def _get_config():
  16. from config.config.settings import config
  17. return config
  18. def _get_api_urls():
  19. config = _get_config()
  20. return config.get_pc2_url('qa_callback'), config.get_pc2_url('led')
  21. API_QA_CALLBACK_URL, API_LED_URL = _get_api_urls()
  22. # 防重复调用机制
  23. _last_qa_request = {"time": 0, "content": ""}
  24. _last_led_request = {"time": 0, "mode": "", "color": ""}
  25. _REQUEST_INTERVAL = 0.5 # 请求间隔(秒)
  26. async def _send_qa_task_async(result):
  27. """将结果异步发送到外部接口--欣网前端"""
  28. headers = {
  29. "Content-Type": "application/json",
  30. "Authorization": "Bearer your_access_token"
  31. }
  32. logger.info(f"开始识别内容 result: {result}")
  33. # 组织 payload
  34. payload = {}
  35. if result.get("question"):
  36. payload = {
  37. "question": result["question"],
  38. "time": time.time(),
  39. }
  40. elif result.get("result"):
  41. payload = {
  42. "answer": result["result"],
  43. "time": time.time(),
  44. }
  45. logger.info(f"准备发送识别结果到 QA callBack 接口: {payload}")
  46. try:
  47. async with aiohttp.ClientSession() as session:
  48. async with session.post(API_QA_CALLBACK_URL, json=payload, headers=headers, timeout=5) as response:
  49. if response.status == 200:
  50. logger.info("结果已成功发送到 QA callBack 接口")
  51. return True
  52. else:
  53. text = await response.text()
  54. logger.error(f"接口返回错误状态码: {response.status}, 响应内容: {text}")
  55. return False
  56. except Exception as e:
  57. logger.error(f"QA callBack 接口请求失败: {e}")
  58. return False
  59. async def _send_led_color_task_async(mode, color):
  60. """异步改变灯带颜色"""
  61. payload = {"mode": mode, "color": color}
  62. try:
  63. async with aiohttp.ClientSession() as session:
  64. async with session.post(API_LED_URL, json=payload, timeout=5) as response:
  65. if response.status == 200:
  66. logger.info("灯带颜色设置成功")
  67. return True
  68. else:
  69. text = await response.text()
  70. logger.error(
  71. f"灯带颜色设置失败,状态码: {response.status}, 响应: {text}")
  72. return False
  73. except aiohttp.ClientConnectionError:
  74. logger.error("LED 接口调用失败,连接错误")
  75. return False
  76. except Exception as e:
  77. logger.error(f"LED 接口调用失败: {e}")
  78. return False
  79. def _send_qa_task(self, result):
  80. """同步包装器,用于兼容现有代码"""
  81. global _last_qa_request
  82. # 防重复调用检查
  83. current_time = time.time()
  84. content_hash = str(result)
  85. # 如果内容相同且时间间隔太短,跳过请求
  86. if (_last_qa_request["content"] == content_hash and
  87. current_time - _last_qa_request["time"] < _REQUEST_INTERVAL):
  88. logger.debug(f"跳过重复的QA请求: {result}")
  89. return True
  90. # 更新最后请求记录
  91. _last_qa_request["time"] = current_time
  92. _last_qa_request["content"] = content_hash
  93. def run_async():
  94. asyncio.run(_send_qa_task_async(result))
  95. # 在后台线程中运行异步函数,不阻塞主流程
  96. thread = threading.Thread(target=run_async, daemon=True)
  97. thread.start()
  98. return True
  99. def _send_led_color_task(self, mode, color):
  100. """同步包装器,用于兼容现有代码"""
  101. global _last_led_request
  102. # 防重复调用检查
  103. current_time = time.time()
  104. # 如果参数相同且时间间隔太短,跳过请求
  105. if (_last_led_request["mode"] == mode and
  106. _last_led_request["color"] == color and
  107. current_time - _last_led_request["time"] < _REQUEST_INTERVAL):
  108. logger.debug(f"跳过重复的LED请求: mode={mode}, color={color}")
  109. return True
  110. # 更新最后请求记录
  111. _last_led_request["time"] = current_time
  112. _last_led_request["mode"] = mode
  113. _last_led_request["color"] = color
  114. def run_async():
  115. asyncio.run(_send_led_color_task_async(mode, color))
  116. # 在后台线程中运行异步函数,不阻塞主流程
  117. thread = threading.Thread(target=run_async, daemon=True)
  118. thread.start()
  119. return True