Fitness Apps with Web Bluetooth

Andre Bandarra
Dev Channel
Published in
5 min readFeb 20, 2017

With the launch of Chrome 56, users can select nearby Bluetooth Low Energy devices to provide to web sites that use the Web Bluetooth API. This opens the opportunity to create types of web applications that were only available to native platforms.

For a great introduction on how to implement applications on the browser using Web Bluetooth, check François Beaufort’s “Interact with Bluetooth Devices on the Web” article.

Building a Rowing Monitor

Many fitness tracking applications track exercises by connecting to Bluetooth enabled devices, such as Health Monitors and Treadmills. Due to the previous lack of Bluetooth connectivity on the browser, those applications are, in most cases, developed using native platforms. With Web Bluetooth now being available, it becomes possible to connect and log exercises in real-time, from the browser. So, I decided to give it a try and build such application for my rowing machine.

The machine in question is a Concept2 Model D, but the most important part is it’s PM5 monitor. The monitor is BLE enabled, and, in fact, Concept2 offers native applications for both Android and iOS. A quick search on Google took me to the protocol used by the monitor.

The resulting application is hosted here, and the source code is publicly available on GitHub.

Connecting to the Monitor

The PM5 specification outlines 4 different Bluetooth GATT services on the device: The Information, Discovery, Control and Rowing services. The Discovery service is the one that announces the device, so we need to pass it as a filter for the connection.

The PM5 advertises itself using the discovery service, so this is the service we must use to filter our connection. The characteristics we want to use are accessed through the other services. In order to have access to those services later, we need to pass them as optionalServices when requesting the device.

Selecting a device

When the application requests the device, the user needs to authorize the application’s access to the bluetooth device. In order to provide this authorization, the browser will open a native interface, showing the devices that are compatible with the requested configuration. This dialog doubles both as a request for the application to access the bluetooth and a device selection screen!

For developers who have gone through the process of developing a Bluetooth application on native platforms, this is very welcome news: On most platforms, developers have to build an interface that deals with device scans and handles the user selecting the devices by themselves. In fact, on the Web, it’s impossible for the app to connect to a device without the user explicitly selecting it.

Accessing characteristics

There are 2 ways to access characteristics. It’s possible to request them at any time for the application and, more interesting to our objectives, sign up for notifications for when a characteristic changes.

Then, retrieve the characteristic itself. Call characteristic.startNotifications and setup an eventListener to get updates on the characteristic.

Some characteristics will have values that are strings. The serial number characteristic, from the Information Service is one example. Here’s how a developer can parse a characteristic like this.

On the Rowing Monitor, most characteristics are made of data. The specific format for that data is specified on the documentation, and it can can be accessed from the event object, in the form of a DataView. Here’s how a developer can parse such data.

Always test on multiple devices

The Bluetooth LE stack doesn’t support parallel access to the API yet. On some operating systems, the bluetooth stack implements a queue and serializes the calls to the API. But on Android the OS does not queue the calls and it’s up to the application developer to manage the queue. For more context around this, check this Github issue, where it’s under active discussion.

This leads to an interesting problem when developing using Web Bluetooth: A developer may create an app and not care about serializing the calls to the API. The application would work flawlessly on a Mac OS, but fails on Android, with error messages that are not so obvious.

Developers can implement their own queue to serialize API calls, or carefully design their application so that parallel calls don’t happen. It’s also important to test the application on multiple Operating Systems to make sure apps behave properly.

Look mom, no internet!

An application without access to the internet can be a dull application. But the Rowing Monitor takes advantages of Progressive Web App features such as Service Workers and IndexedDB to create an application that fully works offline: Once the user visits the website for the first time, the service worker is installed and it fully caches the application for offline usage.

The Rowing Monitor’s service worker is generated during build time, using the sw-precache library. Here’s what the service worker generator task looks like in Gulp:

The workouts are persisted using IndexedDB, so even if the user doesn’t have connection the application is fully functional. The data is only persisted locally, but the application could be easily extended to offer the user the chance to login and persist the workout data to a remote server, once it is online.

Almost there!

The Web Bluetooth API offers the functionality needed to connect and gather information from Bluetooth enabled devices, but there’s still one thing missing to transform the Rowing Monitor into a fully functional fitness tracker.

When using the application to track an exercise, the screen may go to sleep after a few seconds and the bluetooth connection may be lost. This is due to the lack of a Wake Lock API. Fortunately, such a Web API is already under discussion on W3C.

In fact, Chrome already implements an early version of the API, and it can be enabled by activating Chrome’s experimental features flag. To activate it, go to chrome://flags/#enable-experimental-web-platform-features and click Enable.

The Rowing Monitor encapsulates the Bluetooth protocol inside the pm5.js class, which exposes a connect method and a disconnect event. Here’s how a developer could use this API to acquire a WakeLock when the device connects to a device and release when it is disconnected.

Conclusion

The potential of integrating fitness equipment with Web Bluetooth is amazing. Imagine someone arriving to the gym and instead of having to download a full app to track the exercise, they can just receive the URL through a Physical Web Beacon, scan a NFC tag or a QR code, and the application is made available instantly — no download involved.

It also opens the possibility of deeper integrations. The Rowing Monitor application, for instance could be evolved into an online racing application, a game or a VR experience that lets users row at different parts of the world.

Another application worth checking is https://kinomap.tv/, which lets a user sync a YouTube riding video with a smart trainer, using Web Bluetooth.

Originally published at bandarra.me on February 20, 2017.

--

--