会社の受付やソフトバンクショップでの接客などで見かけるようになった人型ロボット「Pepper」。IBMのクラウド・サービス「IBM Bluemix(以下、Bluemix)」を使ったIoTアプリの開発方法を学ぶ連載最終回は、BluemixからPepperの目のLED色を変更する指令を送り、Pepperの目の色を変化させます。
※今回の記事は、BluemixのIoT Foundation、MQTT、Choregrapheの知識があることを前提としています
Bluemixでの作業
Bluemixのボイラープレートから「Internet of Things Foundation Starter」アプリを作成し、サービスに「Internet of Things Foundation」を追加します。
サービス登録後の再ステージが終了したら、Bluemixダッシュボードの「経路」からNode-Redのエディタにアクセスします。初回起動時はいくつかノードが作成されているので、いったんすべて削除し、図のようにInjectionノードとPublish to Bluemixノードを接続します。
Injectionノードからは、各ノード名と同じ色名が書かれたJSONデータが、
{"d": {"eyes": "orange"}}
といった形式で「Publish to Bluemix」ノードに送信されます。
ibmiot out nodeの設定は以下の通りです。
今回はデバイスタイプを「TestDevice」、デバイスIDを「Pepper1234」としています。Authenticationに「Bluemix Service」が表示されない場合は、Bluemixダッシュボードから再ステージすると表示されます。
この後は、Pepper側でSubscriberを作ればOKですが、せっかくinノードがあるのでibmiot in ノードとdebugノードを使用して、Publishしたデータが取得できるか確認します。
ibmiot in nodeの設定は以下の通りです。
Formatの「JSON」は大文字・小文字が区別されるので、必ず大文字で設定します。
debugノード設定で「Output」の「message property」を選択して、「msg.」に「payload.d.eyes」と入力します。各色のノードをクリックするとdebugにメッセージが表示され、Pub/Sub(Publish-Subscribe)が動作しているのがわかります。
Pepperでの作業
Pepper側の処理は、Pepper用アプリの開発環境である「Choregraphe」を使います。
※Mac仕様のChoregrapheを使っている人にはおなじみかもしれませんが、非常にクラッシュしやすいので、作業中はこまめな保存を推奨します
Choregrapheのboxは以下のように、自作のSubscriber IoT Foundationボックスと、eyesボックスだけを使う、とてもシンプルな構成です。
・Subscriber IoT Foundationボックス
IoT FoundationからPublishしたデータを取得して、PepperのALMemoryイベントを発生させます。
・eyesボックス
発生したイベントを検知して指定色に応じて目の色を変更します。
Subscribe IoT Foundationボックスの作成
Subscribe IoT Foundationボックスを作成します。新規Pythonボックスを作成した後、「ボックスの編集」から以下の変数を追加します。
- Endpointタイプ:文字列
- Client IDタイプ:文字列
- API Keyタイプ:文字列
- API Tokenタイプ:文字列(「パスワード」にチェックを入れる)
追加した変数に、各項目を入力します。
今回はBluemix Serviceを使用して接続するため、アプリケーション接続になります。IoT Foundationで登録したデバイスを使用して接続をする場合は、デバイス接続になり設定も異なります。表を参考にしてください。
デバイス接続 | アプリケーション接続 | |
---|---|---|
Client ID | d:{org_id}:{device_type}:{device_id} | a:{org_id}:{app_id} |
event topic | iot-2/evt/{event_id}/fmt/{format} | iot-2/type/{device_type}/id/{device_id}/evt/{event_id}/fmt/{format} |
command topic | iot-2/cmd/{command_id}/fmt/{format} | iot-2/type/{device_type}/id/{device_id}/cmd/{command_id}/fmt/{format} |
セキュリティ | User: use-token-auth | User: サービスのAPIキー |
PW: デバイス追加時のトークン | PW: サービスのトークン |
org_idはIoT Foundationサービスのダッシュボードから、サービスのAPIキーとトークンはBluemixのダッシュボードから確認できます。
ボックス設定が終わったら、MQTTのやりとりに使うライブラリ「Paho」の読み込み処理から追加していきます。プロジェクトファイルにlibディレクトリを作成し、Pahoのライブラリファイルをインポートしておきます。
▼Pahoの読み込み処理を追加
# onLoad時に初期化
def onLoad(self):
self.framemanager = ALProxy("ALFrameManager")
self.folderName = None
.....
def onInput_onStart(self):
import sys, os
# lib以下に設置しない場合はパスに気をつける
self.folderName = os.path.join(self.framemanager.getBehaviorPath(self.behaviorId), "../lib")
if self.folderName not in sys.path:
sys.path.append(self.folderName)
.....
def onUnload(self):
import sys
if self.folderName and self.folderName in sys.path:
sys.path.remove(self.folderName)
self.folderName = None
.....
ブローカーに接続し、Subscribeする処理を追加します。
▼ブローカーに接続後、Subscribeする処理を追加
def onInput_onStart(self):
.....
# Pahoをインポートする
import paho.mqtt.client as mqtt
# ボックスの設定で追加した変数をgetParameterで取得
self.topic = self.getParameter('Topic')
self.endpoint = self.getParameter('Endpoint')
self.client_id = self.getParameter('Client ID')
self.api_key = self.getParameter('API Key')
self.api_token = self.getParameter('API Token')
self.client = mqtt.Client(self.client_id)
self.client.username_pw_set(self.api_key, self.api_token)
self.client.on_connect = self.on_connect
self.client.on_message = self.on_message
self.client.connect(self.endpoint, 1883)
self.client.loop_forever()
# 接続が完了した場合、メッセージを表示し、subscribeを行う
def on_connect(self, client, userdata, flags, rc):
self.logger.info("Connected with result code "+str(rc))
client.subscribe(self.topic)
# subscribeしているtopicの内容を処理
def on_message(self, client, userdata, msg):
# ログビューアでSubscribeができているかを確認
self.logger.info("Subscribe: "+str(msg.topic))