Azure IoT Hub を使用してデバイスからクラウドにファイルをアップロードする (Python)

この記事では、Python を使って、IoT Hub のファイル アップロード機能でファイルを Azure BLOB ストレージにアップロードする方法を説明します。

デバイスから IoT ハブへのテレメトリの送信のクイックスタートと IoT Hub を使用したクラウドからデバイスへのメッセージの送信に関するアーティクルには、IoT Hub のデバイスからクラウドへのメッセージングとクラウドからデバイスへのメッセージングの基本的な機能が示されています。 「IoT Hub を使用してメッセージ ルーティングを構成する」チュートリアルでは、device-to-cloud メッセージを Microsoft Azure BLOB ストレージに確実に格納する方法を示します。 ただし、一部のシナリオでは、デバイスが送信するデータを、IoT Hub が受け入れる比較的小さな device-to-cloud メッセージに簡単にはマップできません。 次に例を示します。

  • ビデオ
  • イメージを含む大きなファイル
  • 高頻度でサンプリングされる振動データ
  • 何らかの形式の前処理済みデータ。

これらのファイルは通常、Azure Data FactoryHadoop スタックなどのツールを使ってクラウドでバッチ処理されます。 デバイスからファイルをアップロードする必要がある場合も、IoT Hub のセキュリティと信頼性を利用できます。 この記事では、その方法について説明します。

この記事の最後に、Python デバイス SDK を使ってストレージにファイルをアップロードする Python コンソールアプリ FileUpload.py を実行します。

注意

IoT Hub は、Azure IoT device SDK を介して、多数のデバイス プラットフォームと言語 (C、Java、Python、JavaScript を含む) をサポートしています。 デバイスを Azure IoT Hub に接続する方法については、Azure IoT デベロッパー センターを参照してください。

重要

X.509 証明機関 (CA) 認証を使用するデバイスのファイル アップロード機能はパブリック プレビュー段階であり、プレビュー モードを有効にする必要があります。 これは、Azure デバイス プロビジョニング サービスで x.509 拇印認証または x.509 証明書の構成証明を使用するデバイスで一般提供されています。 IoT Hub での X.509 認証の詳細については、「サポートされている X.509 証明書」を参照してください。

前提条件

  • アクティブな Azure アカウントアカウントがない場合、Azure 試用版にサインアップして、最大 10 件の無料 Mobile Apps を入手できます。 (アカウントがない場合は、無料アカウント を数分で作成できます)。

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

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

  • Python バージョン 3.7 以降をお勧めします。 必ず、セットアップに必要な 32 ビットまたは 64 ビットのインストールを使用してください。 インストール中に求められた場合は、プラットフォーム固有の環境変数に Python を追加します。

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

IoT Hub への Azure Storage アカウントの関連付け

デバイスからファイルをアップロードするには、IoT ハブに関連付けられている Azure Storage アカウントと Azure Blob Storage コンテナーが必要です。 ストレージ アカウントとコンテナーを IoT ハブに関連付けると、デバイスから要求されたときに、その IoT ハブで SAS URI の要素を提供できます。 デバイスではその後、これらの要素を使用して SAS URI を構築でき、この URI を使用して Azure Storage との間で認証を行い、BLOB コンテナーにファイルをアップロードします。

Azure Storage アカウントを IoT ハブに関連付けるには:

  1. IoT ハブの左側のペインにある [Hub settings](ハブの設定) で、 [ファイルのアップロード] を選びます。

    ポータルから [ファイルのアップロード] 設定の選択を示すスクリーン キャプチャ。

  2. [ファイルのアップロード] ペインで、 [Azure Storage コンテナー] を選択します。 この記事の場合は、ストレージ アカウントと IoT Hub を同じリージョンに配置することをお勧めします。

    • 使おうとしているストレージ アカウントが既にある場合は、一覧からそれを選択します。

    • 新しいストレージ アカウントを作成するには、 [+ストレージ アカウント] を選択します。 ストレージ アカウントの名前を指定し、 [場所] が、お使いの IoT ハブと同じリージョンに設定されていることを確認し、 [OK] を選択します。 IoT ハブと同じリソース グループに新しいアカウントが作成されます。 デプロイが完了したら、一覧からそのストレージ アカウントを選択します。

    ストレージ アカウントを選択すると、 [コンテナー] ペインが開きます。

  3. [コンテナー] ペインで、BLOB コンテナーを選択します。

    • 使おうとしている BLOB コンテナーが既にある場合は、一覧からそれを選択し、 [選択] をクリックします。

    • 新しい BLOB コンテナーを作成するには、 [+ コンテナー] を選択します。 新しいコンテナーの名前を指定します。 この記事の目的上、他のフィールドはすべて既定のままにすることができます。 [作成] を選択します デプロイが完了したら、一覧からコンテナーを選択し、 [選択] をクリックします。

  4. [ファイルのアップロード] ペインに戻り、ファイル通知が [オン] に設定されていることを確認します。 他の設定はすべて既定値のままにすることができます。 [保存] を選択し、設定が完了するのを待ってから次のセクションに進みます。

    ポータルの [ファイルのアップロード] 設定の確認を示すスクリーン キャプチャ。

Azure Storage アカウントを作成する方法の詳細な手順については、「ストレージ アカウントを作成する」を参照してください。 ストレージ アカウントと BLOB コンテナーを IoT ハブに関連付ける方法の詳細な手順については、Azure portal を使用してファイルのアップロードを構成することに関するページを参照してください。

デバイス アプリからのファイルのアップロード

このセクションでは、IoT Hub にファイルをアップロードするデバイス アプリを作成します。

  1. コマンド プロンプトで次のコマンドを実行して azure-iot-device パッケージをインストールします。 このパッケージを使用して、IoT ハブでファイルのアップロードを調整します。

    pip install azure-iot-device
    
  2. コマンド プロンプトで次のコマンドを実行して azure.storage.blob パッケージをインストールします。 このパッケージを使用して、ファイルのアップロードを実行します。

    pip install azure.storage.blob
    
  3. BLOB ストレージにアップロードするテスト ファイルを作成します。

  4. テキスト エディターを使用して、作業フォルダーに FileUpload.py ファイルを作成します。

  5. FileUpload.py ファイルの先頭に次の import ステートメントと変数を追加します。

    import os
    from azure.iot.device import IoTHubDeviceClient
    from azure.core.exceptions import AzureError
    from azure.storage.blob import BlobClient
    
    CONNECTION_STRING = "[Device Connection String]"
    PATH_TO_FILE = r"[Full path to local file]"
    
  6. ファイル内で、[Device Connection String] を IoT Hub デバイスの接続文字列に置き換えます。 [Full path to local file] を、作成したテスト ファイル、またはアップロードするデバイス上の任意のファイルのパスに置き換えます。

  7. ファイルを BLOB ストレージにアップロードする関数を作成します。

    def store_blob(blob_info, file_name):
        try:
            sas_url = "https://{}/{}/{}{}".format(
                blob_info["hostName"],
                blob_info["containerName"],
                blob_info["blobName"],
                blob_info["sasToken"]
            )
    
            print("\nUploading file: {} to Azure Storage as blob: {} in container {}\n".format(file_name, blob_info["blobName"], blob_info["containerName"]))
    
            # Upload the specified file
            with BlobClient.from_blob_url(sas_url) as blob_client:
                with open(file_name, "rb") as f:
                    result = blob_client.upload_blob(f, overwrite=True)
                    return (True, result)
    
        except FileNotFoundError as ex:
            # catch file not found and add an HTTP status code to return in notification to IoT Hub
            ex.status_code = 404
            return (False, ex)
    
        except AzureError as ex:
            # catch Azure errors that might result from the upload operation
            return (False, ex)
    

    この関数は、渡されたblob_info 構造体を解析して、azure.storage.blob.BlobClient を初期化するために使用する URL を作成します。 次に、このクライアントを使用して、ファイルが Azure Blob Storage にアップロードされます。

  8. 次のコードを追加して、クライアントを接続し、ファイルをアップロードします。

    def run_sample(device_client):
        # Connect the client
        device_client.connect()
    
        # Get the storage info for the blob
        blob_name = os.path.basename(PATH_TO_FILE)
        storage_info = device_client.get_storage_info_for_blob(blob_name)
    
        # Upload to blob
        success, result = store_blob(storage_info, PATH_TO_FILE)
    
        if success == True:
            print("Upload succeeded. Result is: \n") 
            print(result)
            print()
    
            device_client.notify_blob_upload_status(
                storage_info["correlationId"], True, 200, "OK: {}".format(PATH_TO_FILE)
            )
    
        else :
            # If the upload was not successful, the result is the exception object
            print("Upload failed. Exception is: \n") 
            print(result)
            print()
    
            device_client.notify_blob_upload_status(
                storage_info["correlationId"], False, result.status_code, str(result)
            )
    
    def main():
        device_client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)
    
        try:
            print ("IoT Hub file upload sample, press Ctrl-C to exit")
            run_sample(device_client)
        except KeyboardInterrupt:
            print ("IoTHubDeviceClient sample stopped")
        finally:
            # Graceful exit
            device_client.shutdown()
    
    
    if __name__ == "__main__":
        main()
    

    このコードでは IoTHubDeviceClient が作成され、次の API を使用して IoT ハブでファイルのアップロードを管理します。

    • get_storage_info_for_blob は、前に作成したリンクされたストレージ アカウントに関する情報を IoT ハブから取得します。 この情報には、ホスト名、コンテナー名、BLOB 名、および SAS トークンが含まれます。 ストレージ情報は store_blob 関数 (前の手順で作成) に渡されるため、その関数の BlobClient は Azure ストレージで認証できます。 get_storage_info_for_blob メソッドでは、notify_blob_upload_status メソッドで使用される correlation_id も返されます。 correlation_id は、IoT Hub で作業している BLOB をマークする方法です。

    • notify_blob_upload_status により、BLOB ストレージ操作の状態が IoT Hub に通知されます。 get_storage_info_for_blob メソッドによって取得された correlation_id を渡します。 これは、ファイルのアップロード タスクの状態に関する通知をリッスンしている可能性があるサービスに通知するために IoT Hub によって使用されます。

  9. FileUpload.py ファイルを保存して閉じます。

アプリケーションの実行

これで、アプリケーションを実行する準備が整いました。

  1. 作業フォルダーのコマンド プロンプトで、次のコマンドを実行します。

    python FileUpload.py
    
  2. 次のスクリーン ショットは、FileUpload アプリからの出力を示しています。

    FileUpload アプリを実行したときの出力を示すスクリーンショット。

  3. ポータルを使用して、構成したストレージ コンテナーにアップロードされたファイルを表示できます。

    アップロードされたファイルが表示されている Azure portal のコンテナーのスクリーンショット。

次の手順

この記事では、IoT Hub のファイル アップロード機能を使用して、デバイスからのファイルのアップロードを簡素化する方法を学習しました。 この機能をさらに詳しく知るには、以下の記事を参考にしてください。

Azure Blob Storage の詳細については、次のリンク先を参照してください。