Blog

BLOG

2019.11.18

MQTTライブラリ Paho Python を理解しようとしてみる

このエントリーをはてなブックマークに追加

こんにちは、R&Mグループの内田です。

最近、IoT向けといわれているプロトコル「MQTT」を使い始めてみました。

様々なモノとモノがつながるIoTでは各デバイス・サーバの間でデータの受け渡しが発生します。

MQTTは軽量であること、ネットワーク環境が不安定でも動作すること、1対多通信などの特徴があり、IoT向けといわれているようです。
QoS(通信保障),Retain(最終メッセージ保存),will(遺言)など様々な機能が備わっています。

MQTTでは中継サーバである「Broker(ブローカ)」とクライアントである「Publisher(パブリッシャ)」、「Subscriber(サブスクライバ)」という3種類の役割が登場します。

主なメッセージ配信の流れは

  1. SubscriberはあらかじめどのTopic(アドレス)を購読するかbrokerに登録しておく
  2. PublisherがTopicを指定し、Brokerへメッセージを配信する
  3. Brokerはpublisherが指定したTopic購読中のSubscriber(複数可)へ配信する

といった形です。

  • 参考: 絵で見てわかるIoT/センサの仕組みと活用<翔泳社> 
  • 著    : 株式会社NTTデータ,河村雅人,大塚紘史,小林佑輔,小山武士,宮崎智也,石黒佑樹,小島康平

さて、タイトルにあるPahoについてです。
※今回MQTTの各環境立ち上げについては割愛します。気になった方はネットで検索などしてみてください。

Pahoは、MQTTのクライアント(Publisher/Subscriber)を実装するためのライブラリです。
対応言語は複数あるようですがPythonを使いました。

試しに以下のスクリプトを作ってみます。

Publisher:topic名="Topic1"に "test1"というメッセージを送信する
Subscriber :topic名="Topic1"のメッセージを受け取る

Publisher(pub_test1.py)

# -*- coding: utf-8 -*-

import paho.mqtt.client as mqtt  # ライブラリのimport

# MQTT Broker
MQTT_HOST = "MQTT_broker"       # brokerのアドレス
MQTT_PORT = 1883                # brokerのport
MQTT_KEEP_ALIVE = 60            # keep alive

# broker接続時
def on_connect(mqttc, obj, flags, rc):
    print("rc: " + str(rc))             # 接続結果表示

mqttc = mqtt.Client()    #clientオブジェクト作成
mqttc.on_connect = on_connect  # 接続時に実行するコールバック関数設定

mqttc.connect(MQTT_HOST, MQTT_PORT, MQTT_KEEP_ALIVE)  # MQTT broker接続

mqttc.loop_start() # 処理開始

mqttc.publish("topic1", "test1")  # topic名="Topic1"に "test1"というメッセージを送信

Subscriber(sub_test1.py)

import paho.mqtt.client as mqtt

# MQTT Broker
MQTT_HOST = "MQTT_broker"       # brokerのアドレス
MQTT_PORT = 1883                # brokerのport
MQTT_KEEP_ALIVE = 60            # keep alive

# broker接続時
def on_connect(mqttc, obj, flags, rc):
    print("rc: " + str(rc))

#メッセージ受信時
def on_message(mqttc, obj, msg):
    print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))

mqttc = mqtt.Client()
mqttc.on_message = on_message  # メッセージ受信時に実行するコールバック関数設定
mqttc.on_connect = on_connect
mqttc.connect(MQTT_HOST, MQTT_PORT, MQTT_KEEP_ALIVE)

mqttc.subscribe("topic1")  # Topic名:"topic1"を購読

mqttc.loop_forever()  # 永久ループ

実行結果

# python pub_test1.py
rc: 0

# python sub_test1.py
rc: 0
topic1 0 b'test1'

無事メッセージを受け取ることができました。

次に、受け取ったメッセージ次第でメインのループの処理を変えたいなと思ったのですが
on_message側から、mainループに値を返す or 共有する方法はないのか調べてみました。

以下サイトを読み解いてみると

コールバック関数は別スレッドで動いて非同期なので
on_messageのコールバック関数で変数をglobal宣言をして値を共有するのが正解みたいです。

Subscriberを改造してみます。

Publisher:topic名="Topic1"に "test1"というメッセージを送信する
Subscriber :topic名="Topic1"のメッセージを受け取ったらフラグ有効化し、ループを抜ける

Subscriber(sub_test2.py)

# -*- coding: utf-8 -*-

import paho.mqtt.client as mqtt
import time

# MQTT Broker
MQTT_HOST = "MQTT_broker"       # brokerのアドレス
MQTT_PORT = 1883                # brokerのport
MQTT_KEEP_ALIVE = 60            # keep alive

# broker接続時
def on_connect(mqttc, obj, flags, rc):
    print("rc: " + str(rc))

#メッセージ受信時
def on_message(mqttc, obj, msg):
    global on_message_Flag         # メインループと共有するグローバル変数
    print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
    on_message_Flag=True          # flagを有効化

mqttc = mqtt.Client()
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.connect(MQTT_HOST, MQTT_PORT, MQTT_KEEP_ALIVE)

mqttc.subscribe("topic1")
mqttc.loop_start()
on_message_Flag=False                # 共有するグローバル変数
i=0
while True:
    print(i)
    i+=1
    time.sleep(1)
    if on_message_Flag:              # フラグがTrueになるとループEND
        print("END!")
        break

実行結果

# python pub_test1.py
rc: 0

# python sub_test2.py
0
rc: 0
1
2
3
4
5
topic1 0 b'test1'
END!

メッセージを受け取ったのち無事ループを抜けました。

いろいろインターネットで検索をかけたり、公式のexamplesを参考にすると、もっと色々なことができそうですね!

関連記事
一緒に開発しませんか?

サンビット株式会社では、開発技術者を募集しています!
興味のある方はぜひお問い合わせください。

カレンダー

«11月»
     1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

最近のエントリー

水木しげるさんの戦記を読む|戦後90年に向けて

2026.04.27

水木しげるさんの戦記や関連著作を5冊読み比べながら、それぞれの本の魅力と心に残った点を紹介します。戦争の過酷さや生き残ったことの重みが描かれる一方で、文章や絵の力によって不思議と「もっと知りたい」と思わされる読書体験が綴られています。戦後90年に向けて、戦争を知らない世代が何を受け取り、どうつないでいくかを考えるきっかけになる内容です。

Salesforce のダッシュボードの機能 〜動的ゲージグラフの数式を使った目標値〜

2026.04.24

Salesforceの動的ゲージグラフにおいて、数式を用いた目標値の設定方法を解説します。年間目標から月次目標を算出する基本的な使い方に加え、役職や勤続年数に応じて目標値を変動させる方法を紹介。IF関数や日付項目を活用することで、複数条件に基づいた柔軟な目標設定が可能になります。さらに、カスタムオブジェクトやフローを組み合わせることで、より高度な管理にも対応できる点についても触れています。

春のアレルギーに負けないためのシンプル習慣

2026.04.20

春は新生活のスタートとともに、アレルギーに悩まされる方も多い季節です。対処療法で乗り切ってきた中で、睡眠や食事といった基本を見直すことで体調の安定を実感しています。

ラージボール卓球 ~2025年度ラージボール卓球選手権大会(年齢別シングルス)

2026.04.13

2026年2月に開催された佐賀県ラージボール卓球選手権大会に出場し、60~64歳クラスで優勝した体験を振り返ります。予選リーグを順調に勝ち上がり、トーナメントでは日頃から対戦経験のある選手との接戦を制して決勝へ。決勝ではファイナルゲームまでもつれる白熱した試合となり、最後は接戦をものにしました。これまでの経験や戦術の変化を実感しながら、試合ならではの緊張感も味わうことができました。

アーカイブ

ブログ内検索

  1. TOP
  2. BLOG
  3. MQTTライブラリ Paho Python を理解しようとしてみる