Using Bluetooth for in-home positioning services

Helping Spirits

Article from Issue 212/2018

The GPS tracking service isn't precise enough to provide positioning information within a home. Home automation expert Gunnar Beutner decided to harness the invisible spirits of Bluetooth for a home-grown indoor positioning system.

Imagine coming home on a cold winter's day; it's already cosily warm, the lights are switched on automatically, and a favorite song is playing through the speakers. Everyday users can already implement this scenario without great difficulty. Software tools such as the open source Home Assistant [1] offer various components for determining the presence of home residents. GPS location capabilities, combined with automation rules, result in some interesting applications for heating and lighting control.

In most cases, however, GPS is not a suitable solution for automating light switches for the rooms within a house. The signal quality of GPS inside buildings is often too poor to allow fast detection, and it is not precise enough to allow location down to the room level.

A few commercial systems offer in-home positioning services. These systems usually rely on a series of sensors that receive signals from portable radio beacons. They then calculate their position based on the signal strength or the time difference of the received signals. However, most systems are proprietary and not intended for private users. One promising tool within this category is the DecaWave DWM1000 [2], which claims to have a detection accuracy of up to 10 centimeters indoors. Unfortunately, I couldn't find any manufacturer-independent information on its suitability for everyday use.

But what about Bluetooth?

Bluetooth as an Alternative

My next attempt was to explore the possibility of room location using Bluetooth beacons and Happy Bubbles [3] Bluetooth detectors, with one sensor in each room. The detectors have open source firmware and include the software necessary to collate the values measured by the individual detectors and determine the spatial position of the Bluetooth beacons.

Unfortunately, real-world application of this technique comes with some complications. For example, the firmware on the Bluetooth module used by the sensors had a bug that caused the Happy Bubbles detector to crash if it received too many Bluetooth signals within a certain period of time. Although the latest hardware revision fixes the problem, older modules are difficult to update.

What is even more problematic is the fact that the signal strength of the Bluetooth signals generally fluctuates, even if the user does not move at all. In fact, it can happen that the Bluetooth beacon is close to the sensor, but the sensor reports that it is very far away, thus causing the software to detect a transition to another room and switch off the light.

This effect is amplified when the owner sits in an unfavorable position relative to the sensor, thus shielding the signal. The human body mainly consists of water, which absorbs radio waves at a frequency of 2.4GHz very well. If you sit in the way, you can expect the room to get dark again.

My Own Sensor Platform

Given the complications of commercial alternatives, I decided to try my own approach. As a starting point, I decided on the ESP32 [4] as the hardware platform. For just EUR10, this microcontroller offers two integrated 240MHz processor cores and 512KB RAM. It also has a 2.4GHz wireless module, which it uses to communicate with other WLAN and Bluetooth devices.

The power is supplied via a micro-USB port, which also serves as a virtual serial interface for writing your own programs to the flash memory of the microcontroller and tracking the output.

You cannot install Linux on the ESP32 chip. You can, however, use a Linux-ready open source SDK called the IoT Development Framework (ESP-IDF,[5]) from the manufacturer Espressif [6]. The SDK is based on the real-time operating system FreeRTOS [7], as well as a number of other open source projects, and it provides the experienced hobby developer with easy access to the built-in hardware. Using the SDK means you won't have to deal with too many platform-specific details.

You can connect external components like temperature sensors, LEDs or – as necessary for this project – additional Bluetooth modules via various GPIO pins. My goal was to install an ESP32 in each room and use its integrated Bluetooth module to measure the signal strength of the received Bluetooth beacons. In addition, I wanted to connect two more HM-10 Bluetooth modules to each ESP32 (Figure 1) and strategically distribute them in the rooms to enable ideal reception of the Bluetooth signals.

Figure 1: The ESP32 microprocessor (left) is connected to an HM-10 Bluetooth module on a plugin board for test purposes.

Connecting the Bluetooth modules requires four connections: Ground, supply voltage (3.3 volts provided by a voltage converter integrated on the ESP32), and one transmit and one receive line each for bidirectional communication.

The firmware [8] developed for the ESP32 communicates with the HM-10 modules via a serial interface. The modules offer all their functionality via AT commands, which some people may still be familiar with from analog modems (Figure 2). Thus, the AT+DISI? command enables receive mode, whereupon the HM-10 module returns a list of detected Bluetooth beacons, including their signal strength.

Figure 2: The firmware outputs log entries on the serial console: This excerpt shows the scan results for one of the Bluetooth modules.

The scan results initiate an OK+ DISIS. Each individual result starts with OK+DISC and contains the Bluetooth MAC address (for example cfa16a361b93) and the signal strength (about -66dBm). When all results are transmitted, the ESP32 receives a line with the contents OK+DISCE. This line marks the end of reception and the beginning of the next scan process.

An application must collect the sensor data in order to process it. The MQTT message bus protocol, which enjoys great popularity in the IoT sphere, does this job. Any number of MQTT clients log on to the central MQTT broker and exchange information via publish-subscribe messages. Each message has a topic that determines which clients receive the message. The ESP32 modules publish their sensor results every second with the topic happy-bubbles/ble/Hostname/raw/MAC. Hostname stands for the name of the ESP32 sensor, and MAC stands for the Bluetooth MAC address of the beacon.

The name of the topic has a historical meaning in my case, because I gradually switched my sensor network from Happy Bubbles sensors to my own hardware. An MQTT client like MQTT.fx (Figure 3, [9]), which is based on Eclipse Paho [10], finds out which messages are routed through the MQTT broker. RPM and Deb packages for MQTT.fx v1.6.0 are available online [11].

Figure 3: MQTT.fx displays the messages that the MQTT broker receives from the sensors.

Once the MQTT broker has collected all sensor results, another software component evaluates them. The Bluetooth Beacon Presence Detection Server (Presence, [12]) which is written in Go, logs on to the MQTT broker as an MQTT client and receives the sensor data from it.

Based on signal strength, Presence decides on the room in which each user's beacon is most likely found (Figure 4) and publishes its own results via MQTT.

Figure 4: The room map shows the location of the Bluetooth beacon. The smaller the circle around the sensor, the closer the beacon is to the viewer.

The MQTT broker then sends the exact room position of the residents in real time to the home automation tool Home Assistant [1]. A template sensor calculates one of the following states for each room:

  • At least one person is in the room.
  • Nobody is in the room (but in one of the others).
  • No one is home.

The Home Assistant rule would look like Listing 1.

Listing 1

Anybody Home?


Other automation rules now access this state and control the heating, for example, so that the temperature in the kitchen rises to 21 degrees Celsius when someone is in the room. If someone else is in the apartment, the Home Assistant reduces the temperature to 19 degrees (Listing 2).

Listing 2

Heating Depending on Location


For lighting control, Home Assistant starts a timer on leaving a room that switches off the light after five minutes. If someone enters the room during this time, the timer stops (Listing 3).

Listing 3

Lighting Control



Commercial Bluetooth sensors have proven their value in practical applications. However, even a tiny error can cause complications. For example, if the light goes out due to an inaccurate reading, the user is left suddenly sitting in the dark.

The solution described in this article, which is based on the ESP32 hardware platform and the Home Assistant open source automation framework, offers an alternative approach that could improve your chances for keeping the room lit, and along the way, you just might learn a little more about Bluetooth, MQTT, and home automation.

The Author

Gunnar Beutner has been developing software since 1994. At Netways, he discovered Icinga 2, which is now his favorite project.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • WiFi Thermo-Hygrometer

    A WiFi sensor monitors indoor humidity and temperature and a Node-RED dashboard reports the results, helping you to maintain a pleasant environment.

  • Home Assistant

    Home Assistant brings an open standards approach to home automation and control.

  • Bluetooth Communication

    We use a Raspberry Pi, a Pi Pico, and a smartphone to communicate over Bluetooth.

  • Home Assistant with MQTT

    Automating your four walls does not necessarily require commercial solutions. With a little skill, you can develop your own projects on a low budget.

  • IoT with RabbitMQ

    Connect multiple protocols and servers together on your IoT projects.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More