mqtt_client.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import paho.mqtt.client as mqtt
  2. import json
  3. import logging
  4. from typing import Callable
  5. class MQTTClient:
  6. def __init__(self, config, on_message_callback: Callable[[str, dict], None]):
  7. self.config = config
  8. self.on_message_callback = on_message_callback
  9. self.client = mqtt.Client()
  10. self.client.on_connect = self._on_connect
  11. self.client.on_message = self._on_message
  12. self.connected = False
  13. def connect(self):
  14. if not self.config.enabled:
  15. return
  16. try:
  17. self.client.connect(self.config.broker, self.config.port, 60)
  18. self.client.loop_start()
  19. self.connected = True
  20. except Exception as e:
  21. logging.error(f"MQTT连接失败: {e}")
  22. self.connected = False
  23. def disconnect(self):
  24. if self.connected:
  25. self.client.loop_stop()
  26. self.client.disconnect()
  27. def subscribe(self, topics):
  28. if not self.connected:
  29. return
  30. for topic in topics:
  31. self.client.subscribe(topic)
  32. def _on_connect(self, client, userdata, flags, rc):
  33. if rc == 0:
  34. self.connected = True
  35. for topic in self.config.topics:
  36. client.subscribe(topic)
  37. else:
  38. logging.warning(f"MQTT连接失败,返回码: {rc}")
  39. def _on_message(self, client, userdata, msg):
  40. try:
  41. payload_str = msg.payload.decode('utf-8')
  42. if not payload_str.strip():
  43. return
  44. payload = json.loads(payload_str)
  45. if payload is not None:
  46. self.on_message_callback(msg.topic, payload)
  47. else:
  48. logging.debug("收到 null payload,忽略")
  49. except Exception as e:
  50. logging.exception(f"MQTT消息解析错误") # 打印堆栈