デバイスをリモート監視構成済みソリューションに接続する (Node.js)

シナリオの概要

このシナリオでは、次のテレメトリをリモート監視構成済みソリューションに送信するデバイスを作成します。

  • 外部温度
  • 内部温度
  • 湿度

わかりやすくするために、デバイス上のコードではサンプル値を生成しますが、デバイスに実際のセンサーを接続し、実際のテレメトリを送信して、サンプルを拡張することをお勧めします。

このデバイスでは、ソリューション ダッシュボードから呼び出されたメソッドと、ソリューション ダッシュボードで設定されている必要なプロパティ値に応答することもできます。

このチュートリアルを完了するには、アクティブな Azure アカウントが必要になります。 アカウントがない場合は、無料試用アカウントを数分で作成することができます。 詳細については、「Azure の無料試用版サイト」を参照してください。

開始する前に

デバイス用のコードを作成する前に、リモート監視構成済みソリューションをプロビジョニングし、そのソリューションに新しいカスタム デバイスをプロビジョニングする必要があります。

リモート監視構成済みソリューションをプロビジョニングする

このチュートリアルで作成するデバイスは、リモート監視構成済みソリューションのインスタンスにデータを送信します。 リモート監視構成済みソリューションを Azure アカウントにまだプロビジョニングしていない場合は、次の手順を使用します。

  1. https://www.azureiotsolutions.com/ ページで、 +をクリックしてソリューションを作成します。
  2. [リモート監視] パネルで [選択] をクリックして、ソリューションを作成します。
  3. [Create Remote monitoring solution (リモート監視ソリューションの作成)] ページで任意のソリューション名を入力し、デプロイ先のリージョンを選択したら、使用する Azure サブスクリプションを選択します。 その後、 [ソリューションの作成]をクリックします。
  4. プロビジョニング プロセスが完了するまで待機します。

警告

構成済みソリューションでは、課金対象の Azure サービスを使用します。 不必要な課金を避けるために、使用が済んだら、必ずサブスクリプションから構成済みソリューションを削除してください。 https://www.azureiotsolutions.com/ ページで、構成済みのソリューションをサブスクリプションから完全に削除できます。

リモート監視ソリューションのプロビジョニング プロセスが完了したら、 [起動] をクリックしてブラウザーでソリューション ダッシュボードを開きます。

ソリューションのダッシュボード

リモート監視ソリューションでデバイスをプロビジョニングする

Note

ソリューションにデバイスを既にプロビジョニングしている場合は、この手順を省略して構いません。 クライアント アプリケーションを作成するときに、デバイスの資格情報が必要です。

デバイスが構成済みソリューションに接続するには、有効な資格情報を使用して IoT Hub に対してデバイス自身の ID を証明する必要があります。 デバイスの資格情報は、ソリューション ダッシュボードから取得できます。 このチュートリアルの後半で、クライアント アプリケーションにデバイスの資格情報を含めます。

デバイスをリモート監視ソリューションに追加するには、ソリューション ダッシュボードで次の手順を実行します。

  1. ダッシュボードの左下隅にある [デバイスの追加]をクリックします。

    デバイスを追加する

  2. [カスタム デバイス] パネルで、[新規追加] をクリックします。

    カスタム デバイスを追加する

  3. [デバイス ID を自分で定義する] を選択します。 mydevice などのデバイス ID を入力します。[ID の確認] をクリックして、その名前がまだ使用されていないことを確認し、[作成] をクリックしてデバイスをプロビジョニングします。

    デバイス ID を追加する

  4. デバイスの資格情報 (デバイス ID、IoT Hub ホスト名、デバイス キー) を書き留めておきます。 クライアント アプリケーションがリモート監視ソリューションに接続する際に、この値が必要になります。 次に、 [Done] をクリックします。

    デバイスの資格情報を表示する

  5. ソリューション ダッシュボードのデバイスの一覧でデバイスを選択します。 次に、[デバイスの詳細] パネルで、[デバイスの有効化] をクリックします。 現在、デバイスの状態は [実行中] です。 リモート監視ソリューションはデバイスからテレメトリを受信し、デバイス上でメソッドを呼び出すことができます。

node.js のサンプル ソリューションを作成する

開発コンピューターに Node.js のバージョン 0.11.5x 以降がインストールされていることを確認します。 バージョンを確認するには、コマンド ラインで node --version を実行します。

  1. 開発用コンピューターに RemoteMonitoring という名前のフォルダーを作成します。 コマンドライン環境内でこのフォルダーに移動します。

  2. 次のコマンドを実行して、サンプル アプリケーションを完成させるために必要なパッケージをダウンロードしてインストールします。

    npm init
    npm install azure-iot-device azure-iot-device-mqtt --save
    
  3. RemoteMonitoring フォルダーで、remote_monitoring.js という名前のファイルを作成します。 このファイルをテキスト エディターで開きます。

  4. remote_monitoring.js ファイルに次の require ステートメントを追加します。

    'use strict';
    
    var Protocol = require('azure-iot-device-mqtt').Mqtt;
    var Client = require('azure-iot-device').Client;
    var ConnectionString = require('azure-iot-device').ConnectionString;
    var Message = require('azure-iot-device').Message;
    
  5. require ステートメントの後に次の変数宣言を追加します。 リモート監視ソリューション ダッシュボードで、プレースホルダー [Device Id] と [Device Key] の値を、書き留めておいたデバイス用の値に置き換えます。 ソリューション ダッシュボードの IoT Hub ホスト名を使用して、[IoTHub Name] を置き換えます。 たとえば、IoT Hub ホスト名が contoso.azure-devices.net である場合は、[IoTHub Name] を contoso に置き換えます。

    var connectionString = 'HostName=[IoTHub Name].azure-devices.net;DeviceId=[Device Id];SharedAccessKey=[Device Key]';
    var deviceId = ConnectionString.parse(connectionString).DeviceId;
    
  6. 基本のテレメトリ データをいくつか定義するために、次の変数を追加します。

    var temperature = 50;
    var humidity = 50;
    var externalTemperature = 55;
    
  7. 操作結果を出力するために、次のヘルパー関数を追加します。

    function printErrorFor(op) {
        return function printError(err) {
            if (err) console.log(op + ' error: ' + err.toString());
        };
    }
    
  8. テレメトリの値をランダム化するために使用する次のヘルパー関数を追加します。

    function generateRandomIncrement() {
        return ((Math.random() * 2) - 1);
    }
    
  9. 起動時にデバイスから送信する DeviceInfo オブジェクトについて、次の定義を追加します。

    var deviceMetaData = {
        'ObjectType': 'DeviceInfo',
        'IsSimulatedDevice': 0,
        'Version': '1.0',
        'DeviceProperties': {
            'DeviceID': deviceId,
            'HubEnabledState': 1
        }
    };
    
  10. デバイス ツインの報告される値について、次の定義を追加します。 この定義には、デバイスでサポートされるダイレクト メソッドの説明が含まれます。

    var reportedProperties = {
        "Device": {
            "DeviceState": "normal",
            "Location": {
                "Latitude": 47.642877,
                "Longitude": -122.125497
            }
        },
        "Config": {
            "TemperatureMeanValue": 56.7,
            "TelemetryInterval": 45
        },
        "System": {
            "Manufacturer": "Contoso Inc.",
            "FirmwareVersion": "2.22",
            "InstalledRAM": "8 MB",
            "ModelNumber": "DB-14",
            "Platform": "Plat 9.75",
            "Processor": "i3-9",
            "SerialNumber": "SER99"
        },
        "Location": {
            "Latitude": 47.642877,
            "Longitude": -122.125497
        },
        "SupportedMethods": {
            "Reboot": "Reboot the device",
            "InitiateFirmwareUpdate--FwPackageURI-string": "Updates device Firmware. Use parameter FwPackageURI to specifiy the URI of the firmware file"
        },
    }
    
  11. Reboot ダイレクト メソッドの呼び出しを処理する次の関数を追加します。

    function onReboot(request, response) {
        // Implement actual logic here.
        console.log('Simulated reboot...');
    
        // Complete the response
        response.send(200, "Rebooting device", function(err) {
            if(!!err) {
                console.error('An error occurred when sending a method response:\n' + err.toString());
            } else {
                console.log('Response to method \'' + request.methodName + '\' sent successfully.' );
            }
        });
    }
    
  12. InitiateFirmwareUpdate ダイレクト メソッドの呼び出しを処理する次の関数を追加します。 このダイレクト メソッドは、パラメーターを使用して、ダウンロードするファームウェア イメージの場所を指定し、デバイスでファームウェアの更新を非同期に開始します。

    function onInitiateFirmwareUpdate(request, response) {
        console.log('Simulated firmware update initiated, using: ' + request.payload.FwPackageURI);
    
        // Complete the response
        response.send(200, "Firmware update initiated", function(err) {
            if(!!err) {
                console.error('An error occurred when sending a method response:\n' + err.toString());
            } else {
                console.log('Response to method \'' + request.methodName + '\' sent successfully.' );
            }
        });
    
        // Add logic here to perform the firmware update asynchronously
    }
    
  13. クライアント インスタンスを作成するために次のコードを追加します。

    var client = Client.fromConnectionString(connectionString, Protocol);
    
  14. 次の処理を行うために、以下のコードを追加します。

    • 接続を開きます。
    • DeviceInfo オブジェクトを送信します。
    • 必要なプロパティのハンドラーを設定します。
    • 報告されたプロパティを送信します。
    • ダイレクト メソッドのハンドラーを登録します。
    • テレメトリの送信を開始します。
    client.open(function (err) {
        if (err) {
            printErrorFor('open')(err);
        } else {
            console.log('Sending device metadata:\n' + JSON.stringify(deviceMetaData));
            client.sendEvent(new Message(JSON.stringify(deviceMetaData)), printErrorFor('send metadata'));
    
            // Create device twin
            client.getTwin(function(err, twin) {
                if (err) {
                    console.error('Could not get device twin');
                } else {
                    console.log('Device twin created');
    
                    twin.on('properties.desired', function(delta) {
                        console.log('Received new desired properties:');
                        console.log(JSON.stringify(delta));
                    });
    
                    // Send reported properties
                    twin.properties.reported.update(reportedProperties, function(err) {
                        if (err) throw err;
                        console.log('twin state reported');
                    });
    
                    // Register handlers for direct methods
                    client.onDeviceMethod('Reboot', onReboot);
                    client.onDeviceMethod('InitiateFirmwareUpdate', onInitiateFirmwareUpdate);
                }
            });
    
            // Start sending telemetry
            var sendInterval = setInterval(function () {
                temperature += generateRandomIncrement();
                externalTemperature += generateRandomIncrement();
                humidity += generateRandomIncrement();
    
                var data = JSON.stringify({
                    'DeviceID': deviceId,
                    'Temperature': temperature,
                    'Humidity': humidity,
                    'ExternalTemperature': externalTemperature
                });
    
                console.log('Sending device event data:\n' + data);
                client.sendEvent(new Message(data), printErrorFor('send event'));
            }, 5000);
    
            client.on('error', function (err) {
                printErrorFor('client')(err);
                if (sendInterval) clearInterval(sendInterval);
                client.close(printErrorFor('client.close'));
            });
        }
    });
    
  15. 変更を remote_monitoring.js ファイルに保存します。

  16. コマンド プロンプトで次のコマンドを実行して、サンプル アプリケーションを起動します。

    node remote_monitoring.js
    

デバイスのテレメトリをダッシュボードに表示する

リモート監視ソリューションのダッシュボードでは、デバイスが IoT Hub に送信するテレメトリを表示できます。

  1. ブラウザーでリモート監視ソリューションのダッシュボードに戻り、左側のパネルの [デバイス] をクリックし、[デバイスの一覧] に移動します。

  2. [デバイスの一覧] で、デバイスの状態が [実行中] であることを確認してください。 実行中でない場合は、[デバイスの詳細] パネルで [デバイスの有効化] をクリックします。

    デバイスの状態を表示する

  3. [ダッシュボード] をクリックしてダッシュボードに戻り、[表示するデバイス] ボックスの一覧からテレメトリを表示するデバイスを選択します。 サンプル アプリケーションから送信されるテレメトリは、内部温度では 50 単位、外部温度では 55 単位、湿度では 50 単位です。

    デバイス テレメトリの表示

デバイスでメソッドを呼び出す

リモート監視ソリューションのダッシュボードでは、IoT Hub を介してデバイスでメソッドを呼び出すことができます。 たとえば、リモート監視ソリューションで、デバイスの再起動をシミュレートするメソッドを呼び出すことができます。

  1. リモート監視ソリューションのダッシュボードで、左側のパネルの [デバイス] をクリックし、[デバイスの一覧] に移動します。

  2. [デバイスの一覧] で、デバイスの [デバイス ID] をクリックします。

  3. [デバイスの詳細] パネルで、[メソッド] をクリックします。

    デバイス メソッド

  4. [メソッド] ドロップダウンで [InitiateFirmwareUpdate] を選択し、[FWPACKAGEURI] にダミーの URL を入力します。 [メソッドの呼び出し] をクリックして、デバイスでメソッドを呼び出します。

    デバイス メソッドを呼び出す

  5. デバイスがメソッドを処理しているとき、デバイス コードを実行しているコンソールにメッセージが表示されます。 メソッドの結果は、ソリューション ポータルの履歴に追加されます。

    メソッドの履歴を表示する

次のステップ

構成済みソリューションのカスタマイズ」では、このサンプルを拡張する方法をいくつか確認できます。 可能な拡張には、実際のセンサーの使用やその他のコマンドの実装などがあります。

azureiotsuite.com サイトでのアクセス許可の詳細について確認できます。