pythonでMQTT送受信

# はじめに
このページは，

[ドローン操作システムを作ろう](https://qiita.com/hsgucci/items/86eedb5555b4234ee0e7)

の１ページです．
全体を見たい場合は上記ページへお戻りください．

# 概要

前回はmosquittoのコマンドラインツールを使って，PublishとSubscribeを行いました．
今回はPythonプログラムでPublishとSubscribeを行います．

いい加減，Publish/Subscribeと書くのが大変になってきたので，
今後はPub/Subと省略して書こうと思います(^^;)

# 準備するもの

今回もdronekit-sitlのために準備したUbuntu Linuxの入ったＰＣを利用します．

# 参考サイト

このサイトのプログラムを改変しました．

**Raspberry PiでMQTTの動作環境を作る（RabbitMQ + Paho + Python）**
https://make-muda.net/2015/06/2898/

当該サイトは，ブローカーにRabbitMQを使っているのですが，
Pythonプログラムは，どんなブローカーにも繋がるので，
一番シンプルで読みやすかったここのプログラムを利用させてもらいました．

# Pythonライブラリのインストール

PythonでMQTTを取り扱うためには，**paho-mqtt**というライブラリを使用します．
そのため，pipコマンドを使ってインストールする必要があります．

```
$pip install paho-mqtt
```

※pipの利用状況によっては`sudo`を付けてルート権限でインストールしないといけないかもしれません．


# Subscribeプログラム
Sub側のプログラムです．
コメントを細かく書いておきました．

ダウンロードは　[ここ](https://raw.githubusercontent.com/DCoJA/OpenUVTM/master/chapter08/sample_sub.py)　を右クリックして保存してください．

```python:sample_sub.py
#!usr/bin/env python
# -*- coding: utf-8 -*- 

import paho.mqtt.client as mqtt     # MQTTのライブラリをインポート
 
# ブローカーに接続できたときの処理
def on_connect(client, userdata, flag, rc):
  print("Connected with result code " + str(rc))  # 接続できた旨表示
  client.subscribe("drone/001")  # subするトピックを設定 

# ブローカーが切断したときの処理
def on_disconnect(client, userdata, rc):
  if  rc != 0:
    print("Unexpected disconnection.")

# メッセージが届いたときの処理
def on_message(client, userdata, msg):
  # msg.topicにトピック名が，msg.payloadに届いたデータ本体が入っている
  print("Received message '" + str(msg.payload) + "' on topic '" + msg.topic + "' with QoS " + str(msg.qos))

# MQTTの接続設定
client = mqtt.Client()                 # クラスのインスタンス(実体)の作成
client.on_connect = on_connect         # 接続時のコールバック関数を登録
client.on_disconnect = on_disconnect   # 切断時のコールバックを登録
client.on_message = on_message         # メッセージ到着時のコールバック
 
client.connect("localhost", 1883, 60)  # 接続先は自分自身
 
client.loop_forever()                  # 永久ループして待ち続ける
```

#Publishプログラム
Pub側のプログラムです．
こちらもコメントを多めに書いておきました．

ダウンロードは　[ここ](https://raw.githubusercontent.com/DCoJA/OpenUVTM/master/chapter08/sample_pub.py)　を右クリックして保存してください．

```python:sample_pub.py
#!usr/bin/env python
# -*- coding: utf-8 -*- 

import paho.mqtt.client as mqtt     # MQTTのライブラリをインポート
from time import sleep              # 3秒間のウェイトのために使う

# ブローカーに接続できたときの処理
def on_connect(client, userdata, flag, rc):
  print("Connected with result code " + str(rc))

# ブローカーが切断したときの処理
def on_disconnect(client, userdata, rc):
  if rc != 0:
     print("Unexpected disconnection.")

# publishが完了したときの処理
def on_publish(client, userdata, mid):
  print("publish: {0}".format(mid))

# メイン関数   この関数は末尾のif文から呼び出される
def main():
  client = mqtt.Client()                 # クラスのインスタンス(実体)の作成
  client.on_connect = on_connect         # 接続時のコールバック関数を登録
  client.on_disconnect = on_disconnect   # 切断時のコールバックを登録
  client.on_publish = on_publish         # メッセージ送信時のコールバック

  client.connect("localhost", 1883, 60)  # 接続先は自分自身
 
  # 通信処理スタート
  client.loop_start()    # subはloop_forever()だが，pubはloop_start()で起動だけさせる

  # 永久に繰り返す
  while True:
    client.publish("drone/001","Hello, Drone!")    # トピック名とメッセージを決めて送信
    sleep(3)   # 3秒待つ

if __name__ == '__main__':          # importされないときだけmain()を呼ぶ
  main()    # メイン関数を呼び出す
```



**※末尾のif文について**
`__name__ `に `'__main__'`が入っているとき，というのは，
`python sample_pub.py` のようにファイル自身が実行された事を意味しています．

`__name__ `に `'__main__'`が入っていない場合は，
`import sample_pub` のように別のプログラムからサブルーチンとして呼び出された事を意味します．

すなわち，`if __name__ == '__main__':`の中に書かれた命令は，
自分自身が実行されたときにだけ動作させたい，という意志で書かれています．
Pythonプログラムでよく使われる記述です．

# 実行と実行結果

sub側，pub側をそれぞれ別の端末(ターミナル)で実行してください．

```bash:sample_sub.pyの実行画面
$python sample_sub.py
Connected with result code 0
Receive message 'Hello, Drone!' on topic 'drone/001' with QoS 0
Receive message 'Hello, Drone!' on topic 'drone/001' with QoS 0
Receive message 'Hello, Drone!' on topic 'drone/001' with QoS 0
...
```

```bash:sample_pub.pyの実行画面
$python sample_pub.py
Connected with result code 0
publish: 1
publish: 2
publish: 3
...
```

sample_pub.pyが3秒おきに送ってくるメッセージを，
sample_sub.pyが受信している様子がわかると思います．

# おわりに

pythonプログラムからメッセージの送受信ができました．
次回はdronekit-sitlの情報をPub/Subしてみたいと思います．



[^2]: Raspberry PiでMQTTの動作環境を作る（RabbitMQ + Paho + Python） https://make-muda.net/2015/06/2898/