Upload files from your device to the cloud with IoT Hub

This tutorial builds on the code in the Send Cloud-to-Device messages with IoT Hub tutorial to show you how to use the file upload capabilities of IoT Hub to upload a file to Azure blob storage. The tutorial shows you how to:

  • Securely provide a device with an Azure blob URI for uploading a file.
  • Use the IoT Hub file upload notifications to trigger processing the file in your app back end.

The Get started with IoT Hub tutorial demonstrates the basic device-to-cloud messaging functionality of IoT Hub. However, in some scenarios you cannot easily map the data your devices send into the relatively small device-to-cloud messages that IoT Hub accepts. For example:

  • Large files that contain images
  • Videos
  • Vibration data sampled at high frequency
  • Some form of pre-processed data.

These files are typically batch processed in the cloud using tools such as Azure Data Factory or the Hadoop stack. When you need to upland files from a device, you can still use the security and reliability of IoT Hub.

At the end of this tutorial you run two Node.js console apps:

  • SimulatedDevice.js, which uploads a file to storage using a SAS URI provided by your IoT hub.

  • ReadFileUploadNotification.js, which receives file upload notifications from your IoT hub.

Note

IoT Hub supports many device platforms and languages (including C, .NET, Javascript, Python, and Java) through Azure IoT device SDKs. Refer to the [Azure IoT Developer Center] for step-by-step instructions on how to connect your device to Azure IoT Hub.

To complete this tutorial, you need the following:

  • Node.js version 4.0.x or later.

  • An active Azure account. (If you don't have an account, you can create a free account in just a couple of minutes.)

Associate an Azure Storage account to IoT Hub

Because the simulated device app uploads a file to a blob, you must have an Azure Storage account associated with your IoT hub. When you associate an Azure Storage account with an IoT hub, the IoT hub generates a SAS URI. A device can use this SAS URI to securely upload a file to a blob container. The IoT Hub service and the device SDKs coordinate the process that generates the SAS URI and makes it available to a device to use to upload a file.

Follow the instructions in Configure file uploads using the Azure portal. Make sure that a blob container is associated with your IoT hub and that file notifications are enabled.

Enable File Notifications in portal

Upload a file from a device app

In this section, you create the device app to upload a file to IoT hub.

  1. Create an empty folder called simulateddevice. In the simulateddevice folder, create a package.json file using the following command at your command prompt. Accept all the defaults:

    npm init
    
  2. At your command prompt in the simulateddevice folder, run the following command to install the azure-iot-device Device SDK package and azure-iot-device-mqtt package:

    npm install azure-iot-device azure-iot-device-mqtt --save
    
  3. Using a text editor, create a SimulatedDevice.js file in the simulateddevice folder.

  4. Add the following require statements at the start of the SimulatedDevice.js file:

    'use strict';
    
    var fs = require('fs');
    var mqtt = require('azure-iot-device-mqtt').Mqtt;
    var clientFromConnectionString = require('azure-iot-device-mqtt').clientFromConnectionString;
    
  5. Add a deviceconnectionstring variable and use it to create a Client instance. Replace {deviceconnectionstring} with the name of the device you created in the Create an IoT Hub section:

    var connectionString = '{deviceconnectionstring}';
    var filename = 'myimage.png';
    

    Note

    For the sake of simplicity the connection string is included in the code: this is not a recommended practice and depending on your use-case and architecture you may want to consider more secure ways of storing this secret.

  6. Add the following code to connect the client:

    var client = clientFromConnectionString(connectionString);
    console.log('Client connected');
    
  7. Create a callback and use the uploadToBlob function to upload the file.

    fs.stat(filename, function (err, stats) {
        const rr = fs.createReadStream(filename);
    
        client.uploadToBlob(filename, rr, stats.size, function (err) {
            if (err) {
                console.error('Error uploading file: ' + err.toString());
            } else {
                console.log('File uploaded');
            }
        });
    });
    
  8. Save and close the SimulatedDevice.js file.

  9. Copy an image file to the simulateddevice folder and rename it myimage.png.

Receive a file upload notification

In this section, you create a Node.js console app that receives file upload notification messages from IoT Hub.

You can use the iothubowner connection string from your IoT Hub to complete this section. You will find the connection string in the Azure portal on the Shared access policy blade.

  1. Create an empty folder called fileuploadnotification. In the fileuploadnotification folder, create a package.json file using the following command at your command prompt. Accept all the defaults:

    npm init
    
  2. At your command prompt in the fileuploadnotification folder, run the following command to install the azure-iothub SDK package:

    npm install azure-iothub --save
    
  3. Using a text editor, create a FileUploadNotification.js file in the fileuploadnotification folder.

  4. Add the following require statements at the start of the FileUploadNotification.js file:

    'use strict';
    
    var Client = require('azure-iothub').Client;
    
  5. Add a iothubconnectionstring variable and use it to create a Client instance. Replace {iothubconnectionstring} with the connection string to the IoT hub you created in the Create an IoT Hub section:

    var connectionString = '{iothubconnectionstring}';
    

    Note

    For the sake of simplicity the connection string is included in the code: this is not a recommended practice and depending on your use-case and architecture you may want to consider more secure ways of storing this secret.

  6. Add the following code to connect the client:

    var serviceClient = Client.fromConnectionString(connectionString);
    
  7. Open the client and use the getFileNotificationReceiver function to receive status updates.

    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'));
            });
          }
        });
      }
    });
    
  8. Save and close the FileUploadNotification.js file.

Run the applications

Now you are ready to run the applications.

At a command prompt in the fileuploadnotification folder, run the following command:

node FileUploadNotification.js

At a command prompt in the simulateddevice folder, run the following command:

node SimulatedDevice.js

The following screenshot shows the output from the SimulatedDevice app:

Output from simulated-device app

The following screenshot shows the output from the FileUploadNotification app:

Output from read-file-upload-notification app

You can use the portal to view the uploaded file in the storage container you configured:

Uploaded file

Next steps

In this tutorial, you learned how to use the file upload capabilities of IoT Hub to simplify file uploads from devices. You can continue to explore IoT hub features and scenarios with the following articles: