Caricare file da un dispositivo nel cloud con hub IoT di Azure

Questo articolo illustra come:

  • Usare le funzionalità di caricamento di file di hub IoT per caricare un file in Archiviazione BLOB di Azure, usando un sdk per dispositivi e servizi IoT di Azure.
  • Notificare hub IoT che il file è stato caricato correttamente e creare un servizio back-end per ricevere notifiche di caricamento di file da hub IoT, usando gli SDK del servizio Azure IoT.

In alcuni scenari, non è possibile eseguire facilmente il mapping dei dati inviati dai dispositivi nei messaggi da dispositivo a cloud relativamente piccoli che hub IoT accetta. Le funzionalità di caricamento dei file in hub IoT consentono di spostare dati complessi o di grandi dimensioni nel cloud. Ad esempio:

  • Video
  • File di grandi dimensioni che contengono immagini
  • Dati di vibrazione campionati ad alta frequenza
  • Qualche tipo di dati pre-elaborati

Questi dati in genere vengono elaborati in batch nel cloud con strumenti come Azure Data Factory o lo stack Hadoop. Quando è necessario caricare i file da un dispositivo, è comunque possibile usare la sicurezza e affidabilità dell'hub IoT. Questo articolo illustra i passaggi da eseguire.

Il presente articolo è destinato a integrare gli esempi di SDK eseguibili a cui si fa riferimento al suo interno.

Per altre informazioni, vedi:

Importante

La funzionalità di caricamento dei file nei dispositivi che usano l'autenticazione dell'autorità di certificazione X.509 è in anteprima pubblica e modalità di anteprima deve essere abilitata. È disponibile a livello generale nei dispositivi che usano l'autenticazione con identificazione personale X.509 o l'attestazione del certificato X.509 con servizio Provisioning di dispositivi di Azure. Per altre informazioni sull'autenticazione X.509 con l'hub IoT, vedere Certificati X.509 supportati.

Prerequisiti

  • Un hub IoT. Alcune chiamate SDK richiedono il stringa di connessione primario hub IoT, quindi prendere nota del stringa di connessione.

  • Un dispositivo registrato. Alcune chiamate SDK richiedono il stringa di connessione primario del dispositivo, quindi prendere nota del stringa di connessione.

  • hub IoT'autorizzazione di Service Connect: per ricevere messaggi di notifica di caricamento file, il servizio back-end necessita dell'autorizzazione Service Connect. Per impostazione predefinita, ogni hub IoT viene creato con un servizio con nome di criteri di accesso condiviso che concede tale autorizzazione. Per altre informazioni, vedere Connettersi a un hub IoT.

  • Configurare il caricamento di file nell'hub IoT collegando un account Archiviazione di Azure e Archiviazione BLOB di Azure contenitore. È possibile configurare questi elementi usando il portale di Azure, l'interfaccia della riga di comando di Azure o Azure PowerShell.

Panoramica

Questa procedura contiene due sezioni:

  • Caricare un file da un'applicazione del dispositivo
  • Ricevere una notifica di caricamento di file in un'applicazione back-end

Caricare un file da un'applicazione del dispositivo

Questa sezione descrive come caricare un file da un dispositivo in un hub IoT usando la classe DeviceClient in Azure IoT SDK per .NET.

Seguire questa procedura per caricare un file da un dispositivo all'hub IoT:

  1. Connettersi all'hub IoT
  2. Ottenere un URI di firma di accesso condiviso dall'hub IoT
  3. Caricare il file in Archiviazione di Azure
  4. Notificare all'hub IoT lo stato di caricamento del file

Connettersi al dispositivo

Chiamare CreateFromConnectionString per connettersi al dispositivo. Passare il stringa di connessione primario del dispositivo.

AMQP è il protocollo di trasporto predefinito.

static string connectionString = "{device primary connection string}";
deviceClient = DeviceClient.CreateFromConnectionString(connectionString);

Ottenere un URI di firma di accesso condiviso dall'hub IoT

Chiama GetFileUploadSasUriAsync per ottenere i dettagli di caricamento dei file. L'URI di firma di accesso condiviso viene usato nel passaggio successivo per caricare un file da un dispositivo nell'archivio BLOB.

const string filePath = "TestPayload.txt";
using var fileStreamSource = new FileStream(filePath, FileMode.Open);
var fileName = Path.GetFileName(fileStreamSource.Name);
var fileUploadSasUriRequest = new FileUploadSasUriRequest
{
    BlobName = fileName
};

FileUploadSasUriResponse sasUri = await _deviceClient.GetFileUploadSasUriAsync(fileUploadSasUriRequest, System.Threading.CancellationToken cancellationToken = default);
Uri uploadUri = sasUri.GetBlobUri();

Caricare un file in Archiviazione di Azure

Per caricare un file in Archiviazione di Azure:

  1. Creare un oggetto blockBlobClient , passando un URI di caricamento di file.

  2. Usare il metodo UploadAsync per caricare un file nell'archivio BLOB, passando l'URI di firma di accesso condiviso. Facoltativamente, è possibile aggiungere opzioni di caricamento BLOB e parametri del token di annullamento.

Il client BLOB di Azure usa sempre HTTPS come protocollo per caricare il file in Archiviazione di Azure.

In questo esempio BlockBlobClient viene passato l'URI di firma di accesso condiviso per creare un client BLOB in blocchi Archiviazione di Azure e carica il file:

var blockBlobClient = new BlockBlobClient(uploadUri);
await blockBlobClient.UploadAsync(fileStreamSource, null, null);

Notificare all'hub IoT lo stato di caricamento del file

Usare CompleteFileUploadAsync per notificare all'hub IoT che il client del dispositivo ha completato il caricamento, passando un oggetto FileUploadCompletionNotification . Il IsSuccess flag indica se il caricamento è riuscito o meno. Dopo la notifica, l'hub IoT rilascia le risorse associate al caricamento (URI di firma di accesso condiviso).

Se le notifiche di caricamento dei file sono abilitate, l'hub IoT invia un messaggio di notifica di caricamento file ai servizi back-end configurati per la notifica di caricamento file.

var successfulFileUploadCompletionNotification = new FileUploadCompletionNotification
{
    // Mandatory. Must be the same value as the correlation id returned in the sas uri response
    CorrelationId = sasUri.CorrelationId,

    // Mandatory. Will be present when service client receives this file upload notification
    IsSuccess = true,

    // Optional, user defined status code. Will be present when service client receives this file upload notification
    StatusCode = 200,

    // Optional, user-defined status description. Will be present when service client receives this file upload notification
    StatusDescription = "Success"
};

await _deviceClient.CompleteFileUploadAsync(successfulFileUploadCompletionNotification);

Esempio di caricamento di file SDK

L'SDK include questo esempio di caricamento di file.

Ricevere una notifica di caricamento di file in un'applicazione back-end

È possibile creare un servizio back-end per ricevere messaggi di notifica di caricamento file dall'hub IoT.

La classe ServiceClient contiene metodi che i servizi possono usare per ricevere notifiche di caricamento file.

Per ricevere la notifica di caricamento file:

  1. Chiamare CreateFromConnectionString per connettersi all'hub IoT. Passare il stringa di connessione primario dell'hub IoT.
  2. Creare un cancellationToken.
  3. Chiamare GetFileNotificationReceiver per creare un ricevitore di notifica.
  4. Usare un ciclo con ReceiveAsync per attendere la notifica di caricamento del file.

Ad esempio:

using Microsoft.Azure.Devices;
static ServiceClient serviceClient;
static string connectionString = "{IoT hub connection string}";
serviceClient = ServiceClient.CreateFromConnectionString(connectionString);

// Define the cancellation token
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;

// Create a notification receiver
var notificationReceiver = serviceClient.GetFileNotificationReceiver();
Console.WriteLine("\nReceiving file upload notification from service");

// Check for file upload notifications
while (true)
{
    var fileUploadNotification = await notificationReceiver.ReceiveAsync(token);
    if (fileUploadNotification == null) continue;
    Console.ForegroundColor = ConsoleColor.Yellow;
    Console.WriteLine("Received file upload notification: {0}", 
        string.Join(", ", fileUploadNotification.BlobName));
    Console.ResetColor();
    await notificationReceiver.CompleteAsync(fileUploadNotification);
}

Panoramica

Questa procedura contiene due sezioni:

  • Caricare un file da un'applicazione del dispositivo
  • Ricevere una notifica di caricamento di file in un'applicazione back-end

Caricare un file da un'applicazione del dispositivo

Questa sezione descrive come caricare un file da un dispositivo in un hub IoT usando la classe DeviceClient di Azure IoT SDK per Java.

Seguire questa procedura per caricare un file da un dispositivo all'hub IoT:

  1. Connettersi al dispositivo
  2. Ottenere un URI di firma di accesso condiviso dall'hub IoT
  3. Caricare il file in Archiviazione di Azure
  4. Inviare una notifica sullo stato di caricamento dei file all'hub IoT

Protocollo di connessione

Le operazioni di caricamento dei file usano sempre HTTPS, ma DeviceClient può definire IotHubClientProtocol per altri servizi, ad esempio telemetria, metodo del dispositivo e dispositivo gemello.

IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;

Connettersi al dispositivo

Creare un'istanza di DeviceClient per connettersi al dispositivo usando il stringa di connessione primario del dispositivo.

String connString = "{IoT hub connection string}";
DeviceClient client = new DeviceClient(connString, protocol);

Ottenere un URI di firma di accesso condiviso dall'hub IoT

Chiamare getFileUploadSasUri per ottenere un oggetto FileUploadSasUriResponse .

FileUploadSasUriResponse include questi metodi e valori restituiti. I valori restituiti possono essere passati ai metodi di caricamento dei file.

metodo Valore restituito
getCorrelationId() ID correlazione
getContainerName() Nome contenitore
getBlobName() Nome BLOB
getBlobUri() URI BLOB

Ad esempio:

FileUploadSasUriResponse sasUriResponse = client.getFileUploadSasUri(new FileUploadSasUriRequest(file.getName()));

System.out.println("Successfully got SAS URI from IoT hub");
System.out.println("Correlation Id: " + sasUriResponse.getCorrelationId());
System.out.println("Container name: " + sasUriResponse.getContainerName());
System.out.println("Blob name: " + sasUriResponse.getBlobName());
System.out.println("Blob Uri: " + sasUriResponse.getBlobUri());

Caricare il file in Archiviazione di Azure

Passare l'endpoint URI BLOB a BlobClientBuilder.buildclient per creare l'oggetto BlobClient .

BlobClient blobClient =
    new BlobClientBuilder()
        .endpoint(sasUriResponse.getBlobUri().toString())
        .buildClient();

Chiamare uploadFromFile per caricare il file nell'archivio BLOB.

String fullFileName = "Path of the file to upload";
blobClient.uploadFromFile(fullFileName);

Inviare una notifica sullo stato di caricamento dei file all'hub IoT

Inviare una notifica di stato di caricamento all'hub IoT dopo un tentativo di caricamento di file.

Creare un oggetto FileUploadCompletionNotification . Passare lo stato di esito positivo del caricamento del correlationId file e isSuccess . Passare un isSuccess true valore quando il caricamento del file ha avuto esito positivo, false quando non lo è.

FileUploadCompletionNotification deve essere chiamato anche quando il caricamento del file non riesce. L'hub IoT ha un numero fisso di URI di firma di accesso condiviso che può essere attivo in qualsiasi momento. Dopo aver completato il caricamento del file, è necessario liberare l'URI di firma di accesso condiviso in modo che possa essere generato un altro URI di firma di accesso condiviso. Se un URI di firma di accesso condiviso non viene liberato tramite questa API, alla fine viene liberato in base alla durata della configurazione degli URI di firma di accesso condiviso in un hub IoT.

In questo esempio viene passato uno stato di esito positivo.

FileUploadCompletionNotification completionNotification = new FileUploadCompletionNotification(sasUriResponse.getCorrelationId(), true);
client.completeFileUpload(completionNotification);

Chiudere il client

Liberare le client risorse.

client.closeNow();

Ricevere una notifica di caricamento di file in un'applicazione back-end

È possibile creare un'applicazione back-end per ricevere notifiche di caricamento file.

Per creare un'applicazione di notifica di caricamento file:

  1. Connettersi al client del servizio hub IoT
  2. Verificare la presenza di una notifica di caricamento di file

La classe ServiceClient contiene metodi che i servizi possono usare per ricevere notifiche di caricamento file.

Connettersi al client del servizio hub IoT

Creare un oggetto IotHubServiceClientProtocol. La connessione usa il AMQPS protocollo .

Chiamare createFromConnectionString per connettersi all'hub IoT. Passare il stringa di connessione primario dell'hub IoT.

private static final String connectionString = "{IoT hub primary connection string}";
private static final IotHubServiceClientProtocol protocol = IotHubServiceClientProtocol.AMQPS;
ServiceClient sc = ServiceClient.createFromConnectionString(connectionString, protocol);

Verificare lo stato di caricamento dei file

Per verificare lo stato di caricamento dei file:

  1. Creare un oggetto getFileUploadNotificationReceiver .
  2. Usare open per connettersi all'hub IoT.
  3. Chiamare la ricezione per verificare lo stato di caricamento del file. Questo metodo restituisce un oggetto fileUploadNotification . Se viene ricevuto un avviso di caricamento, è possibile visualizzare i campi di stato di caricamento usando i metodi fileUploadNotification .

Ad esempio:

FileUploadNotificationReceiver receiver = sc.getFileUploadNotificationReceiver();
receiver.open();
FileUploadNotification fileUploadNotification = receiver.receive(2000);

if (fileUploadNotification != null)
{
    System.out.println("File Upload notification received");
    System.out.println("Device Id : " + fileUploadNotification.getDeviceId());
    System.out.println("Blob Uri: " + fileUploadNotification.getBlobUri());
    System.out.println("Blob Name: " + fileUploadNotification.getBlobName());
    System.out.println("Last Updated : " + fileUploadNotification.getLastUpdatedTimeDate());
    System.out.println("Blob Size (Bytes): " + fileUploadNotification.getBlobSizeInBytes());
    System.out.println("Enqueued Time: " + fileUploadNotification.getEnqueuedTimeUtcDate());
}
else
{
    System.out.println("No file upload notification");
}

// Close the receiver object
receiver.close();

Esempi di caricamento di file SDK

Sono disponibili due esempi di caricamento di file Java.

Installare i pacchetti

Prima di chiamare qualsiasi codice correlato, è necessario installare la libreria azure-iot-device.

pip install azure-iot-device

Il pacchetto azure.storage.blob viene usato per eseguire il caricamento del file.

pip install azure.storage.blob

Caricare un file da un'applicazione del dispositivo

Questa sezione descrive come caricare un file da un dispositivo a un hub IoT usando la classe IoTHubDeviceClient di Azure IoT SDK per Python.

Seguire questa procedura per caricare un file da un dispositivo all'hub IoT:

  1. Connettersi al dispositivo
  2. Ottenere informazioni sull'archiviazione BLOB
  3. Caricare il file nell'archiviazione BLOB
  4. Notifica allo stato di caricamento dell'hub IoT

Importare le librerie

import os
from azure.iot.device import IoTHubDeviceClient
from azure.core.exceptions import AzureError
from azure.storage.blob import BlobClient

Connettersi al dispositivo

Per connettersi al dispositivo:

  1. Chiamare create_from_connection_string per aggiungere il stringa di connessione primario del dispositivo.

  2. Chiamare connect per connettere il client del dispositivo.

Ad esempio:

# Add your IoT hub primary connection string
CONNECTION_STRING = "{Device primary connection string}"
device_client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)

# Connect the client
device_client.connect()

Ottenere informazioni sull'archiviazione BLOB

Chiamare get_storage_info_for_blob per ottenere informazioni da un hub IoT su un account Archiviazione di Azure collegato. Queste informazioni includono il nome host, il nome del contenitore, il nome del BLOB e un token di firma di accesso condiviso. Il get_storage_info_for_blob metodo restituisce anche un correlation_idoggetto , utilizzato nel notify_blob_upload_status metodo . correlation_id è hub IoT modo di contrassegnare il BLOB su cui si sta lavorando.

# Get the storage info for the blob
PATH_TO_FILE = "{Full path to local file}"
blob_name = os.path.basename(PATH_TO_FILE)
blob_info = device_client.get_storage_info_for_blob(blob_name)

Caricare un file nell'archiviazione BLOB

Per caricare un file nell'archivio BLOB:

  1. Usare from_blob_url per creare un oggetto BlobClient da un URL del BLOB.
  2. Chiamare upload_blob per caricare il file nell'archivio BLOB.

In questo esempio viene analizzata la blob_info struttura per creare un URL usato per inizializzare un BLOBClient. Chiama quindi upload_blob per caricare il file nell'archiviazione BLOB.

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)

Notifica allo stato di caricamento dell'hub IoT

Usare notify_blob_upload_status per notificare all'hub IoT lo stato dell'operazione di archiviazione BLOB. Passare l'oggetto correlation_id ottenuto dal get_storage_info_for_blob metodo . Viene correlation_id usato dall'hub IoT per notificare a qualsiasi servizio che potrebbe essere in ascolto di una notifica relativa allo stato dell'attività di caricamento file.

Questo esempio notifica all'hub IoT di un caricamento di file riuscito:

device_client.notify_blob_upload_status(storage_info["correlationId"], True, 200, "OK: {}".format(PATH_TO_FILE)

Arrestare il client del dispositivo

Arrestare il client. Una volta chiamato questo metodo, qualsiasi tentativo di chiamate client comporta la generazione di un clientError .

device_client.shutdown()

Esempi di caricamento di file SDK

L'SDK include due esempi di caricamento di file:

Panoramica

Questa procedura contiene due sezioni:

  • Caricare un file da un'applicazione del dispositivo
  • Ricevere una notifica di caricamento di file in un'applicazione back-end

Caricare un file da un'applicazione del dispositivo

Questa sezione descrive come caricare un file da un dispositivo in un hub IoT usando il pacchetto azure-iot-device in Azure IoT SDK per Node.js.

Installare pacchetti SDK

Eseguire questo comando per installare azure-iot-device device SDK, azure-iot-device-mqtt e i pacchetti @azure/storage-blob nel computer di sviluppo:

npm install azure-iot-device azure-iot-device-mqtt @azure/storage-blob --save

Il pacchetto azure-iot-device contiene oggetti che si interfacciano con i dispositivi IoT.

Seguire questa procedura per caricare un file da un dispositivo all'hub IoT:

  1. Ottenere firme di accesso condiviso BLOB
  2. Caricare il file in Archiviazione di Azure
  3. Inviare una notifica sullo stato di caricamento dei file all'hub IoT

Creare moduli

Creare moduli client, protocollo, errori e percorso usando i pacchetti installati.

const Client = require('azure-iot-device').Client;
const Protocol = require('azure-iot-device-mqtt').Mqtt;
const errors = require('azure-iot-common').errors;
const path = require('path');

Ottenere un URI di firma di accesso condiviso dall'hub IoT

Usare getBlobSharedAccessSignature per ottenere il token di firma di accesso condiviso dell'account di archiviazione collegato dall'hub IoT. Come descritto nei prerequisiti, l'hub IoT è collegato all'archiviazione BLOB.

Ad esempio:

// make sure you set these environment variables prior to running the sample.
const localFilePath = process.env.PATH_TO_FILE;
const storageBlobName = path.basename(localFilePath);
const blobInfo = await client.getBlobSharedAccessSignature(storageBlobName);
if (!blobInfo) {
throw new errors.ArgumentError('Invalid upload parameters');
}

Caricare il file nell'hub IoT

Per caricare un file da un dispositivo all'hub IoT:

  1. Creare una pipeline di flusso
  2. Costruire l'URL del BLOB
  3. Creare un blockBlobClient per il caricamento di file nell'archiviazione BLOB
  4. Chiamare uploadFile per caricare il file nell'archivio BLOB
  5. Chiamare notifyBlobUploadStatus per notificare all'hub IoT che il caricamento ha avuto esito positivo o negativo

Ad esempio:

// Open the pipeline
const pipeline = newPipeline(new AnonymousCredential(), {
retryOptions: { maxTries: 4 },
telemetry: { value: 'HighLevelSample V1.0.0' }, // Customized telemetry string
keepAliveOptions: { enable: false }
});

// Construct the blob URL
const { hostName, containerName, blobName, sasToken } = blobInfo;
const blobUrl = `https://${hostName}/${containerName}/${blobName}${sasToken}`;

// Create the BlockBlobClient for file upload to Blob Storage
const blobClient = new BlockBlobClient(blobUrl, pipeline);

// Setup blank status notification arguments to be filled in on success/failure
let isSuccess;
let statusCode;
let statusDescription;

const uploadStatus = await blobClient.uploadFile(localFilePath);
console.log('uploadStreamToBlockBlob success');

  try {
    const uploadStatus = await blobClient.uploadFile(localFilePath);
    console.log('uploadStreamToBlockBlob success');

    // Save successful status notification arguments
    isSuccess = true;
    statusCode = uploadStatus._response.status;
    statusDescription = uploadStatus._response.bodyAsText;

    // Notify IoT hub of upload to blob status (success)
    console.log('notifyBlobUploadStatus success');
  }
  catch (err) {
    isSuccess = false;
    statusCode = err.code;
    statusDescription = err.message;

    console.log('notifyBlobUploadStatus failed');
    console.log(err);
  }

// Send file upload status notification to IoT hub
await client.notifyBlobUploadStatus(blobInfo.correlationId, isSuccess, statusCode, statusDescription);

Ricevere una notifica di caricamento di file in un'applicazione back-end

È possibile creare un'applicazione back-end per controllare il client del servizio hub IoT per le notifiche di caricamento dei file del dispositivo.

Per creare un'applicazione di notifica di caricamento file:

  1. Connettersi al client del servizio hub IoT
  2. Verificare la presenza di una notifica di caricamento di file

Connettersi al client del servizio hub IoT

La classe ServiceClient contiene metodi che i servizi possono usare per ricevere notifiche di caricamento file.

Connettersi all'hub IoT usando fromConnectionString. Passare il stringa di connessione primario dell'hub IoT.

const Client = require('azure-iothub').Client;
const connectionString = "{IoT hub primary connection string}";
const serviceClient = Client.fromConnectionString(connectionString);

Aprire la connessione all'hub IoT.

//Open the connection to IoT hub
serviceClient.open(function (err) {
  if (err) {
    console.error('Could not connect: ' + err.message);
  } else {
    console.log('Service client connected');

Verificare la presenza di una notifica di caricamento di file

Per verificare la presenza di notifiche di caricamento file:

  1. Chiamare getFileNotificationReceiver. Specificare il nome di un metodo di callback di caricamento file chiamato quando vengono ricevuti i messaggi di notifica.
  2. Elaborare le notifiche di caricamento dei file nel metodo di callback.

In questo esempio viene configurato un receiveFileUploadNotification ricevitore di callback di notifica. Il ricevitore interpreta le informazioni sullo stato di caricamento del file e stampa un messaggio di stato nella console.

//Set up the receiveFileUploadNotification notification message callback receiver
serviceClient.getFileNotificationReceiver(function receiveFileUploadNotification(err, receiver){
if (err) {
  console.error('error getting the file notification receiver: ' + err.toString());
} else {
  receiver.on('message', function (msg) {
    console.log('File upload from device:')
    console.log(msg.getData().toString('utf-8'));
    receiver.complete(msg, function (err) {
      if (err) {
        console.error('Could not finish the upload: ' + err.message);
      } else {
        console.log('Upload complete');
      }
    });
  });
}

Esempio di caricamento di file SDK

L'SDK include un esempio avanzato di caricamento nel BLOB.