ジョブのスケジュールとブロードキャスト (Node.js)
Azure IoT Hub を使用して、数百万のデバイスを更新するジョブのスケジュールと追跡を行います。 ジョブを使用して、次の操作を行います。
- 必要なプロパティを更新する
- タグを更新する
- ダイレクト メソッドを呼び出す
概念的には、ジョブはこれらのアクションのいずれかをラップし、デバイス ツイン クエリで定義される一連のデバイスに対して実行の進行状況を追跡します。 たとえば、バックエンド アプリでは、ジョブを使用して、10,000 台のデバイスに対して reboot メソッドを呼び出すことができます。これは、デバイス ツイン クエリで指定され、将来の時刻にスケジュールされます。 次に、このアプリケーションを使って、これらの各デバイスが reboot メソッドを受信し実行する進行状況を追跡できます。
これらの各機能について詳しくは、次の記事をご覧ください。
デバイス ツインとプロパティ: デバイス ツインの概要および IoT Hub のデバイス ツインの理解と使用
ダイレクト メソッド: IoT Hub 開発者ガイド - ダイレクト メソッド
Note
この記事で説明されている機能は、Standard レベルの IoT Hub でのみ使用できます。 Basic および Standard または Free レベルの IoT Hub の詳細については、「ソリューションに適した IoT Hub のレベルを選択する」を参照してください。
この記事では、2 つの Node.js アプリを作成する方法について説明します。
バックエンド アプリから呼び出すことができる lockDoor というダイレクト メソッドを実装する Node.js のシミュレートされたデバイス アプリ simDevice.js。
2 つのジョブを作成する Node.js コンソール アプリ scheduleJobService.js。 1 つのジョブが lockDoor ダイレクト メソッドを呼び出し、別のジョブが必要なプロパティの更新を複数のデバイスに送信します。
注意
デバイスとバックエンド アプリの両方の構築に使用できる SDK ツールに関する詳細については、「Azure IoT Hub SDK」を参照してください。
前提条件
Azure サブスクリプション内の IoT ハブ。 ハブがまだない場合は、「IoT ハブの作成」の手順に従うことができます。
お使いの IoT ハブに登録されているデバイス。 IoT ハブ内にデバイスがない場合は、「デバイスの登録」の手順に従ってください。
Node.js バージョン 10.0.x 以降。 開発環境を準備するでは、このアーティクルのために Node.js を Windows または Linux にインストールする方法が説明されています。
ポート 8883 がファイアウォールで開放されていることを確認してください。 この記事のデバイス サンプルでは、ポート 8883 を介して通信する MQTT プロトコルを使用しています。 このポートは、企業や教育用のネットワーク環境によってはブロックされている場合があります。 この問題の詳細と対処方法については、「IoT Hub への接続 (MQTT)」を参照してください。
シミュレート対象デバイス アプリの作成
このセクションでは、クラウドによって呼び出されたダイレクト メソッドに応答する Node.js コンソール アプリを作成します。このアプリはシミュレートされた lockDoor メソッドをトリガーします。
重要
この記事では、Shared Access Signature (対称キー認証とも呼ばれます) を使用してデバイスを接続する手順について説明します。 この認証方法はテストと評価には便利ですが、X.509 証明書を使用してデバイスを認証する方が安全なアプローチです。 詳細については、「セキュリティのベスト プラクティス」>「接続のセキュリティ」をご覧ください。
simDevice という名前の新しい空のフォルダーを作成します。 コマンド プロンプトで次のコマンドを使用して、simDevice フォルダー内に新しい package.json ファイルを作成します。 次の既定値をすべてそのまま使用します。
npm init
コマンド プロンプトで、simDevice フォルダーに移動し、次のコマンドを実行して、azure-iot-device Device SDK パッケージと azure-iot-device-mqtt パッケージをインストールします。
npm install azure-iot-device azure-iot-device-mqtt --save
テキスト エディターを使用して、simDevice フォルダーに新しい simDevice.js ファイルを作成します。
simDevice.js ファイルの先頭に、次の 'require' ステートメントを追加します。
'use strict'; var Client = require('azure-iot-device').Client; var Protocol = require('azure-iot-device-mqtt').Mqtt;
connectionString 変数を追加し、それを使用して Client インスタンスを作成します。
{yourDeviceConnectionString}
プレースホルダーの値は、前にコピーしたデバイス接続文字列に置き換えてください。var connectionString = '{yourDeviceConnectionString}'; var client = Client.fromConnectionString(connectionString, Protocol);
lockDoor メソッドを処理する次の関数を追加します。
var onLockDoor = function(request, response) { // Respond the cloud app for the direct method response.send(200, 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.'); } }); console.log('Locking Door!'); };
lockDoor メソッドのハンドラーを登録する次のコードを追加します。
client.open(function(err) { if (err) { console.error('Could not connect to IotHub client.'); } else { console.log('Client connected to IoT Hub. Register handler for lockDoor direct method.'); client.onDeviceMethod('lockDoor', onLockDoor); } });
simDevice.js ファイルを保存して閉じます。
Note
わかりやすくするために、この記事では再試行ポリシーは実装しません。 運用環境のコードでは、「一時的な障害の処理」の記事で推奨されているように、再試行ポリシー (指数関数的バックオフなど) を実装することをお勧めします。
IoT ハブ接続文字列を取得する
この記事では、デバイス上で直接メソッドを呼び出すようにジョブをスケジュールし、デバイス ツインを更新するようにジョブをスケジュールし、各ジョブの進行状況を監視するバックエンド サービスを作成します。 これらの操作を実行するには、サービスにレジストリ読み取りおよびレジストリ書き込みのアクセス許可が必要です。 既定では、すべての IoT ハブは、これらのアクセス許可を付与する registryReadWrite という名前の共有アクセス ポリシーがある状態で作成されます。
registryReadWrite ポリシーの IoT Hub 接続文字列を取得するには、次の手順を実行します。
Azure portal で、 [リソース グループ] を選択します。 ハブが配置されているリソース グループを選択し、リソースの一覧からハブを選択します。
ハブの左側のウィンドウで、 [共有アクセス ポリシー] を選択します。
ポリシーの一覧から、 [registryReadWrite] ポリシーを選択します。
[プライマリ接続文字列] をコピーし、値を保存します。
IoT Hub の共有アクセス ポリシーとアクセス許可の詳細については、「アクセス制御とアクセス許可」を参照してください。
重要
この記事では、Shared Access Signature を使用してサービスに接続する手順について説明しています。 この認証方法はテストと評価には便利ですが、サービスに対する認証方法としては、Microsoft Entra ID またはマネージド ID を使用する方が安全です。 詳細については、「セキュリティのベスト プラクティス」の「クラウドのセキュリティ」 を参照してください。>
ダイレクト メソッドを呼び出し、デバイス ツインのプロパティを更新するジョブのスケジュール
このセクションでは、ダイレクト メソッドを使用してデバイスでリモート lockDoor を開始する Node.js コンソール アプリを作成し、デバイス ツインのプロパティを更新します。
scheduleJobService という名前の新しい空のフォルダーを作成します。 コマンド プロンプトで次のコマンドを使用して、scheduleJobService フォルダー内に新しい package.json ファイルを作成します。 次の既定値をすべてそのまま使用します。
npm init
コマンド プロンプトで、scheduleJobService フォルダーに移動し、次のコマンドを実行して、azure-iothub Device SDK パッケージと azure-iot-device-mqtt パッケージをインストールします。
npm install azure-iothub uuid --save
テキスト エディターを使用して、scheduleJobService フォルダーに新しい scheduleJobService.js ファイルを作成します。
scheduleJobService.js ファイルの先頭に、次の "require" ステートメントを追加します。
'use strict'; var uuid = require('uuid'); var JobClient = require('azure-iothub').JobClient;
次の変数宣言を追加します。
{iothubconnectionstring}
プレースホルダーの値を、先ほど「{iothubconnectionstring}
」でコピーしておいた値に置き換えます。 myDeviceId とは異なるデバイスを登録した場合は、クエリ条件内の値を変更してください。var connectionString = '{iothubconnectionstring}'; var queryCondition = "deviceId IN ['myDeviceId']"; var startTime = new Date(); var maxExecutionTimeInSeconds = 300; var jobClient = JobClient.fromConnectionString(connectionString);
ジョブの実行を監視するために使用する次の関数を追加します。
function monitorJob (jobId, callback) { var jobMonitorInterval = setInterval(function() { jobClient.getJob(jobId, function(err, result) { if (err) { console.error('Could not get job status: ' + err.message); } else { console.log('Job: ' + jobId + ' - status: ' + result.status); if (result.status === 'completed' || result.status === 'failed' || result.status === 'cancelled') { clearInterval(jobMonitorInterval); callback(null, result); } } }); }, 5000); }
次のコードを追加して、デバイス メソッドを呼び出すジョブをスケジュールします。
var methodParams = { methodName: 'lockDoor', payload: null, responseTimeoutInSeconds: 15 // Timeout after 15 seconds if device is unable to process method }; var methodJobId = uuid.v4(); console.log('scheduling Device Method job with id: ' + methodJobId); jobClient.scheduleDeviceMethod(methodJobId, queryCondition, methodParams, startTime, maxExecutionTimeInSeconds, function(err) { if (err) { console.error('Could not schedule device method job: ' + err.message); } else { monitorJob(methodJobId, function(err, result) { if (err) { console.error('Could not monitor device method job: ' + err.message); } else { console.log(JSON.stringify(result, null, 2)); } }); } });
次のコードを追加して、デバイス ツインを更新するようにジョブをスケジュールします。
var twinPatch = { etag: '*', properties: { desired: { building: '43', floor: 3 } } }; var twinJobId = uuid.v4(); console.log('scheduling Twin Update job with id: ' + twinJobId); jobClient.scheduleTwinUpdate(twinJobId, queryCondition, twinPatch, startTime, maxExecutionTimeInSeconds, function(err) { if (err) { console.error('Could not schedule twin update job: ' + err.message); } else { monitorJob(twinJobId, function(err, result) { if (err) { console.error('Could not monitor twin update job: ' + err.message); } else { console.log(JSON.stringify(result, null, 2)); } }); } });
scheduleJobService.js ファイルを保存して閉じます。
アプリケーションの実行
これで、アプリケーションを実行する準備が整いました。
コマンド プロンプトで、simDevice フォルダーに移動し、次のコマンドを実行して再起動のダイレクト メソッドのリッスンを開始します。
node simDevice.js
コマンド プロンプトで、scheduleJobService フォルダーに移動し、次のコマンドを実行して、ドアをロックしてツインを更新するジョブをトリガーします。
node scheduleJobService.js
ダイレクト メソッドに対するデバイスの応答とジョブの状態がコンソールに表示されます。
ダイレクト メソッドに対するデバイスの応答を次に示します。
ダイレクト メソッドとデバイス ツインの更新に対するサービス スケジュール ジョブと、実行中のジョブ、および完了したジョブを次に示します。
次の手順
この記事では、ダイレクト メソッドを実行してデバイス ツインのプロパティを更新するようにジョブをスケジュールしました。
IoT Hub とデバイス管理パターンの調査を続けるには、「Raspberry Pi 3 B+ 参照イメージを使用した Device Update for Azure IoT Hub のチュートリアル」でイメージを更新してください。