I have somewhat unstable wifi network at home. I have pyhon code running on raspberry pi which tries to connect to "test.mosquitto.com" broker.
Below is the python code which I have written
import time
import paho.mqtt.client as mqtt
bConnected = False
def on_disconnect(client, userdata, msg):
print "Disonnected from broker"
global bConnected
bConnected = False
def on_connect(client, userdata, msg):
print "Connected to broker"
global bConnected
bConnected = True
def worker_thread():
"""Creates mqtt client which check connection between pi and mqtt broker"""
client = mqtt.Client()
client.on_disconnect = on_disconnect
client.on_connect = on_connect
global bConnected
while not bConnected:
try:
print "Trying to connect broker"
client.connect("test.mosquitto.org", 1883, 5)
client.loop_forever()
time.sleep(5)
except:
bConnected = False
It works fine for me.
Please let me know is there another efficient way to do this.(I guess there should be another way).
Thanks in advance.
Related
It's my first time trying to connect to a mqtt broker and it's not really going great. I've been trying to get data from the broker but am unable to figure out how to connect. I've been handed a username, password, port and encrypted port aswell as "Topics. When trying to connect the "client.connect"-line responds with "0". I changed the username and password and I still get the same result so there is something wrong with my configuration. Any help would be much appreciated!
I'm running python 3.6.5
import paho.mqtt.client as mqtt
import time
username="temp"
password="temp"
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe("extapi/data/esm")
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set(username, password)
client.connect("example.io", 1883, 60)
I am new to using MQTT and I would like to run two Python programs simultaneously: one to publish messages to a topic and the other to print out the messages as they are published to the topic. However, the callback function to print out the message isn't working for me.
These are the two programs I have:
Publish messages:
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
print("Connected! Result code: " + str(rc))
client = mqtt.Client(client_id="clientID")
client.on_connect = on_connect
client.username_pw_set(username="username", password="password")
client.loop_start()
client.connect("node02.myqtthub.com", 1883)
while True:
client.publish("my/topic", "test")
Subscribe to and print messages:
import paho.mqtt.client as mqtt
def on_message(client, userdata, msg):
print(msg.payload.decode())
def on_connect(client, userdata, flags, rc):
print("Connected! Result code: " + str(rc))
client.subscribe("my/topic")
client = mqtt.Client(client_id="clientID")
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set(username="username", password="password")
client.connect("node02.myqtthub.com", 1883)
client.loop_forever()
Could someone help me fix this issue?
Both programs are using client_id="clientID"; the mqtt spec states
If the ClientId represents a Client already connected to the Server then the Server MUST disconnect the existing Client [MQTT-3.1.4-2].
So whichever app connects second will cause the first to be disconnected. To fix this change the client id in one of the apps.
Note: This is a comment on something obviously wrong. When asking a question please state what you see happening (any output, errors, what you have tried etc) because there may be another problem.
I have a Python script wherein I'm connected to a MQTT server. I'm expecting to get a message through the topic where I'm subscribed to, but should I not receive the message, I want to terminate the script entirely.
The script I'm working with looks as follows:
#!/usr/bin/python
import sys
import json
import paho.mqtt.client as mqtt
def on_message(client, userdata, msg):
if msg.topic == "discovery":
data = json.loads(msg.payload)
serial = data['serial']
print "test successful!"
sys.exit(0)
def on_connect(client, userdata, flags, rc):
client.subscribe([("discovery", 2)])
client = mqtt.Client()
try:
client.connect('localhost', 4444)
except:
print "ERROR: Could not connect to MQTT
client.on_connect = on_connect
client.on_message = on_message
client.loop_forever()
I have tried using a while True statement to loop and figure the time passing in between starting the script and it getting the message, but it seemed to (obviously) not escape the loop even while it gets the message through.
Is there a way that I can say how long it be connected for, and when it exceeds that time, just terminate the script entirely?
Or perhaps, is there a way (as I tried before) to make a loop but also consider the message coming through while in the loop?
Thanks for your suggestions!
Try something like this
It should wait for about 5 seconds for an incoming message then quit. You can adjust the wait time by changing the value waitTime just before the while loop
I have used the version of the mqtt network loop function that only runs for a short time and put it in a while loop. The loop also checks elapsed time and disconnects the client cleanly before bailing out of the loop. I also added a clean client exit for when a message is received.
#!/usr/bin/python
import sys
import json
import paho.mqtt.client as mqtt
import time
def on_message(client, userdata, msg):
if msg.topic == "discovery":
data = json.loads(msg.payload)
serial = data['serial']
print "test successful!"
client.disconnect()
sys.exit(0)
def on_connect(client, userdata, flags, rc):
client.subscribe([("discovery", 2)])
client = mqtt.Client()
try:
client.connect('localhost', 4444)
except:
print "ERROR: Could not connect to MQTT"
client.on_connect = on_connect
client.on_message = on_message
startTime = time.time()
waitTime = 5
while True:
client.loop()
elapsedTime = time.time() - startTime
if elapsedTime > waitTime:
client.disconnect()
break
I'm trying to send a jpg image using MQTT mosquitto broker(pub and sub) in Raspberry Pi2.
This is my python code pub.py(modified)
import paho.mqtt.client as mqtt
def on_publish(mosq, userdata, mid):
mosq.disconnect()
client = mqtt.Client()
client.connect("test.mosquitto.org", 1883, 60)
client.on_publish = on_publish
f=open("b.jpg", "rb") #3.7kiB in same folder
fileContent = f.read()
byteArr = bytearray(fileContent)
client.publish("image",byteArr,0)
client.loop_forever()
and it's sub.py(modified)
import paho.mqtt.client as mqtt
def on_connect(client, userdata, rc):
print("Connect" + str(rc))
client.subscribe("image")
def on_message(client, userdata, msg):
print "Topic : ", msg.topic
f = open("/tmp/output.jpg", "w") #there is a output.jpg which is different
f.write(msg.payload)
f.close()
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("test.mosquitto.org", 1883, 60)
client.loop_forever()
My python verson is 2.7.9.
After I solved some error, It seems to work but It doesn't.
When I implement the sub.py, It connects successfully so I implement the pub.py in other terminal.
However, There isn't any reaction without connect message which is "Connect with result code 0"
There is no error message so I don't know what my mistake is.
Tested Code:
Requirements:
Install Mosquitto Broker
Install paho.mqtt package.
pub.py
import paho.mqtt.publish as publish
MQTT_SERVER = "xxx.xxx.xxx.xxx" #Write Server IP Address
MQTT_PATH = "Image"
f=open("image_test.jpg", "rb") #3.7kiB in same folder
fileContent = f.read()
byteArr = bytearray(fileContent)
publish.single(MQTT_PATH, byteArr, hostname=MQTT_SERVER)
One small modification, file permission is write byte instead of write mode.
sub.py
import paho.mqtt.client as mqtt
MQTT_SERVER = "localhost"
MQTT_PATH = "Image"
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe(MQTT_PATH)
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
# more callbacks, etc
# Create a file with write byte permission
f = open('output.jpg', "wb")
f.write(msg.payload)
print("Image Received")
f.close()
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(MQTT_SERVER, 1883, 60)
# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()
Expected Output:
Able to transfer the Image from Raspberry Pi to server machine.
In sub.py you have 2 on_public functions which should be renamed on_connect and on_publish respectively.
In pub.py you need to actually set the on_publish method on the client so it will be called once the publish has been completed.
...
client.connect("test.mosquitto.org", 1883, 60)
client.on_publish = on_public
...
Also as #ralight pointed out in his answer to your previous question, you should change client.loop(5) to client.loop_forever() it will still exit once the message has been sent because of the mosq.disconnect()
In your sub.py you need a callback which handles incoming messages for your subscription. The standard callback for that is on_message.
Just rename in your sub.y on_publish(client, userdata, msg) to on_message(client, userdata, msg)and assign client.on_message = on_message.
What is the most reliable way to use the Python Paho MQTT client? I want to be able to handle connection interruptions due to WiFi drops and keep trying to reconnect until it's successful.
What I have is the following, but are there any best practices I'm not adhering to?
import argparse
from time import sleep
import paho.mqtt.client as mqtt
SUB_TOPICS = ("topic/something", "topic/something_else")
RECONNECT_DELAY_SECS = 2
def on_connect(client, userdata, flags, rc):
print "Connected with result code %s" % rc
for topic in SUB_TOPICS:
client.subscribe(topic)
# EDIT: I've removed this function because the library handles
# reconnection on its own anyway.
# def on_disconnect(client, userdata, rc):
# print "Disconnected from MQTT server with code: %s" % rc
# while rc != 0:
# sleep(RECONNECT_DELAY_SECS)
# print "Reconnecting..."
# rc = client.reconnect()
def on_msg(client, userdata, msg):
print "%s %s" % (msg.topic, msg.payload)
if __name__ == "__main__":
p = argparse.ArgumentParser()
p.add_argument("user")
p.add_argument("password")
p.add_argument("host")
p.add_argument("--port", type=int, default=1883)
args = p.parse_args()
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_msg
client.username_pw_set(args.user, args.password)
client.connect(args.host, args.port, 60)
client.loop_start()
try:
while True:
sleep(1)
except KeyboardInterrupt:
pass
finally:
client.loop_stop()
Set a client_id so it's the same across reconnects
Set the clean_session=false connection option
Subscribe at QOS greater than 0
These options will help ensure that any messages published while disconnected will be delivered once the connection is restored.
You can set the client_id and clean_session flag in the constructor
client = mqtt.Client(client_id="foo123", clean_session=False)
And set the QOS of the subscription after the topic
client.subscribe(topic, qos=1)