プログラミング

PythonでMQTTを使ってみよう!


Warning: count(): Parameter must be an array or an object that implements Countable in /home/c9962019/public_html/mochinoki-labo.com/wp-content/plugins/rich-table-of-content/functions.php on line 490

こんにちは、MSKです。
IoT機器の開発をやっていると最近はMQTTを通信プロトコルに使いたいと言われることが多々あります。
今日はPythonでMQTTを使っていきながら、どんなものかを簡単に解説したいと思います。

MQTTについての基礎知識

MQTTの概要

MQTTはTCP/IPの上に構築される軽量なデータ通信のための通信プロトコルになります。
MQTTは「Message Queuing Telemetry Transport」の頭文字をとったものになっています。

Publish/Subscribeメッセージ型のプロトコルになっています。
シンプルかつ軽量なプロトコル仕様になっているという説明が多いですが、組み込みエンジニアとしてはシンプルかと言われるとそうは思わない部分も多々あるプロトコルです。

ただ、ある程度有名なプロトコルになりますので、いろいろな言語でライブラリが公開されていて、シーケンスやパケットの中身を知らなくても使えるようになっています。
(僕が開発を行った環境では、ライブラリが用意されておらず仕様書を読みこんでMQTTライブラリを自作しましたが・・・)

MQTTはBroker、Subscriber、Publisherで構成されます。

Broker

メッセージを中継するサーバーの役割を担うのがBrokerになります。
PC上で試す場合にはいくつか有名なソフトがあります。
以下が有名なソフトです。

  • Mosquitto
  • ActiveMQ
  • RabbitMQ
  • VerneMQ

Subscriber

メッセージを受信する側です。
SubscriberはBrokerに対して、あらかじめ欲しいメッセージをTopicというものにより登録をします。
これをSubscribeと言います。

Topicは「/」により階層構造を持っていて、次のような記述をします。

hoge/fuga/piyo
hoge/fuga/hogehoge
hoge/fugaguga/piyo

Topic登録時にワイルドカードというものを使って、一度に複数のTopicを登録することもできます。

Publisher

メッセージを送信する側です。
PublisherからBrokerに対して、またBrokerからSubscriberに対して、メッセージを送ることをPublishと言います。

準備

Pythonの準備

Pythonのインストールから最初のプログラミングまでは、次の記事を参考にしてください。

Pythonをインストールして使ってみよう!今回はPythonのインストールからIDLEでPythonを実行するところまで解説します。 Pythonは機械学習のデファクトスタンダードになっているなど、人気のプログラミング言語ですので、インストールをしてPythonを使うための第一歩を踏み出しましょう!...

プロジェクトを入れるフォルダを作成して、仮想環境を作ります。

python3 -m venv venv

仮想環境を立ち上げて、必要なライブラリをインストールします。

source /venv/bin/activate

PythonでMQTTを扱うためのライブラリはpaho-mqttというものになります。
paho-mqttをインストールします。

pip install paho-mqtt

Brokerを準備する

今回はmosquittoが簡単に使えそうなBrokerだったので、mosquiitoをインストールしたいと思います。
macであればhomebrewで簡単にインストールできます。

brew install mosquitto

インストール時にsubscriber用とpublisher用のクライアントもインストールされています。
mosquitto本体は/usr/local/opt/mosquitto/sbinにインストールされています。
subscriberやpublisher用のソフトは/usr/local/opt/mosquitto/binにインストールされています。

ターミナルでMQTTを試してみる

Brokerを起動します。

/usr/local/opt/mosquitto/sbin/mosquitto

次にSubscriberを準備します。
登録するtopicはtopic/01/とします。

/usr/local/opt/mosquitto/bin/mosquitto_sub -h localhost -t topic/01/

-hでホスト名を、-tで登録するtopicを設定します。

最後にPublisherを立ち上げて、メッセージを送ります。

/usr/local/opt/mosquitto/bin/mosquitto_pub -h localhost -t topic/01/ -m "Hello"

-h、-tはSubscriberと同じ意味ですが、-mは送信するメッセージを設定します。

コマンドを叩くとSubscriber側でHelloというメッセージを受け取ることができると思います。

topicを変えるとSubscriber側にメッセージが届かないことも確認できると思います。

※–helpでコマンドの意味を確認することができます。

/usr/local/opt/mosquitto/bin/mosquitto_sub --help
/usr/local/opt/mosquitto/bin/mosquitto_pub --help

PythonでMQTTをコーディング

ターミナルで確認できたので、次はPythonのプログラムを作って確認をしていきたいと思います。

※paho-mqttの使い方はここにあります。

import paho.mqtt.client as mqtt 

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

#Brokerに接続できたとき
def on_connect(client, userdata, flag, rc):
  print("connect broker:" + str(rc))
  client.subscribe(TOPIC) 

#Brokerと切断したとき
def on_disconnect(client, userdata, flag, 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()

mqtt.Client()でmqttクライアントの実体を作成します。

on_connect、on_disconnect、on_messageとそれぞれ、Brokerとの接続、切断、BrokerからのPublish受信の処理のコールバックを受け取るために登録を行います。

connectの引数に順番にホスト名、ポート、keep alive時間(秒)を設定して接続を試みます。
その後はBrokerからのメッセージを待ちます。

コールバックのon_messageで大切なのは3番目の引数msgで次のメンバを持ちます。
・topic ・・・ topic
・payload ・・・ メッセージ本体
・qos ・・・ qosレベル
・retain ・・・ メッセージを保持するかどうか

Publisherのプログラム

import paho.mqtt.client as mqtt

MQTT_PORT = 1883
KEEP_ALIVE = 60

TOPIC = "topic/01/"

#Brokerに接続できたとき
def on_connect(client, userdata, flag, rc):
  print("Connect Broker:" + str(rc))

#Brokerと切断したとき
def on_disconnect(client, userdata, flag, 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()

基本的にはSubscriberのプログラムと同じですが、Publishが完了した時のコールバックと接続後のpublishが違います。

publishは引数にtopicとメッセージを設定します。
メッセージをPublishできたら、on_publishが呼ばれます。

動作確認

brokerを立ち上げます。

/usr/local/opt/mosquitto/sbin/mosquitto

Subscriber、Publisherを立ち上げます。

python sub.py
python pub.py

Publisherを立ち上げるとSubscriber側のログに送信したメッセージとtopicが表示されると思います。

まとめ

PythonでMQTTを使ってみました。
MQTTはTCP/IPなどの上に構築される軽量な通信プロトコルです。
MQTTに登場するのはメッセージを中継するBroker、メッセージを待ち受けるSubscriber、メッセージを送信するPublisherです。

今回は有名なBrokerであるmosquittoをインストールして使っています。
Pythonではpaho-mqttというものを使って簡単にMQTTの通信を試すことができます。
MQTTを使って操作できる市販のロボットやドローンなどもあるようですので、試してみたいかなと思っています。

最後までご覧いただき、ありがとうございます。

以上、「PythonでMQTTを使ってみよう!」でした。


ABOUT ME
MSK
九州在住の組み込み系エンジニアです。 2児の父親でもあります。 数学やプログラミングが趣味です。 最近RustとReact、結び目理論と曲面結び目理論にはまっています。