Deploy Azure Function as an IoT Edge module - preview

You can use Azure Functions to deploy code that implements your business logic directly to your IoT Edge devices. This tutorial walks you through creating and deploying an Azure Function that filters sensor data on the simulated IoT Edge device that you created in the Deploy Azure IoT Edge on a simulated device on Windows or Linux tutorials. In this tutorial, you learn how to:

  • Use Visual Studio Code to create an Azure Function
  • Use VS Code and Docker to create a Docker image and publish it to your registry
  • Deploy the module to your IoT Edge device
  • View generated data

The Azure Function that you create in this tutorial filters the temperature data generated by your device and only sends messages upstream to Azure IoT Hub when the temperature is above a specified threshold.

Prerequisites

Create a container registry

In this tutorial, you use the Azure IoT Edge extension for VS Code to build a module and create a container image from the files. Then you push this image to a registry that stores and manages your images. Finally, you deploy your image from your registry to run on your IoT Edge device.

You can use any Docker-compatible registry for this tutorial. Two popular Docker registry services available in the cloud are Azure Container Registry and Docker Hub. This tutorial uses Azure Container Registry.

  1. In the Azure portal, select Create a resource > Containers > Azure Container Registry.
  2. Give your registry a name, choose a subscription, choose a resource group, and set the SKU to Basic.
  3. Select Create.
  4. Once your container registry is created, navigate to it and select Access keys.
  5. Toggle Admin user to Enable.
  6. Copy the values for Login server, Username, and Password. You'll use these values later in the tutorial.

Create a function project

The following steps show you how to create an IoT Edge function using Visual Studio Code and the Azure IoT Edge extension.

  1. Open Visual Studio Code.
  2. To open the VS Code integrated terminal, select View > Integrated Terminal.
  3. To install (or update) the AzureIoTEdgeFunction template in dotnet, run the following command in the integrated terminal:

    dotnet new -i Microsoft.Azure.IoT.Edge.Function
    
  4. Create a project for the new module. The following command creates the project folder, FilterFunction, in the current working folder:

    dotnet new aziotedgefunction -n FilterFunction
    
  5. Select File > Open Folder, then browse to the FilterFunction folder and open the project in VS Code.

  6. In VS Code explorer, expand the EdgeHubTrigger-Csharp folder, then open the run.csx file.
  7. Replace the contents of the file with the following code:

    #r "Microsoft.Azure.Devices.Client"
    #r "Newtonsoft.Json"
    
    using System.IO;
    using Microsoft.Azure.Devices.Client;
    using Newtonsoft.Json;
    
    // Filter messages based on the temperature value in the body of the message and the temperature threshold value.
    public static async Task Run(Message messageReceived, IAsyncCollector<Message> output, TraceWriter log)
    {
         const int temperatureThreshold = 25;
         byte[] messageBytes = messageReceived.GetBytes();
         var messageString = System.Text.Encoding.UTF8.GetString(messageBytes);
    
         if (!string.IsNullOrEmpty(messageString))
         {
             // Get the body of the message and deserialize it
             var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
    
             if (messageBody != null && messageBody.machine.temperature > temperatureThreshold)
             {
                 // Send the message to the output as the temperature value is greater than the threashold
                 var filteredMessage = new Message(messageBytes);
                 // Copy the properties of the original message into the new Message object
                 foreach (KeyValuePair<string, string> prop in messageReceived.Properties)
                 {
                     filteredMessage.Properties.Add(prop.Key, prop.Value);
                 }
                 // Add a new property to the message to indicate it is an alert
                 filteredMessage.Properties.Add("MessageType", "Alert");
                 // Send the message        
                 await output.AddAsync(filteredMessage);
                 log.Info("Received and transferred a message with temperature above the threshold");
             }
         }
     }
    
     //Define the expected schema for the body of incoming messages
     class MessageBody
     {
         public Machine machine {get;set;}
         public Ambient ambient {get; set;}
         public string timeCreated {get; set;}
     }
     class Machine
     {
        public double temperature {get; set;}
        public double pressure {get; set;}         
     }
     class Ambient
     {
        public double temperature {get; set;}
        public int humidity {get; set;}         
     }
    
  8. Save the file.

Publish a Docker image

  1. Build the Docker image.

    1. In VS Code explorer, expand the Docker folder. Then expand the folder for your container platform, either linux-x64 or windows-nano.
    2. Right-click the Dockerfile file and click Build IoT Edge module Docker image.
    3. Navigate to the FilterFunction project folder and click Select Folder as EXE_DIR.
    4. In the pop-up text box at the top of the VS Code window, enter the image name. For example: <your container registry address>/filterfunction:latest. The container registry address is the same as the login server that you copied from your registry. It should be in the form of <your container registry name>.azurecr.io.
  2. Sign in to Docker. In the integrated terminal, enter the following command:

    docker login -u <username> -p <password> <Login server>
    

    To find the user name, password and login server to use in this command, go to the Azure portal. From All resources, click the tile for your Azure container registry to open its properties, then click Access keys. Copy the values in the Username, password, and Login server fields.

  3. Push the image to your Docker repository. Select View > Command Palette... then search for Edge: Push IoT Edge module Docker image.

  4. In the pop-up text box, enter the same image name that you used in step 1.d.

Add registry credentials to your Edge device

Add the credentials for your registry to the Edge runtime on the computer where you are running your Edge device. This gives the runtime access to pull the container.

  • For Windows, run the following command:

    iotedgectl login --address <your container registry address> --username <username> --password <password> 
    
  • For Linux, run the following command:

    sudo iotedgectl login --address <your container registry address> --username <username> --password <password> 
    

Run the solution

  1. In the Azure portal, navigate to your IoT hub.
  2. Go to IoT Edge (preview) and select your IoT Edge device.
  3. Select Set Modules.
  4. If you've already deployed the tempSensor module to this device, it may be automatically populated. If not, follow these steps to add it:
    1. Select Add IoT Edge Module.
    2. In the Name field, enter tempSensor.
    3. In the Image URI field, enter microsoft/azureiotedge-simulated-temperature-sensor:1.0-preview.
    4. Leave the other settings unchanged and click Save.
  5. Add the filterFunction module.
    1. Select Add IoT Edge Module again.
    2. In the Name field, enter filterFunction.
    3. In the Image field, enter your image address; for example <docker registry address>/filterfunction:latest.
    4. Click Save.
  6. Click Next.
  7. In the Specify Routes step, copy the JSON below into the text box. The first route transports messages from the temperature sensor to the filter module via the "input1" endpoint. The second route transports messages from the filter module to IoT Hub. In this route, $upstream is a special destination that tells Edge Hub to send messages to IoT Hub.

    {
       "routes":{
          "sensorToFilter":"FROM /messages/modules/tempSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/filterFunction/inputs/input1\")",
          "filterToIoTHub":"FROM /messages/modules/filterFunction/outputs/* INTO $upstream"
       }
    }
    
  8. Click Next.

  9. In the Review Template step, click Submit.
  10. Return to the IoT Edge device details page and click Refresh. You should see the new filterfunction module running along with the tempSensor module and the IoT Edge runtime.

View generated data

To monitor device to cloud messages sent from your IoT Edge device to your IoT hub:

  1. Configure the Azure IoT Toolkit extension with connection string for your IoT hub:

    1. In the Azure portal, navigate to your IoT hub and select Shared access policies.
    2. Select iothubowner then copy the value of Connection string-primary key.
    3. In the VS Code explorer, click IOT HUB DEVICES and then click ....
    4. Select Set IoT Hub Connection String and enter the Iot Hub connection string in the pop-up window.
  2. To monitor data arriving at the IoT hub, select the View > Command Palette... and search for IoT: Start monitoring D2C message.

  3. To stop monitoring data, use the IoT: Stop monitoring D2C message command in the Command Palette.

Next steps

In this tutorial, you created an Azure Function that contains code to filter raw data generated by your IoT Edge device. To keep exploring Azure IoT Edge, learn how to use an IoT Edge device as a gateway.