我正在使用python-mosquitto订阅我的MQTT代理,该代理支持文件类型上传.从命令行在Mosquitto上使用-f标志可以很好地使用它.但是,当我从python脚本中执行操作时,我无法弄清楚如何使用client.publish(topic,有效负载)指定要发布的文件.
当我尝试向它扔一些奇怪的东西时,Python mosquitto给了我错误TypeError: payload must be a string, bytearray, int, float or None..我已经有一个文件存储在本地目录中,我想将其指定为发布的有效负载.
我对MQTT很有经验,但是我的python非常生锈,我假设我需要在此处执行某种类型的文件流功能,但不确定如何做到这一点.
我要在此处指定图像:mqttc.publish("/v3/device/file", NEED_TO_SPECIFY_HERE)
我尝试通过以下方式打开图像:
f = open("/home/pi/mosq/imagecap/imagefile.jpg", "rb") imagebin = f.read() mqttc.publish("/v3/device/file", imagebin)
但这没用,mqttc.publish("/v3/device/file", bytearray(open('/tmp/test.png', 'r').read()))
也没有client.publish不会引发错误,但是代理未正确接收文件.有什么想法吗?
谢谢!
值得注意的是,这是Python 2和Python 3之间可能存在差异的领域之一.
Python 2 file.read()返回str,而Python 3是bytes. mosquitto.publish()处理这两种类型,因此在这种情况下您应该没事,但这是需要注意的.
我在下面的@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()
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 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.
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.
I want to specify the image 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()))
The client.publish doesnt throw an error with those, but the file is not received properly by the broker. Any ideas?
Thanks!!
It's worth noting that this is one of the areas that can have differences between Python 2 and 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.
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.
#!/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()