節約プログラマー雑記

MQTTブローカーの構築

以前、Arduinoで温度センサーのデータを取得してMQTTで送信することを行いました。今度はその送られたデータを受け取って処理する仕組みをRaspberry pi上に構築しましたので、紹介していこうと思います。

1. 下準備

1-1. MQTTブローカーのインストール

Linuxにはmqttを受け付けるブローカーのソフトとして、mosquittoがありますので、まずはこちらをyum install mosquittoなどでインストールします。

mosquittoは特に設定を行わずとも利用の出来るソフトになっていますので、インストールが完了したら、systemctl start mosquittoでmosquittoを開始すれば、ブローカーの準備は完了です。

1-2. pythonライブラリのインストール

ブローカーのインストールが完了したら、今度はアプリでMQTTが利用できるように、ライブラリのインストールを行います。今回はpythonでの利用を考えていますので、pip install pahoコマンドを実行し、正常終了すれば下準備が全て完了です。

実際にpahoを使い、MQTTクライアントを実装したサンプルが次の章になります。

2. サンプルソース

ファイル名:mqtt_subscribe.py

import paho.mqtt.client as mqtt
import MySQLdb
from module.db_con import DbConn
import logging
import traceback

host = '127.0.0.1'
port = 1883
topic = 'sensor/+'
formatter = '%(levelname)s : %(asctime)s : %(message)s'
logging.basicConfig(filename = '/tmp/mqtt_log.log',level=logging.INFO, format=formatter)

def on_connect(client, userdata, flag, rc):
    print('status {0}'.format(rc))
    logging.info('subscribe start')
    client.subscribe(topic)

def on_disconnect(client, userdata, flag, rc):
    if rc != 0:
        print("Unexpected disconnection.")
        logging.info("Unexpected disconnection.")

def on_message(client, userdata, msg):
    try:
        #analyze mqtt_data
        sensor_id = msg.topic.split('/')[1]
        data = msg.payload.decode('utf-8')
        temperature = str(data).split(';')[0]
        humidity = str(data).split(';')[1]
        # Execute Insert Data
        db = DbConn()
        con = db.conn
        cur = db.cur
        sql = "INSERT INTO sensor_data (sensor_id, time, temperature, humidity) VALUES ( %s, now(), %s, %s)"
        cur.execute(sql,(sensor_id,temperature,humidity))
        con.commit()
        con.close()
    except:
        logging.error(traceback.format_exc())


if __name__ == '__main__':
    client = mqtt.Client()
    client.on_connect = on_connect
    client.on_disconnect = on_disconnect
    client.on_message = on_message

    client.connect(host, port, 60)

    client.loop_forever()

raspberry pi上で動いているmosquittoに対して、'sensor/'のトピック名で飛んできたデータをMySQLに登録する内容となっています。

pahoの構造として、on_connect関数にブローカーに接続したときの挙動と、どのトピック名を購読するかを記載し、on_message関数にメッセージを受信したときの挙動を記載して、後はmain関数で実行するような作りとなっています。

ソースが完成したら、python mqtt_subscribe.py &などで、バックグラウンド実行させれば、常にMQTTを監視し続ける状態になります。

3. 結果

MQTTクライアントの実装が完了すると、「Arduino(ESP32)とMQTTで温湿度データ送信」で送信されたデータを受信し、MySQLにタンキングしていくことができました。

そしてデータのタンキングができるようになったことで、後は「Chart.jsで家計簿をグラフ化」で紹介したようにChart.jsとDjangoを使って、今の部屋の気温の推移を見ていくことができるようになりました。

Sensor_data.png

今回はまだまだ、気温を可視化するにとどまっていますが、ブローカーさえ立ててしまえば、双方向の通信ができるようになりますので、センサー端末への指示やRaspberry piからエアコンの自動制御などもできますので、まだまだやれることは多そうです。(正直、そこまでやるのは面倒ですが笑)

ただ、近年は様々な機器に通信と制御機能が組み込まれており、その手法の一環としてMQTTを勉強するのはとても面白いし、汎用的ですのでおススメです。