IoT Central デバイス ブリッジを使用して他の IoT クラウドを IoT Central に接続する

IoT Central デバイス ブリッジは、SigfoxParticle Device CloudThe Things Network などの他の IoT クラウドを IoT Central アプリケーションに接続するオープン ソース ソリューションです。 デバイス ブリッジは、他の IoT クラウドに接続されているデバイスから IoT Central アプリケーションにデータを転送することで機能します。 デバイス ブリッジでは、IoT Central にデータを転送するだけで、IoT Central からデバイスにコマンドやプロパティの更新を送信しません。

デバイス ブリッジを使用すると、IoT Central の機能を次のようなデバイスと組み合わせることができます。

  • Sigfox の低電力ワイド エリア ネットワークに接続されている資産追跡デバイス。
  • Particle Device Cloud 上の大気質監視デバイス。
  • モノのネットワーク上の土壌水分監視デバイス。

データのルールや分析などの IoT Central アプリケーションの機能を使用したり、Power Automate や Azure Logic Apps でワークフローを作成したり、データをエクスポートしたりすることができます。

デバイス ブリッジ ソリューションでは、デバイス メッセージを変換して IoT Central に転送するために連携して動作する複数の Azure リソースを Azure サブスクリプションにプロビジョニングします。

前提条件

この攻略ガイドの手順を完了するには、次が必要です。

概要

IoT Central デバイス ブリッジは、GitHub のオープン ソース ソリューションです。 カスタム Azure Resource Manager テンプレートを使用して、Azure Functions の関数アプリを含む複数のリソースを Azure サブスクリプションにデプロイします。

関数アプリはデバイス ブリッジの中核部分です。 シンプルな Webhook を介して他の IoT プラットフォームから HTTP POST 要求を受信します。 Azure IoT Central デバイス ブリッジ リポジトリには、Sigfox、Particle、および The Things Network クラウドに接続する方法を示す例が含まれています。 お使いのプラットフォームで関数アプリに HTTP POST 要求を送信できる場合は、カスタムの IoT クラウドに接続するようにこのソリューションを拡張できます。

関数アプリでは、データを IoT Central で受け入れられる形式に変換し、Device Provisioning Service とデバイス クライアントの API を使用してそれを転送します。

コードを示すAzure Functions定義のスクリーンショット。

IoT Central アプリケーションで転送されたメッセージのデバイス ID が認識されると、デバイスからのテレメトリが IoT Central に表示されます。 IoT Central アプリケーションでデバイス ID が認識されない場合、関数アプリはデバイス ID を使用して新しいデバイスの登録を試みます。 新しいデバイスは、IoT Central アプリケーションの [デバイス] ページに [未割り当て] デバイスとして表示されます。 [デバイス] ページでは、新しいデバイスをデバイス テンプレートに割り当ててから、テレメトリを表示することができます。

デバイス ブリッジをデプロイする

デバイス ブリッジをサブスクリプションにデプロイするには:

  1. IoT Central アプリケーションで、[アクセス許可] > [デバイス接続グループ] ページに移動します。

    1. ID スコープを書き留めておきます。 この値は、デバイス ブリッジをデプロイするときに使用します。

    2. 同じページで、 [SAS-IoT-Devices] 登録グループを開きます。 [SAS-IoT-Devices] グループのページで、プライマリ キーをコピーします。 この値は、デバイス ブリッジをデプロイするときに使用します。

  2. 次の [Azure にデプロイ] ボタンを使用して、関数アプリをサブスクリプションにデプロイするカスタム Resource Manager テンプレートを開きます。 前の手順の ID スコーププライマリ キーを使用します。

    [Azure へのデプロイ] ボタン

デプロイが完了したら、関数で必要な npm パッケージをインストールする必要があります。

  1. Azure portal で、サブスクリプションにデプロイされた関数アプリを開きます。 次に、[開発ツール][コンソール] の順に移動します。 コンソールで次のコマンドを実行して、パッケージをインストールします。

    cd IoTCIntegration
    npm install
    

    これらのコマンドの実行には数分かかることがあります。 警告メッセージはすべて無視してかまいません。

  2. パッケージのインストールが完了したら、関数アプリの [概要] ページで [再起動] を選択します。

    Azure Functionsの再起動オプションを示すスクリーンショット。

  3. これで、関数を使用する準備ができました。 外部システムでは、HTTP POST 要求を使用してデバイス データをデバイス ブリッジ経由で IoT Central アプリケーションに送信できます。 関数の URL を取得するには、[関数] [IoTCIntegration] > [コードとテスト] > [関数の URL の取得] に移動します。

    Azure Functionsの get 関数 URL を示すスクリーンショット。

デバイス ブリッジに送信されるメッセージ本文は、次の形式である必要があります。

"device": {
  "deviceId": "my-cloud-device"
},
"measurements": {
  "temp": 20.31,
  "pressure": 50,
  "humidity": 8.5,
  "ledColor": "blue"
}

measurements オブジェクトの各キーは、IoT Central アプリケーションのデバイス テンプレートに含まれるテレメトリの種類の名前と一致する必要があります。 このソリューションでは、メッセージ本文でのインターフェイス ID の指定はサポートされていません。 そのため、2 つの異なるインターフェイスに同じ名前のテレメトリの種類がある場合は、IoT Central アプリケーションの両方のテレメトリ ストリームに測定値が表示されます。

本文に timestamp フィールドを追加して、メッセージの日付と時刻 (UTC) を指定できます。 このフィールドは、ISO 8601 形式である必要があります。 たとえば、「 2020-06-08T20:16:54.602Z 」のように入力します。 タイムスタンプを含めない場合は、現在の日付と時刻が使用されます。

本文に modelId フィールドを追加できます。 プロビジョニング中にデバイスをデバイス テンプレートに割り当てるには、このフィールドを使います。

deviceId は、小文字の英数字でなければならず、ハイフンを含めることができます。

modelId フィールドを含めない場合、または IoT Central でモデル ID が認識されない場合は、認識されない deviceId を持つメッセージによって、IoT Central に新しい "未割り当てデバイス" が作成されます。 オペレーターは、デバイスを適切なデバイス テンプレートに手動で移行できます。 詳細については、Azure IoT Central アプリケーションでデバイスを管理する方法に関するページ デバイスのテンプレートへの移行に関するセクションを参照してください。

注意

デバイスがテンプレートに割り当てられるまで、関数のすべての HTTP 呼び出しから 403 エラー状態が返されます。

Application Insights で関数アプリのログ記録を切り替えるには、Azure portal の関数アプリで [監視] [ログ] に移動します。 [Application Insights を有効にする] を選択します。

プロビジョニングされたリソース

Resource Manager テンプレートでは、Azure サブスクリプションに次のリソースがプロビジョニングされます。

  • 関数アプリ
  • App Service プラン
  • ストレージ アカウント
  • Key Vault

キー コンテナーには、IoT Central アプリケーションの SAS グループ キーが格納されます。

関数アプリは、従量課金プランで実行されます。 このオプションでは、専用のコンピューティング リソースが提供されませんが、デバイス ブリッジで 1 分あたり数百個のデバイス メッセージを処理できます。これは、小規模なデバイス フリートやメッセージを送信する頻度が低いデバイスに適しています。 アプリケーションが多数のデバイス メッセージのストリーミングに依存している場合は、従量課金プランを専用の App Service プランに置き換えます。 このプランでは、専用のコンピューティング リソースが提供されるため、サーバーの応答時間が短縮されます。 Standard App Service プランを使用した場合、このリポジトリで観測された Azure からの関数の最大パフォーマンスは 1 分あたり 1500 個のデバイス メッセージでした。 詳細については、「Azure Functions のホスティング オプション」を参照してください。

従量課金プランではなく専用の App Service プランを使用するには、カスタム テンプレートをデプロイする前に編集します。 [テンプレートの編集] を選択します。

Azure Resource Manager テンプレートの [テンプレートの編集] オプションを示すスクリーンショット。

次のセグメントを置き換えます。

{
  "type": "Microsoft.Web/serverfarms",
  "apiVersion": "2015-04-01",
  "name": "[variables('planName')]",
  "location": "[resourceGroup().location]",
  "properties": {
    "name": "[variables('planName')]",
    "computeMode": "Dynamic",
    "sku": "Dynamic"
  }
},

代入

{
  "type": "Microsoft.Web/serverfarms",
  "sku": {
      "name": "S1",
      "tier": "Standard",
      "size": "S1",
      "family": "S",
      "capacity": 1
  },
  "kind": "app",
  "name": "[variables('planName')]",
  "apiVersion": "2016-09-01",
  "location": "[resourceGroup().location]",
  "tags": {
      "iotCentral": "device-bridge",
      "iotCentralDeviceBridge": "app-service-plan"
  },
  "properties": {
      "name": "[variables('planName')]"
  }
},

次に、テンプレートを編集して、"properties": {"SiteConfig": {...}} の下の functionapp リソースの構成に "alwaysOn": true を含めます。"alwaysOn": trueでは、関数アプリが常に実行されるようになります。

以下の例で、さまざまな IoT クラウドのためにデバイス ブリッジを構成する方法を説明します。

例 1: デバイス ブリッジを介して Particle デバイスを接続する

デバイス ブリッジを介して IoT Central に Particle デバイスを接続するには、Particle コンソールにアクセスし、新しい Webhook 統合を作成します。 [要求の形式][JSON] に設定します。 [詳細設定] で、次のカスタム本文形式を使用します。

{
  "device": {
    "deviceId": "{{{PARTICLE_DEVICE_ID}}}"
  },
  "measurements": {
    "{{{PARTICLE_EVENT_NAME}}}": "{{{PARTICLE_EVENT_VALUE}}}"
  }
}

関数アプリから関数の URL を貼り付けます。IoT Central では、Particle デバイスが未割り当てデバイスとして表示されます。 詳細については、Particle を利用したプロジェクトを Azure IoT Central に統合する方法に関するブログ記事をご覧ください。

例 2: デバイス ブリッジを介して Sigfox デバイスを接続する

一部のプラットフォームでは、Webhook 経由で送信されるデバイス メッセージの形式を指定できない場合があります。 このようなシステムでは、デバイス ブリッジでの処理の前に、メッセージのペイロードを期待される本文形式に変換する必要があります。 この変換は、デバイス ブリッジを実行する同じ関数で行うことができます。

このセクションでは、Sigfox Webhook 統合のペイロードをデバイス ブリッジで期待される本文形式に変換する方法について説明します。 Sigfox クラウドでは、デバイス データを 16 進数の文字列形式で送信します。 便宜上、デバイス ブリッジにはこの形式用の変換関数が含まれています。この関数では、Sigfox デバイスのペイロードで使用可能なフィールドの種類のサブセット (8、16、32、または 64 ビットの int および uint、32 または 64 ビットの float、リトルエンディアンとビッグエンディアン) を受け入れます。 Sigfox Webhook 統合からのメッセージを処理するには、関数アプリの IoTCIntegration/index.js ファイルを次のように変更します。

メッセージのペイロードを変換するため、21 行目の handleMessage の呼び出しの前に次のコードを追加して、payloadDefinition を Sigfox のペイロード定義に置き換えます。

const payloadDefinition = 'gforce::uint:8 lat::uint:8 lon::uint:16'; // Replace this with your payload definition

req.body = {
    device: {
        deviceId: req.body.device
    },
    measurements: require('./converters/sigfox')(payloadDefinition, req.body.data)
};

Sigfox デバイスでは、204 応答コードを期待しています。 21 行目の handleMessage の呼び出しの後に、次のコードを追加します。

context.res = {
    status: 204
};

例 3: デバイス ブリッジを介して The Things Network のデバイスを接続する

The Things Network デバイスを IoT Central に接続するには:

  • 新しい HTTP 統合を The Things Network のアプリケーションに追加します ([アプリケーション] [統合] > [統合の追加] > [HTTP 統合])。
  • デバイス メッセージのペイロードを関数に送信する前に JSON に自動的に変換するデコーダー関数がアプリケーションに含まれていることを確認します ([アプリケーション] [ペイロード関数] > [デコーダー])。

次のサンプルは、バイナリ データから一般的な数値型をデコードするために使用できる JavaScript デコーダー関数を示しています。

function Decoder(bytes, port) {
  function bytesToFloat(bytes, decimalPlaces) {
    var bits = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
    var sign = (bits >>> 31 === 0) ? 1.0 : -1.0;
    var e = bits >>> 23 & 0xff;
    var m = (e === 0) ? (bits & 0x7fffff) << 1 : (bits & 0x7fffff) | 0x800000;
    var f = Math.round((sign * m * Math.pow(2, e - 150)) * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces);
    return f;
  }

  function bytesToInt32(bytes, signed) {
    var bits = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
    var sign = 1;

    if (signed && bits >>> 31 === 1) {
      sign = -1;
      bits = bits & 0x7FFFFFFF;
    }

    return bits * sign;
  }

  function bytesToShort(bytes, signed) {
    var bits = bytes[0] | (bytes[1] << 8);
    var sign = 1;

    if (signed && bits >>> 15 === 1) {
      sign = -1;
      bits = bits & 0x7FFF;
    }

    return bits * sign;
  }

  return {
    temperature: bytesToFloat(bytes.slice(0, 4), 2),
    presscounter: bytesToInt32(bytes.slice(4, 8), true),
    blueLux: bytesToShort(bytes.slice(8, 10), false)
  };
}

統合を定義した後、関数アプリの "handleMessage" ファイルの 21 行目にある handleMessage の呼び出しの前に、次のコードを追加します。 このコードでは、HTTP 統合の本文を期待される形式に変換します。

req.body = {
  device: {
    deviceId: req.body.end_device_ids.device_id.toLowerCase()
  },
  measurements: req.body.uplink_message.decoded_payload
};

注意

前のスニペットでは、人間に優しいデバイス ID が使用されています。 Things Network メッセージには、req.body.dev_eui.toLowerCase() を使用してアクセスできる技術 ID も含まれています。 詳細については、ネットワーク データ形式 に関するページを参照してください。

制限事項

デバイス ブリッジでは、IoT Central にメッセージを転送するだけで、デバイスにメッセージを返信しません。 この制限は、このデバイス ブリッジを介して IoT Central に接続するデバイスではプロパティとコマンドが機能しない理由です。 デバイス ツイン操作はサポートされていないため、デバイス ブリッジを介してデバイスのプロパティを更新することはできません。 これらの機能を使用するには、デバイスでいずれかの Azure IoT device SDK を使用して IoT Central に直接接続する必要があります。

次のステップ

ここでは、IoT Central デバイス ブリッジをデプロイする方法について説明しました。推奨される次の手順は以下のとおりです。