以前、IBM Cloud FunctionsとWatson Assistantとの連携についての記事を作成してその流れでハンズオンを開催しました。その中で参加者の方から「Watson Assistantだけで外部接続できるということはAssistantでIot連携もできるってことだよね?」とお話をされてました。なるほど、それは面白そう!と思ったので、今回はWatson AssistantとWatson IoT Platformを使ったIot連携を試してみました。
今回作るもの
Watson Assistantのwebhookを使用し、Watson IoTで画像のESP32に接続したLEDをつけたり消したりするシンプルなデモです。
デバイス側の設定
Watson IoTの設定
まずはWatson Iot Platformのリソースを作成していきます。IBM Cloudのダッシュボードの中の「リソースの作成」からWatson IoT Platformを選択し、作成します。その後、IoT platformを起動し、左側のメニューから「アプリ(コンパスのアイコン)」を選択して、「APIキーの生成」からWatson IoT platformにデバイスがアクセスするためのAPIキーを生成します。説明は自分が分かりやすいものを自由に設定できます。
次の画面では、アプリケーションのアクセス権限を設定します。ここでは「標準アプリケーション」を選択します。
キーの生成を押すと、APIキーと認証トークンが表示されます。この時、一度画面を閉じると認証トークンは2度と確認できなくなるので、忘れずに認証トークンをメモしておきましょう。
ESP32をWatson IoT Platformに接続する
次にデバイスをWatson IoT Platformに接続する設定を行っていきます。使用するハードウェアはESP32、ファームウェアの書き込みにはmongoose osを使用します。パソコンにESP32を接続した後、こちらの手順1から7を完了した後に、mongoose osのコマンドラインで以下のコマンドを実行し、Watson IoTを使えるようにプロビジョニングをします。
mos watson-iot-setup
その後以下のコマンドを実行し、Watson IoTの接続を完了させます。ここで先程生成したAPIキーと認証トークンを使います。
mos watson-iot-setup --watson-api-key your-api-key --watson-api-auth-token "yourtokenhere"
設定が完了すると、左側のデバッグ画面に以下のような結果が出力されます。コマンドを実行することで、今接続しているデバイスに自動的にデバイスIDが割り当てられます。
Using port /dev/ttyUSB0
Connecting to the device...
esp8266 1AFE34A5930F running demo-c
Org ID: bcdefgh
Device ID: esp8266_A5930F
Checking device type "mos"...
Creating device "esp8266_A5930F"...
Updating config:
device.id = esp8266_A5930F
watson.client_id = d:bcdefgh:mos:esp8266_A5930F
watson.enable = true
watson.host_name = bcdefgh.messaging.internetofthings.ibmcloud.com
watson.token = SECRET
Setting new configuration...
Saving and rebooting...
もう一度Watson IoT Platformの画面に戻り左のメニューからデバイス(CPUのようなアイコン)を選択して、追加したデバイスを確認すると、先程のmosコマンドで設定したデバイスIDが確認できるかと思います。これでESP32をWatson IoTに接続する設定が完了しました。
ハードウェアのセットアップ
それでは、ハードウェアのセットアップをしていきます。まずはLEDを点灯する回路を作成していきます。配線は下図の通りです。LEDは+側を25番のピンに接続しています。
次にESP32のプログラムを書き換えます。お好きなコードエディタでmongoose osのプロジェクトを保存しているフォルダの中にあるfs/init.js
を開きます。中のコードをすべて消して、以下のコードに書き換えます。
// IoT subscriber
load('api_gpio.js');
load('api_mqtt.js');
load('api_sys.js');
let LEDpin = 25;
let topic = 'iot-2/cmd/cid/fmt/json';
let obj;
GPIO.set_mode(LEDpin, GPIO.MODE_OUTPUT);
GPIO.write(LEDpin, 0);
MQTT.sub(topic, function(conn, topic, msg) {
print('Topic: ', topic, 'message:', msg);
obj = JSON.parse(msg);
print('ok');
if (obj.d.on){
GPIO.write(LEDpin, 1);
}else{
GPIO.write(LEDpin, 0);
}
}, null);
書き換えたら、mongoose osのコマンドラインから以下のコマンドを順に実行します。
mos put fs/init.js
mos call Sys.reboot
これでデバイス側の設定は全て終わりました。
Publisherの設定
今度はデバイスにPublishする設定を行います。今回はIBM CloudのNode-REDを使って設定します。IBM CloudでNode-REDのリソースを作成したら、まずはWatson IoT PlatformをAPIキーやトークンを使わずに実行できるようにNode-REDとの接続を作成します。Node-REDのリソース画面を開き、「接続の作成」をクリックします。「既存の互換性のあるサービスの接続」からWatson IoT Platformのリソースを選択して右端に出てくる「接続」をクリックします。
すると、以下の画面が表示されるので、設定はそのままで「接続」をクリックします。その後再ステージングを要求されるので、そのまま「再ステージング」をクリックします。
再ステージングをした後にNode-REDを起動してフローエディタを開きます。まずは、Webhookを使えるようにhttpノードをセットします。メソッドはPOST
、URLにはsubdata
を設定します。
次にpostされたデータを変換してIBM IoTノードでプッシュします。jsonを変換するためにFunctionノードを追加します。
Functionノードを開き、以下のコードに書き換えます。
msg.payload = {
"d":{
"on":msg.payload.on
}
}
return msg;
IBM IoTノードの設定は以下の通りです。デバイスIDはご自身が設定したものを記入します。
Watson Assistantの設定
いよいよ最後のステップです。Watson Assistantを使ってLEDを制御する設定します。Watson Assistantのリソースを作成し、Skillsタブ(画面右上にある吹き出しマークではない方のアイコン)をクリックして、Create skillで新たにスキルを作成します。以下の画面が出てきたら、Dialog skillを選択して、Nextボタンをクリックします。
インテントの設定
次にインテントを設定します。今回は、LEDをつけるか消すかの2種類のインテントを用意します。
今回はLEDのONとOFFが分かればいいので、インテントの中身は何でもいいですが、迷っている方はこちら
のCSVにサンプルを載せてあるのでダウンロードして、Asisstantにインポートして使ってください。インポートするには上の画像の中のアップロードアイコンをクリックしてダンロードしたCSVを読み込みます。
webhookの設定
こちらを参考にwebhookの設定をしていきます。今回はIBM Cloud functionsを使っていないので、設定するURLは「(/redより前のNode-REDのURL)/subdata」の形式になります。
フローの作成
それでは、フローを作成していきます。Dialog
タブをクリックします。今回はLEDをつけるノードと消すノードを並べて設定します。送信するパラメータはブーリアン型なので、VALUE
はダブルクオーテーションで囲みません。まずはLEDをつけるノードです。今回はNode-REDのレスポンスをちゃんと設定していないので、webhookのレスポンスに関係なく同じ返答を返すようにしました。
同様にLEDを消すアクションを設定します。
動作確認
それでは、動作確認です。AssistantのTry it
からメッセージを送信してLEDをつけたり消したり出来たら成功です。ちょっと見づらいですが、実際に動作させた時の動画です。
Watson AssistantからLEDのON/OFFが出来た。詳しくは今年のIBM Cloudのアドベントカレンダーにてー#Watson #IBMCloud pic.twitter.com/pdyqA187Ze
— K.Miura (@k_miura_io) November 21, 2019