5

ファイルタイプのアップロードをサポートする MQTT ブローカーにサブスクライブするために python-mosquitto を使用しています。コマンドラインで Mosquitto から移動するときに -f フラグを使用して問題なく使用できます。ただし、pythonスクリプト内から実行するときに、client.publish(topic、payload)を使用して公開するファイルを指定する方法がわかりません。

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 はそれらでエラーをスローしませんが、ファイルはブローカーによって適切に受信されません。何か案は?

ありがとう!!

4

2 に答える 2

12

パブリッシュは一度にファイル全体である必要があるため、ファイル全体を読み込んで一度にパブリッシュする必要があります。

次のコードが機能します

#!/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)

と受け取ることができます

#!/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)
于 2013-10-22T07:37:25.907 に答える
6

これは、Python 2 と Python 3 で異なる可能性のある領域の 1 つであることは注目に値します。

Python 2file.read()は a を返しますが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()
于 2013-10-22T09:11:10.913 に答える