Reputation: 833
I am trying to send a message using publish.single
and then receive it and act upon the data received. Hence, I can't proceed unless I receive something from the server, so is there a way to write a statement that will wait for a message from MQTT before proceeding?
Example code:
publish.single("$topic", data, ip_address)
#can't do anything here
receive(data_from_broker) #or anythin that looks like it!
#continue with the program here
Upvotes: 0
Views: 5677
Reputation: 2292
As hardillb noted, this is not the right approach for working with MQTT. If you still want to do it, you can write a function that blocks the main thread until a message arrives.
For example as follows (copy & paste solution):
import ssl
import paho.mqtt.client as mqtt
import time
def mqtt_get_value_blocking(broker, port, username, password, topic):
def on_connect(client, userdata, flags, rc):
if rc == 0:
client.subscribe(topic)
else:
print(f"Connection failed with error code {rc}")
def on_message(client, userdata, msg):
nonlocal val
val = msg.payload.decode()
val = None
client = mqtt.Client()
client.username_pw_set(username, password)
client.on_connect = on_connect
client.on_message = on_message
client.tls_set(certfile=None, keyfile=None, cert_reqs=ssl.CERT_REQUIRED)
client.connect(broker, port=port)
client.loop_start()
while val is None:
time.sleep(0.1)
client.loop_stop()
client.disconnect()
return val
Call the function as follows:
# TODO: adjust the following broker details
BROKER = "<mqtt broker address>"
PORT = 8883
USERNAME = "<mqtt username>"
PASSWORD = "<mqtt password>"
topic = "test/test"
val = mqtt_get_value_blocking(BROKER, PORT, USERNAME, PASSWORD, topic)
print(val)
Note: This function assumes that you are not using SSL. If you want to or must use SSL, adapt the line client.tls_set(certfile=None, keyfile=None, cert_reqs=ssl.CERT_REQUIRED)
accordingly.
Upvotes: 0
Reputation: 59608
The short answer is you don't.
At least not in the way you describe. MQTT is an asynchronous protocol, there is no sense of sending a message and waiting for a response, a publishing client has no way to know if the is 0, 1 or n subscribing clients listening on the topic the message is published.
You will need to build something called a state machine to keep track of where in the program flow you are when messages are received.
e.g.
To subscribe to a topic you will have to move on from using publish.single to the full MQTT client so you can setup the onMessage callback to handle the incoming messages.
Upvotes: 3