IBM Developer Japan Webサイトは2021年3月15日をもって終了となり、日本語コンテンツの一部は、オープンソースとして、提供予定です。 URLはこちら

単純な地震監視システムを構築する

このチュートリアルに取り組むと、Node-RED とそのノードおよびフローベースのプログラミング・モデルについて理解できるようになります。さらに、Node-RED を拡張するために追加のノードをインストールする方法、外部ライブラリーを操作してダッシュボードを作成する方法も学ぶことができます。このチュートリアルで作成するアプリケーションは、地震関連のデータを気象データと併せて分析し、いつ、世界のどこで地震が発生しているかを把握するためのものです。

Node-RED は、視覚的なフローベースでモノのインターネット (IoT) のコンポーネントを接続できる、オープンソースのプログラミング・ツールです。さらに、IBM Cloud に用意されているサービス API を含め、Node-RED を使用して一連のサービス API を統合することもできます。Node-RED 内の各ノードは特定の機能を実行します。これらのノードを使用することで、通常は、所定のアプリケーションを構築するために必要なコーディングの作業量が最小限になります。 これまで Node-RED を使用した経験がないとしたら、まず、この短い動画チュートリアル「Creating your first Node-RED flow」を見ることをお勧めします。

このチュートリアルでは、単純化した地震監視システムを作成します。このアプリケーションは次の 2 つのメイン・コンポーネントで構成されています。

  • Web サービス: USGS Earthquake Hazard Program から送信されるリアルタイムの GeoJSON フィードを使用して地震情報を 1 時間ごとに更新します。また、所定の地震発生ポイントの場所の座標 (緯度と経度) に基づき、OpenWeatherMap を使用して現在の気象状態を取得します。

  • ダッシュボード: Web サービス・コンポーネントから取得した地震発生ポイントを世界地図上に表示します。地震発生ポイントの詳細は Cloudant データベース内にも保存されます。さらに、このダッシュボードには最新の地震関係のツイートと、各地域での地震の発生頻度も表示されます。

それでは開始しましょう!

学習の目的

このチュートリアルを完了すると、以下の方法がわかるようになります。

  • IBM Cloud 上で稼働する Node-RED Starter アプリケーションを作成する。
  • Node-RED Library 内で利用可能なノードをインストールして操作する。
  • 外部パッケージまたはモジュールを関数ノードで使用できるようにする。
  • ダッシュボード・ノードを操作する。
  • Node-RED Starter アプリケーション内に作成された Web API をセキュリティーで保護する。

前提条件

  • IBM Cloud Lite (ライト) アカウントを作成します (IBM Cloud アカウントをまだお持ちでない場合)。
  • API キーを取得するために、OpenWeatherMap 上でアカウントを作成します。
  • Twitter 上でアカウントを作成し、Twitter アプリケーションを作成します。

所要時間

前提条件を含め、このチュートリアルを完了するには約 1 時間かかります。

1

Node-RED Starter アプリケーションを作成する

  1. IBM Cloud アカウントにログインします。
  2. IBM Cloud のカタログ (ソフトウェア・タブ)を開きます。
  3. スターター・キット・カテゴリーを選択し、「Node-RED App」をクリックします。
  4. Create App (アプリの作成)」をクリックし、アプリ名として一意の名前を入力します。入力した名前はホスト名としても使用されます。ライト・アカウントを使用している場合、「Region (リージョン)」、「Organization (組織)」、「Space (スペース)」の各フィールドには適切な値が事前に取り込まれています。
  5. Selected Plan (選択したプラン)」セクションで、Cloudant データベースに対して「Lite (ライト)」項目を選択します。
  6. Create (作成)」ボタンをクリックします。

    IBM Cloud 内の Node-RED Starter アプリケーションのスクリーン・キャプチャー

  7. アプリケーションのステータスが Running (実行中) に変わったら、「Visit App URL (アプリ URL にアクセス)」をクリックします。

  8. 指示に従って Node-RED フロー・エディター にアクセスします。許可されたユーザーだけにアクセスを制限するために、Node-RED フロー・エディターをセキュリティーで保護するよう促されます。

    Node-RED のセキュリティー保護を示す画面のスクリーン・キャプチャー

  9. Go to your Node-RED flow editor (Node-RED フロー・エディターの表示)」をクリックします。すると、Flow 1 という名前の新しいフローが Node-RED フロー・エディターで開きます。Node-RED フロー・エディターをセキュリティーで保護した場合、最初にユーザー名パスワードを入力するよう求められます。

2

アプリケーションを開発する

このチュートリアルで作成する地震監視システム・アプリケーションは、次の 2 つのメイン・コンポーネントで構成されています。

  • Web サービス・コンポーネント
  • ダッシュボード・コンポーネント

以下に、Node-RED アプリ内でこの 2 つのコンポーネントを作成する手順を説明します。この手順に従って、Node-RED を使用してアプリを作成するのがいかに簡単であるかを確認することをお勧めします。

このチュートリアルで説明するフローの両方をインポートすることもできます。それにはまず、flows.json ファイルをダウンロードするか、このファイルの内容をクリップボードにコピーします。次に、Node-RED エディター内のハンバーガー・メニューから 「Import (インポート)」 > 「Clipboard (クリップボード)」の順に選択します。コピーした内容をダイアログに貼り付けて、「Import (インポート)」をクリックします。ファイルをダウンロードする方法を選んだ場合は、必ず「select a file to import (インポートするファイルの選択)」でファイルを選択してから、「Import (インポート)」をクリックしてください。フローをインポートしたとしても、すべてのノードを構成してパッケージを関数ノードで使用可能にするには、このチュートリアルの手順に従う必要があります。

2a

Web サービスを作成する

  1. デフォルトのフロー名が付いたタブをダブルクリックし、Earthquake Details という名前に変更します。
  2. ハンバーガー・メニューをクリックし、「Manage palette (パレットの管理)」をクリックします。node-red-node-openweathermap を見つけて、これらの追加ノードをパレット内にインストールします。

    Node-RED のパレットの設定を示す画面のスクリーン・キャプチャー

  3. フローに「HTTP input (HTTP 入力)」ノードを追加します。

  4. ノードをダブルクリックして、編集します。メソッドを GET に設定し、URL を /earthquakeinfo-hr に設定します。
  5. HTTP response (HTTP レスポンス)」ノードを追加し、前に追加した「HTTP input (HTTP 入力)」ノードに接続します。このサブセクションで説明するその他すべてのノードは、この「HTTP input (HTTP 入力)」ノードと「HTTP response (HTTP レスポンス)」ノードの間に追加します。
  6. HTTP request (HTTP リクエスト)」ノードを追加します。URLhttps://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson に設定し、メソッド を「GET」に、戻り値 を「a parsed JSON object (解析済み JSON オブジェクト)」に設定します。この設定により、過去 1 時間以内に発生したすべての地震を抽出できるようになります。このノードには Get Earthquake Info from USGS という名前を付けます。

    変更

  7. change (変更)」ノードを追加します。ノードをダブルクリックして、変更を加えます。このノードには Set Earthquake Info という名前を付けます。「Rules (ルール)」セクションで、msg.topicmsg.headersmsg.statusCodemsg.responseUrlmsg.redirectList削除 するルールを追加し、msg.payload を以下の JSONata 式に設定 します。

    payload.features.{
       "type":properties.type,
       "magnitude": properties.mag,
       "location": properties.place,
       "longitude":geometry.coordinates[0],
       "latitude":geometry.coordinates[1],
       "depth":geometry.coordinates[2],
       "timestamp": $fromMillis(
           properties.time,
           '[H01]:[m01]:[s01] [z]',
           '+0400'
       ),
       "source": properties.net
    }
    
  8. split (分割)」ノードを追加します。このノードは、地震情報に含まれる地震発生ポイントを、それぞれの場所に応じて異なるメッセージに分割します。

  9. change (変更)」ノードを追加して、緯度と経度を適切なプロパティーに設定します。これらのプロパティーは、「openweathermap」ノードに取り込まれます。「Rules (ルール)」セクションで、msg.detailsmsg.payload に、 msg.location.lonmsg.payload.longitude に、 msg.location.latmsg.payload.latitude設定 します。このノードには Set Lon & Lat という名前を付けます。

    Node-RED の変更ノードのスクリーン・キャプチャー

  10. openwethermap」ノードを追加し、OpenWeatherMap サイトから API キーを取得してこのノードに追加します (OpenWeatherMap 上で作成したアカウントを使用してサイトにログインしてください)。

  11. 別の「change (変更)」ノードを追加します。このノードでは msg.payload を、メッセージを適切にフォーマット設定するための JSONata 式の出力に設定 します。このノードには Add Weather Data という名前を付けます。JSONata 式は以下のとおりです。

     msg.{
       "name": parts.index,
       "Place": details.place,
       "Location":details.location,
       "Country":location.country,
       "mag":details.magnitude,
       "Source":details.source,
       "Timestamp":details.timestamp,
       "lon": location.lon,
       "lat":location.lat,
       "Type":details.type,
       "Temperature":data.main.temp & ' Kelvin',
       "Pressure":data.main.pressure & ' hPa',
       "Humidity":data.main.humidity & ' %',
       "Wind Speed":data.wind.speed & ' meter(s)/sec',
       "Wind Direction":data.wind.deg & ' degree(s)',
       "Cloud Coverage":data.clouds.all & ' %',
       "icon":'earthquake',
       "intensity":details.magnitude / 10
    }
    
  12. Deploy (デプロイ)」をクリックして、すべての変更を適用します。

countryjs パッケージを追加する

Web サービス・コンポーネントを完成させるには、countryjs パッケージを関数ノードで使用可能にする必要があります。これにより、地震発生ポイントごとに地域と国を設定できるようになります。

  1. 作成した IBM Cloud アプリケーションのページに戻ります。
  2. Overview (概要)」をクリックします。 「Continuous delivery (継続的デリバリー)」セクションで「Enable (有効化)」をクリックします。

    IBM Cloud アプリの概要ページのスクリーン・キャプチャー

  3. 事前に取り込まれたすべての詳細を確認してから、「Tool Integrations (ツールの統合)」セクションで「Delivery Pipeline (デリバリー・パイプライン)」を選択し、「Create+ (作成+)」をクリックします。これで、IBM Cloud API キーが生成されます。

  4. ページの下部にある「Create (作成)」ボタンをクリックします。

    IBM Cloud アプリの継続的デリバリーの設定を示す画面のスクリーン・キャプチャー

  5. 次は、いくつかのファイルを構成して countryjs パッケージを関数ノードで使用可能にする必要があります。 「Toolchains (ツールチェーン)」ウィンドウで、次のいずれかの手順に従ってください。

    • Git」アクションを使用してリポジトリーを複製し、ローカルでファイルを編集する。
    • Eclipse Orion Web IDE を開いて、IBM Cloud 内でファイルを編集する。

    Eclipse Orion Web IDE のスクリーン・キャプチャー

  6. bluemix-settings.js ファイルを編集します。

    bluemix-setting.js ファイルの内容を示す画面のスクリーン・キャプチャー

  7. functionGlobalContext オブジェクトの定義を見つけて、そこに countryjs を追加します。

     functionGlobalContext: {
         countryjs:require('countryjs')
     },
    
  8. package.json ファイルを編集して、countryjs を依存関係として定義します。

     "dependencies": {
         ...,
         "countryjs":"1.8.0"
     },
    

    package.json ファイルの内容を示す画面のスクリーン・キャプチャー

  9. Git を使用して、すべての変更をコミットしてからプッシュします。

  10. アプリケーションのページに戻り、アプリケーションがデプロイを完了するまで待ちます。デプロイが完了したかどうかは、「Delivery Pipeline (デリバリー・パイプライン)」カードを見るとわかります。

    「Deploy Stage (デプロイ・ステージ)」が表示された「Delivery Pipeline (デリバリー・パイプライン)」カードのスクリーン・キャプチャー

Web サービスを仕上げる

  1. 前に追加した「change (変更)」ノードの後ろに「function (関数)」ノードを追加します。 この関数ノードには Set Region & Country using countryjs という名前を付けます。このノードに、以下の JavaScript コードを追加します。

    var countryjs = global.get('countryjs');
    
    msg.payload.Country = countryjs.name(msg.location.country)
    msg.payload.Region = countryjs.region(msg.location.country)
    
    return msg;
    
  2. 冗長なプロパティーのすべてを削除する「change (変更)」ノードを追加します。「Rules (ルール)」セクションで、 msg.detailsmsg.locationmsg.datamsg.titlemsg.description削除 するルールを追加します。このノードには Remove Unnecessary Properties という名前を付けます。

    Node-RED の変更ノードのプロパティーを示す画面のスクリーン・キャプチャー

  3. 前に分割したメッセージを結合して 1 つのメッセージに戻す「join (結合)」ノードを追加します。HTTP リクエストを送信すると、このノードによって結合されたメッセ—ジが返されます。

  4. change (変更)」ノードを追加して、Set Headers という名前を付けます。「Rules (ルール)」セクションで、msg.headers{ "Content-Type": "application/JSON" }設定 するルールを追加し、Web サービス への HTTP リクエストに対するレスポンスが JSON 形式で返されるように定義します。
  5. フローをクリーンアップした後、フローの内容は以下に示すようになっているはずです。

    完成した Node-RED フローのスクリーン・キャプチャー

  6. Deploy (デプロイ)」をクリックして、すべての変更を適用します。

2b

ダッシュボードを作成する

Web サービス・コンポーネントの作成が完了したら、ダッシュボード・コンポーネントの作成を開始できます。

ダッシュボード内に同様のウィジェットをまとめる

  1. 新しいフローを追加して、Dashboard という名前を付けます。
  2. Manage palette (パレットの管理)」を表示して、node-red-contrib-web-worldmap パッケージと node-red-dashboard パッケージをインストールします。node-red-contrib-web-worldmap は、地図を作成するためのパッケージであり、このパッケージによって作成された地図上に、過去 1 時間以内に地震が発生した場所に対応するポイントが描画されます。node-red-dashboard は、地震に関する最新のツイートと、地域ごとの地震発生頻度を表示するためのパッケージです。
  3. Node information (ノード情報)」タブと「Debug messages (デバッグ・メッセージ)」タブの横に追加された「Dashboard (ダッシュボード)」タブを表示します。このタブには、「Layout (レイアウト)」、「Site (サイト)」、「Theme (テーマ)」という 3 つのサブタブがあります。これらのサブタブのそれぞれを使用して、UI のルック・アンド・フィールを変更します。
  4. Layout (レイアウト)」タブで、「+tab (+タブ)」をクリックしてタブを作成します。これにより、UI 内にページに似たタブを作成できます。作成されたタブを以下の図に示すように編集してから、「Update (更新)」をクリックします。

    Node-RED フロー内の「Dashboard (ダッシュボード)」タブを示す画面のスクリーン・キャプチャー

  5. +group (+グループ)」をクリックして、同様のウィジェットをまとめるために使用するグループをタブに追加します。全部で 3 つのグループを追加する必要があります (地図用の Map グループ、最新のツイート用の Latest Tweet グループ、地震発生頻度用の Earthquake Frequency グループ)。「dashboard (ダッシュボード)」ノードを追加するときは、これらのグループのいずれかに追加します。

    Node-RED のダッシュボード・グループ・ノードを示す画面のスクリーン・キャプチャー

ダッシュボード・フローを定義する

  1. ダッシュボード・フローの編集スペースで、「inject (注入)」ノードを追加します。このノードは、各デプロイメントが完了してから 0.1 秒後に 1 回、空の JSON オブジェクト ({}) にペイロードを注入します。
  2. Node-RED の「template (テンプレート)」ノードを追加し、以下の HTML コードを追加します。これにより、/worldmap エンドポイント内の変更を反映します。このノードには Display という名前を付けます。

     <iframe src="/worldmap" height=670 width=670></iframe>
    
  3. ダッシュボードの「template (テンプレート)」ノードを追加し、以下のように編集します。このノードには Map という名前を付けます。

    Node-RED のダッシュボード・テンプレート・ノードを示す画面のスクリーン・キャプチャー

  4. 空の JSON オブジェクト ({}) にペイロードを注入する「inject (注入)」ノードを追加します。注入するタイミングはデプロイメントが完了してから 5 秒後、および 60 分間隔に設定します。

     Node-RED の注入ノードを示す画面のスクリーン・キャプチャー

  5. inject (注入)」ノードを、前に作成した Web サービスを呼び出す「HTTP request (HTTP リクエスト)」ノードに接続します。リクエストに対して返されるデータは、worldmap エンドポイントを介して地図上に表示されるとともに、Cloudant データベースに格納されます。また、このデータが分析されて地域ごとの地震発生頻度のグラフが描画されます。「HTTP request (HTTP リクエスト)」ノードを編集して、<APPURL> を Node-RED アプリケーションの URL で置き換え、「Return (戻り値)」が「a parsed JSON object (解析済み JSON オブジェクト)」に設定されていることを確認してください。このノードには Get Earthquake Info という名前を付けます。

    Node-RED の HTTP リクエスト・ノードを示す画面のスクリーン・キャプチャー

  6. split (分割)」ノードを「HTTP request (HTTP リクエスト)」ノードに接続します。このノードは、返された出力を分割して、場所を表すポイントのそれぞれを描画します。ノードの構成はデフォルトのままにしてください。 また、「split (分割)」ノードを「worldmap」ノードにも接続し、Web マップ上に各ポイントを描画できるよう、worldmap ノードを以下のように編集します。

    Node-RED の HTTP リクエスト・ノードを示す画面のスクリーン・キャプチャー

  7. 前述のとおり、ポイントを保管する必要があります。それには、前に追加した「HTTP request (HTTP リクエスト)」ノードに「cloudant out (Cloudant 出力)」ノードを接続し、この Cloudant 出力ノードを以下に示すように構成します。

    Cloudant 出力ノードを示す画面のスクリーン・キャプチャー

  8. 次は、地域ごとの地震発生頻度を調べるための線グラフを描画できるよう、「change (変更)」ノードを「HTTP request (HTTP リクエスト)」ノードに追加して、地域の名前をフィルタリングします。また、msg.payload を JSON 式 payload.Region設定 するルールを追加します。このノードには Filter Regions という名前を付けます。

    別の変更ノードを示す画面のスクリーン・キャプチャー

  9. この「change (変更)」ノードに「function (関数)」ノードを接続します。地域ごとに現在発生している地震の数をカウントするために、「function (関数)」ノードに以下の JavaScript コードを追加します。このノードには Count という名前を付けます。

    var arr = msg.payload;
    
    var counts = {};
    for (var i = 0; i < arr.length; i++) {
        counts[arr[i]] = 1 + (counts[arr[i]] || 0);
    }
    
    msg.payload = counts;
    
    return msg;
    
  10. 別の「function (関数)」ノードを追加します。このノードで実際の頻度を計算し、そのデータを、ダッシュボードの「chart (チャート)」ノードにフィード可能なフォームに挿入します。次に、関数からの出力数を 5 に変更します。このノードには Earthquake Frequency という名前を付けます。以下の JavaScript コードを使用してください。

    msg1 = {topic:"Africa", payload:msg.payload.Africa};
    msg2 = {topic:"Americas", payload:msg.payload.Americas};
    msg3 = {topic:"Asia", payload:msg.payload.Asia};
    msg4 = {topic:"Europe", payload:msg.payload.Europe};
    msg5 = {topic:"Oceania", payload:msg.payload.Oceania};
    
    return [msg1, msg2, msg3, msg4, msg5];
    
  11. 前のステップで追加した「function (関数)」ノードの 5 つの出力を、ダッシュボードの「chart (チャート)」ノードに接続します。

  12. chart (チャート)」ノードを編集して、ノードのプロパティーを以下のように設定します。

    チャート・ノードを示す画面のスクリーン・キャプチャー

  13. twitter in (Twitter 入力)」ノードを追加し、「new twitter-credentials config node (新しい Twitter 資格情報構成ノード)」を追加するようにノードを構成します。Twitter からコンシューマー・キーとシークレットおよびアクセス・トークンとシークレットを取得するための手順に従ってください。

  14. 「Search (検索)」には「all public tweets (すべての公開ツイート)」を設定し、「for (検索対象)」には「earthquake magnitude, earthquake hits」を設定して地震の大きさ、地震の発生が検索されるようにします。

    Twitter ノードを示す画面のスクリーン・キャプチャー

  15. twitter in (Twitter 入力)」ノードをダッシュボードの「text (テキスト)」ノードに接続し、テキスト・ノードを以下のように構成します。

    テキスト・ノードを示す画面のスクリーン・キャプチャー

クリーンアップしてノードを編成した後のフローは、以下に示すような内容になります。

Node-RED フローのスクリーン・キャプチャー

_APPURL_/ui にアクセスするか、矢印アイコンをクリックしてダッシュボードを開くと、以下のスクリーン・キャプチャーに示すような画面が表示されます。

Node-RED ダッシュボードのスクリーン・キャプチャー

3

Web API をセキュリティーで保護する

Web サービスをセキュリティーで保護することは必須ではありませんが、そうすることをお勧めします。 Web API については、セキュリティーで保護することを強くお勧めします。

  1. アプリケーションの「Overview (概要)」ページに戻り、ページの一番下までスクロールダウンして「Continuous delivery (継続的デリバリー)」セクションを見つけます。
  2. View toolchain (ツールチェーンを表示)」をクリックします。
  3. Eclipse Orion Web IDE」をクリックしてオンライン・エディターを開きます。
  4. エディター内の「Edit (編集)」メニュー項目を使用して、bluemix-setting.js ファイルを表示します。
  5. functionGlobalContext オブジェクトの定義を見つけます。
  6. 以下の JavaScript スニペットを、前に追加した functionGlobalContext オブジェクトの前に追加し、基本認証を使用して API をセキュリティーで保護するためのユーザー名とパスワードを定義します。

     httpNodeAuth:{
         user: "apiUser"
         pass: ""
     }
    
  7. bcrypt を使用してパスワードを取得します。それには、フロー・エディターを表示し、「Manage pallete (パレットの管理)」を使用して「bcrypt」ノードをインストールします。

  8. 同じフロー内で「inject (注入)」ノードを追加して「bycrypt」ノードに接続し、「bycrypt」ノードを「debug (デバッグ)」ノードに接続します。

    注入ノードと bcrypt ノードのフローを示す画面のスクリーン・キャプチャー

  9. inject (注入)」ノードに文字列型のパスワードを格納し、そのパスワードを「bcrypt」ノードに注入します (「Action (アクション)」が「Encrypt (暗号化)」に設定されていることを確認してください)。

  10. パスワードを注入した後、「debug (デバッグ)」ノードの出力をコピーし、bluemix-setting.js を再表示して、そのコピーを pass (基本認証で使用する API のパスワードを表します) に追加します。
  11. エディター内で「Git」を使用して、すべての変更をコミットしてからプッシュします。
  12. IBM Cloud ダッシュボード」に戻り、アプリケーションを表示して、アプリケーションがデプロイを完了するまで待ちます。デプロイが完了したかどうかは、「Delivery Pipeline (デリバリー・パイプライン)」を見るとわかります。
  13. Node-RED フロー・エディターに戻り、もう一度 API をセキュリティーで保護します。
  14. HTTP response (HTTP レスポンス)」ノードを再表示し、「Use authentication (ユーザー認証)」を有効化し、「Type (タイプ)」として「basic authentication (基本認証)」を選択します。その上で、定義したユーザー名とパスワードを入力します。パスワードは「bcrypt」ノードの出力ではなく、「bcrypt」ノードに注入された文字列です。

    HTTP レスポンス・ノードを示す画面のスクリーン・キャプチャー

  15. Deploy (デプロイ)」をクリックして変更をデプロイします。

これで、アプリケーション内で定義するすべての API に基本認証が適用されます。

次のステップ

さまざまな地域の地震を監視できるアプリケーションを実装してデプロイすることができました。次は、「IBM Watson」ノードを含め、使用できる他の各種のノードを調べてください。 それには、このチュートリアル 「Build a spoken universal translator using Node-RED and Watson AI services」に取り組むことをお勧めします。