株式会社インデペンデンスシステムズ横浜

システム開発エンジニアの西田五郎が運営しております。Raspberry Pi や Arduino その他新規開発案件のご依頼をお待ちしております。

Raspberry Pi SkyWay

SkyWayでRaspberry Piの遠隔操作(その1)MQTT over WebSocket

投稿日:2020年1月8日 更新日:

前回までの記事でSkyWayのJavaScriptでの動作確認を行いました。またRaspberry Piでの動作も確認出来ました。そうすると今回はSkyWayを利用してRaspberry Piの遠隔操作をしてみようという内容です。今回はまずはRaspberry Pi側でのブラウザ(JavaScript)からMQTT over WebSocketを使ってRaspberry PiのGPIOを操作するという内容です。

全体的な遠隔操作の方法について

以前に以下から始まる一連の記事でもRaspberry Piでの遠隔操作について書きました。これらの記事で書いた方法はMQTTをインターネット上で利用して遠隔操作を行うという方法です。
Raspberry PiでIoT(MQTTで遠隔操作編 その1)MQTTでの通信

今回の遠隔操作の方法は、MQTTはローカルのRaspberry Pi内で利用して、インターネット上はSkyWayを利用します。この方法のメリットはSkyWayのP2Pのイメージの延長線で遠隔操作が出来るということです。より直接的な遠隔操作のイメージになると思います。

最終的にはリモート側で以下のように遠隔操作と映像モニターが出来ます。

MQTT over WebSocketを利用する

そこでまず今回は、そのRaspberry PiローカルでのMQTTの通信の確認です。上の図で左下のRaspberry Piローカルの部分です。要点はブラウザからMQTT over WebSocketを利用してRaspberry Piと通信してGPIOを操作するということです。

以下のような構成(キーボード、マウスもUSBで接続しています。)で画面上のブラウザのボタンをクリックするとRaspberry Piに接続されたLEDのオンとオフを操作出来ます。

Raspberry Pi側ではPythonプログラムでMQTTのsubscribeをしています。ブラウザでボタンをクリックしたらローカルのRaspberry Piにpublishします。これでGPIOを操作します。

Raspberry Piでの準備

実際にやってみます。

Mosiquitto関連のインストール

まずは、Raspberry PiでMosquitto(Broker)をインストールします。
$ sudo apt-get install mosquitto

以下のように状態を確認します。activeが確認出来ます。
$ sudo service mosquitto status

次にMosquittoクライアントをインストールします。
$ sudo apt-get install mosquitto-clients

インストール時のスクリーンショットや基本的な動作確認は以下で書きました。必要な場合はこちらも参照して下さい。
Raspberry PiでIoT(MQTTで遠隔操作編 その1)MQTTでの通信

設定ファイルの編集(重要です。)

/etc/mosquitto/mosquitto.conf を編集します。
以下の内容を追記します。

listener 1883
listener 9090
protocol websockets

これは、以下を指定しています。
MQTTが1883番ポート
WebSocketが9090番ポート

これがないとブラウザと通信出来ないので必ず指定しておきます。
もちろんポート番号は何でもいいですが、この番号が比較的既定のようです。ここから先はこのポート番号を前提にして進みます。

この設定を変更したら以下でmosquittoサービスを再起動します
$sudo systemctl restart mosquitto

Raspberry PiのGPIO操作(Lチカ)のためのsubscribe

python3のプログラムを作成して利用します。
paho-mqttというライブラリを使用しますので以下のようにインストールしておきます。

$sudo pip3 install paho-mqtt

以下のようなpythonプログラムを作成しました。

import paho.mqtt.client as mqtt
import RPi.GPIO as GPIO
import time

def on_connect(client, userdata, flag, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("isyjp/gpio21")

def on_message(client, userdata, msg):
     print(msg.topic+" "+str(msg.payload))
     GPIO.output(21,1)

     if msg.payload == b"on":
         GPIO.output(21,1)
         print("on")
     else:
         GPIO.output(21,0)
         print("off")

def on_disconnect():
    pass

GPIO.setmode(GPIO.BCM)
GPIO.setup(21, GPIO.OUT)

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()

コメントが全くないですが、プログラムの説明は後にして先に動作確認をします。
ここまでのmosquittoの準備が出来ているという前提でこのsubscribeプログラムを起動します。特にGPIOには何も接続されていなくていいです。

待ちの状態になります。

別のターミナルでpublishをします。ホスト、ポート、topicを指定してonというメッセージを送信します。すぐに終了します。

subscribe側に戻ります。

確かにメッセージを受け取りました。

プログラムの説明を書きます。
mqttの処理とgpioの処理で構成されています。
mqttの操作はpaho-mqttのclientを利用しています。clientを生成してmqttのbrokerに対しての接続、切断時とメッセージ到着時の処理を準備してローカルのブローカーに接続して待機しています。

gpioの処理はgpioを出力に設定して、clientのメッセージ到着時の処理で、onが来たらgpio21をonにしてoffが来たらgpio21をoffにしています。

これでgpioにLEDを正確に接続しておけばLチカが出来ます。

ローカル上で稼働するという前提でsslは考慮していないです。

以上でRaspberry Pi側の準備は完了です。
ここではターミナルからpublishして動作確認しましたが以下からはブラウザから同様のことをやります。

ブラウザからのメッセージ送信

ブラウザで表示するページの作成

以下のようなページを作成して利用可能なWebサーバに公開します。Webサーバはどこで稼働していても問題ないです。

ボタンが2個あってLEDのオンとオフを想定しています。

ソースは以下です。

<html lang=ja>
<head>
<title>MQTT over WebSocket test</title>
<meta charset="UTF-8">
<style></style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>

<script type="text/javascript">
        var mqtt;

        $(function()
        {
                mqtt = new Paho.MQTT.Client("localhost", 9090, "cli01");
                console.log("conncting");

                var options = {
                        timeout: 60,
                        onSuccess: onConnect,
                        onFailure: onFailure,
                        };

                mqtt.onMessageArrived = onMessageArrived;
                mqtt.connect(options);
        });

        function onConnect()
        {
                console.log("on Connect");
                mqtt.subscribe("isyjp/tp01");
        }

        function onMessageArrived(msg)
        {
                console.log("on Arrived");
                console.log(msg.payloadString)
                $('#message').text(msg.payloadString);
        }

        function onFailure()
        {
        }

        function ledon()
        {
                message = new Paho.MQTT.Message("on");
                message.destinationName = "isyjp/gpio21";
                mqtt.send(message);
                console.log("led on.");
        }

        function ledoff()
        {
                message = new Paho.MQTT.Message("off");
                message.destinationName = "isyjp/gpio21";
                mqtt.send(message);
                console.log("led off.");
        }
</script>
</head>

<body>
websocket test <br/>
<p><button type="button" onclick="ledon()">ローカル接続のled on</button></p>
<p><button type="button" onclick="ledoff()">ローカル接続のled off</button></p>
<p><div id="message">受信データ</div></p>
</body>
</html>

コメントが何も書いていないですが、Raspberry Piのpythonプログラムと同様にpaho-mqttのライブラリ(こちらはJavaScript)を利用しています。

Raspberry Piのローカルのmqtt brokerと通信するためのclientを生成して(ポート番号はwebsocketの9090の方です。)接続時の処理、メッセージ到着時の処理を定義しています。今回はボタンからのメッセージ送信がメインですが、一応メッセージ到着時を想定して画面に表示するようにしています。

GPIOのボタン処理ですが、mqttのclientで直接送信しています。このように直接送信が出来るのでプログラムも簡単になると思います。これがMQTT over WebSocketを利用するポイントです。

これをRaspberry Pi上でブラウザから操作すると写真の構成でLEDのオンとオフが確認出来ました。これもローカル上で稼働するという前提でsslは考慮していないです。

以上で今回のテーマのMQTT over WebSocketでの動作が確認出来ました。次回は今回の操作をSkyWayを経由して遠隔のブラウザから操作してカメラでモニタしてみます。

次回へ移動する

AdSense

AdSense

-Raspberry Pi, SkyWay

執筆者:

関連記事

Raspberry PiでIoT(温度・湿度・気圧データ編 その1)BME280でデータ取得

Raspberry PiでIoTに取り組んでみるという内容で実際に動作させながら書きたいと思います。まずは、IoTとは、Internet of Thingsの略です。もう既にこの言葉も普及していて様々 …

無線マイコン ToCoStick(トコスティック)をRaspberry Piで使ってみた

無線マイコンの ToCoStick(トコスティック)をRaspberry Piで使ってみました。前回の記事でブレッドボードが親機でToCoStickが子機という設定でとりあえずということで通信が出来る …

Raspberry PiでIoT(MQTTで遠隔操作編 その2)MQTT Brokerの構築とPythonでのpub/sub

Raspberry PiでIoT MQTTで遠隔操作編の2回目です。2台のRaspberry Piでインターネット経由でGPIOを操作するというテーマで書いています。前回はMQTTの基本的な内容とMo …

Raspberry PiでC言語版Lチカを試す(その2)レジスタを操作する

Raspberry PiでC言語を使ったLEDの点灯、消灯(いわいるLチカ)を試してみました。今回は2回目です。前回デバイスドライバを利用する方法を書きました。今回はレジスタを直接操作する方法を使いま …

Raspberry Piでタッチアプリ開発(その3)Kivyでレイアウト・ボタン作成

Raspberry Piでタッチアプリ開発の3回目です。前回はKivyの導入について書きました。今回は具体的なレイアウトとボタンを配置してみます。以下のレイアウトについて順番に書きます。Kivyでのレ …