Using Protocol Buffers with Azure IoT Edge

Google’s Protocol Buffers are a perfect fit with the multilingual approach of Azure IoT Edge. Using ProtoBuf, a message format can be written once and used across multiple frameworks and languages while benefiting from the speed and message size intrinsic to ProtoBuf. For this Azure IoT Edge use case, we will generate a message in C++ and send it to a module written in Python to filter out the values that are sent to IoT Hub.

Steps

  • Create the message format
  • Create a C Azure IoT Edge Module
    • Add ProtoBuffers to build
    • Create C models
  • Create a Python Azure IoT Edge Module
    • Add ProtoBuffers to project
    • Create Python Module

Create the message format

Creating the message format is trivial. Following the language guide, there are two message types to create.

  1. A temperature reading, consisting of a float and a string
  2. An array of the previous reading with a string
syntax = "proto3";

message TemperatureReading {
  int reading = 1;
  string timestamp = 2;
}

message TemperatureReadingUpload {
  string uploaded_timestamp = 1;
  repeated TemperatureReading readings = 2;
}

The above is all that is needed to create the model for ProtoBuf. Creating the language specific code for each module is covered in their module sections.

Create a C Azure IoT Edge Module

Prerequisites

This article assumes that you use a computer or virtual machine running Windows or Linux as your development machine. And you simulate your IoT Edge device on your development machine.

Needs:

To create a module, you need Docker to build the module image, and a container registry to hold the module image:

Create a new solution template

Take these steps to create an IoT Edge module based on Azure IoT C SDK using Visual Studio Code and the Azure IoT Edge extension. First you create a solution, and then you generate the first module in that solution. Each solution can contain more than one module.

  1. In Visual Studio Code, select View > Integrated Terminal.
  2. Select View > Command Palette.
  3. In the command palette, enter and run the command Azure IoT Edge: New IoT Edge Solution.Run New IoT Edge Solution
  4. Browse to the folder where you want to create the new solution. Choose Select folder.
  5. Enter a name for your solution.
  6. Select C Module as the template for the first module in the solution.
  7. Enter a name for your module. Choose a name that’s unique within your container registry.
  8. Provide the name of the module’s image repository. VS Code autopopulates the module name with localhost:5000. Replace it with your own registry information. If you use a local Docker registry for testing, then localhost is fine. If you use Azure Container Registry, then use the login server from your registry’s settings. The login server looks like .azurecr.io.

VS Code takes the information you provided, creates an IoT Edge solution, and then loads it in a new window.

View IoT Edge solution

There are four items within the solution:

  • .vscode folder contains debug configurations.
  • modules folder has subfolders for each module. At this point, you only have one. But you can add more in the command palette with the command Azure IoT Edge: Add IoT Edge Module.
  • An .env file lists your environment variables. If Azure Container Registry is your registry, you’ll have an Azure Container Registry username and password in it.

    Note

    The environment file is only created if you provide an image repository for the module. If you accepted the localhost defaults to test and debug locally, then you don’t need to declare environment variables.

  • deployment.template.json file lists your new module along with a sample tempSensor module that simulates data you can use for testing. For more information about how deployment manifests work, see Learn how to use deployment manifests to deploy modules and establish routes.

Develop your module

The default C module code that comes with the solution is located at modules >> main.c. The module and the deployment.template.json file are set up so that you can build the solution, push it to your container registry, and deploy it to a device to start testing without touching any code. The module is built to simply take input from a source (in this case, the tempSensor module that simulates data) and pipe it to IoT Hub.

When you’re ready to customize the C template with your own code, use the Azure IoT Hub SDKs to build modules that address the key needs for IoT solutions such as security, device management, and reliability.

Compile the Protocol Buffer file

To compile the Protocol Buffer file, use the command line compiler protoc. For more information on how to use protoc for each platform, check out the Protocol Buffer documentation. For the C module, we will use the C++ compiler options:

protoc --proto_path=src --cpp_out=model src/temp.proto

To create and serialize the object, use the following code:

TemperatureReading reading;
reading.set_reading(get_temperature_reading()); //get_temperature_reading is your function on generating the temperature reading value
auto message_body = reading.SerializeAsString();

 

Build and deploy your module for debugging

In each module folder, there are several Docker files for different container types. Use any of these files that end with the extension .debug to build your module for testing. Currently, C modules support debugging only in Linux amd64 containers.

  1. In VS Code, navigate to the deployment.template.json file. Update your module image URL by adding .debug to the end.Add **.debug** to your image name
  2. Replace the C module createOptions in deployment.template.json with below content and save this file:
    "createOptions": "{\"HostConfig\": {\"Privileged\": true}}"
    
  3. In the VS Code command palette, enter and run the command Edge: Build IoT Edge solution.
  4. Select the deployment.template.json file for your solution from the command palette.
  5. In Azure IoT Hub Device Explorer, right-click an IoT Edge device ID. Then select Create deployment for Single device.
  6. Open your solution’s config folder. Then select the deployment.json file. Choose Select Edge Deployment Manifest.

You’ll see the deployment successfully created with a deployment ID in a VS Code-integrated terminal.

Check your container status in the VS Code Docker explorer or by running the docker ps command in the terminal.

Start debugging C module in VS Code

VS Code keeps debugging configuration information in a launch.json file located in a .vscode folder in your workspace. This launch.json file was generated when you created a new IoT Edge solution. It updates each time you add a new module that supports debugging.

  1. Navigate to the VS Code debug view. Select the debug configuration file for your module. The debug option name should be similar to ModuleName Remote Debug (C)Select debug configuration.
  2. Navigate to main.c. Add a breakpoint in this file.
  3. Select Start Debugging or select F5. Select the process to attach to.
  4. In VS Code Debug view, you’ll see the variables in the left panel.

The preceding example shows how to debug C IoT Edge modules on containers. It added exposed ports in your module container createOptions. After you finish debugging your C modules, we recommend you remove these exposed ports for production-ready IoT Edge modules.

Create a Python Azure IoT Edge Module

Create an IoT Edge module project

The following steps create an IoT Edge Python module by using Visual Studio Code and the Azure IoT Edge extension.

Create a new solution

Use the Python package cookiecutter to create a Python solution template that you can build on top of.

  1. In Visual Studio Code, select View > Integrated Terminal to open the VS Code integrated terminal.
  2. In the integrated terminal, enter the following command to install (or update) cookiecutter, which you use to create the IoT Edge solution template in VS Code:
    pip install --upgrade --user cookiecutter

    Ensure the directory where cookiecutter will be installed is in your environment’s Path in order to make it possible to invoke it from a command prompt.

  3. Select View > Command Palette to open the VS Code command palette.
  4. In the command palette, enter and run the command Azure: Sign in and follow the instructions to sign in your Azure account. If you’re already signed in, you can skip this step.
  5. In the command palette, enter and run the command Azure IoT Edge: New IoT Edge solution. In the command palette, provide the following information to create your solution:
    1. Select the folder where you want to create the solution.
    2. Provide a name for your solution or accept the default EdgeSolution.
    3. Choose Python Module as the module template.
    4. Name your module PythonModule.
    5. Specify the Azure container registry that you created in the previous section as the image repository for your first module. Replace localhost:5000 with the login server value that you copied. The final string looks like <registry name>.azurecr.io/pythonmodule.

The VS Code window loads your IoT Edge solution workspace: the modules folder, a deployment manifest template file, and a .env file.

Add your registry credentials

The environment file stores the credentials for your container repository and shares them with the IoT Edge runtime. The runtime needs these credentials to pull your private images onto the IoT Edge device.

  1. In the VS Code explorer, open the .env file.
  2. Update the fields with the username and password values that you copied from your Azure container registry.
  3. Save this file.

Compile the Protocol Buffer file

To compile the Protocol Buffer file, use the command line compiler protoc. For more information on how to use protoc for each platform, check out the Protocol Buffer documentation. For the Python module, we will use the Python compiler options:

protoc --proto_path=src --python_out=model src/temp.proto

Update the module with custom code

Each template includes sample code, which takes simulated sensor data from the tempSensor module and routes it to the IoT hub. In this section, add the code that expands the PythonModule to analyze the messages before sending them.

  1. In the VS Code explorer, open modules > PythonModule > main.py.
  2. At the top of the main.py file, import the temp_pb3 library that was created by protoc:
    import temp_pb3
    
  3. Add the TEMPERATURE_THRESHOLD and TWIN_CALLBACKS variables under the global counters. The temperature threshold sets the value that the measured machine temperature must exceed for the data to be sent to the IoT hub.
    TEMPERATURE_THRESHOLD = 25
    TWIN_CALLBACKS = 0
    
  4. Replace the receive_message_callback function with the following code:
    # receive_message_callback is invoked when an incoming message arrives on the specified 
    # input queue (in the case of this sample, "input1").  Because this is a filter module, 
    # we forward this message to the "output1" queue.
    def receive_message_callback(message, hubManager):
        global RECEIVE_CALLBACKS
        global TEMPERATURE_THRESHOLD
        message_buffer = message.get_bytearray()
        map_properties = message.properties()
        key_value_pair = map_properties.get_internals()
        print ( "    Properties: %s" % key_value_pair )
        RECEIVE_CALLBACKS += 1
        print ( "    Total calls received: %d" % RECEIVE_CALLBACKS )
        data = TemperatureReading.ParseFromString(message_buffer)
        if data.reading > TEMPERATURE_THRESHOLD:
            map_properties.add("MessageType", "Alert")
            print("Machine temperature %s exceeds threshold %s" % (data["machine"]["temperature"], TEMPERATURE_THRESHOLD))
        hubManager.forward_event_to_output("output1", message, 0)
        return IoTHubMessageDispositionResult.ACCEPTED
    
  5. Add a new function called module_twin_callback. This function is invoked when the desired properties are updated.
    # module_twin_callback is invoked when the module twin's desired properties are updated.
    def module_twin_callback(update_state, payload, user_context):
        global TWIN_CALLBACKS
        global TEMPERATURE_THRESHOLD
        print ( "\nTwin callback called with:\nupdateStatus = %s\npayload = %s\ncontext = %s" % (update_state, payload, user_context) )
        data = json.loads(payload)
        if "desired" in data and "TemperatureThreshold" in data["desired"]:
            TEMPERATURE_THRESHOLD = data["desired"]["TemperatureThreshold"]
        if "TemperatureThreshold" in data:
            TEMPERATURE_THRESHOLD = data["TemperatureThreshold"]
        TWIN_CALLBACKS += 1
        print ( "Total calls confirmed: %d\n" % TWIN_CALLBACKS )
    
  6. In the HubManager class, add a new line to the init method to initialize the module_twin_callback function that you just added:
    # Sets the callback when a module twin's desired properties are updated.
    self.client.set_module_twin_callback(module_twin_callback, self)
    
  7. Save this file.

Build your IoT Edge solution

In the previous section, you created an IoT Edge solution and added code to the PythonModule to filter out messages where the reported machine temperature is below the acceptable threshold. Now you need to build the solution as a container image and push it to your container registry.

  1. Sign in to Docker by entering the following command in the Visual Studio Code integrated terminal. Then you can push your module image to your Azure container registry:
    docker login -u <ACR username> -p <ACR password> <ACR login server>
    

    Use the username, password, and login server that you copied from your Azure container registry in the first section. You can also retrieve these values from the Access keys section of your registry in the Azure portal.

  2. In the VS Code explorer, open the deployment.template.json file in your IoT Edge solution workspace.This file tells the $edgeAgent to deploy two modules: tempSensor, which simulates device data, and PythonModule. The PythonModule.image value is set to a Linux amd64 version of the image. To learn more about deployment manifests, see Understand how IoT Edge modules can be used, configured, and reused.This file also contains your registry credentials. In the template file, your user name and password are filled in with placeholders. When you generate the deployment manifest, the fields are updated with the values that you added to the .env file.
  3. Add the PythonModule module twin to the deployment manifest. Insert the following JSON content at the bottom of the moduleContent section, after the $edgeHub module twin:
        "PythonModule": {
            "properties.desired":{
                "TemperatureThreshold":25
            }
        }
    
  4. Save this file.
  5. In the VS Code explorer, right-click the deployment.template.json file and select Build and Push IoT Edge solution.

When you tell Visual Studio Code to build your solution, it first takes the information in the deployment template and generates a deployment.json file in a new folder named config. Then it runs two commands in the integrated terminal: docker build and docker push. These two commands build your code, containerize the Python code, and then push the code to the container registry that you specified when you initialized the solution.

You can see the full container image address with tag in the docker build command that runs in the VS Code integrated terminal. The image address is built from information in the module.json file with the format <repository>:<version>-<platform>. For this tutorial, it should look like registryname.azurecr.io/pythonmodule:0.0.1-amd64.

Deploy and run the solution

You can use the Azure portal to deploy your Python module to an IoT Edge device like you did in the quickstarts. You can also deploy and monitor modules from within Visual Studio Code. The following sections use the Azure IoT Edge extension for VS Code that was listed in the prerequisites. Install the extension now, if you didn’t already.

  1. Open the VS Code command palette by selecting View > Command Palette.
  2. Search for and run the command Azure: Sign in. Follow the instructions to sign in your Azure account.
  3. In the command palette, search for and run the command Azure IoT Hub: Select IoT Hub.
  4. Select the subscription that contains your IoT hub, and then select the IoT hub that you want to access.
  5. In the VS Code explorer, expand the Azure IoT Hub Devices section.
  6. Right-click the name of your IoT Edge device, and then select Create Deployment for IoT Edge device.
  7. Browse to the solution folder that contains the PythonModule. Open the config folder, select the deployment.json file, and then choose Select Edge Deployment Manifest.
  8. Refresh the Azure IoT Hub Devices section. You should see the new PythonModule running along with the TempSensor module and the $edgeAgent and $edgeHub.

Update Conference Prague

I have been selected to speak at Update Conference Prague during 

  •  Enable IoT with Edge Computing and Machine Learning
  • Virtual Reality and IoT – Interacting with the changing world

Enable IoT with Edge Computing and Machine Learning

Being able to run compute cycles on local hardware is a practice predating silicon circuits. Mobile and Web technology has pushed computation away from local hardware and onto remote servers. As prices in the cloud have decreased, more and more of the remote servers have moved there. This technology cycle is coming full circle with pushing the computation that would be done in the cloud down to the client. The catalyst for the cycle completing is latency and cost. Running computations on local hardware softens the load in the cloud and reduces overall cost and architectural complexity.

The difference now is how the computational logic is sent to the device. As of now, we rely on app stores and browsers to deliver the logic the client will use. Delivery mechanisms are evolving into writing code once and having the ability to run that logic in the cloud and push that logic to the client through your application and have that logic run on the device. In this presentation, we will look at how to accomplish this with existing Azure technologies and how to prepare for upcoming technologies to run these workloads.

Virtual Reality and IoT – Interacting with the changing world

Using IoT Devices, powered by Windows 10 IoT and Raspbian, we can collect data from the world surrounding us. That data can be used to create interactive environments for mixed reality, augmented reality, or virtual reality. To move the captured data from the devices to the interactive environment, the data will travel through Microsoft’s Azure. First it will be ingested through the Azure IoT Hub which provides the security, bi-directional communication, and input rates needed for the solution. We will move the data directly from the IoT Hub to an Azure Service Bus Topic. The Topic allows for data to be sent to every Subscription listening for the data that was input. Azure Web Apps subscribe to the Topics and forward the data through a SignalR Hub that forwards the data to a client. For this demo, the client is a Unity Application that creates a Virtual Reality simulation showcasing that data.

Once finished with this introduction to these technologies, utilizing each component of this technology stack should be approachable. Before seeing the pieces come together, the technologies used in this demonstration may not seem useful to a developer. When combined, they create a powerful tool to share nearly unlimited amounts of incoming data across multiple channels.

MVP Renewal

Proudly, I will be entering my second year as a Microsoft MVP. This will be under the Microsoft Azure category again. Moving forward, I look forward to doing a large amount of work and training with Azure Edge and Azure ML. Specifically, I look forward to working on the Scry Unlimited and West World of Warcraft projects. To contact me for for your project, please visit the contact page.

As a start, on 7/2/2018 I will be presenting AI on the Edge at the Atlanta Intelligent Devices user group. Following that up I will be speaking at events around the country and hopefully internationally. In addition to my normal speaking on Mobile, Cloud, and Edge; I will be adding Machine Learning and Artificial Intelligence specifically focusing on the integration with Edge and Mobile computing. If you are looking for a speaker, check out my speaker page and fill out the form.

Finally, I am still putting together events in Atlanta. If you would like to participate in any of the following events, just follow their links or message me on Twitter:

TechBash 2018

This year I will be presenting Enable IoT with Edge Computing and Machine Learning at TechBash. Here is the outline:

Being able to run compute cycles on local hardware is a practice predating silicon circuits. Mobile and Web technology has pushed computation away from local hardware and onto remote servers. As prices in the cloud have decreased, more and more of the remote servers have moved there. This technology cycle is coming full circle with pushing the computation that would be done in the cloud down to the client. The catalyst for the cycle completing is latency and cost. Running computations on local hardware softens the load in the cloud and reduces overall cost and architectural complexity.

The difference now is how the computational logic is sent to the device. As of now, we rely on app stores and browsers to deliver the logic the client will use. Delivery mechanisms are evolving into writing code once and having the ability to run that logic in the cloud and push that logic to the client through your application and have that logic run on the device. In this presentation, we will look at how to accomplish this with existing Azure technologies and how to prepare for upcoming technologies to run these workloads.

 

IRIS Conference

April 14th is the Integrative Research and Ideas Symposium (IRIS) hosted by the UGA Graduate-Professional Student Association. I will be speaking on three separate topics at the event:

  • Virtual Reality and IoT – Interacting with the Changing World
  • Enable IoT with Edge Computing and Machine Learning
  • Alternative Device Interfaces and Machine Learning

More than that though I look forward to hearing about the innovations and research provided by the graduate students and professionals at UGA. Here is their synopsis of IRIS:

The UGA Graduate-Professional Student Association is proud to announce IRIS 2018, a unique and exciting opportunity for students and other researchers from throughout the UGA community. 

This initiative’s focus on community-building, cross-pollination of ideas, transferrable skills, and service will:

  • Provide an excellent opportunity to enhance research communication skills and present research to an interdisciplinary audience. 
  • Expose students to cutting-edge scholarship, industry professionals, and rich professional development opportunities.
  • Help attendees refine the content and language of their C.V.’s and resumés through career workshops. 
  • Encourage shared scholarship, research, and service.
  • Equip attendees with new knowledge and skills which can strengthen teaching, learning, and career outcomes. 
  • Empower attendees to translate skills and research interests into career competencies. 

CodeStock

I’m proud to be presenting Alternative Device Interfaces and Machine Learning at CodeStock this year. With AI becoming more and more ubiquitous, it is important to note the effect on a user’s experience. This presentation is meant to show how to create modern applications using machine learning provided by a third party and showcase what some third parties provide.

In this presentation, we will look at the how users interface with machines without the use of touch. These different types of interaction have their benefits and pitfalls. To showcase the power of these user interactions we will explore: Voice commands with mobile applications, Speech Recognition, and Computer Vision. After this presentation, attendees will have the knowledge to create applications that can utilize voice, video, and machine learning.

Users use voice (Alexa, Cortana, Google Now) or video as a mode of interaction with applications. More than a fad, this is a natural interface for users and is becoming more and more common with the ever-decreasing size of hardware.

Different types of interaction have their benefits and pitfalls. To showcase the power of these user interactions we will explore: Voice commands with two app types: UWP and Xamarin Forms (iOS and Android). Speech Recognition with Cognitive Services: Verifying the speaker with Speaker Recognition API. Computer Vision with Cognitive Services: Verifying a user with Face API.

By utilizing UWP, Xamarin, and Cognitive services; a device with the ultimate in customization for user interactions will be created. Come and see how!

Azure IoT Edge – exec user process caused “exec format error”

If running Edge on a Raspberry Pi  and an Edge container’s logs show  ‘exec user process caused “exec format error”‘ as an error then most likely you are running a non Raspberry Pi container on the Raspberry Pi. If the docker file used to build the container starts with:

  • FROM microsoft/dotnet:2.0.0-runtime

or

  • FROM microsoft/dotnet:2.0.0-runtime-nanoserver-1709

then the line above should be changed to one of the following:

  • FROM microsoft/dotnet:2.0.5-runtime-stretch-arm32v7
  • FROM microsoft/dotnet:2.0-runtime-stretch-arm32v7
  • FROM microsoft/dotnet:2.0.5-runtime-deps-stretch-arm32v7
  • FROM microsoft/dotnet:2.0-runtime-deps-stretch-arm32v7