Location Awareness in IoT with Beacon Technology

In this article I’ll share the findings of my feasibility tests for implementing a location service with Bluetooth beacon using iOS and Linux-powered devices. I’ll be very detailed for two reasons: on the one hand, because location is a key element and the biggest challenge in my current project, on the other hand, because I want to provide my findings to support other people building their own solutions using beacon technology. Find links to the github repositories of my example iOS apps in the Resources section.

With my entry for the eclipse Open IoT Challenge I want to build an IoT solution that integrates resources that are available in the current context. The physical relationship between IoT devices establishes the spatial context of a service integrating them. For a complete overview of the project see my previous post on Medium: Autonomy Of Things

If I am in a room with a wireless speaker and a wall panel, I want to be able to select my favourite audio streams on that panel. If a different person is in the room with the wall panel, the hardware resources could serve a different purpose — in my project, it will reconfigure itself to a weather panel.

To determine the location of a service’s owner (i.e. the user), some location awareness technology must be put into effect. Since I don’t want to wear an extra wristband or another special device, I decided to go with the thing most of us carry around anyway: the mobile phone.

Most modern mobile phones are equipped with Bluetooth 4.0 Low Energy — a technology that allows to scan a physical environment for so called beacons. A beacon is a Bluetooth device, that periodically broadcasts a specific ID. By measuring the strength of the incoming signal, a receiver would not only be able to identify specific devices by their ID, but can also estimate the distance to them from the strength of the radio signal.

To implement a beacon-based location solution, I have considered two different approaches that I wanted to test before integrating them into the project:

  1. The mobile device broadcasts beacons, that can be received by nearby IoT devices to determine whether the service owner is in the proximity of resources that can be dynamically integrated into the solution.
  2. The IoT devices broadcast beacons, that can be received by the mobile phone of the service owner and trigger a reconfiguration of the service according to nearby available IoT devices.

Receiving beacons emitted from mobile devices with Linux-powered IoT

There are different specifications of the beacon advertising data — a popular one is the iBeacon specification. Receiver and Transmitter obviously have to be able to use the same specs. Apple has integrated transmitter capabilities in its CoreLocation framework, so it is fairly easy to build an iBeacon sending mobile app. Although, this approach has a catch — and quite a big one for my intended purpose, since I want to be able to seamlessly detect the location of a user and his distance to surrounding devices in order to start a user-specific reconfiguration of the devices, which requires a permanent location device monitoring. That’s where it gets tricky: iBeacon transmitting apps work well in foreground, but put into the background, they stop sending data.

While researching feasible workarounds, I found this article that proposes to advertise an ID by sending just Bluetooth Low Energy (BLE) data packages, regardless of the iBeacon protocol. The Apple CoreBluetooth framework allows this. That way it wouldn’t be possible to use specific iBeacon receivers, but since I would implement my own receiver in the external hardware devices, this wouldn’t be a problem. To scan and process BLE advertising data, I used standard software that is freely available — the bluez Bluetooth software stack. I installed it on the Raspberry Pi running Raspbian:

$ sudo apt-get install bluez bluez-hcidump

The app was configured to transmit BLE advertising data:

NSDictionary *advertisingData = @{CBAdvertisementDataLocalNameKey:@”BLE Beacon Test”,
@[[CBUUID UUIDWithString:@”123F0000–503E-4C75-BA94–3148F18D941E”]]};

[_peripheralManager startAdvertising:advertisingData];

Now I will scan for the beacon:

$ sudo hcitool lescan --duplicates
LE Scan …
7A:1B:F2:B1:B9:EB (unknown)
7A:1B:F2:B1:B9:EB BLE Beacon Test
C0:28:8D:83:75:9E (unknown)
7A:1B:F2:B1:B9:EB (unknown)
7A:1B:F2:B1:B9:EB BLE Beacon Test
D3:51:FC:ED:FE:DD (unknown)
D3:51:FC:ED:FE:DD estimote

There it was: the beacon name I assigned previously. But now I had to face the next problem: If I put the iOS beacon app into the background by pressing the home button, this name will disappear and only the Bluetooth MAC (7A:1B:F2:B1:B9:EB) could be used to identify the beacon. But no, it can’t be used for identification, because this MAC will change when I re-launch the app (privacy protection). So this sort of scan is not sufficient to detect the beacon, i.e. the first approach to get location information with beacon technology doesn’t work for my project.

As a side note — if you’re experimenting with BLE scanning your home, and you might encounter the following error message from the hcitool:

Set scan parameters failed: Input/output error

In most cases this error can be fixed like an old misbehaving windows system — just turn it off and on again:

 $ hciconfig hci0 down
$ hciconfig hci0 up

Receiving iBeacons with iOS mobile devices

For the alternative way of getting the location of nearby devices I will scan for BLE beacons with an iOS app. If it finds a beacon that is registered to my location service, the app will call a web service and relay that information.
This time I stick to the iBeacon format, because for the narrow goal of this project it would be sufficient to recognize whether the mobile phone is near the wall panel. I will build this using a Raspberry Pi with a few user interaction elements attached. This device also has USB connectors — I add Bluetooth connectivity to the Pi with a mini Bluetooth dongle [image](image) (actually, I already did this for the previous tests).
To broadcast beacons, I also need software. I have the IoT framework Eclipse Kura running on the Raspberry Pi, and, lucky me, the Eclipse marketplace has a package for iBeacon advertising. So I just drag and drop the add-on into my Kura window to install the package:

Easy installation: drag packages from Eclipse marketplace into the Kura Web-UI

In the configuration for the iBeacon I add the UUID, for which I register monitoring in the iOS app. I define arbitrary values for the major and minor number. Finally, I activate the Beacon and turn my focus to the location service.

Minimal iBeacon configuration: set UUID, major, minor & bluetooth-adapter arguments

Each time the beacon scanning iOS app detects a transition into or out from the proximity range of a beacon, it will invoke a call to a webserver. The beacon ID and the subject ID (that is tied to the mobile phone) get passed as URL arguments. The webserver will then evaluate the incoming data and eventually trigger the reconfiguration of the affected devices.

To complete the test, I set up a small nginx webserver in a virtual server instance of the Shmoogle compute engine. The (temporary) IP gets compiled into the iOS beacon locating app. Then I display the server logfile to monitor web service calls, while I enable and disable the iBeacon service to simulate moving towards and then away from the beacon:

$ tail -f /var/log/nginx/access.log

What comes next

For the purpose of my project, I’ll go with the second approach, because it proved much more stable than the first one, where the emitter of the person’s location is an iOS device, that is currently not able to broadcast beacons permanently. It stopped sending data after a few hours. For future iterations, I might consider one of the small key-finder Bluetooth tags as a person-bound location emitter. Those little devices are fairly cheap and broadcast their location without interruption. But for now I will implement an iBeacon detecting iOS app that communicates the beacon-defined location to a web-service.

One thing I did not mention in this article is the privacy aspect of a location service implementation. Every user who uses location services should be able to control his or her data, the circumstances in which other services are able to locate him or her, and the parties whom he or she wants to share this data with. But since I only cover the feasibility testing here, I’ll keep those concerns in mind when developing the project further.

In the next article I will connect a small TFT display to an IoT device and add some buttons and knobs to it. Stay tuned to find out more about the building steps of my wall panel: a wall-mount Human-Machine-Interface for IoT!

Make sure you won’t miss any updates — subscribe right now!