如何在python中使用Mosquitto发布文件?

时间:2022-09-02 10:05:41

I am using python-mosquitto to subscribe to my MQTT broker which support file type uploads. I can use it just fine using the -f flag when going from Mosquitto on the command line. However, I can't figure out how to use the client.publish(topic, payload) to specify a file to publish when doing it from within my python script.

我正在使用python-mosquitto订阅支持文件类型上传的MQTT代理。从命令行的Mosquitto开始,我可以使用-f标志。但是,我无法弄清楚如何使用client.publish(topic,payload)来指定在我的python脚本中执行时要发布的文件。

Python mosquitto gives me the error TypeError: payload must be a string, bytearray, int, float or None. when I try to throw something weird at it. I have a file stored in local directory already which I want to specify as the payload of the publish.

Python mosquitto给出了错误TypeError:payload必须是字符串,bytearray,int,float或None。当我试图抛出奇怪的东西时。我有一个存储在本地目录中的文件,我想指定它作为发布的有效负载。

I'm experienced with MQTT but my python is very rusty, I am assuming I need to do some type of file stream function here, but not sure how to do it.

我对MQTT很有经验,但我的python非常生疏,我假设我需要在这里做一些类型的文件流功能,但不知道该怎么做。

I want to specify the image here: mqttc.publish("/v3/device/file", NEED_TO_SPECIFY_HERE)

我想在这里指定图像:mqttc.publish(“/ v3 / device / file”,NEED_TO_SPECIFY_HERE)

I have tried opening the image by doing:

我试过打开图像:

    f = open("/home/pi/mosq/imagecap/imagefile.jpg", "rb")
    imagebin = f.read()
    mqttc.publish("/v3/device/file", imagebin)

But that didn't work and neither did mqttc.publish("/v3/device/file", bytearray(open('/tmp/test.png', 'r').read()))

但这没有用,mqttc.publish(“/ v3 / device / file”,bytearray(open('/ tmp / test.png','r')。read()))也没有用。

The client.publish doesnt throw an error with those, but the file is not received properly by the broker. Any ideas?

client.publish不会引发错误,但代理无法正确接收该文件。有任何想法吗?

Thanks!!

谢谢!!

2 个解决方案

#1


5  

It's worth noting that this is one of the areas that can have differences between Python 2 and Python 3.

值得注意的是,这是Python 2和Python 3之间可能存在差异的领域之一。

Python 2 file.read() returns a str whereas Python 3 is bytes. mosquitto.publish() handles both types so you should be ok in that case, but it is something to be aware of.

Python 2 file.read()返回str而Python 3是字节。 mosquitto.publish()处理这两种类型,因此在这种情况下你应该没问题,但需要注意的是。

I've added what I consider some minor improvements to @hardillb 's code below. Please don't accept my answer in preference to his because he wrote it originally and got there first! I would have edited his answer, but I think it's useful to see the difference.

我已经添加了我认为对@hardillb代码的一些小改进。请不要接受我的回答而不是他的回答,因为他最初写的并首先到达那里!我会编辑他的答案,但我认为看到差异是有用的。

#!/usr/bin/python

import mosquitto

def on_publish(mosq, userdata, mid):
  # Disconnect after our message has been sent.
  mosq.disconnect()

# Specifying a client id here could lead to collisions if you have multiple
# clients sending. Either generate a random id, or use:
#client = mosquitto.Mosquitto()
client = mosquitto.Mosquitto("image-send")
client.on_publish = on_publish
client.connect("127.0.0.1")

f = open("data")
imagestring = f.read()
byteArray = bytes(imagestring)
client.publish("photo", byteArray ,0)
# If the image is large, just calling publish() won't guarantee that all 
# of the message is sent. You should call one of the mosquitto.loop*()
# functions to ensure that happens. loop_forever() does this for you in a
# blocking call. It will automatically reconnect if disconnected by accident
# and will return after we call disconnect() above.
client.loop_forever()

#2


10  

The publish has to be the whole file at once, so you will need to read the whole file in and publish it in one go.

发布必须同时是整个文件,因此您需要读取整个文件并一次发布。

The following code works

以下代码有效

#!/usr/bin/python

import mosquitto

client = mosquitto.Mosquitto("image-send")
client.connect("127.0.0.1")

f = open("data")
imagestring = f.read()
byteArray = bytes(imagestring)
client.publish("photo", byteArray ,0)

And can be received with

并且可以收到

#!/usr/bin/python

import time
import mosquitto

def on_message(mosq, obj, msg):
  with open('iris.jpg', 'wb') as fd:
    fd.write(msg.payload)


client = mosquitto.Mosquitto("image-rec")
client.connect("127.0.0.1")
client.subscribe("photo",0)
client.on_message = on_message

while True:
   client.loop(15)
   time.sleep(2)

#1


5  

It's worth noting that this is one of the areas that can have differences between Python 2 and Python 3.

值得注意的是,这是Python 2和Python 3之间可能存在差异的领域之一。

Python 2 file.read() returns a str whereas Python 3 is bytes. mosquitto.publish() handles both types so you should be ok in that case, but it is something to be aware of.

Python 2 file.read()返回str而Python 3是字节。 mosquitto.publish()处理这两种类型,因此在这种情况下你应该没问题,但需要注意的是。

I've added what I consider some minor improvements to @hardillb 's code below. Please don't accept my answer in preference to his because he wrote it originally and got there first! I would have edited his answer, but I think it's useful to see the difference.

我已经添加了我认为对@hardillb代码的一些小改进。请不要接受我的回答而不是他的回答,因为他最初写的并首先到达那里!我会编辑他的答案,但我认为看到差异是有用的。

#!/usr/bin/python

import mosquitto

def on_publish(mosq, userdata, mid):
  # Disconnect after our message has been sent.
  mosq.disconnect()

# Specifying a client id here could lead to collisions if you have multiple
# clients sending. Either generate a random id, or use:
#client = mosquitto.Mosquitto()
client = mosquitto.Mosquitto("image-send")
client.on_publish = on_publish
client.connect("127.0.0.1")

f = open("data")
imagestring = f.read()
byteArray = bytes(imagestring)
client.publish("photo", byteArray ,0)
# If the image is large, just calling publish() won't guarantee that all 
# of the message is sent. You should call one of the mosquitto.loop*()
# functions to ensure that happens. loop_forever() does this for you in a
# blocking call. It will automatically reconnect if disconnected by accident
# and will return after we call disconnect() above.
client.loop_forever()

#2


10  

The publish has to be the whole file at once, so you will need to read the whole file in and publish it in one go.

发布必须同时是整个文件,因此您需要读取整个文件并一次发布。

The following code works

以下代码有效

#!/usr/bin/python

import mosquitto

client = mosquitto.Mosquitto("image-send")
client.connect("127.0.0.1")

f = open("data")
imagestring = f.read()
byteArray = bytes(imagestring)
client.publish("photo", byteArray ,0)

And can be received with

并且可以收到

#!/usr/bin/python

import time
import mosquitto

def on_message(mosq, obj, msg):
  with open('iris.jpg', 'wb') as fd:
    fd.write(msg.payload)


client = mosquitto.Mosquitto("image-rec")
client.connect("127.0.0.1")
client.subscribe("photo",0)
client.on_message = on_message

while True:
   client.loop(15)
   time.sleep(2)