クラウド経由でPaPeRo iを制御する-WebSocket中継1-Node-RED編

 httpでポーリング編はアプリレベルの通信によってクラウド経由でPaPeRo iを制御する方法でしたが、今回は下のレイヤの、PaPeRo i 制御用WebSocket通信アドオンシナリオとPaPero i 制御用ライブラリ(Python用/golang用)を使用したPaPeRo iアプリ間の通信を、クラウドで中継してPaPeRo iを制御する方法を紹介します。

PaPeRo iとアプリの接続について

 PaPeRo i 制御用WebSocket通信アドオンシナリオをインストールしたPaPeRo i(以後単にPaPeRo iと書きます)はWebSocketサーバとして動作しますので、起動後にはクライアントからの接続待ちになります。一方PaPeRo iアプリ側に組み込まれた制御用ライブラリはWebSocketクライアントとして動作し、自分の側からPaPeRo iに接続しに行き、接続確立後にデータを送受信することでPaPeRo iを制御します。PaPeRo iとアプリが接続可能なのは、
(1) PaPeRo iとアプリが同じPaPeRo i内で動作する
(2) PaPeRo iとアプリが同じLAN内にある
(3) PaPeRo iとアプリが同じVPN内にある
(4) PaPeRo iがインターネット上に直接公開されている
のいずれかの場合になると思います。(3)と(4)ではそれぞれ設定や手続きが必要ですがインターネットを経由した接続が可能です。
今回は、
(5) PaPeRo iとアプリが違うLAN上にあって、どちらもインターネット側からは直接アクセスできない
という場合に、PaPeRo i(アドオンシナリオ)やアプリ自体は変更せずに、インターネットを経由した接続ができるようにするという方法です。

実現する方法

 アプリについては、シミュレータとも接続できているので明らかですが、接続先がインターネット上にあっても問題なく、接続先以外変更の必要はありません。そこでクラウド上にWebSocketサーバを用意し、アプリからはそちらに接続することにします。
 PaPeRo i側はクライアントからの接続を待つ動作なので、このままでは困ります。そこで、PaPeRo iと同一LAN上に「中継クライアント」を設置することにします。PaPeRo iからは中継クライアントがアプリに見えますが、実際には中継クライアントはクラウド上のWebSocketサーバにも接続してデータを中継します。クラウド上のサーバはアプリと中継クライアントを中継します。
つまり、矢印をサーバ←クライアントという向きに書くと、通常
 PaPeRo i←アプリ
であったところを
 PaPeRo i←中継クライアント→クラウド←アプリ
と接続してデータを流します。今回は簡単のためクラウドと中継クライアントではデータの中身には一切手を触れず中継のみを行うことにします。

クラウド側プログラム

 今回も無期限無料のIBM Cloudライト・アカウントとNode-REDを使用することにします。プログラムは図のようになりました。

 単なる中継なので双方向分の2本のデータフローがあるだけで、パス以外の記述はありません。中継の両端ともにサーバ動作なのですべてのwebsocketノードの「種類」を「待ち受け」にします。パスは図の通りで、「メッセージ全体を送信/受信」にする必要があります。
以下のフローデータを右上メニューの読み出し→クリップボードでペーストすることでフローを再現できます。

[{"id":"ef9210e9.f2b46","type":"websocket out","z":"deb0d57.1c46528","name":"","server":"25d0a7f3.dd3d88","client":"","x":460,"y":200,"wires":[]},{"id":"d7669eba.8b6aa","type":"websocket in","z":"deb0d57.1c46528","name":"","server":"bdfe0841.366468","client":"","x":150,"y":100,"wires":[["ef9210e9.f2b46","640264f3.dd8cbc"]]},{"id":"640264f3.dd8cbc","type":"debug","z":"deb0d57.1c46528","name":"","active":true,"console":"false","complete":"true","x":430,"y":140,"wires":[]},{"id":"1de48ae7.f17205","type":"websocket in","z":"deb0d57.1c46528","name":"","server":"25d0a7f3.dd3d88","client":"","x":140,"y":300,"wires":[["a95d70a2.2b6cd","6305e0b4.1bb24"]]},{"id":"a95d70a2.2b6cd","type":"websocket out","z":"deb0d57.1c46528","name":"","server":"bdfe0841.366468","client":"","x":470,"y":400,"wires":[]},{"id":"6305e0b4.1bb24","type":"debug","z":"deb0d57.1c46528","name":"","active":true,"console":"false","complete":"true","x":430,"y":340,"wires":[]},{"id":"25d0a7f3.dd3d88","type":"websocket-listener","z":"","path":"/ws/papero","wholemsg":"true"},{"id":"bdfe0841.366468","type":"websocket-listener","z":"","path":"/ws/controller","wholemsg":"true"}]

中継クライアント

 今回は中継クライアントもNode-REDで済ませたいと思います。Node-REDはWindows等でも動作する様ですが、今回は最初からNode-REDがインストールされているRaspberry Pi3B(Raspbian Stretch)を使って動作確認しました。メニュー→プログラミング→Node-REDで起動し、ブラウザでラズパイのIPアドレス:1880にアクセスするとNode-REDのフローエディタが開きます。中継クライアントのプログラムは図のようになりました。

 こちらも単なる中継なのでパス以外の記述はありません。こちらは両端ともクライアント動作なので、すべてのwebsocketノードの「種類」は「接続」にします。パスは図の通りで、「メッセージ全体を送信/受信」にする必要があります。
フローデータ:

[{"id":"e402458c.dd04a8","type":"websocket in","z":"c52ee001.c0916","name":"","server":"","client":"39ec7d7a.0b7f92","x":250,"y":100,"wires":[["60fcde4b.78a1d","32bd3f02.530d2"]]},{"id":"32bd3f02.530d2","type":"debug","z":"c52ee001.c0916","name":"","active":true,"console":"false","complete":"true","x":570,"y":160,"wires":[]},{"id":"60fcde4b.78a1d","type":"websocket out","z":"c52ee001.c0916","name":"","server":"","client":"5ae4dff0.fc03e","x":670,"y":220,"wires":[]},{"id":"aaf79491.adb8b8","type":"websocket out","z":"c52ee001.c0916","name":"","server":"","client":"39ec7d7a.0b7f92","x":730,"y":460,"wires":[]},{"id":"2ad8c522.8be27a","type":"websocket in","z":"c52ee001.c0916","name":"","server":"","client":"5ae4dff0.fc03e","x":180,"y":320,"wires":[["aaf79491.adb8b8","b17d9974.395658"]]},{"id":"b17d9974.395658","type":"debug","z":"c52ee001.c0916","name":"","active":true,"console":"false","complete":"true","x":570,"y":400,"wires":[]},{"id":"39ec7d7a.0b7f92","type":"websocket-client","z":"","path":"wss://spiiottest20180116e.mybluemix.net/ws/papero","wholemsg":"true"},{"id":"5ae4dff0.fc03e","type":"websocket-client","z":"","path":"ws://192.168.1.188:8088/papero","wholemsg":"true"}]

 なおPaPeRo iのIPアドレス(192.168.1.188)、Node-REDのサーバのURL(xxxx.myblumix.net/ws/papero)は、実際の環境に合わせて修正してください。

動作確認

 同一LAN内のPaPeRo i(192.168.1.188)に対し、Windows PCから

> python3 xxxx.py -wssvr ws://192.168.1.188:8088/papero

で起動するpythonアプリが、

> python3 xxxx.py -wssvr wss://spiiottest20180116e.mybluemix.net/ws/controller

でも動作しました。ボタンの反応などは若干遅くなりますが思ったほどではなく、インターネット経由の制御でも普通にアプリが動作することが確認できました。ラズパイに3G/LTEドングルを接続することで、LANが無い客先環境でもPaPeRo iをこの方法で制御することができます。

課題

 今回のやり方はひとまずできるかどうか試してみたというレベルで、制御できるのは1台のPaPeRo iだけですし、認証手続きも無いので実用的ではありません。中継クライアント用に別途Raspberry Piが必要なのも問題です。
 そもそもこの様にインターネットに制御用WebSocket通信を流すのであれば、アプリ自体をクラウドで動かす方が理にかなっていると言えそうです。


0