【Python】MQTT通信をする方法【Paho】

アイキャッチ画像
  • PythonでMQTT通信をするには?
  • MQTT通信の仕組みとは?
  • Pahoやmosquittoの使い方とは?

本記事ではこのような疑問を解決します。


最近、IoT開発の現場へ参画した際にPythonでMQTT通信を実装しました。

それまで「MQTT通信」という言葉を聞いたことすらなかったのですが、
IoT開発の現場ではよく利用されているみたいですね。

そこで今回はPythonでMQTT通信をする方法を解説します。

MQTTとは?

MQTTとはブローカーを介して軽量なデータを送受信するプロトコルのことです。
※MQTTは「Message Queuing Telemetry Transport」の略

MQTTはHTTPと比較して、ヘッダーサイズを少なくでき、1対多の通信を非同期で行うことができます。

このようにMQTTは通信データ量が少ないことから、ネットワークやデバイスへの負荷が軽くなるため、主にIoT開発において利用される技術になります。

ちなみに筆者がMQTTを用いた現場は顔認証機器とサーバの通信を行うものでした。

そして、MQTT通信にはBroker、Subscriber、Publisherの三者が登場します。


以下の画像で全体像を確認してから、それぞれの中身を見ていきましょう。

MQTT通信

Broker

Brokerとはメッセージを中継するサーバの役割を担うものです。

つまり、Publisherからメッセージを受け取ってSubscriberに渡すという流れです。

Brokerは自身のホスト名やポート番号をPublisher・Subscriberに指定してもらってメッセージの受け渡しを行います。

今回はBrokerとしてmosquittoというパッケージを使用します。

Subscriber

Subscriberとはメッセージを受信する側のことです。

Brokerに対して、あらかじめ欲しいメッセージをトピックというもので登録しておくと、
その登録したトピックのメッセージを受け取ることができます。

なお、トピックは「/」で区切られた階層構造になっていて、以下のように記述します。

・tokyo/shibuya
・tokyo/shibuya/ebisu
・tokyo/shinjuku

ちなみにSubscriberはサーバの場合もあればIoT機器の場合もあります。

Publisher

Publisherとはメッセージを送信する側のことです。

Publisherがトピックを付けてメッセージを送ることで、
Subscriberがそのトピックのメッセージを受け取ることができます。

Publisherについてもサーバの場合もあればIoT機器の場合もあります。

必要なパッケージ・ライブラリをインストールする

MQTT通信の概要をつかめたところで実装に移っていきます。

最初に必要なパッケージ・ライブラリをインストールしていきましょう。

なお、今回はmacOSで開発を進めていきますが、
OSごとに異なる部分はBroker(mosquitto)のインストール方法のみです。

Brokerをインストールする

まずは今回使用するBrokerソフトのmosquittoをインストールします。

$ brew install mosquitto

インストール後、mosquittoを実行してみます。

$ mosquitto

実行結果:
bash: mosquitto: command not found

上記のようにパスが通っていないなどの理由でmosquittoを起動できない場合があります。
(起動できている場合はこちらは飛ばしてください!)

その場合は以下のコマンドを実行して”Warning”に従って問題を潰していきましょう。

$ brew doctor

実行結果:
Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry or file an issue; just ignore this. Thanks!

Warning: Homebrew's "sbin" was not found in your PATH but you have installed
formulae that put executables in /usr/local/sbin.
Consider setting your PATH for example like so:
echo 'export PATH="/usr/local/sbin:$PATH"' >> /Users/kosuke/.bash_profile

ちなみに「brew doctor」はHomebrewにおける問題点をチェックしてくれるコマンドです。

$ echo 'export PATH="/usr/local/sbin:$PATH"' >> /Users/kosuke/.bash_profile

上記でパスを通したら再度mosquittoを起動します。

$ mosquitto

実行結果:
1669536205: mosquitto version 2.0.15 starting
1669536205: Using default config.
1669536205: Starting in local only mode. Connections will only be possible from clients running on this machine.
1669536205: Create a configuration file which defines a listener to allow remote access.
1669536205: For more details see https://mosquitto.org/documentation/authentication-methods/
1669536205: Opening ipv4 listen socket on port 1883.
1669536205: Opening ipv6 listen socket on port 1883.
1669536205: mosquitto version 2.0.15 running

これでmosquittoが動作することを確認できました。

一旦、「control + C」で終了しておきましょう。

なお、WindowsやLinuxをお使いの方はこちらを参考にインストールしてください。

Windowsの方はインストーラをダウンロードし、
Linuxの方は各ディストリビューションのパッケージ管理ツールを使ってインストールする形になります。

ちなみに、筆者は実際の開発現場ではWindows環境だったので、
インストール後はWindowsサービス(デーモン)として動かしました。

Pythonライブラリをインストールする

それぞれお使いのPythonパッケージ管理ツールでpaho-mqttをインストールします。

$ pip install paho-mqtt

Pythonスクリプトを記述する

ここではSubscriber・Publisher両者のPythonスクリプトを記述していきます。

Subscriber

Subscriber側のコードを以下のように記述します。

import paho.mqtt.client as mqtt

MQTT_PORT = 1883
KEEP_ALIVE = 60
TOPIC = "topic/B/"

# Brokerに接続した時の処理
def on_connect(client, userdata, flag, rc):
  print("connect broker:" + str(rc))
  client.subscribe(TOPIC)

# Brokerから切断した時の処理
def on_disconnect(client, userdata, rc):
  if  rc != 0:
    print("disconnect broker")

# メッセージを受信した時の処理
def on_message(client, userdata, msg):
  print("Received message '" + str(msg.payload) + "' on topic '" + msg.topic + "' with QoS " + str(msg.qos))


client = mqtt.Client()
# コールバック関数を登録する
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_message = on_message

client.connect("localhost", MQTT_PORT, KEEP_ALIVE)

# メッセージを待ち受ける
client.loop_forever()

Publisher

Publisher側のコードを以下のように記述します。

import paho.mqtt.client as mqtt

MQTT_PORT = 1883
KEEP_ALIVE = 60

TOPIC = "topic/B/"

# Brokerに接続した時の処理
def on_connect(client, userdata, flag, rc):
  print("Connect Broker:" + str(rc))

# Brokerから切断した時の処理
def on_disconnect(client, userdata, rc):
  if rc != 0:
     print("disconnect broker")

# publishが完了した時の処理
def on_publish(client, userdata, mid):
  print("publish Done")


client = mqtt.Client()

# コールバック関数を登録する
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish

client.connect("localhost", MQTT_PORT, KEEP_ALIVE)

client.publish(TOPIC,"Hello!")
client.disconnect()

実際にMQTT通信をしてみる

それでは実際にMQTT通信を行なってみましょう。

ここではデーモンとして処理を実行しないため、
Broker、Subscriber、Publisherをそれぞれ起動するためのターミナルの画面を3つ用意します。

まずはBrokerであるmosquittoを起動します。

$ mosquitto

次にSubscriberであるsubscriber.pyを実行してメッセージを待ち受けます。

$ python subscriber.py

最後にPublisherであるpublisher.pyを実行してメッセージを送ります。

$ python publisher.py

すると、それぞれのターミナルで以下のような実行結果が出力されます。

Broker(mosquitto)

1670056569: New connection from ::1:50373 on port 1883.
1670056569: New client connected from ::1:50373 as auto-79C5DD35-D437-E667-CD6D-ADE8941C00CA (p2, c1, k60).
1670056573: New connection from ::1:50379 on port 1883.
1670056573: New client connected from ::1:50379 as auto-0566DAAB-DD1A-374C-DDDB-5DEAEF85E8E9 (p2, c1, k60).
1670056573: Client auto-0566DAAB-DD1A-374C-DDDB-5DEAEF85E8E9 disconnected.

Subscriber(subscriber.py)

connect broker:0
Received message 'b'Hello!'' on topic 'topic/B/' with QoS 0

Publisher(publisher.py)

publish Done

これで無事にMQTT通信が行われたことを確認できました!

まとめ

以上がPythonでMQTT通信をする方法になります。

急速なIT化によってIoT開発の分野は絶賛市場拡大中です。

Pythonで簡単にMQTT通信ができたら可能性が拡がるのではないでしょうか。

本記事がIoT開発をするきっかけになったら嬉しいです。