Help us understand the problem. What is going on with this article?

pythonでMQTT送受信

More than 1 year has passed since last update.

はじめに

このページは,

ドローン操作システムを作ろう

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

概要

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

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

準備するもの

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

参考サイト

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

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側のプログラムです.
コメントを細かく書いておきました.

ダウンロードは ここ を右クリックして保存してください.

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, flag, 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側のプログラムです.
こちらもコメントを多めに書いておきました.

ダウンロードは ここ を右クリックして保存してください.

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, flag, 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側をそれぞれ別の端末(ターミナル)で実行してください.

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
...
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してみたいと思います.

hsgucci
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした