目次


位置認識機能を備えた IoT アプリを作成する、第 1 回

IoT デバイスから GPS データを取得して使用する PHP アプリを作成する

IBM Watson IoT Platform、IBM Cloud、MQTT を使用してモノのインターネットに対応する PHP アプリを開発する

Comments

コンテンツシリーズ

このコンテンツは全2シリーズのパート#です: 位置認識機能を備えた IoT アプリを作成する、第 1 回

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:位置認識機能を備えた IoT アプリを作成する、第 1 回

このシリーズの続きに乞うご期待。

ここのところ巷では、モノのインターネット (IoT) に関する話題で溢れています。自宅、自動車、ボート、あるいは太陽電池式の機器からその動作状態に関するリアルタイムのデータ・ストリームをどのように送信するかがもっぱらの話題になっており、これによって新たな技術アプリケーションやビジネス機会が幅広く切り開かれます。

けれども IoT アプリを作成しようとする PHP 開発者にとって、IoT に関する誇大宣伝に惑わされることなく実際に IoT デバイスやアプリケーションがテクノロジー・レベルまたは実装レベルでどのように動作するのかを理解するのは簡単なことではありません。少なくとも、私にとってはそうでした。基礎を理解できるようになるまでは、私は IoT 対応の世界を利用するアプリケーションを思い描いて作成し始めるのは難しいという感がありました。

私にとって IoT の世界を理解し始めるのには、かなりの時間がかかり (今でもまだ、学んでいる最中です)、かなりの数の実験を行わなければなりませんでした。そこで、皆さんがその時間と労力を節約できるように、この入門者向けチュートリアルでは、私のお気に入りのプログラミング言語である PHP を使用して IoT アプリケーションを作成するプロセスを案内します。

具体的には、IoT Starter という Android 用アプリを使用して Android フォンを GPS センサーに変身させ、その位置情報を継続的に IBM Cloud にパブリッシュする方法を説明します。その後で、この Android フォンから送られてくるデータ・ストリームを PHP アプリが利用できるようにし、そのデータを使って Web ブラウザーで Android フォンの位置情報をリアルタイムで追跡する方法を説明します。

興味深い内容だと思いませんか?是非とも、この続きを読んでください。

必要になるもの

Google Maps API を使用するアプリケーションは例外なく、「Google Maps APIs Terms of Service」、「Google APIs Terms of Service」、および「Google プライバシー ポリシー」に従う必要があります。プロジェクトを開始する前に時間をとってこれらの要求事項を読んで、アプリケーションがすべての要求事項を満たすようにしてください。

1

Internet of Things Platform Starter ボイラープレートを使用して IBM Cloud アプリを構築する

IoT を開始する最短の道の 1 つは、IBM Watson IoT Platform を利用することです。IBM Watson IoT Platform はクラウドでホストされたプラットフォームであり、すべての IoT 対応デバイスとアプリケーションを接続する中心点としての役割を果たします。簡単に言えば、IoT 対応のデバイスはそのデータをクラウド内の IBM Watson IoT Platform にパブリッシュし、モバイル・アプリケーションや Web アプリケーションが IBM Watson IoT Platform からデータを取り込むという仕組みです。

これから作成するアプリケーションでは IBM Watson IoT Platform が極めて重要な構成要素となるので、最初にこのサービスをセットアップします。IBM Watson IoT Platform を導入するのに最も簡単な方法として、Internet of Things Platform Starter ボイラープレートを使用して新しい IBM Cloud アプリケーションを作成します。ボイラープレートによってアプリケーションに Internet of Things Platform サービス・インスタンスがバインドされます。

  1. IBM Cloud アカウントにログインします。
  2. 皆さんの IBM Cloud アカウントのダッシュボードで、「CREATE APP (アプリの作成)」をクリックします。 「CREATE APP (アプリの作成)」ボタンが含まれるダッシュボードのスクリーン・キャプチャー
    「CREATE APP (アプリの作成)」ボタンが含まれるダッシュボードのスクリーン・キャプチャー
  3. ボイラープレートのリストから、「Internet of Things Platform Starter」ボイラープレートを選択します。 Internet of Things Platform Starter ボイラープレートのアイコンのスクリーン・キャプチャー
    Internet of Things Platform Starter ボイラープレートのアイコンのスクリーン・キャプチャー
  4. 「Create a Cloud Foundry App (Cloud Foundry アプリケーションの作成)」領域で、作成する IBM Cloud アプリケーションの名前とホスト名を指定し、「Create (作成)」をクリックします。Internet of Things Platform サービスのプランとしては、必ず「Lite」プランを選択してください。 入力フィールドが強調表示して示された、アプリケーション作成ダイアログのスクリーン・キャプチャー
    入力フィールドが強調表示して示された、アプリケーション作成ダイアログのスクリーン・キャプチャー
  5. しばらくすると、ステージングを経たアプリケーションが起動されます。この状態になったら、IBM Cloud ダッシュボード内でアプリケーションの名前をクリックしてアプリケーションのステータスを表示し、利用可能なサービスのリストでアプリケーションが Internet of Things Platform サービスにバインドされていることを確認します。 IBM Cloud アプリの「Overview (概要)」画面のスクリーン・キャプチャー
    IBM Cloud アプリの「Overview (概要)」画面のスクリーン・キャプチャー
2

デバイスを IBM Watson IoT Platform に登録する

Internet of Things Platform サービスの構成が完了したら、次は、このサービスに接続するデバイスに関する情報を提供する必要があります。

セキュリティー上の理由から、IBM Watson IoT Platform はデバイスとそのデータを別個のアカウントに隔離します。このアカウントは、組織とも呼ばれます。各組織には、IBM Watson IoT Platform 内部で自動的に作成される 6 文字の固有 ID が割り当てられます。IBM Watson IoT Platform 組織の間では、特定の組織に属するデバイスとアプリケーションが他の組織に可視になることはありません。

  1. アプリケーションの詳細ページで、Internet of Things Platform サービスを選択します。サービスの詳細ページが開きます。
  2. 「Launch (起動)」ボタンをクリックします。組織専用の IBM Watson IoT Platform ダッシュボードが開き、ダッシュボードの最上部にその組織の ID が示されます。
  3. 組織内で初めて起動されるプラットフォームは、デバイスが 1 つも登録されていない状態になっています。そこで、最初のステップとして必要なのは、デバイス・タイプを作成することです。作成したデバイス・タイプは、特定のタイプのデバイスを登録するためのテンプレートとして機能します。デバイス・タイプを作成したら、次のステップとして、そのテンプレートを使用してデバイスを IBM Watson IoT Platform に登録します。
    1. 「Devices (デバイス)」メニューから、「Device Types (デバイス・タイプ)」セクションを見つけて「Create Type (タイプの作成)」をクリックします。「Create Device Type (デバイス・タイプの作成)」ページで、デバイス・タイプの名前を指定して、簡単な説明を入力します。デバイス・タイプとして任意のストリングを選択できますが、使用するデバイスを Internet of Things Platform サービスで認証する際は、それらのデバイスがすべて同じストリングを使用している必要があります。このチュートリアルでは、「Android」というデバイス・タイプを指定してください。次のステップで使用する IoT Starter アプリケーションは、このデバイス・タイプを使用するようにハードコーディングされているためです。

      ユーザーが新しいデバイスを登録するときに指定しなければならない属性を他にも選択することができますが (シリアル番号やハードウェア・バージョンなど)、この単純なアプリケーションの場合、追加の属性は必要ありません。追加の属性は選択せずに、デバイス・タイプを保存してください。

    2. 「Devices (デバイス)」メニューから、「Browse (参照)」セクションを見つけて「Add Device (デバイスの追加)」をクリックし、デバイス・タイプとして「Android」を選択します。

      デバイスの一意の ID を入力します。この ID はランダムな文字列にすることも、説明的な文字列にすることもできます。このチュートリアルでは、例として「A111」という ID を使用します。このデバイス ID を覚えておいてください。この ID は、IBM Watson IoT Platform で認証を行う際に、デバイスが使用するクライアント ID の一部になります。

  4. ここで、デバイスの認証トークンを提供するか新しく生成するよう求められるので、システムに認証トークンを生成させます。すると、この自動生成されたトークンを含む、新しく登録されたデバイスの詳細が、サマリー画面にリスト表示されます。トークンを後で再表示することはできないので、このトークンをクリップボードにコピーして、チュートリアルの後のステップで使用できるようにしてください。

デバイス「A111」が IBM Watson IoT Platform に登録されました。これで、認証トークンが有効であることを条件に、Internet of Things Platform サービスがこのデバイスからのデータ受け入れを開始できます。

3

Android 用 IoT Starter アプリをコンパイルしてインストールする

Android 用 IoT Starter は、Android 対応のスマートフォンまたはタブレット上で稼働するサンプル・アプリケーションです。このアプリケーションはデバイス内部の加速度計やその他のセンサーからのストリーム・データおよびイベントを IBM Watson IoT Platform サービスにパブリッシュします。また、IBM Watson IoT Platform からコマンドを受け取ることもできるので、IBM Watson IoT Platform を使ってリアルタイムのデータ・ストリームと相互作用するアプリケーションを実験的に構築するには、うってつけのアプリケーションです。

Android 開発に熟練している読者の方は、GitHub からコードをダウンロードして Android 開発環境にインポートして、APK ファイルをビルドすることができます。そうでない場合、以下の手順に従うことで、アプリを迅速にインストールして実行中の状態にすることができます。

  1. プロジェクトのソース・コード・リポジトリーを複製します。
    1. Android Studio を起動します。
    2. 「Quick Start (クイック・スタート)」 > 「Check out project from Version Control (バージョン管理からプロジェクトをチェックアウトする)」 > 「Git」の順にクリックします。
    3. 「Clone Repository (リポジトリーの複製)」ダイアログで、以下の GitHub リポジトリーを指定します。

      https://github.com/ibm-messaging/iot-starter-for-android

    4. 「Clone (複製)」をクリックします。
  2. アプリケーションをコンパイルするために、「Build (ビルド)」 > 「Build APK (APK のビルド)」メニューの順にクリックします。これにより、Android アプリケーション・パッケージ (.apk ファイル) がプロジェクトの出力ディレクトリー (例: app/build/outputs/apk) 内に生成されます。
  3. .apk ファイルを Android デバイスにコピーし、ES File Explorer などのファイル・マネージャーを使ってインストールします。
4

Android 用 IoT Starter アプリケーションからのデータを IBM Watson IoT Platform にパブリッシュする

  1. Android デバイス上で、前のステップでインストールしたアプリを起動します。
  2. ウェルカム画面で、組織 ID、デバイス ID、そしてステップ 2 でコピーした認証トークンを入力します。
  3. 「Activate Sensor (センサーをオンにする)」ボタンをクリックします。

     

    Android デバイス上での Android 用 IoT Starter アプリのスクリーン・キャプチャー

    アプリは組織に接続して自身の認証を試みます。認証に成功すると、アプリケーションのウェルカム画面に「Connected to IoT:Yes (IoT への接続状況: 成功)」といった通知が表示され、デバイスがその内部の加速度計から IBM Watson IoT Platform へのデータ送信を自動的に開始します。

     

    Android デバイス上に表示された加速度計データのスクリーン・キャプチャー

IoT デバイスによって送信されたデータは「トピック」にパブリッシュされます。トピックとは、ラジオのチャンネルのようなものです。イベントを、そのタイプに応じて異なるトピックにパブリッシュすることができます。例えば、このデバイスの場合、加速度計のイベントはトピック iot-2/evt/accel/fmt/json にパブリッシュされ、タッチ・イベントはトピック iot-2/evt/touchmove/fmt/json にパブリッシュされます。

IBM Watson IoT Platform ダッシュボードに戻ると、デバイスからの着信データ・ストリームが JSON ドキュメントとして表示されているはずです。以下に、一例を記載します。

特に、各 JSON メッセージに含まれている「latitude」キーと「longitude」キーに注目してください。この 2 つは、デバイスが位置している場所の GPS 座標値を格納するキーです。これらのキーが表示されない場合は、Android デバイスがその位置情報をレポートするように設定されていることを確認してから、Android 用 IoT Starter アプリを再起動してください。

5

アプリがアクセスできるようにするための API キーを生成する

これで、登録済み端末からのデータ・ストリームが IBM Watson IoT Platform 組織に到達するようになりました。全体像の残りの部分を埋めるには、このデータを IBM Watson IoT Platform 組織から取得して、何らかの目的で利用するアプリケーションが必要です。

まず始めに、アプリケーションが IBM Watson IoT Platform 組織にアクセスできるようにすることが必要です。それには、ステップ 2 でデバイスの認証トークンを生成したように、アプリの API キーをこの時点で生成する必要があります。

  1. 組織の IBM Watson IoT Platform ダッシュボードを開きます。
  2. 「Apps (アプリケーション)」 > 「API Keys (API キー)」の順に選択します。
  3. 「Generate API Key (API キーの生成)」ボタンをクリックします。
  4. 自動的に生成された API キーと認証トークンをメモします。次のステップで、この両方の値が必要になります。

     

  5. 「Generate (生成)」をクリックして API キーを保存します。
6

IBM Watson IoT Platform からのデータを PHP アプリケーションに取り込む

ここからが面白い部分です。デバイスとアプリケーションは、MQTT (Message Queue Telemetry Transport) という軽量のメッセージング・プロトコルを使用して、IBM Watson IoT Platform との間でデータを送受信することができます。Android 用 IoT Starter アプリケーションも MQTT を使用して、加速度計データを IBM Watson IoT Platform にパブリッシュします。皆さんが作成するアプリケーションでも、通常は IBM Watson IoT Platform からデータを受信するために「MQTT と対話」する必要があります。

デバイスは特定のトピックにデータをパブリッシュしますが、それと同じく、アプリはそれらのトピックをサブスクライブして、トピックからデータを取り込むことができます。トピック名には、デバイス・タイプとデバイスの名前を含める必要があります。例えば、デバイス「A111」の「accel」イベントをサブスクライブする場合、トピック名は iot-2/type/Android/id/A111/evt/accel/fmt/json となります。+ 記号をワイルドカード文字として使用して、すべてのデバイス・タイプまたはすべてのデバイスを指定することもできます。

アプリに PHP を使用している場合、MQTT サポートを追加する最も簡単な方法の 1 つは、phpMQTT ライブラリーを使用することです。この PHP クラスを使用して、MQTT メッセージと MQTT ブローカーを扱うことができます。phpMQTT ライブラリーを使用するには、このライブラリーを PHP 開発環境に複製するかダウンロードします。このチュートリアルのために用意されている PHP スクリプトは、phpMQTT ライブラリーを呼び出すようになっています。

以下の 3 つの PHP スクリプトを使用した 3 つの PHP アプリケーションが作成されています。

  1. cli-app.php および db-app.php: これらのスクリプトは、サーバーのコンソールまたはコマンド・ラインで実行されます。
  2. web-app.php: このスクリプトには、Web ブラウザーからアクセスします。

上記の 3 つの .php ファイルをダウンロードして、テキスト・エディターで開いてください。

script cli-app.php は、まず、新しい phpMQTT オブジェクトを初期化します。初期化されたこのオブジェクトが、IBM Watson IoT Platform とのすべての通信の制御点としての役割を果たします。このオブジェクトに必要な複数のパラメーターはすべて、先頭の $config 配列に格納されます。

以下のコード・リストに示されているプレースホルダーは、このチュートリアルの前のステップで取得した実際の値で更新してください。

// set configuration values
$config = array(
  'org_id' => 'IOTF-ORG-ID',
  'port' => '1883',
  'app_id' => 'phpmqtt',
  'iotf_api_key' => 'IOTF-API-KEY',
  'iotf_api_secret' => 'IOTF-API-TOKEN',
  'device_id' => 'DEVICE-ID'
);

$config['server'] = $config['org_id'] . '.messaging.internetofthings.ibmcloud.com';
$config['client_id'] = 'a:' . $config['org_id'] . ':' . $config['app_id'];
$location = array();

phpMQTT に必要なパラメーターは以下のとおりです。

  • サーバー名: 通常は、messaging.internetofthings.ibmcloud.com ドメイン内にある組織 ID にちなんだ名前が付けられます。
  • サーバー・ポート: 非暗号化接続の場合は 1883、暗号化接続の場合は 8883 です。
  • クライアント ID: アプリは自身を認証するために、a:<組織 ID>:<アプリ ID> というフォーマットのクライアント ID を使用する必要があります。ここで、<アプリ ID> はユーザー指定の値です。
  • クライアントの API キーとシークレット: これらはサービスにアクセスするために必要です。

オブジェクトが初期化された後は、そのオブジェクトの connect() を使用して、ステップ 5 で取得した API キーと認証トークンを渡すことで、IBM Watson IoT Platform に接続できます。subscribe() メソッドは、accel トピックをサブスクライブするために使用します。このメソッドは、受信される各メッセージに対して実行するユーザー定義関数も指定します。

このスクリプトでのユーザー定義関数は getLocation() です。この関数の役目は、PHP の json_decode() 関数を使用して各メッセージから GPS データを抽出して画面に表示することです。proc() メソッドは、継続的なループで対象トピックに到達したメッセージのストリームを検査し、処理します。

以下に、このスクリプトからの出力例を示します。

 

GPS データを表示するだけでなく、そのデータをデータベースに保存して、一定期間にわたるデバイスの移動を「追跡」することもできます。db-app.php スクリプトは cli-app.php スクリプトの変形として、デバイスからの GPS ストリームを表示するのではなく、PHP を使用してそのデータを継続的に MySQL データベースに保存します。この保存されたデータは、さまざまなアプリケーション用に分析して活用することができます。その一例として、ユーザーの一定期間にわたる移動を示すグラフの作成があります。

このグラフを作成するには、スクリプトの先頭で MySQL データベースへの接続を作成し、その接続を使用して、MQTT で受信するデータ・パケットごとに INSERT クエリーを実行します。そのための変更は、前に説明した getLocation 関数内だけで行います。この変更内容のすべてはソース・コードを見ると確認できますが、ここでもその一部を記載しておきます。

// connect to database
$mysqli = new mysqli($config['db_host'], $config['db_user'], $config['db_pass'], $config['db_name']);
if ($mysqli->connect_errno) {
  echo 'ERROR: Could not connect to MySQL (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error;
  exit();
}

// ...

function getLocation($topic, $msg) {
  $mysqli = $GLOBALS['mysqli'];
  $json = json_decode($msg);
  $latitude = $json->d->latitude;
  $longitude = $json->d->longitude;
  if (!$mysqli->query("INSERT INTO data(ts, latitude, longitude) VALUES (NOW(), '$latitude', '$longitude')")) {
    echo 'ERROR: Data insertion failed';
    exit();
  }
}

以下に、データベースに保存されたデータの例を示します。

 

より高度なアプリケーションとして、GPS データを表示または保存するのではなく、デバイスの位置を地図上に表示する PHP Web アプリケーションを作成することもできます。

想像がつくと思いますが、この GPS データ・ストリームを使用して有用な処理を行うのはごく簡単なことです。例えば、デバイスの位置情報を示す地図を生成して、リアルタイムでその位置情報を更新するとしたら、そのために必要なものはすべて Google Static Maps API に揃っています。

Google Static Maps API を使用するには、その前に、作成した Web アプリを Google に登録する必要があります。それには、Google アカウントの資格情報で Google にログインし、Google Developers Console にアクセスします。新規プロジェクトを作成して名前を割り当てた後、Google Static Maps API へのアクセスを有効にします。

この API の使用量の制限をよく把握しておいてください。

次に、資格情報画面に表示される、ブラウザー・アクセス用の API キーをメモします。アプリで行うすべての API リクエストを許可するには、この API キーを使用することになります。

以上の作業が終わった後、地図に GPS データを表示する web-app.php スクリプトを作成または更新することができます。

前述のスクリプトは、トピックで受信した各メッセージを処理して画面に表示することを目的としていましたが、このスクリプトの要件はそれとはわずかに異なり、Web ブラウザーのコンテキストでこのスクリプトを使用するにはさまざまな次善策が必要になります。

  • 第一に、ただ単にコンソールに値を出力するのではなく、ブラウザーに地図を表示するために、受信されるデータ・ストリームを処理して、そこから GPS 座標値を抽出しなければなりません。従って、getLocation() メソッドの実行中に抽出された値をスクリプトの残りの部分に公開する必要があります。つまり、座標値をグローバル変数にする必要があるということです。
  • 第二に、地図を表示するために、アプリは GPS 座標値を Google Maps API エンドポイントに挿入してから、そのエンドポイントの URL を使って地図の画像を要求する必要があります。しかし一般には、クライアント・ブラウザーがこのリクエストを実行して画像をレンダリングするには時間がかかります。そこで、前のリクエストによる処理を完了しないうちに新しいメッセージのそれぞれが Google Maps API に対する新しいリクエストを送信することがないように、最初のメッセージを受信した時点で自動的に proc() ループが終了します。

    前の実装での問題は、当然のことながら、デバイスから受信した最初のメッセージだけが処理され、その後のメッセージはすべて無視されるという点です。このシナリオだと、地図にはデバイスの最初の位置情報しか反映されません。この問題を修正するために、<meta http-equiv="refresh"> タグを使用して、10 秒間隔でページの再ロードを強制します。このタグによって事実上、スクリプトは 10 秒ごとにページを再ロードし、定期的に更新された地図を生成することになります。

  • 第三に、デバイスの電源がオフにされていたり、デバイスと IBM Watson IoT Platform との接続が切断されたりすると、proc() ループは (スクリプトがタイムアウトになるまで) 永遠にメッセージを待機します。その場合、ユーザーは空のブラウザー・ページを見続けた末に、タイムアウトのエラー・メッセージを受け取ることになります。このような実装はあまりユーザー・フレンドリーとは言えないため、この状況を回避するために sleep() メソッドを使用して、サブスクライブ済みトピックでメッセージを受信しない期間が 5 秒続いた時点で proc() の処理ループから抜け出し、ページに該当するエラー・メッセージを表示します。

以下は、このスクリプトに Web ブラウザーからアクセスすると表示される画面の一例です。

PHP アプリの出力のスクリーンショット
PHP アプリの出力のスクリーンショット

まとめ

従来型の Web アプリケーションに慣れている開発者にとって、IoT 世界でのリアルタイムのデータ・ストリームとパブリッシュ/サブスクライブ・メカニズムに慣れるまでには時間がかかります。この学習曲線を短縮する一助として、IBM Cloud と IBM Watson IoT Platform は、IoT センサーとの間でデータを受信し、管理し、送信するために必要なものをすべて揃えたインフラストラクチャーを提供します。そこに PHP を結び付けられるようにすれば、すぐに IBM Cloud を利用して IoT アプリの作成を開始することができます。

このチュートリアルで取り上げた概念は、氷山の一角に過ぎません。例えば、このチュートリアルでは IoT センサーからイベント・データを受信して処理する方法しか説明していません。これはいわゆる片方向の通信ですが、同じく簡単に (しかも、さらに興味深いことに)、双方向の通信ループを実装して IoT センサーにリクエストに応じてタスクや計算を実行させることもできます。詳細を学びたい場合は、m2m @ IBM チームによる以下のデモとチュートリアルを参照してください。

  • Connected Car
  • Portfolio
  • RaceTracker

謝辞

このチュートリアルのステップ 1 から 5 は、m2m @ IBM に掲載されている、Mark Halliday 氏と Bryan Boyd 氏が作成した IoT Starter アプリのチュートリアルに基づいています。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Open source, Web development, Mobile development
ArticleID=1028031
ArticleTitle=位置認識機能を備えた IoT アプリを作成する、第 1 回: IoT デバイスから GPS データを取得して使用する PHP アプリを作成する
publish-date=11242017