In the following script i can subscribe from a topic but it wont publish my data strings and i don't get an error message. Are some functions out of order?
import paho.mqtt.client as mqtt
broker = "broker" #Broker address
port = 1883 #Broker port
user = "user" #Connection username
psw = "psw" #Connection password
client = mqtt.Client("Python")
client.username_pw_set(user, psw)
client.connect(broker, port, 60)
pubtopic = 'pubtopic'
def on_publish(client, pubtopic, msg):
print("publish data")
client.publish(pubtopic, msg.payload)
on_publish(client, msg.payload)
subtopic = 'subtopic'
def on_connect(client, userdata, flags, rc):
print("received: " + str(rc))
client.subscribe(subtopic)
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
client.on_publish = on_publish
client.on_connect = on_connect
client.on_message = on_message
client.loop_forever()
Remove the on_publish callback it's not doing anything useful here, as #Brits mentioned, it is only called when this particular client publishes a message (which you are not doing in your current code) and the 3rd argument is not a full message object, it is just a message id field.
Please send some time and read the Python Paho doc section on callbacks.
It clearly lays out under what conditions each callback will be triggered.
If you want to react to a message you have subscribed to then you need an on_message callback. It is within this function that you need do any actions as a result of receiving that message.
e.g.
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
client.publish(pubtopic, msg.payload)
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.
This is my code
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc): # The callback for when the client connects to the broker
print("Connected with result code {0}".format(str(rc))) # Print result of connection attempt
def on_message(client, userdata, message): # The callback for when a PUBLISH message is received from the server.
print("message received " ,str(message.payload.decode("utf-8")))
print("message topic=",message.topic)
print("message qos=",message.qos)
print("message retain flag=",message.retain)
#creating client instance
client = mqtt.Client(client_id="random_id_name")
print("client created ......")
client.on_connect = on_connect # Define callback function for successful connection
client.on_message = on_message # Define callback function for receipt of a message
#connecting to broker/server
hostname = "hostname_I_am_trying_to_connect" #give the host/server/broker name
portnumber = **random_port_number_as_integer_value** #give the port number
client.username_pw_set("username", "password") #give the username and password for the broker/server/host
client.connect(host= hostname ,port= portnumber)
print("client connected to- ",hostname," on port_number:",portnumber)
client.subscribe("login")
print("subscribed to the topic")
client.publish("login","some_message")
print("message published")
client.loop_forever() # Start networking daemon
Here I am expecting to receive some_message/unique_id from the broker , i.e. 1234/1234_qyehfj_1234_jfjfj.
Instead, I am receiving some random numbers. See the screenshot:
What is the problem here? Is the problem in my code or something wrong with the broker I am sending messages to?
If something is wrong with the code please let me know how to fix this.
I solved the problem last night. So here I am going to explain what happened.
I subscribed to the wrong topic, that's why I was receiving everything that other people may or may not have published on that particular topic.
In the future, if anyone is facing the same problem, double-check if you are subscribed to the right topic.
I have an issue with MQTT lib ( https://pypi.python.org/pypi/paho-mqtt/1.1 ).
I want to have async and sync tasks for multiple requests, but it seems I cannot get around an issue to make a response on web, for requested url /mqtt when actual subscribed message is received, because on_message is a callback function.
#app.route('/mqtt', methods=['POST', 'GET'])
def main():
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
test = on_message
client.username_pw_set('x', 'x')
client.connect("x", 1883, 60)
client.subscribe("/message/1")
client.loop_forever()
# how do I get the message from callback function on_message and then stop loop_forever?
#I thought about: return msg but it doesn't work.
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
#how to pass this msg to the main function?
print(msg.topic + " " + str(msg.payload))
To stop loop_forever when get message, you can use client.disconnect
Sample code:
def on_message(client, userdata, msg):
print(msg.topic + " " + str(msg.payload))
client.disconnect() # disconnect when get message
To pass message to main function, you can simply use global variable. But my suggestion is to start another process for mqtt client, pass variables via shared memory. It's a lot of overhead for connecting to mqtt broker every time got a GET or POST .
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.