You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
3.5 KiB

import json
import logging
import random
import time
from datetime import datetime
from paho.mqtt import client as mqtt_client
class MQTTClient:
def __init__(self, broker='218.3.126.49', port=1883, topic="wybb/mqtt",
username='emqx', password='public',client_id=''):
self.BROKER = broker
self.PORT = port
self.TOPIC = topic
# generate client ID with pub prefix randomly
self.CLIENT_ID = client_id if client_id!='' else f'wybb_{datetime.now().strftime("%Y%m%d_%H%M%S")}'
self.USERNAME = username
self.PASSWORD = password
self.FIRST_RECONNECT_DELAY = 1
self.RECONNECT_RATE = 2
self.MAX_RECONNECT_COUNT = 10
self.MAX_RECONNECT_DELAY = 60
self.FLAG_EXIT = False
self.client = None
def on_connect(self, client, userdata, flags, rc, properties=None):
if rc == 0 and client.is_connected():
print("Connected to MQTT Broker!")
else:
print(f'Failed to connect, return code {rc}')
def on_disconnect(self, client, userdata, flags, rc, properties=None):
logging.info("Disconnected with result code: %s", rc)
reconnect_count, reconnect_delay = 0, self.FIRST_RECONNECT_DELAY
while reconnect_count < self.MAX_RECONNECT_COUNT:
logging.info("Reconnecting in %d seconds...", reconnect_delay)
time.sleep(reconnect_delay)
try:
client.reconnect()
logging.info("Reconnected successfully!")
return
except Exception as err:
logging.error("%s. Reconnect failed. Retrying...", err)
reconnect_delay *= self.RECONNECT_RATE
reconnect_delay = min(reconnect_delay, self.MAX_RECONNECT_DELAY)
reconnect_count += 1
logging.info("Reconnect failed after %s attempts. Exiting...", reconnect_count)
self.FLAG_EXIT = True
def connect(self):
self.client = mqtt_client.Client(mqtt_client.CallbackAPIVersion.VERSION2, self.CLIENT_ID)
self.client.username_pw_set(self.USERNAME, self.PASSWORD)
self.client.on_connect = self.on_connect
self.client.on_disconnect = self.on_disconnect
self.client.connect(self.BROKER, self.PORT, keepalive=120)
return self.client
def publish(self, msg:str):
if not self.client:
logging.error("MQTT client is not initialized!")
return
if not self.client.is_connected():
logging.error("publish: MQTT client is not connected!")
time.sleep(1)
return
result = self.client.publish(self.TOPIC, msg)
# result: [0, 1]
status = result[0]
if status == 0:
# logging.info(f'Send topic [{self.TOPIC}] to `{msg}` ')
pass
else:
logging.info(f'Failed to send topic [{self.TOPIC}]')
def start(self):
self.client = self.connect()
self.client.loop_start()
time.sleep(1)
if self.client.is_connected():
logging.info("MQTT client is connected!")
else:
self.client.loop_stop()
return False
return True
def stop(self):
if self.client:
self.client.loop_stop()
self.client.disconnect()
# 示例用法
if __name__ == '__main__':
mq = MQTTClient()
if mq.start():
msg = {"a": 123}
mq.publish(msg)
time.sleep(2) # 等待消息发送完成
mq.stop()
print("==========")