How to manage local IoT complexity with Azure IoT Edge

Niels Daalhuisen

Whenever there is a more complex IoT solution with dependency on local business logic and the need for autonomous operations an edge device is quickly an important part of the solution. This article demonstrates the implementation of Azure IoT edge as part of two business cases that rely heavily on edge-based logic. To make it practical I created two small IoT cases that represent real live cases and (more important to me) are more manageable and practical in an office environment.

I have created two IoT systems that rely heavily on Azure IoT Edge. These are an autonomous plant and LEGO windmill. In this blog I will explain the process of creating these edge devices. This includes running IoT Edge on a Raspberry Pi, using VS Code to create and deploy IoT Edge modules and debugging the created module.

IoT Windmill and Autonomous Plant

What is Azure IoT Edge?

With the immense growth in quantity and scale of IoT Systems, the issues with cloud dependent systems have become apparent. Performing all or most compute tasks in the cloud can be both expensive and slow to react. A solution to this problem is edge computing. Edge computing means performing calculations as close to the data source as possible. Doing this creates advantages in the amount of data send, latency and security. You do not want to send all data to the cloud, this will clog the data processing and fill the data lake with unnecessary data points. Latency can be very important as some decisions cannot wait for a round trip to the cloud and need an immediate response within milliseconds. Some systems are not allowed to share data outside of the local system. In this case the cloud only gets a summary, but the vulnerable data will stay locally.

Microsoft’s solution for the creation and connection of edge devices is Azure IoT Edge. IoT Edge consists of a combination of three components: 1) IoT Edge modules, 2) IoT Edge runtime and 3) a cloud-based interface. IoT Edge modules are Docker containers that run business logic on the device. Several Azure services and third-party services are available as modules. These can be found on the Azure marketplace. Custom modules can be created when existing modules don’t suffice. IoT Edge Runtime takes care of module management and communication. The cloud-based interface is based on Azure IoT Hub. Through IoT Hub edge devices can be managed and monitored.

IoT Edge on a local compute unit

For the sake of this demonstration, I used a Raspberry Pi as my local logic module. In productional systems this will be a PLC or SCADA system, of course. Microsoft offers a set of instructions for installing IoT Edge on Linux. These are found here. This documentation includes instructions for Raspberry Pi OS Stretch. The current version however is Raspberry Pi OS Buster. Most of these instructions can still be followed, except the use of Moby as container engine. Moby cannot be installed on Buster. A workaround for this problem is to install Docker CE on the Raspberry Pi.

Install Docker CE by finding the latest version of, docker-ce-cli and docker-ce on Docker for Buster. Download all three by running wget commands and install by running the following commands:

sudo dpkg -i* && \
sudo dpkg -i docker-ce-cli* && \
sudo dpkg -i docker-ce_* && \
sudo usermod -aG docker $USER && \
sudo reboot

Follow the remaining instructions in the Microsoft documentation to install IoT Edge.

Creating an IoT Edge module

I decided the best way to create the desired functionality with IoT Edge was to create custom modules. By following this tutorial, I created custom NodeJS modules. Using VS Code in combination with the Azure IoT Tools extension makes creating modules incredibly simple. VS Code generates a complete project, including Dockerfile and deployment template based on the chosen device architecture. The Raspberry Pi uses the arm32v7 architecture. The tutorial also explains how to simulate the module and deploy the module to the edge device using VS Code.

Accessing Gpio pins, I2C and Bluetooth

The systems contain several sensors and actuators to achieve the desired physical functionality. This includes the Bluetooth Xiaomi plant monitor, Grove plant care kit, GrovePi+ and I2C Hub.

Since IoT Edge modules are containers, several changes to the deployment needed to be made to reach these I/O devices. First we need to add python3, build-base and linux-headers using apk. These packages are needed to run the grovepi and rpio npm libraries. Because IoT Edge uses Docker containers we need to provide access to hardware drivers outside the container. This blog from Sander van de Velde describes this process.

First the user specification in the Dockerfile needs to be taken out. By not specifying a user, Docker defaults to using the root user. Then the following JSON configuration needs to be added to createOptions of the module in the deployment.template.json file:

"NetworkingConfig": {
  "EndpointsConfig": {
    "host": {}
"HostConfig": {
  "NetworkMode": "host",
  "Privileged": true,
  "device": "/dev/i2c-1"

This JSON configures the creation and run options for the Docker container. Access to i2c device is given by running as privileged and specifying the device. Device “dev/mem” is used in the case of the rpio library. IoT Edge sets the network to bridge by default. To gain access to the Raspberry Pi’s Bluetooth functionality the host network needs to be used.

Debugging on the edge device

When accessing hardware components, the VS Code simulator doesn’t always suffice to debug code. When a module is dependent on specific hardware we need to see the logs on the actual device. The container logs can be accessed by running the command “iotedge logs <container name>” in the terminal. This option is only available if the Raspberry Pi is directly accessible. A Direct Method can be used to retrieve the logs if the edge device is only accessible through IoT Hub. How this can be achieved is described in the documentation.

The result

After performing these configurations and programming the desired logic in the custom  module, an edge device has been created. The device can be entirely managed from the cloud, while retaining functionality if the connection is interrupted because the logic runs locally. Messages that couldn’t be send to IoT Hub will still be send when the connection returns. Practically this means critical local systems will continue working, even if the connection to the cloud is lost. No data will be lost, because the edge device will retain the data until it can be send. This data restoration and other management tasks will be performed automatically. Other advantages include central monitoring, security and remote control of the device.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Next Post

Schedule Spotify Good Morning Playlist–using AutoIt and Windows Task Scheduler

Facebook 0 Twitter Linkedin I would like to have my Spotify playlist played to me every morning at 8AM sharp. Using the Windows Task Scheduler and an AutoIt script I can have the Spotify App started and subsequently automate the steps to run my preferred Spotify playlist. I can even […]