从云接收MQTT数据时的延迟

2024-05-28 16:38:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Arduino板,有一些传感器和一个执行器。它通过USB电缆连接到树莓派。在

想法是,通常Arduino会将数据以串行方式打印。这是由Raspberry Pi在Python脚本的帮助下检索的。如果在云端遇到任何事件,或者我单击云端上的按钮,就会触发Arduino侧的执行器。在

我有以下MQTT客户机代码。在

#!/usr/bin/env python
import logging
import time
import json
import serial
import paho.mqtt.client as mqtt
MQTT_BROKER = "things.ubidots.com"
MQTT_PORT = 1883  # Default MQTT Port is 1883
MQTT_KEEPALIVE_INTERVAL = 45  # In seconds
MQTT_USER_NAME = "Broker_User_Name"
MQTT_USER_PASSWORD = "Broker_User_Password"
PUB_TOPIC1 = "/v1.6/devices/mqtt/temperature"
SUB_TOPIC1 = "/v1.6/devices/mqtt/temperature"
PUB_TOPIC2 = "/v1.6/devices/mqtt/humidity"
SUB_TOPIC2 = "/v1.6/devices/mqtt/humidity"
PUB_TOPIC3 = "/v1.6/devices/mqtt/luminance"
SUB_TOPIC3 = "/v1.6/devices/mqtt/luminance"
PUB_TOPIC4 = "/v1.6/devices/mqtt/ADC"
SUB_TOPIC4 = "/v1.6/devices/mqtt/ADC"
PUB_TOPIC5 = "/v1.6/devices/mqtt/Battery_Status"
SUB_TOPIC5 = "/v1.6/devices/mqtt/Battery_Status"
Quqlity_of_Service = 0

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)                                                                               
handler = logging.FileHandler('MQTT_log_file.log')  # create a file handler
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') # create a logging format
handler.setFormatter(formatter)
logger.addHandler(handler)# add the handlers to the logger
logger.info("")
logger.info("######## Program started ########")

MQTT_MSG1 = 0
MQTT_MSG2 = 0
MQTT_MSG3 = 0
MQTT_MSG4 = 0
MQTT_MSG5 = 0
msg_body = ""
rc = 0  # For error checking

time.sleep(0.3)
pub_sub_option = int(raw_input("Do you want to be:\n 1.Publisher\n 2.Subscriber\n 3.Both\n :"))
logger.info("\nPublisher and Subscriber Option: {}".format(pub_sub_option))
if pub_sub_option == 1:
    print("")
    print("You have selected only Publisher")
    print("")
elif pub_sub_option == 2:
    print("")
    print("You have selected only Subscriber")
    print("")
elif pub_sub_option == 3:
    print("")
    print("You have selected both Publisher and Subscriber")
    print("")
else:
    print("")
    print("Please select the correct option.")
    print("")

if pub_sub_option == 1:
    publisher_check = 1
    subscriber_check = 0
elif pub_sub_option == 2:
    publisher_check = 0
    subscriber_check = 1
elif pub_sub_option == 3:
    publisher_check = 1
    subscriber_check = 1

serial_data = serial.Serial(port='/dev/ttyACM0', baudrate=115200) # Read the Sensor Data
logger.debug("Serial Data: {}".format(serial_data))

#  ----# Json Data Converter Function #----
def json_data_publish(PUB_TOPIC, sensor_variable, Quqlity_of_Service):
    message = {'value': sensor_variable}
    logger.debug("Json Data Publisher Value: {}".format(message))
    mqttc.publish(PUB_TOPIC, json.dumps(message), Quqlity_of_Service)

def connack_string(connack_code):
    """Return the string associated with a CONNACK result"""
    if connack_code == 0:
        return "Connection Accepted."
    elif connack_code == 1:
        return "Connection Refused: unacceptable protocol version."
    elif connack_code == 2:
        return "Connection Refused: identifier rejected."
    elif connack_code == 3:
        return "Connection Refused: broker unavailable."
    elif connack_code == 4:
        return "Connection Refused: bad user name or password."
    elif connack_code == 5:
        return "Connection Refused: not authorised."
    else:
        return "Connection Refused: unknown reason."

# Define on_connect event Handler
def on_connect(client, userdata, flags, rc):
    logger.debug(connack_string(int(rc)))
    print(connack_string(int(rc)))

# Define on_message event Handler for Topic 1
def on_message(client, userdata, msg):
    logger.debug("Control is in On_Message")
    received_topic = str(msg.topic)
    received_message = str(msg.payload.decode())

    if received_topic != "" and received_message != "":
        if received_topic == SUB_TOPIC1:
            received_temp_data = int(received_message)
            print("The Received Temperature Data is: {}\n".format(received_temp_data))
            logger.debug("The Received Temperature Data is: {}".format(received_temp_data))

        elif received_topic == SUB_TOPIC2:
            received_humid_data = int(received_message)
            print("The Received Humidity Data is: {}\n".format(received_humid_data))
            logger.debug("The Received Humidity Data is: {}".format(received_humid_data))

# Define on_publish event Handler
def on_publish(client, userdata, mid):
    pass

# Initiate MQTT Client
mqttc = mqtt.Client()
logger.debug("MQTT Client is Initialized")

# Connect with MQTT Broker
mqttc.username_pw_set(MQTT_USER_NAME, MQTT_USER_PASSWORD)
mqttc.connect(MQTT_BROKER, MQTT_PORT, MQTT_KEEPALIVE_INTERVAL)
logger.debug("Connected to MQTT Broker")

# Register Event Handlers
mqttc.on_connect = on_connect
logger.debug("Control is in On_Connect Event Handler")
mqttc.on_message = on_message
logger.debug("Control is in On_Message Event Handler")

# subscribe for topic
if subscriber_check == 1:
    mqttc.subscribe(SUB_TOPIC1, Quqlity_of_Service)
    mqttc.subscribe(SUB_TOPIC2, Quqlity_of_Service)
    mqttc.subscribe(SUB_TOPIC3, Quqlity_of_Service)
    mqttc.subscribe(SUB_TOPIC4, Quqlity_of_Service)
    mqttc.subscribe(SUB_TOPIC5, Quqlity_of_Service)

while rc == 0:
    try:
        rc = mqttc.loop()
        if publisher_check == 1:
#    ----  # Data from Real Sensors #----
            data = serial_data.readline(20)
            pieces = data.split(":")
            if pieces[0] == "Temperature":
                MQTT_MSG1 = pieces[1]
            if pieces[0] == "Humidity":
                MQTT_MSG2 = pieces[1]
            if pieces[0] == "Luminance":
                MQTT_MSG3 = pieces[1]
            if pieces[0] == "ADC":
                MQTT_MSG4 = pieces[1]
            if pieces[0] == "Battery_Status":
                MQTT_MSG5 = pieces[1]
            logger.debug("Json Enabled")
            json_data_publish(PUB_TOPIC1, MQTT_MSG1, Quqlity_of_Service)
            print("Temperature {} Published\n".format(MQTT_MSG1))
            logger.debug("Temperature {} Published with QOS = {}".format(MQTT_MSG1, Quqlity_of_Service))
            time.sleep(1)
            json_data_publish(PUB_TOPIC2, MQTT_MSG2, Quqlity_of_Service)
            print("Humidity {} Published\n".format(MQTT_MSG2))
            logger.debug("Humidity {} Published with QOS = {}".format(MQTT_MSG2, Quqlity_of_Service))
            time.sleep(1)
            json_data_publish(PUB_TOPIC3, MQTT_MSG3, Quqlity_of_Service)
            print("Luminance {} Published\n".format(MQTT_MSG3))
            logger.debug("Luminance {} Published with QOS = {}".format(MQTT_MSG3, Quqlity_of_Service))
            time.sleep(1)
            json_data_publish(PUB_TOPIC4, MQTT_MSG4, Quqlity_of_Service)
            print("ADC {} Published\n".format(MQTT_MSG4))
            logger.debug("ADC {} Published with QOS = {}".format(MQTT_MSG4, Quqlity_of_Service))
            time.sleep(1)
            json_data_publish(PUB_TOPIC5, MQTT_MSG5, Quqlity_of_Service)
            print("Battery_Status {} Published\n".format(MQTT_MSG5))
            logger.debug("Battery_Status {} Published with QOS = {}".format(MQTT_MSG5, Quqlity_of_Service))
            time.sleep(1)
    except keyboardInterrupt:
        print("\nThe Process is Terminated")
        break

此代码可以用作

  1. MQTT发布程序
  2. MQTT订户
  3. MQTT发布者和订阅者

但通常在我的设置中,它总是在模式3(发布者和订阅者)下运行,因为我想触发执行器。在

代码上传数据没有任何问题。但问题是在收到的时候。接收数据时会有延迟。但是如果我在我的笔记本电脑上运行与订阅者相同的代码(模式2),它就完美地工作了。一旦数据被上传到我的笔记本电脑里。在

如果我能用更有效的方式写同样的代码,请告诉我。在


Tags: ofdebugformatmessagedataifservicelogger
1条回答
网友
1楼 · 发布于 2024-05-28 16:38:09

我猜测延迟在while循环中的sleep方法中。为什么不把代码分为“sub”和“pub”代码,并在Raspberry Pi上分别运行它们呢。我不是Python专家,但我认为所有的东西都是在一个线程下运行的,因此,当你睡觉的时候,它是在暂停唯一的线程。在

相关问题 更多 >

    热门问题