IoTで使うPython入門Step2-MQTT (2) Publisher/Subscriver

 前回、MQTTを利用する中でかなめになるBrokerのソフトmosquittoをラズパイ・ゼロにインストールしました。アクセスするときは、hostnameがraspberrypiなので、raspberrypi.localもしくは今回固定アドレスをふった192.168.111.51を使います。もし用意できないときは、test.mosquitto.orgなどの公開サーバを利用もできます。
 ここでは、MQTTの仕組みを簡単に説明します。

MQTTは非同期通信

 Brokerに対して、たくさんのクライアントがいます。センサのデータを送るのはクライアントの中でPublisher、Brokerからセンサ・データを受け取るのがSubscriverと呼ばれます。


 センサのデータは「メッセージ」で伝えられます。Publisherが「メッセージ」を発行してBrokerに届きます。そのメッセージをSubscriverが購読します。Brokerは一時的に「メッセージ」をためておきます。
 通常、1対1でPublisherとSubscriverが「メッセージ」をやり取りするためには、両方が送信と受信のタイミングを同期しなければなりません。プログラム的には、Subscriverは「メッセージ」を待ち続けるという状態です。
 それは1対1でも大変だし、1000対1になろうものなら、対応するのは無理かもしれません。でも、センサの数はうなぎのぼりに増えていきます。途中にBrokerをはさむことで、MQTTは非同期通信の形態にして解決したのです。

 Publisherは誰が、何台自分の送ったメッセージを受け取るかは知りません。SubscriverはどのPublisherから発行されたものかを知らずに受け取ります。その出会い系サイトがBrokerです。互いに何か取り決めがないとよい結婚相手には巡り合えません。そのためのルールがちょっとだけあります。

メッセージの中身

 メッセージは、「ヘッダ、Topic、payload」から構成されています。メッセージはTopic別に扱われます。

 センサで測定した温度データがあります。ラズパイ-2につながっているLM75Bの1個目で読み出したとします。Topicを次のように書きます。

raspberrypi-2/lm75b-1/temp

 センサで測定した温度データがあります。ラズパイ-2につながっているLM75Bの2個目で読み出したとします。Topicを次のように書きます。

raspberrypi-2/lm75b-2/temp

 センサで測定した温度データがあります。ラズパイ-2につながっているSHT31の1個目で読み出したとします。Topicを次のように書きます。

raspberrypi-2/sht31-1/temp

 センサで測定した湿度データがあります。ラズパイ-2につながっているSHT31の1個目で読み出したとします。Topicを次のように書きます。

raspberrypi-2/sht31-1/RH

 tempとRHの発行した温度や湿度の内容=payloadは、毎回異なります。

 上記のように、Topicはスラッシュで区切られた階層構造をもちます。Subscriverはワイルド・カードを指定できます。Subscriverは複数のTopicを購読できます。いいかえると、BrokerはそのTopicを購読しているすべてのSubscriverにメッセージを転送します。

 ちょっと整理。
 Subscriverがメッセージを受信することをサブスクライブといいますが、購読をここでは使っています。Publisherがメッセージを送信することをパブリッシュといいますが、発行をここでは使っています。

 Topicはテキストです。mosquittoはutf-8です。
 payloadはJSON形式のテキストが使われることが多いです。そうでないこともあります。ヘッダは2バイトで、httpに比べても小さいのが特徴です。

paho-mqttのインストールと送信テスト

 PythonのMQTTライブラリをインストールします。インストールしているのは2台目のrasberrypiというhostnameのマシンです。アドレスはraspberrypi-2.local(192.168.111.113)です。

pip install paho-mqtt

 発行を行うプログラムpublish.pyの内容です。実行権を付けて、ターミナルでpython publish.pyで動かします。

  • Broker(raspberrypi.local)に対して
  • Topicは「raspberrypi-2/lm75b-1/temp」
  • payloadは「23.0度」という毎回同じダミー・データ

を1秒ごとに発行しています。

#coding:utf-8
import paho.mqtt.publish as publish
from time import sleep

topic = "raspberrypi-2/lm75b-1/temp"
host = "raspberrypi.local"

while 1:
publish.single(topic, "23.0度", hostname=host)
sleep(1)

 paho.mqtt.pythonのドキュメントはこちらにあります。

テストに使うクライアント

 クライアントのソフトウェアをインストールします。

sudo apt-get install mosquitto-clients

 ターミナルで利用できるMQTT用のツールです。インストールして動かしているのは、3台目のラズパイです。hostnameはraspberrypiで、アドレスはraspberrypi-3.local(192.168.111.115)です。Broker(raspberrypi.local)からTopicが「raspberrypi-2/lm75b-1/temp」なるものを購読しています。
 payloadの中身「23.0度」を正しく購読できています。

mosquitto_sub -d -t raspberrypi-2/lm75b-1/temp -h raspberrypi.local

 2台目のラズパイ、つまりPublishしているマシンでも動かしましたが、同じ結果です。

  3台のラズパイの関係です。

 

 次回、Node-REDで通信の様子を観測しますが、そこでも、同じようにデータを表示できています。

(※)paho-mqttのドキュメント paho.mqtt.pythonのソース