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しているマシンでも動かしましたが、同じ結果です。
次回、Node-REDで通信の様子を観測しますが、そこでも、同じようにデータを表示できています。