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.
Related
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)
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 written a code that can do both publishing and subscribing in the same python file. My aim is to be able to send endlessly color temperature to a lamp and receive back its state (ON/OFF or online/offline).
However, when I run the code, I can send messages to the lamp but I don't receive anything (note that publisher and subscriber worked well separately)
import paho.mqtt.client as mqtt
import sys
import time
topic = "testtopic/3"
topic_casa = "testtopic/1"
def on_connect(client, userdata, flags, rc):
print("Connection to the broker. Result : "+str(rc))
client.subscribe(topic_casa, qos=1)
client.publish(topic, light.circadianLight())
def on_message(client, userdata, msg):
Message = str(msg.payload)
print("[MSG RECEBIDA] Topico: "+msg.topic+" / Mensagem: "+Message)
def on_publish(client,userdata,result):
client.publish(topic, light.circadianLight())
time.sleep(10)
def on_disconnect(client, userdata, rc):
if rc != 0:
print("Unexpected disconnection.")
try:
print("[STATUS] Inicializando MQTT...")
#inicializa MQTT:
client = mqtt.Client()
client.username_pw_set(username, password)
client.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect
client.on_publish = on_publish #with this callback we won't be able to
#receive messages
client.connect(Broker, PortaBroker, KeepAliveBroker)
client.loop_forever()
except KeyboardInterrupt:
print ("\nCtrl+C pressionado, encerrando aplicacao e saindo...")
sys.exit(0)
The problem is two fold, first that you are calling time.sleep(10) in the on_publish() callback.
This is blocking the MQTT client network loop so it will not send/receive any messages for 10 seconds every time you publish a message.
You should not be doing any blocking or long running tasks in any of the MQTT client callbacks.
The other problem is that without the sleep the client will spend all it's time publishing messages (because everytime it finishes publishing a message it trigger the on_publish() callback which kicks off another publish. It will never get round to handing the incoming messages.
If you want to publish messages at a regular interval then you need to start a separate thread to do it, not try to do it in the callbacks.
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.