IDCフロンティアさんが企画、主催されている、サバフェス2016に出てきました!
ほんとに楽しいイベントで、また是非参加させていただきたいと思いました。
で、折角いろいろ勉強できたので思い出せるうちにシェアしておきたいと思います。
ライトニングトークでもチラッと言ったのですが、一番ハマったのは、myThingsとIDCFチャンネル、Mashbluあたりのところでした。
ハマる原因の一つとしては、概念的にいくつかの要素が重層的に絡み合っていてちょっとわかりにくいところがあるので、この記事では、概念部分についてまとめます。続きとなる記事では、実際の使い方に重点を置こうと思っています。
重要な概念について
なるべくレイヤの高い方から書いていきます。
myThings
Yahoo! さんの提供するサービスです。誤解を恐れずに言えばIFTTTと同じようなカテゴリに属する、複数のWebサービス「等」の間の連携を実現する、マッシュアップ(死語?)系のサービスとなります。
わかりやすそうな例で言えば、はてなブックマークでブックマークをつけると、それをmyThingsが検出して、Facebookに投稿してくれる、といった感じです。
上記の例で言うと、はてなブックマークだったりFacebookだったりの「情報を取得したり、情報を送出したりする相手」のことをチャンネルと呼びます。
このチャンネルには更に下位概念があり、「トリガー」と「アクション」があります。これは読んで字の如くで、「トリガー」がイベントの発火(上記の例で言えば「はてブでブックマークをつける」)を意味していて、「アクション」がその発火を受けて目に見える形での結果を意味しています。
各チャンネルには、トリガーやアクションが設定されています。チャンネルによっては、トリガーしかないもの、アクションしかないものも存在します。
IDCFチャンネル
上述のように、myThingsは主としてWebサービス間をつなぐ印象が強いですが、実はWebサービスだけではなく、fitbitのような物理的なデバイスもチャンネルの中に含まれています(fitbitチャンネルは2016年3月26日時点ではトリガーしかありません)。
なお、この「デバイス」という用語は、この記事の中で複数の意味を持ってきますのでご注意ください。
ただ、fitbitのような「デバイス系のチャンネル」の多くは、裏でWebサービスが動いていて、実際の連携はこのWebサービスと行なっています。
では、昨今ホットな話題も提供している、Raspberry PiやArduinoなどのシングルボードコンピュータ、ワンボードマイコンといった自作系のデバイスの場合にはどうかというと、fitbitなどのような「統一的なインタフェースを持ったバックグラウンド」がないため、そのままではmyThingsと連携することが出来ません。
そんな状況に対し、「自作系デバイスに対する統一的なインタフェースを持ったバックグラウンド」として機能するのがIDCフロンティアさんが提供している「IDCFチャンネル」となります。
IDCFチャンネルのトリガーになるのは、Trigger-1〜Trigger-5、アクションになるのはAction-1〜Action-5となっていますが、これは後で説明します。
なお、上で「デバイスという用語には複数の意味がある」と描きましたが、「トリガー」「アクション」についても複数の意味があり、これが混乱の原因になっていると思われるので要注意です。
IDCFチャンネルの仕組みをIDCFクラウド上のサーバにインストールする方法については次の記事で書きますが、インストールする中身は、dockerにカプセル化されたMeshbluを中心としたツール群となります。
Meshblu
IDCFチャンネルの根幹部分となります。IoTで用いられる色々なプロトコルに対応したサーバプログラムです。私が利用した範囲では、MQTTとHTTP(S)ですが、他にも複数のプロトコルに対応しています。
理解が混乱しやすい原因として、このMeshbluで使う用語というか概念がちょっとクセがあることがあげられると思います。
デバイス
まず大前提として、Meshbluが何者なのかというと、ノード間の情報のやり取りです。Meshbluの公式サイトの説明の中でもノード(node)という用語は出てきますがあくまでも一般的な単語として出てきており、一般的にいうノードのことをMeshbluでは「デバイス」と表現します。これ、超重要。テストにでます。テストないけど。
更なる前提として、Meshbluにおける「デバイス(=ノード)」は基本的にすべて公平に扱われます。IDCFチャンネルで利用するdockerのパッケージでは、Trigger-1〜Trigger5とAction-1〜Action5、それにownerという合計11個のデバイスが初期状態で登録されるのですが、この中で公平でないデバイス(=ノード)はownerだけです。Trigger-XとAction-Xは、その名前がたまたま(?)myThingsでいう「トリガー」や「アクション」と合致してしまっているので、混乱しがちですが、そことは完全に切り離して考えるべきです。Trigger-XもAction-Xもデバイスとしては同じ立ち位置です。これも超重要。テストにでます。
さて、上記で「基本的に公平に」と書いたのには意味があって、二つだけ特殊事情があります。
Meshbluはデバイス(=ノード)間で情報をやり取りするための仕組みなのですが、この「情報のやり取り」に際して、
- ownerデバイスはすべてのデバイス(=ノード)に対して情報を送出・受診できる
- Trigger-XはAction-Xに対して情報を送出できる
という設定が初期状態で入っています。
これは、IDCFチャンネルをmyThingsに登録するときに意味を持つのですが、とりあえずここでは「あーそうなのね」くらいに思っておいて大丈夫です。
そしてこちらは重要なこと。
どうしても「デバイス」と言われると、具体的なデバイスをイメージしてしまいますが、Meshbluにおける「デバイス」は、むしろ「アカウント」として捉えたほうがわかりやすいと思います。次回以降の記事で、実際の例を出しますが、Meshbluに接続する際、必ず「meshblu_auth_uuid」と「meshblu_auth_token」という情報が必要になります。これは、事実上、ユーザ名とパスワードに該当します。
そして、とてもとても重要な事ですが、物理的には同じデバイスであっても、上記のuuidとtokenのセットが異なれば、Meshbluからは異なるデバイス(=ノード)として扱われます。
逆に、物理的には異なるデバイスであっても、同一のuuidとtokenを名乗ってMeshbluにつなぎにいけば、同一のデバイス(=ノード)として扱われます
つまり、一般的な意味での「デバイス」あるいは「クライアント」と、Meshbluにおける「デバイス」との繋がりは非常に疎になっています。
これは本当にとても重要な事です。
トピックとパブリッシュとサブスクライブ
これはIDCFチャンネルの説明ではあまり重きを置かれていませんが、実装していくにあたっては理解しておく必要があります。どうもMQTTの用語っぽいです。
まず、トピックとは何かというと、SlackとかIRCとかでいう「チャンネル」に相当します(また用語がかぶるので、Slackのことは今はすぐに忘れちゃってください)。つまり、トピックは文字通り「話題」です。
この「トピック」に対して「パブリッシャー」と「サブスクライバー」という二つの関わり方があります。「パブリッシャー」は「情報を送出する役割」で、「サブスクライバー」は「情報を受信する役割」です。
で、この「パブリッシャー」や「サブスクライバー」になる主体は何かというと、「デバイス(=ノード)」なのです。つまり、MQTTの世界においては、トピックに対して情報を送出できる「パブリッシャー」の役割を持つデバイス(=ノード)と、そのトピックに送信された情報を受け取れる「サブスクライバー」の役割を持つデバイス(=ノード)があります。
はいココ重要。絶対にテストに出ます。
蛇足ですが、サブスクライバーは多分日本語では「購読者」という訳が当てられると思います。この訳は、Meshbluの概念を理解する上ではかなり妥当な訳ではないかと思います。なお、以下ではそれぞれPublisher、Subscriberと英語表記することにします。
基本的にはリアルタイム
はいここハマりやすいとこです。私はどっぷりハマりました。
情報の送受信、ということで、なんとなくメールとかのイメージを持っていると、「情報がどこかに届いて、受信者はそれを取りに行く」という感覚があると思います。
最終的にはちゃぶ台ひっくり返るのですが、とりあえず今のところは、上記のイメージは捨てたほうが良いです。
Meshbluにおいて、基本的に情報はリアルタイムのやり取りになります。
ここ超重要ですよー。テストにでますよー。
どういうことかというと、Subscriberは、情報が送信されたトピックに対してSubscribeしているときだけ情報を受け取れます。
とってもとっても重要なのでもう一度書きます。
Subscriberは、情報が送信されたトピックに対してSubscribeしているときだけ情報を受け取れます。
つまり、情報を受け取るとき、Subscriberは、そのトピックに対して口を開きっぱなしにしていなくてはいけません。
メールのイメージ、あるいはチャットのイメージを持っていると、自分がトピックから離れている時に誰か(=Publisher)から送信された情報は、次に自分が当該のトピックに繋いだ時に見えるような気がしてしまいますが、そうではありません。これは本当にとても重要な事だと思います。
…ちゃぶ台はこの後ひっくり返るんだけどな。
上の図のようになっている場合、topic-1に情報を「投稿」できるのはdevice-Aだけとなります。このトピックはすべてのデバイスがsubscribeしているので、すべてのデバイスが情報を「購読」することが出来ます。
ただし、device-Cは接続が切れているので、このタイミングでdevice-Aがtopic-1にpublishした情報を device-Cは受け取ることが出来ません。
リアルタイムじゃない時はどうするのか
とは言っても、必ずしも全てのデバイス(=ノード)が常にSubscribeしているわけではありません。具体的な例で考えると、myThingsは、リアルタイムに反応しません。15分に一度巡回します。実際問題として、何人ものユーザを抱える(可能性のある)サービスが、数あるMeshbluのトピックに対して常に口を開いていたら、セッション食いつぶしちゃいます。
はいここからちゃぶ台ひっくり返しますよ〜。
じゃぁどうしているのかというと、特定の情報の送出の仕方をすると、ちょっとメールっぽい挙動になります。つまり、自分が席を外している時にPublishされた情報「も含めて」サーバ側に蓄積されていて、次回アクセスしたときに、デバイス側から「ワタクシこういうものですが私宛の情報ある?」と問い合わせることで、過去に蓄積された情報がどかーんと送られてきます。
デバイス(=ノード)間の情報のやり取りについてまとめ
はい混乱してきましたねー。ここで一度まとめます。
Meshbluにおいて、基本的には情報はリアルタイムでやり取りされます。
ですが、情報を蓄積しておいてあとから参照することも出来ます。
前者の、リアルタイムにやり取りする方は「メッセージ」と呼ばれます。
後者の、リアルタイムではなくやり取りする方は「データ」と呼ばれます。
「メッセージ」として送信された情報は、そのトピックに対してSubscribeしているデバイス(=ノード)に直接送信されます。
「データ」として送信された情報は、IDCFチャンネルのパッケージにおいては、裏側にいるmongodbというデータベースに蓄積されます。
では、送出した情報が「データ」として扱われるのか「メッセージ」として扱われるのかをどうやって切り替えているのかというと、どうやら「トピック」としてどちらを指定するのかで扱われ方が変わるようです。
MQTTの説明とかをみると、トピックは自由にいくつでも作れて、それぞれに対してPublisherとSubscriberが登録できるように記載されていますが(そしてそれはおそらく正しいのですが)、Meshbluの実装においては、トピックは「data」と「message」の2種類となり、どちらのトピックに送出されるかで挙動が変わります。これら以外のトピックもあるのかもしれないですが、少なくともmyThingsとIDCFチャンネルと自作デバイスという登場人物を考えるときにはこの2種類のトピックだけ考えればよいものと思われます。
余談ですが、ここで「message」「data」という用語が、一般的な意味でなく特定の意味を持つため、ここまでの説明ではあえて「ノード間のメッセージのやり取り」とかの表現を避けてきました。
myThingsとMeshbluの連携 〜次回へのイントロとして〜
なんだかとても長くなってしまったのでまずはここまでにします。
とは言え折角なので、ちょこっとだけ次回へのイントロとして、MeshbluとmyThingsが連携するときのことを書いておきます。
myThingsはデフォルトでは「15分に1回」の周期でIDCFチャンネル(=自分で構築したMeshbluサーバ)を見に来ます。
ということはこれはリアルタイムではないので、トピックとしてはdataを見に来ています。
myThingsにIDCFチャンネルを登録するときに、「トリガー(myThings側の用語、という意味でカタカナ表記しています)」として「Trigger1〜Trigger5」がありますが、実際の動きとしては、myThingsはこれらのデバイス(=ノード)に蓄積されたdataを見に来ています。
でも、myThingsにIDCFチャンネルを登録するときに、Trigger1とかの具体的なデバイスのuuidとかtokenとかって入力していないですよね?
このタネ明かしは、ずーっと前の方で説明した、ownerデバイスと関係があります。
myThingsにIDCFチャンネルを登録するときに、IPアドレスと併せて「ownerのtoken」を入力したかと思います。そして、ownerデバイス(=ノード)は、全てのノードに対して情報の送出と受信ができると書きました。
つまり、myThingsは、ownerとしてのアクセス権限を持っているので「Trigger1〜Trigger5」に蓄積されたdataを見ることができるわけです。(なんでuuidは必要でないのかについてはよくわかんないです)
で、逆に「アクション(myThings側の用語、という意味でカタカナ表記しています)」としては「Action-1〜Action-5」が登録されていて、上記の事情でownerデバイスの認証情報を持っているmyThingsはこれらのデバイス(=ノード)に対して情報を送出できるわけですが、こちらはmessageとして情報を送出しています。
はい、ここ絶対にテストに出ますよー。myThings側から見て「トリガー」なときは「data」、「アクション」なときは「message」のトピックに対してアクセスが有る、というのが、次回の記事に向けてのイントロとなります。
コメント