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

システム開発エンジニアの西田五郎が運営しております。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

執筆者:

関連記事

SkyWayでRaspberry Piの遠隔操作(その2)SkyWayからの操作

前回の続きです。全体的にはSkyWayを利用してRaspberry Piの遠隔操作をしてみようという内容です。 前回はRaspberry Pi側でのブラウザ(JavaScript)からMQTT ove …

Raspberry PiでIoT(温度・湿度・気圧データ編 その3)データ表示とグラフ表示

Raspberry PiでIoT 温度・湿度・気圧データ編の3回目です。前回までで、Raspberry Piから温度、湿度、気圧データをWebサーバへ送信してそのデータを蓄積出来るようになりました。今 …

Raspberry PiでAC100V(ソリッド・ステート・リレー)制御

Raspberry PiでAC100VのON/OFF制御を試してみました。今回そのために以下のソリッド・ステート・リレーキットを利用しました。この製品を選んだ理由としては「扱いが簡単」かなと思ったから …

Raspberry Piでも温度センサADT7310をつかってみる

以下の記事でArduino Unoで温度センサのADT7310を使ってみました。 Arduino UnoでSPI通信(その2)温度センサADT7310 以下の製品です。 ADT7310使用 高精度・高 …

Raspberry PiでIoT(温度・湿度・気圧データ編 その2)Webサーバ側構築とデータ送信

Raspberry PiでIoT 温度・湿度・気圧データ編の2回目です。前回はRaspberry Piに温度・湿度・気圧データが測定出来るセンサモジュールのBME280を接続して値を取得しました。 以 …