Bluetooth Low Energy BLE devices with Azure IoT Edge

One of the major reasons for utilizing an Azure Iot Edge Gateway is to connect devices to the internet that can’t directly establish a connection themselves. A very common case are Bluetooth beacons, that can provide sensor data through a Bluetooth Low Energy (BLE) connection but are not able to send this information directly to an Azure IoT Hub.

For this scenario a bridge or gateway is required to create an IoT message from the Bluetooth payload. This is called Protocol Translation and can be achieved by creating a custom IoT Edge Module. Interestingly enough Microsoft has still not managed to provide a sample or best practice on how to do this with the IoT Edge Runtime V2, so here’s how we did it in our latest IoT project.

In our case we are using the Open Source Ruuvi Bluetooth Tags since they are robust, affordable and there are already a number of SDKs available for different programming languages. For the Gateway we are using the Dell Edge Gateway 3001 running Ubuntu Server 18.04.

To get Bluetooth working inside a IoT Edge Module there are some pitfalls to be aware of that I will be highlighting throughout this article. The full source code can be found on GitHub. Let’s start with the necessary container configurations to be able to access the devices. After creating a new module, you need to adjust the deployment settings so the docker container runs in the host network.

"modules": {
"BLEModule": {
"version": "1.0",
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
"image": "${MODULES.BLEModule}",
"createOptions": {
"NetworkingConfig": {
"EndpointsConfig": {
"host": {}
"HostConfig": {
"NetworkMode": "host",
"Privileged": true

We chose to build the module using NodeJs & the node-ruuvitag package. This way we don’t need to handle any of the BLE-specific communication & protocol translations ourselves but instead get easy-to-work-with JSON messages whenever a nearby tag sends an update.

Most of the code is just the generated Node boilerplate code that the IoT Edge SDK provides when generating a new module. After the module client initialization, we listen for new Bluetooth tags. Once found, we subscribe to the messages sent by them. Those get wrapped in a new Message object and passed to the IoT Edge Runtime through the defined output for delivery to the Azure IoT Hub.

Client.fromEnvironment(Transport, function (err, client) {
if (err) {
throw err;
} else {
client.on('error', function (err) {
throw err;
// connect to the Edge instance (err) {
if (err) {
throw err;
} else {
console.log('IoT Hub module client initialized');
// listens to ruuvi tags nearby and subscribes to their messages
function initRuuviTag() {
ruuvi.on('found', tag => {
console.log('Found RuuviTag, id: ' +;
tag.on('updated', async data => {
var json = JSON.stringify(data, null, '\t')
var sensorMsg = new Message(json);
// send received ruuvi message through module identity
client.sendOutputEvent('output1', sensorMsg, printResultFor('Sending ble payload'));
view raw app.js hosted with ❤ by GitHub

The only thing left now to do now is to make sure you’re running the app in a properly configured Docker Image with all the Bluetooth tools installed that are required by node-ruuvitag or rather the underlying noble package. I mentioned that we’re using a Dell Gateway with Ubuntu, meaning I have adjusted the default Dockerfile.amd64, but the same setup also works for example on a Raspberry Pi with an ARM base image.

Besides installing the required dependencies note that the node process is being started as root to make sure there are no permission issues when calling the Bluetooth APIs.

FROM node:10-slim
RUN apt-get update || : && apt-get -y install bluetooth bluez libbluetooth-dev libudev-dev build-essential make python
COPY package*.json ./
RUN npm install –production
COPY app.js ./
USER root
CMD ["node", "app.js"]
view raw Dockerfile.amd64 hosted with ❤ by GitHub

If you want to wrap each Ruuvi Tag into their own Azure IoT Hub device identity you can find a post on Identity Translation here:

Again, the full code can be found over at GitHub. Hope this post helped you getting started working with Bluetooth on Azure IoT Edge.

Azure IoT Edge Identity Translation: Getting Started

In a lot of IoT solutions Gateways play important roles. They can help connect downstream devices to the Cloud through Access Points, provide offline caching capabilities or translate protocols that are not suitable for direct internet access like Bluetooth. With Azure IoT Edge Microsoft has a great product for these kinds of devices which allows you to deploy custom docker modules for different kinds of tasks like evaluating data on the Edge before sending everything to a connected Azure IoT Hub.

Continue reading Azure IoT Edge Identity Translation: Getting Started

Stop using npm install in your CI/CD pipelines

TLDR: npm install can update your npm packages potentially destabilizing your build process by using untested dependency versions. Use npm ci instead!

If you’re like me you might have several node-based apps, nicely configured to be built and deployed using automatic build & release pipelines.

So one of the first things you’re probably doing in that build pipeline is installing all required dependencies from npm, with your process looking something like this:

Continue reading Stop using npm install in your CI/CD pipelines

Remember to set the Content Type when using Static website hosting for Azure Storage

Currently I’m playing around with the new Static website hosting for Azure Storage feature which has recently been launched in public preview. This allows you to serve static web content (HTML, CSS, JS, images) directly from a dedicated blob directory inside Azure Storage without setting up any kind of web app or proxy function.

Continue reading Remember to set the Content Type when using Static website hosting for Azure Storage