Carga de archivos desde un dispositivo a la nube con Azure IoT Hub (Node.js)

Este artículo demuestra cómo las capacidades de carga de archivos de IoT Hub cargan un archivo a Azure blob storage, mediante Node.js.

En el inicio rápido Envío de telemetría de un dispositivo a IoT hub y los artículos de Envío de mensajes de la nube al dispositivo con IoT Hub se muestra cómo usar la funcionalidad básica de mensajería del dispositivo a la nube y de la nube al dispositivo de IoT Hub. En el tutorial Configuración del enrutamiento de mensajes con IoT Hub se muestra una forma de almacenar de manera confiable los mensajes del dispositivo a la nube en Microsoft Azure Blob Storage. Sin embargo, en algunos escenarios, no se pueden asignar fácilmente los datos que los dispositivos envían en los mensajes del dispositivo a la nube de un tamaño relativamente reducido que acepta IoT Hub. Por ejemplo:

  • Vídeos
  • Archivos grandes con imágenes
  • Datos de vibración muestreados con alta frecuencia
  • Alguna forma de datos procesados previamente.

Dichos archivos se suelen procesar por lotes en la nube mediante herramientas como Azure Data Factory o la pila Hadoop. Cuando necesite cargar archivos desde un dispositivo, todavía puede usar la seguridad y confiabilidad de IoT Hub. Este artículo le muestra cómo.

Al final de este artículo, ejecutará dos aplicaciones de consola de Node.js:

  • FileUpload.js, que carga un archivo en el almacenamiento mediante un URI de SAS proporcionado por un centro de IoT.

  • FileUploadNotification.js, que recibe notificaciones de carga de archivos del centro de IoT.

Nota

IoT Hub admite muchas plataformas de dispositivos y lenguajes (entre los que se incluyen C, Java, Python y JavaScript), mediante los SDK de dispositivo IoT de Azure. Consulte el Centro de desarrollo de Azure IoT para saber cómo conectar su dispositivo a Azure IoT Hub.

Importante

La funcionalidad de carga de archivos de los dispositivos que usan la autenticación de la entidad de certificación X.509 está disponible como versión preliminar pública, y se debe habilitar el modo de vista previa. Está disponible con carácter general en dispositivos que usan la autenticación de huella digital X.509 o la atestación de certificado X.509 con el servicio de aprovisionamiento de dispositivos de Azure. Para obtener más información acerca de la autenticación X.509 con IoT Hub, consulte Certificados X.509 compatibles.

Requisitos previos

  • Una instancia de IoT Hub. Cree uno con la CLI o el Azure Portal.

  • Dispositivo registrado. Registre uno en el Azure Portal.

  • Node.js versión 10.0.x o posteriores. Se recomienda la versión LTS. Puede descargar Node.js de nodejs.org.

  • El puerto 8883 debería estar abierto en su firewall. En el ejemplo de dispositivo de este artículo se usa el protocolo MQTT, que se comunica mediante el puerto 8883. Este puerto puede estar bloqueado en algunos entornos de red corporativos y educativos. Para más información y para saber cómo solucionar este problema, consulte el artículo sobre la conexión a IoT Hub (MQTT).

Asociación de una cuenta de Azure Storage a IoT Hub

Para cargar archivos desde un dispositivo, debe tener una cuenta de Azure Storage y un contenedor de Azure Blob Storage asociado al centro de IoT. Una vez que asocie la cuenta de almacenamiento y el contenedor con el centro de IoT, este puede proporcionar los elementos de un URI de SAS cuando lo solicite un dispositivo. A continuación, el dispositivo puede usar estos elementos para construir el URI de SAS que usa para autenticarse con Azure Storage y cargar archivos en el contenedor de blobs.

Para asociar una cuenta de Azure Storage con el centro de IoT:

  1. En Configuración del centro, seleccione Carga de archivos en el panel izquierdo del centro de IoT.

    Captura de pantalla que muestra la configuración de carga de archivos seleccionada en el portal.

  2. En el panel Carga de archivos, seleccione Contenedor de Azure Storage. En este artículo, se recomienda que la cuenta de almacenamiento e IoT Hub se encuentren en la misma región.

    • Si ya tiene una cuenta de almacenamiento que desea usar, selecciónela de la lista.

    • Para crear una nueva cuenta de almacenamiento, seleccione + Cuenta de almacenamiento. Proporcione un nombre a la cuenta de almacenamiento y asegúrese de que Ubicación esté establecida en la misma región que el centro de IoT y, a continuación, seleccione Aceptar. La nueva cuenta se crea en el mismo grupo de recursos que el centro de IoT. Cuando se complete la implementación, seleccione la cuenta de almacenamiento de la lista.

    Después de seleccionar la cuenta de almacenamiento, se abre el panel Contenedores.

  3. En el panel Contenedores, seleccione el contenedor de blobs.

    • Si ya tiene un contenedor de blobs que desea usar, selecciónelo en la lista y haga clic en Seleccionar.

    • Para crear un contenedor de blobs, seleccione + Contenedor. Proporcione un nombre para el nuevo contenedor. Para los fines de este artículo, puede dejar todos los demás campos en su valor predeterminado. Seleccione Crear. Cuando finalice la implementación, seleccione el contenedor de la lista y haga clic en Seleccionar.

  4. De nuevo en el panel Carga de archivos, asegúrese de que las notificaciones de archivos estén establecidas en Activadas. Puede dejar el resto de la configuración en sus valores predeterminados. Seleccione Guardar y espere a que se complete la configuración antes de pasar a la siguiente sección.

    Captura de pantalla que muestra la configuración de confirmación de carga de archivos en el portal.

Para obtener instrucciones detalladas sobre cómo crear una cuenta de Azure Storage, consulte Crear una cuenta de almacenamiento. Para obtener instrucciones detalladas sobre cómo asociar una cuenta de almacenamiento y un contenedor de blobs a un centro de IoT, consulte Configuración de cargas de archivos mediante Azure Portal.

Carga de un archivo desde una aplicación de dispositivo

En esta sección, creará una aplicación para dispositivos para cargar un archivo en un centro de IoT. El código se basa en el código disponible en el ejemplo upload_to_blob_advanced.js en los ejemplos de dispositivos del SDK de Azure IoT Node.js.

  1. Cree una carpeta vacía denominada fileupload. En la carpeta fileupload, cree un archivo package.json con el siguiente comando en el símbolo del sistema. Acepte todos los valores predeterminados:

    npm init
    
  2. En el símbolo del sistema, en la carpeta fileupload, ejecute el siguiente comando para instalar el SDK de dispositivo azure-iot-device y los paquetes azure-iot-device-mqtt y @azure/storage-blob:

    npm install azure-iot-device azure-iot-device-mqtt @azure/storage-blob --save
    
  3. Con un editor de texto, cree un archivo FileUpload.js en la carpeta fileupload y copie en ella el código siguiente.

    'use strict';
    
    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');
    
    const {
      AnonymousCredential,
      BlockBlobClient,
      newPipeline
    } = require('@azure/storage-blob');
    
    // make sure you set these environment variables prior to running the sample.
    const deviceConnectionString = process.env.DEVICE_CONNECTION_STRING;
    const localFilePath = process.env.PATH_TO_FILE;
    const storageBlobName = path.basename(localFilePath);
    
    async function uploadToBlob(localFilePath, client) {
      const blobInfo = await client.getBlobSharedAccessSignature(storageBlobName);
      if (!blobInfo) {
        throw new errors.ArgumentError('Invalid upload parameters');
      }
    
      const pipeline = newPipeline(new AnonymousCredential(), {
        retryOptions: { maxTries: 4 },
        telemetry: { value: 'HighLevelSample V1.0.0' }, // Customized telemetry string
        keepAliveOptions: { enable: false }
      });
    
      // Construct the blob URL to construct the blob client for file uploads
      const { hostName, containerName, blobName, sasToken } = blobInfo;
      const blobUrl = `https://${hostName}/${containerName}/${blobName}${sasToken}`;
    
      // Create the BlockBlobClient for file upload to the Blob Storage Blob
      const blobClient = new BlockBlobClient(blobUrl, pipeline);
    
      // Setup blank status notification arguments to be filled in on success/failure
      let isSuccess;
      let statusCode;
      let statusDescription;
    
      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);
      }
    
      await client.notifyBlobUploadStatus(blobInfo.correlationId, isSuccess, statusCode, statusDescription);
    }
    
    // Create a client device from the connection string and upload the local file to blob storage.
    const deviceClient = Client.fromConnectionString(deviceConnectionString, Protocol);
    uploadToBlob(localFilePath, deviceClient)
      .catch((err) => {
        console.log(err);
      })
      .finally(() => {
        process.exit();
      });
    
  4. Guarde y cierre el archivo FileUpload.js.

  5. Copie un archivo de imagen en la carpeta fileupload y asígnele un nombre, por ejemplo, myimage.png.

  6. Agregue variables de entorno para la cadena de conexión del dispositivo y la ruta de acceso al archivo que quiere cargar. Ha conseguido la cadena de conexión de dispositivo al registrar un dispositivo en el centro de IoT.

    • Para Windows:

      set DEVICE_CONNECTION_STRING={your device connection string}
      set PATH_TO_FILE={your image filepath}
      
    • Para Linux/Bash:

      export DEVICE_CONNECTION_STRING="{your device connection string}"
      export PATH_TO_FILE="{your image filepath}"
      

Obtención de la cadena de conexión de IoT Hub

En este artículo, creará un servicio de back-end para recibir mensajes de notificación de carga de archivos desde el centro de IoT que ha creado. Para recibir mensajes de notificación de carga de archivos, el servicio necesita el permiso de conexión de servicio. De forma predeterminada, todas las instancias de IoT Hub se crean con una directiva de acceso compartido denominada servicio que concede este permiso.

Para obtener la cadena de conexión de IoT Hub para la directiva service, siga estos pasos:

  1. En Azure Portal, seleccione Grupos de recursos. Seleccione el grupo de recursos donde se encuentra el centro y, a continuación, seleccione el centro en la lista de recursos.

  2. En el panel de la izquierda de IoT Hub, seleccione Directivas de acceso compartido.

  3. En la lista de directivas, seleccione la directiva service.

  4. Copie la Cadena de conexión principal y guarde el valor.

Captura de pantalla que muestra cómo recuperar la cadena de conexión de su IoT Hub en el Azure Portal.

Para obtener más información sobre las directivas de acceso compartido y los permisos de IoT Hub, consulte Permisos y control del acceso.

Recepción de una notificación de carga de archivos

En esta sección, se crea una aplicación de consola de Node.js que recibe mensajes de notificación de carga de archivos de IoT Hub.

  1. Cree una carpeta vacía denominada fileuploadnotification. En la carpeta fileuploadnotification, cree un archivo package.json con el siguiente comando en el símbolo del sistema. Acepte todos los valores predeterminados:

    npm init
    
  2. En el símbolo del sistema, en la carpeta fileuploadnotification, ejecute el siguiente comando para instalar el paquete del SDK azure-iothub:

    npm install azure-iothub --save
    
  3. Con un editor de texto, cree un archivo FileUploadNotification.js en la carpeta fileuploadnotification.

  4. Agregue las siguientes instrucciones require al principio del archivo FileUploadNotification.js:

    'use strict';
    
    const Client = require('azure-iothub').Client;
    
  5. Lea la cadena de conexión del centro de IoT desde el entorno:

    const connectionString = process.env.IOT_HUB_CONNECTION_STRING;
    
  6. Agregue el código siguiente para crear un cliente de servicio a partir de la cadena de conexión:

    const serviceClient = Client.fromConnectionString(connectionString);
    
  7. Abra el cliente y use la función getFileNotificationReceiver para recibir las actualizaciones de estado.

    serviceClient.open(function (err) {
      if (err) {
        console.error('Could not connect: ' + err.message);
      } else {
        console.log('Service client connected');
        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');
                }
              });
            });
          }
        });
      }
    });
    

    Nota:

    Si desea recibir notificaciones de desconexión mientras escucha las notificaciones de carga de archivos, debe registrarse 'error' mediante receiver.on. Para seguir recibiendo notificaciones de carga de archivos, debe volver a conectarse a IoT Hub mediante el método serviceClient.open.

  8. Guarde y cierre el archivo FileUploadNotification.js.

  9. Agregue una variable de entorno para la cadena de conexión de IoT Hub. Ha copiado esta cadena anteriormente en Obtención de la cadena de conexión de IoT Hub.

    • Para Windows:

      set IOT_HUB_CONNECTION_STRING={your iot hub connection string}
      
    • Para Linux/Bash:

      export IOT_HUB_CONNECTION_STRING="{your iot hub connection string}"
      

Ejecución de las aplicaciones

Ahora está listo para ejecutar las aplicaciones.

En la carpeta fileuploadnotification del símbolo del sistema, ejecute el siguiente comando:

node FileUploadNotification.js

En la carpeta fileupload del símbolo del sistema, ejecute el siguiente comando:

node FileUpload.js

La siguiente salida corresponde a la aplicación FileUpload una vez completada la carga:

uploadStreamToBlockBlob success
notifyBlobUploadStatus success

La siguiente salida de ejemplo corresponde a la aplicación FileUploadNotification una vez completada la carga:

Service client connected
File upload from device:
{"deviceId":"myDeviceId","blobUri":"https://{your storage account name}.blob.core.windows.net/device-upload-container/myDeviceId/image.png","blobName":"myDeviceId/image.png","lastUpdatedTime":"2021-07-23T23:27:06+00:00","blobSizeInBytes":26214,"enqueuedTimeUtc":"2021-07-23T23:27:07.2580791Z"}

Comprobación de la carga de archivos

Puede usar el portal para ver el archivo cargado en el contenedor de almacenamiento que configuró:

  1. Vaya a la cuenta de almacenamiento en Azure Portal.

  2. En el panel izquierdo de la cuenta de almacenamiento, seleccione Contenedores.

  3. Seleccione el contenedor donde cargó el archivo.

  4. Seleccione la carpeta que nombró tras el dispositivo.

  5. Seleccione el blob donde cargó el archivo. En este artículo, es el blob con el mismo nombre que el archivo.

    Captura de pantalla de la visualización del archivo cargado en Azure Portal.

  6. Vea las propiedades del blob en la página que se abre. Puede seleccionar Descargar para descargar el archivo y ver su contenido localmente.

Pasos siguientes

En este artículo ha aprendido a usar la función de carga de archivos de IoT Hub para simplificar la carga de archivos desde los dispositivos. Puede seguir explorando esta característica con los siguientes artículos: