J'ai une carte Arduino avec quelques capteurs et un actionneur. Il est connecté à un Raspberry Pi via un câble USB. L'idée est, normalement l'Arduino sera l'impression des données sur Serial. Ceci est récupéré par le Raspberry Pi à l'aide de ce script Python. Si un événement est rencontré du côté du nuage, ou si je clique sur un bouton sur le nuage, cela devrait déclencher l'actionneur du côté Arduino.Délai pendant la réception des données MQTT à partir du cloud
J'ai le code client MQTT suivant.
#!/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
Ce code peut être utilisé comme
- MQTT Editeur
- MQTT Abonné
- MQTT Éditeur et Abonné
Mais normalement dans ma configuration, il est alway fonctionne en mode 3 (à la fois éditeur et abonné), car je veux déclencher l'actionneur.
Le code télécharge les données sans aucun problème. Mais le problème vient quand on le reçoit. Il y aura un délai pendant la réception des données. Mais si je cours le même code en tant qu'abonné (mode 2) à partir de mon ordinateur portable, cela fonctionne parfaitement. Dès que les données sont téléchargées, elles sont reçues sur mon ordinateur portable.
Et s'il vous plaît laissez-moi savoir si je peux écrire le même code d'une manière beaucoup plus efficace.
Oui. J'utilise un service gratuit du fournisseur de services cloud. Donc, je ne peux envoyer des données que pour une seconde, donc j'ai utilisé le délai entre les deux. Je vérifie avec multithreading comme vous l'avez suggéré. Je vous remercie – Arunkrishna