デバイス ツインの使用 (Node.js)

デバイス ツインは、デバイスに関する情報 (メタデータ、構成、状態など) を格納する JSON ドキュメントです。 IoT Hub は、IoT Hub に接続する各デバイスにデバイス ツインを保持します。

Note

この記事で説明されている機能は、Standard レベルの IoT Hub でのみ使用できます。 Basic および Standard または Free レベルの IoT Hub の詳細については、ソリューションに適した IoT Hub のレベルの選択に関するページを参照してください。

次の場合にデバイス ツインを使用します。

  • ソリューション バックエンドからデバイス メタデータを格納する。

  • デバイス アプリで利用できる機能や状態 (たとえば、使用される接続方法) などの現在の状態に関する情報をレポートする。

  • デバイス アプリとバックエンド アプリの間で実行時間の長いワークフロー (ファームウェアや構成の更新など) の状態を同期する。

  • デバイス メタデータ、構成、または状態を照会する。

デバイス ツインは、同期のほか、デバイスの構成と状態の照会に対応しています。 デバイス ツインの使用方法など、デバイス ツインの詳細については、デバイス ツインの理解に関するページを参照してください。

IoT ハブには、次の要素を含むデバイス ツインが格納されます。

  • タグ。 ソリューション バックエンドからのみアクセスできるデバイス メタデータです。

  • 必要なプロパティ。 ソリューション バックエンドから変更でき、デバイス アプリから監視できる JSON オブジェクトです。

  • 報告されるプロパティ。 デバイス アプリから変更でき、ソリューション バックエンドから読み取り可能な JSON オブジェクトです。

タグとプロパティには配列を含めることはできませんが、入れ子になったオブジェクトを含めることができます。

次の図は、デバイス ツイン組織を示しています。

デバイス ツインの概念図のスクリーンショット。

さらに、ソリューション バックエンドは、上記のすべてのデータに基づいてデバイス ツインに対してクエリを実行できます。 デバイス ツインの詳細については、デバイス ツインの理解に関するページを参照してください。 クエリ実行の詳細については、IoT Hub クエリ言語に関するページを参照してください。

この記事で取り上げるテクニック:

  • シミュレートされたデバイス アプリを使用して、その接続チャネルをデバイス ツインで報告されたプロパティとして報告します。

  • 以前に作成したタグとプロパティのフィルターを使用して、バックエンド アプリからデバイスに対してクエリを実行します。

この記事では、次の 2 つの Node.js コンソール アプリを作成します。

  • AddTagsAndQuery.js: タグの追加とデバイス ツインのクエリを実行するバックエンド アプリ。

  • TwinSimulatedDevice.js: IoT ハブに接続してその接続状態を報告するシミュレートされたデバイス アプリ。

Note

デバイスとバックエンド アプリの両方の構築に使用できる SDK ツールに関する詳細については、「Azure IoT Hub SDK」を参照してください。

前提条件

この記事を完了するには、以下が必要です。

  • IoT Hub。 CLI または Azure portal を使って作成します。

  • 登録済みのデバイス。 Azure portal に登録してください。

  • Node.js バージョン 10.0.x 以降。

  • ポート 8883 がファイアウォールで開放されていることを確認してください。 この記事のデバイス サンプルでは、ポート 8883 を介して通信する MQTT プロトコルを使用しています。 このポートは、企業や教育用のネットワーク環境によってはブロックされている場合があります。 この問題の詳細と対処方法については、「IoT Hub への接続 (MQTT)」を参照してください。

IoT ハブ接続文字列を取得する

この記事では、デバイス ツインに必要なプロパティを追加した後、ID レジストリに対してクエリを実行し、適切に更新された報告されるプロパティを持つデバイスをすべて検索するバックエンド サービスを作成します。 そのサービスには、必要なデバイス ツインのプロパティを変更するためのサービス接続アクセス許可と、ID レジストリに対してクエリを実行するためのレジストリ読み取りアクセス許可が必要となります。 その 2 つのアクセス許可だけを含んだ既定の共有アクセス ポリシーは存在しないため、共有アクセス ポリシーを独自に作成する必要があります。

サービス接続レジストリ読み取りのアクセス許可を付与する共有アクセス ポリシーを作成し、そのポリシーの接続文字列を取得するには、次の手順を実行します。

  1. Azure portal で、 [リソース グループ] を選択します。 ハブが配置されているリソース グループを選択し、リソースの一覧からハブを選択します。

  2. ハブの左側のウィンドウで、 [共有アクセス ポリシー] を選択します。

  3. ポリシー一覧の上にある最初のメニューから、[共有アクセス ポリシーの追加] を選びます。

  4. 右側の [共有アクセス ポリシーの追加] ウィンドウで、serviceAndRegistryRead などのポリシーのわかりやすい名前を入力します。 [アクセス許可][レジストリ読み取り][サービス接続] を選び、[追加] を選びます。

    新しい共有アクセス ポリシーを追加する方法を示すスクリーン キャプチャ。

  5. ポリシーの一覧から、新しいポリシーを選択します。

  6. [プライマリ接続文字列] のコピー アイコンを選び、その値を保存します。

    接続文字列を取得する方法を示すスクリーン キャプチャ。

IoT Hub の共有アクセス ポリシーとアクセス許可の詳細については、「アクセス制御とアクセス許可」を参照してください。

報告されたプロパティを更新するデバイス アプリを作成する

このセクションでは、myDeviceId としてハブに接続される Node.js コンソール アプリを作成し、報告されたデバイス ツインのプロパティを更新して、接続に携帯ネットワークが使用されていることを確認します。

  1. reportconnectivity という名前の新しい空のフォルダーを作成します。 reportconnectivity フォルダー内に、コマンド プロンプトで次のコマンドを使用して新しい package.json ファイルを作成します。 --yes パラメーターではすべての既定値を使用できます。

    npm init --yes
    
  2. reportconnectivity フォルダーのコマンド プロンプトで、次のコマンドを実行して、azure-iot-device パッケージと azure-iot-device-mqtt パッケージをインストールします。

    npm install azure-iot-device azure-iot-device-mqtt --save
    
  3. テキスト エディターを使用して、reportconnectivity フォルダーに新しいReportConnectivity.js ファイルを作成します。

  4. 次のコードを ReportConnectivity.js ファイルに追加します。 {device connection string} を、「IoT ハブにデバイスを登録する」で表示されたデバイス接続文字列に置き換えます。

        'use strict';
        var Client = require('azure-iot-device').Client;
        var Protocol = require('azure-iot-device-mqtt').Mqtt;
    
        var connectionString = '{device connection string}';
        var client = Client.fromConnectionString(connectionString, Protocol);
    
        client.open(function(err) {
        if (err) {
            console.error('could not open IotHub client');
        }  else {
            console.log('client opened');
    
            client.getTwin(function(err, twin) {
            if (err) {
                console.error('could not get twin');
            } else {
                var patch = {
                    connectivity: {
                        type: 'cellular'
                    }
                };
    
                twin.properties.reported.update(patch, function(err) {
                    if (err) {
                        console.error('could not update twin');
                    } else {
                        console.log('twin state reported');
                        process.exit();
                    }
                });
            }
            });
        }
        });
    

    Client オブジェクトに、デバイスからデバイス ツインとやりとりするのに必要なすべてのメソッドが表示されます。 前のコードでは、Client オブジェクトを初期化した後、myDeviceId のデバイス ツインを取得して、報告されるプロパティに接続情報を含めるよう更新します。

  5. デバイス アプリを実行する

        node ReportConnectivity.js
    

    twin state reported というメッセージが表示されます。

  6. これで、デバイスが接続情報を報告したため、両方のクエリで表示されるようになります。 addtagsandqueryapp フォルダーに戻り、クエリを再度実行します。

        node AddTagsAndQuery.js
    

    今回は、myDeviceId が両方のクエリ結果に表示されるはずです。

    両方のクエリ結果で myDeviceId を表示します

目的のプロパティおよびクエリ ツインを更新するサービス アプリを作成する

このセクションでは、myDeviceId に関連付けられたデバイス ツインに場所のメタデータを追加する Node.js コンソール アプリを作成します。 このアプリは、IoT ハブで米国内にあるデバイスのクエリを実行した後、携帯ネットワーク接続を報告しているデバイスのクエリを実行します。

  1. addtagsandqueryapp という名前の新しい空のフォルダーを作成します。 addtagsandqueryapp フォルダー内に、コマンド プロンプトで次のコマンドを使用して新しい package.json ファイルを作成します。 --yes パラメーターではすべての既定値を使用できます。

    npm init --yes
    
  2. コマンド プロンプトで、addtagsandqueryapp フォルダーに移動し、次のコマンドを実行して、azure-iothub パッケージをインストールします。

    npm install azure-iothub --save
    
  3. テキスト エディターを使用して、addtagsandqueryapp フォルダーに新しい AddTagsAndQuery.js ファイルを作成します。

  4. 次のコードを AddTagsAndQuery.js ファイルに追加します。 {iot hub connection string} を、「IoT ハブ接続文字列を取得する」でコピーしておいた IoT ハブ接続文字列に置き換えます。

         'use strict';
         var iothub = require('azure-iothub');
         var connectionString = '{iot hub connection string}';
         var registry = iothub.Registry.fromConnectionString(connectionString);
    
         registry.getTwin('myDeviceId', function(err, twin){
             if (err) {
                 console.error(err.constructor.name + ': ' + err.message);
             } else {
                 var patch = {
                     tags: {
                         location: {
                             region: 'US',
                             plant: 'Redmond43'
                       }
                     }
                 };
    
                 twin.update(patch, function(err) {
                   if (err) {
                     console.error('Could not update twin: ' + err.constructor.name + ': ' + err.message);
                   } else {
                     console.log(twin.deviceId + ' twin updated successfully');
                     queryTwins();
                   }
                 });
             }
         });
    

    Registry オブジェクトに、サービスからデバイス ツインとやりとりするのに必要なすべてのメソッドが表示されます。 前のコードでは、まず Registry オブジェクトを初期化し、myDeviceId のデバイス ツインを取得して、最後にタグを目的の位置情報で更新します。

    タグの更新後、queryTwins 関数を呼び出します。

  5. AddTagsAndQuery.js の末尾に次のコードを追加して、queryTwins 関数を実装します。

         var queryTwins = function() {
             var query = registry.createQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43'", 100);
             query.nextAsTwin(function(err, results) {
                 if (err) {
                     console.error('Failed to fetch the results: ' + err.message);
                 } else {
                     console.log("Devices in Redmond43: " + results.map(function(twin) {return twin.deviceId}).join(','));
                 }
             });
    
             query = registry.createQuery("SELECT * FROM devices WHERE tags.location.plant = 'Redmond43' AND properties.reported.connectivity.type = 'cellular'", 100);
             query.nextAsTwin(function(err, results) {
                 if (err) {
                     console.error('Failed to fetch the results: ' + err.message);
                 } else {
                     console.log("Devices in Redmond43 using cellular network: " + results.map(function(twin) {return twin.deviceId}).join(','));
                 }
             });
         };
    

    前のコードは 2 つのクエリを実行します。1 つ目では、Redmond43 工場にあるデバイスのデバイス ツインのみを選択し、2 つ目のクエリで携帯ネットワーク経由で接続しているデバイスのみを選択するよう絞り込みます。

    コードでクエリ オブジェクトが作成されると、2 番目のパラメーターで返されるドキュメントの最大数が指定されます。 query オブジェクトには、nextAsTwin メソッドを複数回呼び出してすべての結果を取得する際に使用できる hasMoreResults のブール型プロパティが含まれます。 next というメソッドは、集計クエリの結果など、デバイス ツインではない結果で使用できます。

  6. 以下を使用してアプリケーションを実行します。

        node AddTagsAndQuery.js
    

    Redmond43 にあるすべてのデバイスを照会するクエリの結果には、1 件のデバイスが表示され、携帯ネットワークを使用するデバイスに絞り込んだ結果には 0 件のデバイスが表示されます。

    クエリ結果で 1 つのデバイスを参照してください

この記事では、次の内容について説明します。

  • バックエンド アプリからタグとしてデバイス メタデータを追加しました
  • デバイス ツインでデバイス接続情報を報告しました
  • SQL に似た IoT Hub クエリ言語を使用して、デバイス ツイン情報のクエリを実行しました

次のステップ

参照: