サンプルアプリケーションの概要
今回、サンプルとして作成するアプリケーションは「IoTデバイスのデータを受信してデータベースに保存し、保存したデータをもとに気温、湿度の平均値と不快指数を計算して定期的にTwitterへツイートする」というものです。 次の2つのアプリケーションで構成されます。
- 「IoTデバイスのデータを受信してデータベースに保存する」アプリケーション
- 「蓄積されたデータをもとに気温や湿度の平均値、不快指数を計算して定期的にTwitterへツイートする」アプリケーション
なお、ツイートするコメントには気温や湿度の平均値、不快指数のほか、それが「何年何月のどこ(日本国内のある地点)と同じくらい」かも、体感温度として加えることにしました。これは、気象庁が公開している過去の気象データと比較して割り出します。

Cloudantの概要
IoTでは多数のデバイスからシンプルだが大量のデータが送られてくることが想定されます。 しかもデータ構造は、ビジネス要件やデバイスの変化で日々変わる可能性があります。 これらの非構造化・ビックデータを蓄積・利用するには、それらに適したデータベースの選定が必要です。
こうした要件には、JSONデータを格納できるドキュメント型NoSQLデータベースが便利です。 今回、IoTデバイスから送信されてくるデータの格納先として、そうしたデータベースの1つである「IBM Cloudant」を利用することにします。 CloudantはDBaaS(Database as a Service)として提供されており、セットアップなどは不要で、すぐに使い始めることができます。 また、スケーラビリティが高く、利用者は運用管理や保守から解放されます。
なお、CloudantについてはCodeZineの過去記事「エンタープライズ分野で使えるNoSQLのDatabase as a Service『IBM Cloudant』」が参考になります。
Node-REDの概要
「Node-RED」は、Node.js上で動作するオープンソースのソフトウェアです。 機能をカプセル化したノードと呼ばれるモジュールが用意されており、ブラウザベースのUIからノード同士を繋げて処理の流れを作成していきます。

直感的に操作できるので、複数のサービスを繋げるアプリケーションのプロトタイプ作成には最適です。 筆者は、タブレットから操作ができる点も気に入っています。

昨年、日本でもNode-REDユーザーグループが発足し、利用促進や情報交換が行われるようになりました。 また、IoTデバイスとして利用可能なRaspberry PiのOSである「Raspbian」にプリンストールされたりと今後の展開が期待されます。
Bluemixではボイラーテンプレート「Node-RED Starter」が用意されているので、すぐに使い始めることができます。 Bluemixのサービスと連携するためのノードも標準でいくつか提供されています。 このNode-RED Starterも利用してサンプルアプリケーションを作成します。
IoTセンサーシミュレーターの準備
IoTデータを活用したアプリケーションを作成をするためには、まずデータを計測・発信するデバイスを準備しないといけません。 身近なものとしては、スマートフォン[1]やArduinoやRaspberry Piの機器を利用する方法があります。
注
[1]: スマートフォンは位置情報、ジャイロセンサー、加速度計、コンパスなど、センサーの塊です。
ちなみに、昨年開催されたイベントで、筆者は仲間と協力して、Bluemixのサービス(IBM Watson IoT Platform + Node-RED + IBM XPages)を組み合せてドローンを操作・モニタリングするデモを行いました。 ドローンをブラウザベースのコントローラーで操作し、後ろのスクリーンではドローンからのジャイロセンサーのデータを受信して、ドローンの姿勢を3Dモデルでリアルタイムに表示しています。 データの送受信にはIBM Watson IoT Platform(以下、Watson IoT Platform)を利用しました。

ただし、今回はIoTを利用したアプリケーションの作成をすぐ体験できるように「IoTセンサーシミュレーター」を利用します。 IoTセンサーシミュレーターは、Watson IoT Platformの「Quickstart」で用意されているアプリケーションで、ブラウザから操作可能になっています。
試しに、ブラウザでIoTセンサーシミュレーターを開いてください。

画面右上の12桁の文字列が「デバイスID」です。アクセスするたび、異なる文字列が表示されます。このデバイスIDを使ってデータを取得します。 画面両端の[<]ボタンや[>]ボタンををクリックすると、画面がTemperature(気温)、Humidity(湿度)、Object Temperature(物体温度)に変わります。 画面下部の[↑]ボタンや[↓]ボタンをクリックすると、それぞれの数値を変更できます。
また、デバイスIDをクリックすると、IoTセンサーシミュレーターが送信しているデータがグラフで表示されます。 数値を変更してグラフが変化することを確認してみましょう。 IoTセンサーシミュレーターをスマートフォンやタブレットから操作し、PCでグラフを確認してみると[2]、雰囲気がより伝わるかと思います。

これで、Watson IoT Platformへのデータ送信側の準備ができました。
なお、今回はシミュレーターを利用しましたが、ご興味のある方はIoTデバイス側のアプリケーションの作成にも挑戦してみてください。 Watson IoT Platform導入記事を解説している本連載の第1回が参考になります。 また、IBM Internet of Things Foundation Quickstartの「物理デバイスをお持ちの場合」にも参考になる情報があります。

注
[2]: PCでグラフを見る場合には、デバイスIDは手入力してください。
IoTを始めたい方も・本格導入を検討中の方も:おすすめソリューションのご紹介
ビジネスのパフォーマンスを高めようとさまざまな業種・企業で、IoT活用を前提とするプロジェクトが動き始めています。ただし、検討を始めて最初に出てくるのは、こんな要望ではないでしょうか。
「最初は実験的にスタートしたいから、小さく簡単に素早く始めたい」
「実運用に移ったときには10万・100万単位のセンサ/デバイスに対応できるスケーラビリティも確保したい」
これにお応えできるサービス・製品がIBMにあります。ぜひ、下記の資料をご覧ください。(編集部)
Node-REDの準備
次に、アプリケーションの作成環境の準備を行います。 Bluemixにログインして「ダッシュボード」を開き、画面上部のメニューから「カタログ」をクリックします。

「ボイラーテンプレート」の一覧が表示されるので、「Node-RED Starter」を探してクリックします。 このとき、画面左のメニューで表示するサービスなどを絞り込むこともできます。

Node-RED Starterの作成画面が開いたら、アプリケーションを作成する「スペース」を指定し、アプリケーションの「名前」と「ホスト」を入力して「作成」をクリックします。 ホスト名はBluemix全体でユニークである必要があります。

Bluemix上で環境構築(アプリケーションのステージング)が始まるので、終わるまでしばらく待ちます。

環境構築が完了すると「アプリは稼動しています」と表示されます。

画面左のメニューから「概要」をクリックし、作成されたアプリケーションを確認します。 上段の名前の下に表示されている「経路」が、今回作成したNode-REDフローエディターへのリンクです。
画面右にはアプリケーションの稼動状況およびログが表示されています。 また、画面下部には現在バインドされているサービスが表示されています。 Node-RED Starterでは、標準で「Cloudant NoSQL DB」がバインドされています。 「サービスまたはAPIの追加」から、その他のサービスを追加することもできます。

では、「経路」のリンクをクリックして、Node-REDフローエディターにアクセスしてみましょう。 リンク先の「Go to your Node-RED flow editor」をクリックします。

Node-REDフローエディター画面が開きます。エディター各部分の意味は表のとおりです。

部分 | 名称 | 役割 |
---|---|---|
① | ノードパレット | 分類されたノードの一覧 |
② | シート | シートごとにフローを作成する。「+」からシートを追加できる |
③ | ワークスペース | ノードを配置して繋げ、フローを作成する |
④ | ノード | 機能をカプセル化したモジュール |
⑤ | フロー | ノードを繋げて処理の流れを定義したもの |
⑥ | デプロイ | 作成したフローをデプロイする |
⑦ | 情報またはデバッグコンソール | 選択しているノードの情報またはデバッグコンソールを表示する |
Node-REDでは、画面左のノードパレットからノードを画面中央のワークスペースに配置し、ノード同士を線で繋いでフロー(処理)を作成します。 処理およびデータは、ノードの左(インプットポート)から入り、右(アウトプットポート)から出て行くイメージです。 ノードによっては、左右両方または片方のポートしかないものがあります。

Node-RED Starterには、Bluemixの各種サービス(WatsonやdashDBなど)と連携できるノードがあらかじめ用意されています。

Node-REDの使い方
さて、アプリケーションの作成に入る前に、Node-REDに関するいくつかのトピックを紹介しましょう。
ログインユーザー名とパスワードの設定
Node-RED Starterの環境構築直後は、ログインパスワードが設定されていません。 このままの状態では、アプリケーションのURLにアクセスすると誰でもNode-REDフローエディターを利用できてしまいます。 使い始める前にパスワードを設定しておきましょう。 設定方法は、Node-REDフローエディターを開くボタンの下部にある「Learn how to password-protect your instance」に記述されています。

説明に従って、Bluemixの「環境変数」から「ユーザー定義」にユーザー名とパスワードを設定します。

これで、Node-REDフローエディターにアクセスしようとするとユーザー名とパスワードの入力が求められるようになります。

「Hello World」を書いてみる
それでは、最も簡単な例として、「Hello World」を表示するフローをNode-REDで書いてみましょう。 まず、画面左のノードパレットからInputのInjectノードとOutputのDebugノードをワークスペースにドラッグ&ドロップします。 そして、Injectノードのアウトプットポート(右側)からDebugノードのインプットノード(左側)へマウスをドラッグしてノード同士を繋ぎます。

Injectノードをダブルクリックするとノードの編集画面が開きます。 「Payload」欄のリストから「string」を選択し、“Hello World”と入力します。 入力した文字列は、payloadという名前のキーに格納されて後続のノードに渡されます。 「Name」欄は、ワークスペース上で表示するノードの名称(任意)です。 「Ok」をクリックして画面を閉じます。

画面右上の「Deploy」ボタンをクリックします。

デプロイが成功したら動かしてみましょう。 画面右上にある「debug」タブをクリックして、デバッグコンソールを表示しておきます。 Injectノードの左にあるインジェクトボタンをクリックして、デバッグコンソールに“Hello World”と表示されれば成功です。

Debugノードを使用したデバッグ
Debugノードはとてもよく使うノードです。 デフォルト設定では、受け取ったメッセージのpayloadキーの値のみを表示します。 フローで流れているJSON形式のメッセージ全体を表示したい場合には、Debugノードの編集画面の「Output」欄を「complete msg object」に変更します。

先ほどと同様に画面右上の「Deploy」ボタンをクリックして、実行します。 先ほどとは異なり、デバッグコンソールにJSON形式のメッセージ全体が表示されていることが確認できます。

ゴミ箱のアイコンをクリックするとデバッグコンソールをクリアできます。

デバッグコンソールへの出力を一時的にオフにしたい場合には、Debugノードの右側のボタンでオフにします。 もう一度クリックするとオンに戻ります。
Debugノードが増えてくるとフローのどの部分の情報なのかが分かりづらくなります。 状況に応じて切り替えると、デバッグ作業がしやすくなります。

フローのエクスポート/インポート
作成したフローは、JSON形式でエクスポートまたはインポートできます。
まず、エクスポートの方法です。 エクスポートしたいフローをワークスペース上で選択します。 この時、ドラッグしながら範囲指定すると複数のノードを一括で選択できます。 選択されたノードは淵が橙色で表示されます。 この状態から画面右上のメニューから「Export」-「Clipboard」を選択します。

表示されたテキストをクリップボードにコピーして別途保管します。

次に、インポートの方法です。 画面右上のメニューから「Import」-「Clipboard」を選択します。

先ほどエクスポートしたテキストを貼り付けてみましょう。

ワークスペースにインポートしたフローが追加されます。 ノードによってはインポート後、個別にノードの再設定(各種サービスへの接続情報など)が必要な場合があります。
このように、作成したフローを簡単にエクスポートまたはインポートできます。
Twitterへのツイートを行ってみる
次に、Twitterへツイートするフローを作成してみましょう。 使用可能なTwitterアカウントをお持ちでない方は、事前に登録をお願いします。
最初に、SocialのTwitterノード、Injectノード、Debugノードを配置して、下図のように繋ぎます。

Twitterノードの編集画面を開き、「Twitter ID」欄右端のペンのアイコンをクリックします。

「Click here to authenticate with Twitter.」をクリックします。

連携アプリの認証画面が表示されます。 Twitterへのログイン情報を入力して「連携アプリを認証」をクリックします。

次の表示が出たら認証は完了です。画面を閉じます。

Twitterノードの編集画面に戻ると「Twitter ID」に連携したTwitter IDが表示されます。 「Add」をクリックします。

「Ok」をクリックして編集画面を閉じます。

Twitterノードのステータスが青くなっていれば設定は完了です。

インジェクトボタンをクリックして、Twitterにタイムスタンプ値がツイートされていることを確認してください。

IoTを始めたい方も・本格導入を検討中の方も:おすすめソリューションのご紹介
ビジネスのパフォーマンスを高めようとさまざまな業種・企業で、IoT活用を前提とするプロジェクトが動き始めています。ただし、検討を始めて最初に出てくるのは、こんな要望ではないでしょうか。
「最初は実験的にスタートしたいから、小さく簡単に素早く始めたい」
「実運用に移ったときには10万・100万単位のセンサ/デバイスに対応できるスケーラビリティも確保したい」
これにお応えできるサービス・製品がIBMにあります。ぜひ、下記の資料をご覧ください。(編集部)
IoTセンサーシミュレーターのデータをCloudantへ保存するアプリケーションの作成
前ページまでで、冒頭で紹介したサンプルアプリケーションを作成するための準備や基礎知識を一通り説明できました。 ここから、冒頭で紹介したサンプルアプリケーションの作成を始めます。 サンプルアプリケーションは2つのアプリケーションで構成されますが、まず最初に「IoTセンサーシミュレーターのデータを受信してCloudantへ保存する」アプリケーションを作成します。
IoTセンサーシミュレーターのデータ受信
Watson IoT Platformからのデータを受信するために、InputのibmiotノードとDebugノードを配置して繋ぎます。

ここで、冒頭で説明したIoTセンサーシミュレーターを開いてください[3]。IoTセンサーシミュレーターを開いた状態のまま、Node-REDエディターに戻ります。ibmiotノードの編集画面を開いて、IoTセンサーシミュレーターの画面右上のデバイスIDを「Device Id」欄に入力し、デプロイします。

デプロイ後、2秒ごとに受信したデータがデバッグコンソールに表示されるようになります。

注
[3]: スマートフォンやタブレットから開いてもかまいません。ただし、ロック状態になるとデータの送信が止まります。ロックを解除してIoTセンサーシミュレーターを再読み込みしてください。再読み込みするとデバイスIDが変わるため、ibmiotノードのデバイスIDの設定も変更する必要があります。
タイムスタンプの付与
IoTセンサーシミュレーターには日時のデータがありません。 後の利用を考えて、受信したデータに日時のデータを付与してみましょう。 JavaScriptを記述するためのFunctionのFunctionノードを配置して、次図のように繋ぎ変えてください。 ノードを繋いでいる線は、選択して[Delete]キーで削除できます。

Functionノードの編集画面を開き、JavaScriptコードを記述します。

記述したコードは次のとおりです。 1~11行目は、タイムスタンプの文字列を生成しています(例:“2016-01-31T12:00:00Z”)。 13~19行目は、後続のノードに渡すJSON形式のデータを生成してmsg.payloadプロパティに格納しています。msg.payloadプロパティには出力するデータを格納します。 21行目は、後続のノードにmsgオブジェクトを渡しています。
//タイムスタンプの生成 var getTimestamp = function (date) { var yyyy = date.getFullYear(); var mm = ('0' + (date.getMonth() + 1)).slice(-2); var dd = ('0' + date.getDate()).slice(-2); var h = ('0' + date.getHours()).slice(-2); var m = ('0' + date.getMinutes()).slice(-2); var s = ('0' + date.getSeconds()).slice(-2); var ts = yyyy + '-' + mm + '-' + dd + 'T' + h + ':' + m + ':' + s + 'Z'; return ts; }; msg.payload = { "name": msg.payload.d.name, "temp": msg.payload.d.temp, "humidity": msg.payload.d.humidity, "objectTemp": msg.payload.d.objectTemp, "timestamp": getTimestamp(new Date()) }; return msg;
ibmiotノードから受け取ったデータは、msg.payloadに格納されています。 後で利用しやすいようにpayloadのフォーマットを上書きして変更しています。

デバッグコンソールでタイムスタンプが付与されていることを確認します。

受信データを一定間隔で処理
IoTセンサーシミュレーターのデータは、先ほど見たとおり、2秒ごとに発信されています。 このまま受信したデータをすべてデータベースに保存すると、データが多くなりすぎます。 そこで、FunctionのDelayノードを利用して、一定間隔でデータを処理するようにフローを変更します。

Delayノードを配置して、編集画面を開きます。 「Action」を「Limit rate to」、「Rate」を「1」msg(s) per「Minute」と設定します。 また、途中のデータを破棄するために「drop intermediate messages」を有効にします。

それから、ibmiotノードとFunctionノードの間にDelayノードを繋げてデプロイします。 これで、デバッグコンソールに1分ごとに受信データが表示されるようになりました。

Cloudantへの保存
前項までで、受信データの準備はできました。 今後は、受信データをデータベースであるCloudantへ保存するフローを作成していきます。
まず、StorageのCloudantノードを配置します。StorageのCloudantノードには2種類ありますが、ここではインプットポート(左側)のみのノードを配置してください。

CloudantノードをFunctionノードの後ろに繋げます。

Cloudantノードの編集画面を開きます。 「Service」には、リストから「[アプリ名]-cloudantNoSQLDB」を選択します。 「Database」には、作成するデータベースの名前を任意に入力します(例:iotsensor)。 保存するのはmsg.payloadプロパティに格納されているデータのみでよいので、「Only store msg.payload object?」を有効にしておきます。

作成したフローをデプロイをすると、受信したデータがCloudantへ保存されていきます。簡単ですね。

保存されたデータを確認してみましょう。 Bluemixダッシュボードに戻って、サイドメニューの「サービス」-「Cloudant NoSQL DB」を開いてください。 それから、画面右下の「Launch」をクリックします。

データベースの一覧が表示されるので見てみると、ここまでの操作で作成された2つのデータベースが確認できます。 1つ目は「nodered」で、名前のとおりNode-REDの各種設定や作成したフローの情報が保存されています。 2つ目は、先ほどフローで作成したデータベース(例:iotsensor)です。

2つ目のデータベース名をクリックすると「All Documents」が開きます。 画面右に保存されているデータが表示されます。試しに一番上のデータを見てみましょう。 ペンのアイコンをクリックします。

先ほどNode-REDのフローから保存したデータが表示されます。 このようにCloudantでは、JSON形式でデータを保存しています。

以上で、「IoTセンサーシミュレーターのデータを受信してCloudantへ保存する」アプリケーションは完成です。
IoTを始めたい方も・本格導入を検討中の方も:おすすめソリューションのご紹介
ビジネスのパフォーマンスを高めようとさまざまな業種・企業で、IoT活用を前提とするプロジェクトが動き始めています。ただし、検討を始めて最初に出てくるのは、こんな要望ではないでしょうか。
「最初は実験的にスタートしたいから、小さく簡単に素早く始めたい」
「実運用に移ったときには10万・100万単位のセンサ/デバイスに対応できるスケーラビリティも確保したい」
これにお応えできるサービス・製品がIBMにあります。ぜひ、下記の資料をご覧ください。(編集部)
Cloudantの準備
次は、「蓄積されたデータをもとに気温や湿度の平均値、不快指数を計算して定期的にTwitterへツイートする」アプリケーションの作成です。 ただしその前に、Cloudantに蓄積したIoTセンサーシミュレーターからのデータを検索するときに使用するインデックスと、過去の気象データを保存するための新しいデータベースを作成します。
インデックスの作成(IoTセンサーシミュレーターのデータ検索用)
Cloudantに保存したIoTセンサーシミュレーターからのデータを日付で検索できるように、インデックスを作成します。 「+」アイコンをクリックし、メニューから「New Search Index」を選択します。

「Create Search Index」画面が表示されるので、「_design/」欄に「index」、「Index name」欄にIndex名(ここではindexByTimestamp)を入力してください。画面下段にある「Type」欄では「keyword」(トークン化なし)を選択してください。
「Search index function」には、次のJavaScriptコードを記述します。
function (doc) { index("timestamp", doc.timestamp); }
index
関数の1つ目のパラメータは、インデックスを照会するときに使用するフィールド名です。 2つ目のパラメータは、インデックスを作成するデータです。

新しいデータベースの作成
サンプルアプリケーションでは、過去の気象データから、IoTセンサーシミュレーターのデータから計算した気温、湿度の平均値や不快指数が、何年何月の日本のどこと同じかを求めます。 その過去の気象データをアプリケーションから利用できるように、もう1つデータベースを作成します。
気象データは気象庁のホームページからダウンロードできます。 ダウンロードしたデータをもとにExcelなどを利用してJSON形式のデータを作成し、Cloudantのデータベースにあらかじめ登録しておきます。
なお、気象庁の気象データには不快指数がありません。 そこで、今回は便宜的に月平均気温と月平均相対湿度から不快指数(整数値)を求めることにしました。 不快指数については、Wikipediaを参考にしてください。

では、画面右上の「Create Database」から新規のデータベースを作成します。 データベース名(例:meteorologicaldata)を入力して「Create」ボタンをクリックします。

新規のデータベースが作成されました。 続いて、「All Documents」の「+」アイコンからリストの「New Doc」を選択します。

新規データとして、過去の気象データからサンプルアプリケーション用に加工したJSON形式のデータを貼り付けます。1件のデータは次のような内容になっています。
{ "_id": "07675560228950c3d8374c4092256841", "_rev": "2-80df6c02cae197b66fc0ad6da3db66f7", "discomfort": 18, "temperature": -15.2, "humidity": 56, "year": 2011, "month": 2, "place": "富士山", "min": -26.2, "max": -3.7 }
_idは、デフォルトで表示されているものを利用します。 このとき、_idの最後に「,」(カンマ)を付けるのを忘れないようにしてください。 _idは、ユニークになるようにすれば、任意に設定することも可能です。 _revは、保存すると自動で作成されるので入力する必要はありません。
上記データの意味は、「2011年(year)2月(month)の富士山(place)は平均気温マイナス15.2℃(temprature)、平均湿度56%(humidity)、不快指数18%(discomfort)、過去最低気温マイナス26.2℃(min)、過去最高気温マイナス3.7℃(max)」です。

なお、今回は簡単に登録できる手作業によるデータ登録方法を紹介したましたが、実際の活用では一括でデータを登録するアプリを別途用意したほうがよいでしょう。
インデックスの作成(過去の気象データの検索用)
前項で作成した気象データのデータベースに対してもインデックスを作成しておきます。 設定方法は、IoTセンサーシミュレーターのデータに対してインデックスを作成したときと同じです。
「Search index function」には、次のJavaScriptを記述してください。 検索に使うフィールドは不快指数のフィールドを指定します(例:discomfort)。
function (doc) { index("discomfort", doc.discomfort); }

これでCloudant側の準備が終わりました。 次ページから、用意したデータを利用してツイートするほうのアプリケーションを作成します。
IoTを始めたい方も・本格導入を検討中の方も:おすすめソリューションのご紹介
ビジネスのパフォーマンスを高めようとさまざまな業種・企業で、IoT活用を前提とするプロジェクトが動き始めています。ただし、検討を始めて最初に出てくるのは、こんな要望ではないでしょうか。
「最初は実験的にスタートしたいから、小さく簡単に素早く始めたい」
「実運用に移ったときには10万・100万単位のセンサ/デバイスに対応できるスケーラビリティも確保したい」
これにお応えできるサービス・製品がIBMにあります。ぜひ、下記の資料をご覧ください。(編集部)
平均気温・湿度、不快指数を計算して定期的にツイートするアプリケーションの作成
前項までで、IoTセンサーシミュレーターのデータをCloudantへ保存するアプリケーションができました。 これから、蓄積されたデータを利用して定期的にツイートするアプリケーションを作成していきます。 作業しやすいように、Node-REDで新規のシートを追加してください。
アプリケーションのフローは次図のとおりです。

1段目(②〜⑤のノード)は、1時間ごとに実行して、現在時刻から1時間前までのデータを検索・取得するフローです。
2段目の前半(⑥〜⑦のノード)は、取得したデータをもとに不快指数を計算するフロー。後半(⑧〜⑨のノード)は、不快指数に一致する過去の気象データを検索・取得するフローです。
3段目(⑩〜⑪のノード)は、取得したデータをもとに文章を作成してTwitterへツイートするフローです。
説明は、上図に示したフローにあるノードごとに行っていきます。 ただし、説明の中ではDebugノードを省略しています。 アプリケーション自体には不要なためですが、動作確認を行いたいので、フロー作成後にDebugノードを追加します。
サンプルアプリケーションのフローをダウンロードできます
本記事のタイトル下にあるダウンロードリンクから、サンプルアプリケーションのフローをダウンロードできます。 本記事の2ページ目にある「フローのエクスポート/インポート」節で説明している方法でインポートし、アプリケーションを試すことができます。インポート後に、ibmiot, Cloudant, Twitterノードの設定を行ってデプロイしてください。
- ファイル名「IoT2DB_flow.json」
- 「IoTデバイスのデータを受信してデータベースに保存する」アプリケーションのフロー
- ファイル名「TweetData_flow.json」
- 「蓄積されたデータをもとに気温や湿度の平均値、不快指数を計算して定期的にTwitterへツイートする」アプリケーションのフロー
ノード①:定期的にTweetするフロー(フローの説明)
「定期的にTweetするフロー」はこのフローを説明するコメントです。このノードはワークスペース上にコメントを表示するためのノードで特に機能はありません。 作成するにはFunctionのCommentノードを配置し、「Title」にフローのタイトルを入力します。

ノード②:定期的に実行
このノードは、イベントを定期的に発生させるためのノードです。 Injectノードを配置して次表のように設定してください。
項目 | 設定値 | 備考 |
---|---|---|
Payload | timestamp | このノードからのpayloadは利用しません。デフォルトのままで構いません |
Topic | (空欄) | |
Repeat | interval | 周期は任意に設定してください。テスト中は短めがよいでしょう |
Name | (任意) |

ノード③:検索期間の設定
CloudantからIoTセンサーシミュレーターのデータを取り出すとき、どれくらいの期間(単位:分)のデータを取り出すかを設定します。 Functionノードを配置して、次のJavaScriptコードを設定します。
//検索期間の設定(現在の日時からspanで指定した期間を検索) var getSearchText = function ( nowdate , span ) { var startdate = new Date( nowdate.getFullYear() , nowdate.getMonth() , nowdate.getDate() , nowdate.getHours() , nowdate.getMinutes() - span , nowdate.getSeconds() ); return getTimestamp( startdate ) + " TO " + getTimestamp( nowdate ); }; //タイムスタンプの生成 var getTimestamp = function ( date ) { var yyyy = date.getFullYear(); mm = ('0' + (date.getMonth() + 1)).slice(-2); dd = ('0' + date.getDate()).slice(-2); h = ('0' + date.getHours()).slice(-2); m = ('0' + date.getMinutes()).slice(-2); s = ('0' + date.getSeconds()).slice(-2); ts = yyyy + '-' + mm + '-' + dd + 'T' + h + ':' + m + ':' + s + 'Z'; return ts; }; //表示用日付の生成 var getDisplayDatetime = function ( date ) { date.setTime(date.getTime() + (1000 * 60 * 60 * 9 )); //1000*60秒*60分*9時間 var yyyy = date.getFullYear(); mm = ('0' + (date.getMonth() + 1)).slice(-2); dd = ('0' + date.getDate()).slice(-2); h = ('0' + date.getHours()).slice(-2); ts = yyyy + '年' + mm + '月' + dd + '日' + h + ':' + m + ':' + s; return ts; }; var span = 60; var nowdate = new Date(); msg.payload = getSearchText( nowdate , span ); //グローバル変数に日時を格納 context.global.date = getDisplayDatetime( nowdate ); context.global.span = span; return msg;
1~6行目:検索期間の文字列を作成しています(例:2016年1月31日12:10:20から13:10:20までの場合、”2016-01-31T12:10:20Z TO 2016-01-31T13:10:20Z”)。
18~27行目:ツイート時に使用する日付の文字列を組み立てています。また、日本時間に変更しています。
28行目:検索期間(単位:分)を指定しています。
32~34行目:後続のノードで使用できるように、必要な値をグローバル変数へ設定しています。

ノード④:検索条件の設定
ここでは、Cloudantからデータを取り出すときに指定する条件(検索期間と最大取得数)を設定しています。 Functionノードを配置して、次のJavaScriptコードを設定します。
msg.payload = { 'query': 'timestamp:[' + msg.payload + ']', 'limit': 200 }; return msg;
2行目:ノード④で作成した検索期間の文字列('query')を指定しています。
3行目:検索結果の最大取得数('limit')を指定しています。

IoTを始めたい方も・本格導入を検討中の方も:おすすめソリューションのご紹介
ビジネスのパフォーマンスを高めようとさまざまな業種・企業で、IoT活用を前提とするプロジェクトが動き始めています。ただし、検討を始めて最初に出てくるのは、こんな要望ではないでしょうか。
「最初は実験的にスタートしたいから、小さく簡単に素早く始めたい」
「実運用に移ったときには10万・100万単位のセンサ/デバイスに対応できるスケーラビリティも確保したい」
これにお応えできるサービス・製品がIBMにあります。ぜひ、下記の資料をご覧ください。(編集部)
ノード⑤:期間内のデータを検索
このノードで、CloudantからIoTセンサーシミュレーターのデータを取り出します。 StorageのCloudantノードを配置し、次表のように設定してください。 使用するノードは、左右両方にポートがあるCloudantノードです。

項目 | 設定値 | 備考 |
---|---|---|
Service | [アプリ名]-cloudantNoSQLDB | |
Database | [データベース名] | 例:iotsensor |
Search by | search index | |
index/[インデックス名] | 例:indexByTimestamp | |
Name | [任意] |

ノード⑥:平均気温と平均湿度の計算
ノード⑤で取り出したデータから、平均気温と平均湿度を計算します。 Functionノードを配置して、次のJavaScriptコードを設定します。
//平均値を計算 var getAverage = function( arr ) { var sum = 0; arr.forEach(function( elm ) { sum += elm; }); return Math.round(sum / arr.length); }; var total = msg.cloudant.total_rows; if ( total === 0 ){ //データが見つからなかった場合は処理を終了する(後続にmsgを返さない) } else { //データの取得 var timestamp = []; var temp = []; var humidity = []; obj = msg.payload; for ( var i in obj ) { var iotfdata = obj[ i ]; var name1 = "temp"; var name2 = "humidity"; var name3 = "timestamp"; temp.push(iotfdata[name1]); humidity.push(iotfdata[name2]); timestamp.push(iotfdata[name3]); } msg.payload = { "timestamp" : timestamp , "temp" : temp , "humidity" : humidity , "avgtemp" : getAverage( temp ) , "avghumidity" : getAverage( humidity ) }; return msg; }
1~8行目:平均値の計算を行っています。
10行目:検索結果のデータ件数(msg.cloudant.total_rows)を取得しています。
11~12行目:取得したデータ件数が0件の場合、そのまま処理を終了します。 後続のフローにmsgを渡さないと、以降のフローは動作せず終了します。 取得したデータが1件でもある場合、平均気温と平均湿度を求めます。
29~35行目:後続のノードに渡すデータを作成しています。

ノード⑦:不快指数の計算
平均気温、平均湿度に続き、ここでは不快指数を計算します。 Functionノードを配置して、次のJavaScriptコードを設定します。
//不快指数の計算 var getDiscomfortIndex = function ( Td , H ) { return 0.81 * Td + 0.01 * H * (0.99 * Td - 14.3) + 46.3; }; var temp = msg.payload.avgtemp; var humidity = msg.payload.avghumidity; var discomfort = Math.round(getDiscomfortIndex( temp , humidity )); //グローバル変数に不快指数を格納 context.global.temp = temp; context.global.humidity = humidity; context.global.discomfort = discomfort; msg.payload = discomfort; return msg;
1~8行目:不快指数の計算を行っています。
10~13行目:グローバル変数に結果を設定しています。
15行目:後続のノードに渡す不快指数の値を設定しています。

IoTを始めたい方も・本格導入を検討中の方も:おすすめソリューションのご紹介
ビジネスのパフォーマンスを高めようとさまざまな業種・企業で、IoT活用を前提とするプロジェクトが動き始めています。ただし、検討を始めて最初に出てくるのは、こんな要望ではないでしょうか。
「最初は実験的にスタートしたいから、小さく簡単に素早く始めたい」
「実運用に移ったときには10万・100万単位のセンサ/デバイスに対応できるスケーラビリティも確保したい」
これにお応えできるサービス・製品がIBMにあります。ぜひ、下記の資料をご覧ください。(編集部)
ノード⑧:検索条件の設定
ここでは、Cloudantから過去の気象データを取り出すときの検索条件を設定します。 Functionノードを配置して、次のJavaScriptコードを設定します。
msg.payload = { 'query': 'discomfort:' + msg.payload , 'limit': 200 }; return msg;
2行目:ノード⑦で計算した不快指数を指定しています。

ノード⑨:気象データを検索
ノード⑧で設定した検索条件を使って、Cloudantから過去の気象データを取得します。 左右両方にポートがあるCloudantノードを配置して、次表のように設定してください。
項目 | 設定値 | 備考 |
---|---|---|
Service | [アプリ名]-cloudantNoSQLDB | |
Database | [データベース名] | 例:meteorologicaldata |
Search by | search index | |
index/[インデックス名] | 例:indexByDiscomfort | |
Name | [任意] |

ノード⑩:Tweet文書の作成
ノード⑨で取り出した気象データを使って、ここでツイートする文を組み立てます。 Functionノードを配置して、次のJavaScriptコードを設定します。
//体感温度 var getWindchillFactor = function( discomfort ) { var comment = ''; if (discomfort < 55) { comment = 'に寒いですね!'; } else if ( discomfort >= 55 && discomfort < 60 ){ comment = 'に肌寒いですね!'; } else if ( discomfort >= 60 && discomfort < 65 ){ comment = 'ですね!'; } else if ( discomfort >= 65 && discomfort < 70 ){ comment = 'に快いですね!'; } else if ( discomfort >= 70 && discomfort < 75 ){ comment = 'に暑くはないですね!'; } else if ( discomfort >= 75 && discomfort < 80 ){ comment = 'にやや暑いですね!'; } else if ( discomfort >= 80 && discomfort < 85 ){ comment = 'に暑くて汗が出ますね!'; } else { comment = 'に暑くてたまらないですね!'; } return comment; }; var total = msg.cloudant.total_rows; var date = context.global.date; var temp = context.global.temp; var humidity = context.global.humidity; var discomfort = context.global.discomfort; tweetText = date + '頃のデバイス近辺の平均気温は' + temp + '度、平均湿度は' + humidity + '%、不快指数は' + discomfort + 'です。'; if ( total === 0 ){ msg.payload = tweetText + ' ' + '似た気候の場所はどこだろう?'; } else { var obj = msg.payload; msg.payload = tweetText + obj[0].year + '年' + obj[0].month + '月の' + obj[0].place + 'のよう' + getWindchillFactor( discomfort ) + '(最高気温:' + obj[0].max + '度、最低気温:' + obj[0].min + '度)'; } return msg;
1~22行目:不快指数から体感温度のコメントを作成しています。
24行目:検索結果のデータ件数(msg.cloudant.total_rows)を取得しています。
25~28行目:グローバル変数から日付、平均気温と湿度、不快指数を取得しています。
30行目~:ツイートする文章を作成しています。

ノード⑪:Tweet
最後の処理として、ノード⑪で組み立てた文をTwitterにツイートします。 Twitterノードを配置して「Node-REDの使い方 - Twitterへのツイートを行ってみる」の手順に従ってTwiiter IDを設定してください。

Twitterアカウントが準備できない場合は次のステップに進んでください。 ツイートする代わりにデバッグコンソールで確認だけは可能です。
Debugノードの設定
最初に示したフローの図にはありませんでしたが、ノード⑪までの処理の結果を確認するために、フローの最後にDebugノードを配置してください。

以上で、フローは完成です。次ページで実行してみます。
IoTを始めたい方も・本格導入を検討中の方も:おすすめソリューションのご紹介
ビジネスのパフォーマンスを高めようとさまざまな業種・企業で、IoT活用を前提とするプロジェクトが動き始めています。ただし、検討を始めて最初に出てくるのは、こんな要望ではないでしょうか。
「最初は実験的にスタートしたいから、小さく簡単に素早く始めたい」
「実運用に移ったときには10万・100万単位のセンサ/デバイスに対応できるスケーラビリティも確保したい」
これにお応えできるサービス・製品がIBMにあります。ぜひ、下記の資料をご覧ください。(編集部)
アプリケーションの実行
アプリケーションを実行する前に、データがCloudantの中に存在している必要があります。 実行前にIoTセンサーシミュレーターを開いて、ある程度データを蓄積しておいてください。
手動でアプリケーションを実行したい場合は、インジェクトボタンをクリックします。 まずは、デバッグコンソールにツイートした文が表示されていかどうかを確認してください。

そして、Twitterにその文がツイートされていれば実行は成功です!

最後に
Bluemixには、Watson IoT Platform、Cloudant、Node-RED以外にも、Watsonなど魅力的なサービスがあり、それらのサービスと連携したアプリケーションを素早く作成して公開できます。

今回は、Twitterを利用しましたが、例えばWatsonの「Text to Speech(音声合成)」サービスを利用すれば、情報を音声で読み上げるサイトを構築できます。 また、「Insights for Weather」サービスを利用して、現在の天気や今後の予報を取得・表示するなどのアプリケーションも考えられます。
去る2月18日に、日本IBMとソフトバンクが「IBM Watson」を利用した日本語版コグニティブサービスの提供を開始するという発表がありました(記事)。今後、BluemixおよびNode-RED Starterから日本語のWatsonサービスが利用できるようになることが期待されます。筆者も楽しみに待ちたいと思います。
IoTを始めたい方も・本格導入を検討中の方も:おすすめソリューションのご紹介
ビジネスのパフォーマンスを高めようとさまざまな業種・企業で、IoT活用を前提とするプロジェクトが動き始めています。ただし、検討を始めて最初に出てくるのは、こんな要望ではないでしょうか。
「最初は実験的にスタートしたいから、小さく簡単に素早く始めたい」
「実運用に移ったときには10万・100万単位のセンサ/デバイスに対応できるスケーラビリティも確保したい」
これにお応えできるサービス・製品がIBMにあります。ぜひ、下記の資料をご覧ください。(編集部)