Presence detection with iBeacons
Currently Bluetooth Low Energy (BLE) or iBeacons becomming more and more popular. A typical or often mentioned application scenario here is the position or presence detection.
One advantage is that BLE has been greatly improved over “normal” Bluetooth in terms of power consumption. Instead of a few seconds to establish a connection you only need milliseconds. Together with various other protocol optimizations, this results in extremely low energy consumption.
A typical scenario is that iBeacons are distributed throughout the house, the mobile phone constantly scans for the beacons and calculates how far away each beacon is based on the signal strength. This information is then sent to a server.
This variant has however 2 weak points. First, the BLE signal varies in strength extremely and is only partially suitable to calculate the position and second, the phone consumes quite a lot of power when it scans every second and sends the data via Wi-Fi to a server.
For my implementation, I have chosen the reverse way. My mobile phone sends a BLE advertising message as soon as it detects the home WLAN. This happens about 10 times a second with the LOW BLE Profile. Despite this frequency, the battery is hardly charged because BLE advertising messages are extremely short. During the day, it is not even 2% of the battery capacity. As a receiver, I have decided on the newly released Raspberry Pi Zero W which can be obtained via the German distributor pi3g.
This “mini” PC consumes only 0.7 watts and provides BLE and Wi-Fi. Overall, I have distributed 15 of them in all rooms. They do nothing but scan permanently for BLE Advertising messages and then send that data to a central server. If you do not find any messages, they do not send anything to the server, which avoids unnecessary WLAN traffic. Due to the LOW profile, my mobile must also be at least in the next room to be recognized at all.
My server application is written in Java and runs as a Tomcat application. All raspberries are connected via web sockets to minimize reporting latency and network traffic.
To alleviate the aforementioned first problem, the strong signal fluctuation, there are various approaches that I have implemented in my application.
- The server synchronizes all Raspberries to measure within the same 1 second time window. In this way, one has the certainty that all received signals were influenced by the same currently occurring disturbances. This is done by sending messages to the Raspberries via websockets in which interval they should be sent, and every time after you have sent, they also tell you how much it was too late. In this way the accuracy is between 1ms and 20ms. The remaining inaccuracy comes from strongly fluctuating network latencies that unfortunately can not be compensated.
- The server stores spatial relationships. That when I’m in the living room I can completely ignore signals in the bedroom because it’s not directly accessible from the living room. In this way you can ignore signal peaks from unreachable rooms.
- Once you enter a room, you have a strong signal. This strong signal “activates” the room. Now the room remains active until another strong signal activates an adjoining room. In the meantime, the room remains active even if the next room sends a stronger signal for a short time than in its own room.
- Purely arithmetically, at a transmission frequency of 10 Hz, 10 BLE messages would have to be received every second. I interpret the number of received messages as a kind of probability that the average signal is correct. This probability is now used to interpolate between the last measured signal and the currently measured signal.
Example: The last measured RSSI value was -70db. Now I measure an average RSSI value of -80db for 3 received messages. The difference between old and new signal is -10db. My new final value is now 73db. At 6 received messages it would be 76db and at 10 received messages it would be -80db.
The combination of these approaches gives a relatively stable and also fast (1-2 sec) presence detection.
Of course, in order to enable and visualize all these calculations, additional information must be stored in the server. These are the own floor plan as SVG file, the position of the individual trackers in the house as well as the mobile phones to be tracked.
The actual visualization is implemented as a web application which displays the stored SVG file. Communication with the server takes place via websocket. This sends in regular intervals the exact coordinates of the active areas which are then highlighted in the SVG.
Of course, the actual application is not in the visualization. Instead, I send the recognized rooms via REST API into my openHAB System system to process it there.
Currently I use a additional App which can send iBeacon signals. In the near future, however, I will replace this with my own, which automatically does this as soon as my own WLAN is detected.
Later, I’ll be releasing my server application as well as my Android app on GitHub.