MQTTをWebブラウザで受信してみる


はじめに

このページは,

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

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

概要

前回は,dronekit-sitl(シミュレータドローン)の機体情報を
MQTTのPythonプログラムでPublish/Subscribeしました.

今回はSubするのをPythonではなくて,JavaScriptに変更し,
Webブラウザからメッセージを見てみます.

準備するもの

  • これまで使用したLinux PC
      今回は,このPCにWebサーバーを立てます.
      MQTTのSub側のプログラムをHTML/JavaScriptで書きます.

  • 前回のPub側プログラム
      dronekit-sitlの情報をJSONでPubするプログラム,これ です.

セットアップ(Webサーバ)

まずは,更新情報を最新のものにしておきます.

aptのリポジトリを最新に
$sudo apt update

次に,Webサーバ(apache2)をインストールします.
(taskselでLAMP serverをインストールしてもいいです)

aptでインストール
$sudo apt install apache2

インストールが完了したら,Webブラウザでhttp://localhost/を開いてみてください.

ブラウザにこんなページが表示されればインストール成功です.

MQTTブローカーの設定

WebブラウザでMQTTを直接受信することはできないので,
WebSocketを利用して通信します.
これをMQTT over WebSocketと言います.

WebSocketの通信ができるように,MQTTブローカー(mosquitto)の設定を変更する必要があります.

mosquittoの設定ファイル
/etc/mosquitto/mosquitto.conf
を,コンソールであればviやnano,あるいはGUIのテキストエディタで編集します.
その際,管理者権限が必要なのでsudoを付けます.

nanoで編集する場合
$sudo nano /etc/mosquitto/mosquitto.conf

mosquitto.confファイルの先頭に,以下の行を追加します

listener 1883
listener 15675
protocol websockets

これは,
・MQTTを1883番ポートで受信する
・WebSocketを15675番ポートで受信する
を意味しています.

#はコメント行なので,実際にはこんな風になります.

mosquitto.conf
# Place your local configuration in /etc/mosquitto/conf.d/
#
# A full description of the configuration file is at
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example

# ここに3行追加した
listener 1883
listener 15675
protocol websockets

pid_file /var/run/mosquitto.pid

persistence true
persistence_location /var/lib/mosquitto/

log_dest file /var/log/mosquitto/mosquitto.log

include_dir /etc/mosquitto/conf.d

設定が終わったらエディタを終了します.
(nanoの場合,Ctrl+oでファイルを保存し,Ctrl+xで終了)

その後,mosquittoサービスを再起動します.

mosquittoの再起動
$sudo systemctl restart mosquitto

HTMLファイルを取得する

MQTTを受信するWebページを作ります.

まずは,サンプルプログラムをダウンロードしましょう.

参考にするのは,このページです.
https://github.com/rabbitmq/rabbitmq-web-mqtt-examples
このexamplesはMQTTブローカーとしてRabbitMQを使うサンプルですが,
ポート番号さえ合っていればmosquittoでも問題なく使用できます.

このgitのprivフォルダ以下にある,echo.htmlmqttws31.jsが必要です.
htmlというフォルダを作ってダウンロードします.

$mkdir ~/html/
$cd ~html
$wget https://raw.githubusercontent.com/rabbitmq/rabbitmq-web-mqtt-examples/master/priv/echo.html
$wget https://raw.githubusercontent.com/rabbitmq/rabbitmq-web-mqtt-examples/master/priv/mqttws31.js

(wgetで直接ダウンロードしなくても,gitで
$git clone https://github.com/rabbitmq/rabbitmq-web-mqtt-examples
ですべてダウンロードして当該ファイルを取り出しても良いです.)

HTMLファイルを書き換える

ダウンロードしたecho.htmlを,本企画のMQTTに合わせて変更します.
適当なテキストエディタで編集してください

主な変更箇所は2つです.
86行目
message.destinationName = "/topic/test";
 ↓
message.destinationName = "drone/001";

112行目
client.subscribe('/topic/test', {qos: 1});
 ↓
client.subscribe('drone/#', {qos: 1});

また,RabbiMQブローカーを使っていないのに,
RabbitMQ Web MQTT Example
と表示されるのは気持ち悪いので,
5行目48行目
Drone Control Web MQTT Example
と書き換えました.(これは必須の作業ではありません)

変更済みのHTMLファイルを ここ においておきます.

解説

86行目は,エディットボックスに打ち込んだメッセージをMQTTでPublishする際のトピック名です.
これまでの記事で取り扱ってきたトピック名と同じ'drone/001'にしました.

112行目は,MQTTでSubscribeするトピック名です.
注目すべきは,'drone/#'となっていて001ではない点です.
#というのはMQTTトピックのワイルドカードです.
端末のコマンドラインで言えばアスタリスク*です.
したがってdrone/の後には様々な文字列が入って良いことになりますから,
トピック名drone/001はもちろんSubしますが,
drone/002でもdrone/quad/05でもSubします.
つまり,1号機,2号機,クワッド5号機,,,のように,
複数台のドローンのメッセージを同時に受信できるのです.

複数のドローンの位置情報を把握し,
お互いの位置関係を見ながら操作を決めるのは,
航空管制にとって重要な機能ですね.

HTMLファイルをWebサーバのフォルダに置く

編集済みのecho.htmlmqttws31.jsを,
Webサーバのホームディレクトリである/var/www/htmlへコピーします.
このフォルダの操作には管理者権限が必要なので,sudoをつける必要があります.

ファイルのコピー
$cd ~/html
$sudo cp echo.html /var/www/html/
$sudo cp mqttws31.js /var/www/html/

Subscribe側のWebブラウザを開く

それでは,Webブラウザを起動し,アドレス欄にURLを
http://localhost/echo.html
と打ち込んでEnterキーを押してください.
WebブラウザはChromiumでもFireFoxでも,どちらでも大丈夫です.

このようなページが表示されれば,ファイルのコピーは成功です.

また,Logsと書かれたエディットボックスに注目してください.

このように,CONNECTION SUCCESSと出ていれば,
MQTTブローカーへの接続が成功しています.

しかし,もしもCONNECTION FAILUREと出ていたら,失敗です.

・MQTTブローカーが起動していない
・MQTTブローカーのWebSocket設定がうまくいっていない
・ファイアウォールが勝手にブロックしている

などの原因が考えられます.


次に
Receivedのボックスの下にある,
Type here...と書かれた一行だけのボックスに何かメッセージを打ち込んで,
Enterキーを押してみてください.

例えば,hogeと打ち込んでEnterすると,このようになります.

Logsのボックスを見てみると,
SEND ON drone/001 PAYLOAD hoge
と書かれていますから,トピック名 "drone/001" メッセージ "hoge" をPublishしたことがわかります.
また,
RECEIVE ON drone/001 PAYLOAD hoge
と書かれているので,Pubされたメッセージを即座にSubしたこともわかります.
Subしたデータ(hoge)そのものは,Receivedのボックスに表示されています.

Publish側のdronekit-sitlを起動する

それでは,Pub側のシミュレータを起動してみましょう.
前回の記事で作ったsitl_mqtt_pub_json.pyを起動します.

シミュレータの起動
$python sitl_mqtt_pub_json.py 

実行結果

一連の設定がうまくできていれば,
drone/001というトピック名でSubされたメッセージがし,
ReceivedおよびLogsに表示されます.

おわりに

今回は,PythonのMQTTがPublishしたドローンの位置情報を,
WebブラウザでSubscribeして表示させてみました.

しかし,文字列だけが表示されるのはつまらないですね.
やはり地図上に表示させたいものです.

次回は地図の表示を行います.