Files
lzwcai-mcp/temi_mcpserver/temiRobot/mcp_mqtt.py

114 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import paho.mqtt.client as mqtt
import json
import logging
import threading
from typing import Optional
import uuid
import threading
import requests
from os import getenv
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
MQTT_CLIENT_ID = f"MCPMQTT-{uuid.uuid4().hex[:8]}"
def getConfig_url(array):
url = "http://lzwcai-demp-corp-manager:8086/system/config/getConfig"
data = [array]
try:
response = requests.post(url, json=data, timeout=5)
response.raise_for_status()
data = response.json()['data']
return data[0]['configValue']
except Exception as e:
print(f"Error fetching config for {array}: {e}")
return None
class MQTTHandler:
def __init__(self):
self.client = mqtt.Client()
self.tasks = {} # {task_id: task_data}
self._lock = threading.Lock()
# 获取MQTT配置提供默认值
self.mqtt_username = getenv('MQTT_USERNAME') or 'lzwc'
self.mqtt_password = getenv('MQTT_PASSWORD') or 'Lzwc@4187.'
mqtt_broker_raw = getenv('MQTT_BROKER') or 'tcp://dempmana.lzwcai.com'
# 移除协议前缀,只保留主机名
self.mqtt_broker = mqtt_broker_raw.replace('tcp://', '').replace('mqtt://', '')
mqtt_port_str = getenv('MQTT_PORT')
self.mqtt_port = int(mqtt_port_str) if mqtt_port_str else 1883
# 记录配置信息
logger.info(f"MQTT配置 - Broker: {self.mqtt_broker}, Port: {self.mqtt_port}, Username: {self.mqtt_username}")
if not getenv('MQTT_BROKER'):
logger.warning("MQTT_BROKER环境变量未设置使用默认值")
if not mqtt_port_str:
logger.warning("MQTT_PORT环境变量未设置使用默认端口1883")
self.client.username_pw_set(self.mqtt_username, self.mqtt_password)
self.client.on_connect = self._on_connect
self.client.on_message = self._on_message
self.client.on_disconnect = self._on_disconnect
try:
logger.info(f"正在连接 MQTT 代理: {self.mqtt_broker}:{self.mqtt_port}")
self.client.connect(self.mqtt_broker, self.mqtt_port, 60)
self.client.loop_start()
except Exception as e:
logger.error(f"连接 MQTT 失败: {e}")
def _on_connect(self, client, userdata, flags, rc):
"""MQTT 连接回调"""
if rc == 0:
logger.info("已成功连接到 MQTT 代理服务器")
else:
logger.error(f"连接 MQTT 代理服务器失败,返回码: {rc}")
def get_status(self, task_id: str = None):
"""获取任务状态
Args:
task_id: 可选参数指定任务ID。如果为None则返回所有任务状态
Returns:
如果指定task_id则返回该任务的状态否则返回所有任务状态
"""
with self._lock:
if task_id:
return self.tasks.get(task_id, {}).copy()
return {k: v.copy() for k, v in self.tasks.items()}
def _on_message(self, client, userdata, msg):
try:
payload = json.loads(msg.payload.decode())
logger.info(f"[MQTT] topic={msg.topic} msg: {payload}")
# task_id = payload.get('task_id')
# if task_id and task_id in self.tasks:
# with self._lock:
# self.tasks[task_id].update({
# 'status': payload.get('status', 'UNKNOWN'),
# 'description': payload.get('description', '')
# })
except Exception as e:
logger.error(f"[错误] 处理消息失败: {e}")
def _on_disconnect(self, client, userdata, rc):
"""MQTT 断开连接回调"""
if rc != 0:
logger.warning("意外断开与 MQTT 代理服务器的连接。")
try:
logger.info("尝试重新连接 MQTT...")
client.reconnect()
except Exception as e:
logger.error(f"重新连接 MQTT 失败: {e}")
# 单例模式
_instance: Optional[MQTTHandler] = None
def get_mcpmqtt_handler() -> MQTTHandler:
"""获取单例"""
global _instance
if _instance is None:
_instance = MQTTHandler()
return _instance