平均気温・湿度、不快指数を計算して定期的にツイートするアプリケーションの作成
前項までで、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にあります。ぜひ、下記の資料をご覧ください。(編集部)