I have a simple script on a Raspberry Pi that publishes a sample message every 3 seconds. I have declared the callbacks on_connect, on_publish and on_disconnect. This client connects successfully but on_connect is not called, publishes and on_publish is called, disconnects and on_disconnect is called.
This is my script
import paho.mqtt.client as mqtt
import time
def on_connect(mqttc, userdata, rc):
print("Connected with result code "+str(rc))
if rc!=0 :
mqttc.reconnect()
def on_publish(mqttc, userdata, mid):
print "Published"
def on_disconnect(mqttc, userdata, rc):
if rc != 0:
print("Unexpected disconnection. Reconnecting...")
mqttc.reconnect()
else :
print "Disconnected successfully"
# Setup MQTT
# broker='test.mosquitto.org'
broker = 'iot.eclipse.org'
broker_port=1883
# Create a client instance
mqttc=mqtt.Client(client_id="MyClient")
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
mqttc.on_disconnect = on_disconnect
while 1:
mqttc.connect(broker, broker_port, 60)
# print "Connected." # I don't want this message.
# Why isn't the on_connect callback invoked?
try:
topic = "this/is/a/test/topic"
payload = "test_message"
print "Publishing " + payload + " to topic: " + topic + " ..."
mqttc.publish(topic, payload, 0)
except Exception as e:
print "exception"
log_file=open("log.txt","w")
log_file.write(str(time.time())+" "+e.__str__())
log_file.close()
mqttc.disconnect()
print ""
time.sleep(3)
Although this minor "bug" doesn't affect the message publishing, which is mainly what I want to achieve, why does it happen and how can I resolve it?
The reason this isn't working is that you aren't calling any of the loop*()
functions. These process network traffic. If you don't use one, there is no guarantee your outgoing messages will be sent and absolutely no incoming messages will be processed.
loop_forever()
is a blocking call that processes the network loop - probably not what you want.
loop_start()
starts a thread to process the network loop and so returns straight away.
I would do this:
mqttc.connect(broker, broker_port, 60) # Don't forget to handle errors
mqttc.loop_start()
while 1:
try:
topic = "this/is/a/test/topic"
payload = "test_message"
print "Publishing " + payload + " to topic: " + topic + " ..."
mqttc.publish(topic, payload, 0)
except Exception as e:
print "exception"
log_file=open("log.txt","w")
log_file.write(str(time.time())+" "+e.__str__())
log_file.close()
print ""
time.sleep(3)
You do still need to fix your on_connect callback as @Kiran says.
There is no need to disconnect each time - and in fact there is no guarantee your message will have been sent when you do disconnect. You should use the on_publish
callback to know when the message is sent.
If you want to do a simple connect-publish-disconnect, then maybe use the paho.mqtt.publish
helper module:
import paho.mqtt.publish as publish
while 1:
try:
topic = "this/is/a/test/topic"
payload = "test_message"
print "Publishing " + payload + " to topic: " + topic + " ..."
publish.single(topic, payload, 0, host=broker, port=broker_port)
except Exception as e:
print "exception"
log_file=open("log.txt","w")
log_file.write(str(time.time())+" "+e.__str__())
log_file.close()
print ""
time.sleep(3)