Start Building with Web Bluetooth and Progressive Web Apps
Controlling the Bluetooth-Enabled World from the Comfort of the Web
A Short Introduction
Web
Bluetooth is a a new technology that connects the Web with the Internet
of Things. Web Bluetooth is so new, it’s still being built and
prototyped! But of course, that doesn’t mean we can’t play with it…
Essentially,
Web Bluetooth lets you control any Bluetooth Low Energy device (smart
home appliances, health accessories like heart rate or glucose monitors,
temperature sensors, etc.) directly from your PC or smart phone,
without having to install an app first.
Web
Bluetooth will eventually enable developers to build one solution that
will work on all platforms, including both mobile and desktop, which
means lower development costs, more open source control interfaces for
various physical products, and more innovation.
In
this post I will explain the basics of Web Bluetooth by building a demo
web app that controls the smart bulb that I reversed engineered in the previous post.
In addition, I’ll explore how you can extend this app to become a
Progressive Web App, which is an exciting new approach that we’ll go
into later in the post.
I
will assume for this tutorial you have basic familiarity with Bluetooth
Low Energy terms such as Peripherals, Services and Characteristics — if
not, check out the previous post to learn about them.
You
might be thinking, “But Uri, we can already send commands to the bulb,
and anyway doesn’t the bulb already come with an app?” Well, it does
come with an app, but does that app include voice control?
(It doesn’t, and I’m going to show you how you can build one that does.)
If you are impatient, you can see the code here or try the online demo (see next section for supported browsers/platforms). If you’d like more information about Web Bluetooth, check out this Google Developers article.
Can I use Web Bluetooth?
Currently it works only on Chrome on Android 6, Mac OS X (starting from Chrome 53 — currently in Beta channel), Linux and Chrome OS. However, things change rapidly, so it might be good to periodically check the implementation status page.
I’ll be using Chrome to build my web app in this demonstration. In order to use Web Bluetooth in Chrome, there are two options:
- The website has to be a part of a public experiment (“Origin Trial”) Chrome is running. You can register on this page. Once you enlist your website, all your visitors will be able to use Web Bluetooth from your site if they are using Chrome 53 and have a supported device / operating system.
- You can enable Web Bluetooth for all sites by going to chrome flags. Simply type “chrome://flags” in the address bar, search for “Web Bluetooth” and enable it (also applies to Android 6 users).
The Web Bluetooth API
The API is exposed under the navigator.bluetooth JavaScript namespace. Is it based on Promises, so make sure you are familiar with them first.
In
order to use Web Bluetooth, your site must be served over a secure
connection (HTTPS). A secure website is becoming a requirement for a
growing number of new web APIs, and it is fairly easy to set up one. One
way (which I use here) is using GitHub hosting, a.k.a gh-pages.
Building a Web Bluetooth App
This
is the sequence of actions that will be common that all Web Bluetooth
apps. Before seeing the code, let’s look at the sequence first:
- Scan for a relevant Device
- Connect to it
- Get the Service you are interested in
- Get the Characteristic you are interested in
- Read, Write or Subscribe to the Characteristic
Now for a code example — Connect to the smart bulb, and then write to it:
This code scans for a device with a Service number ffe5, then ask for this service, ask for characteristic number ffe9, and finally write four bytes: bb 25 05 44, which is the command for the bulb to slowly fade between all the rainbow colors and white, as I explained in the previous post.
Now,
how to run it: there are a number of ways to do this, but they’re all a
little tricky. You can paste the code above into Chrome’s Console once
you have enabled the web bluetooth flag, but this only works on
supported operating systems (i.e. Mac with Chrome Beta, Linux or Chrome
OS).
If you
have an Android 6 device, you can enable development mode, connect it to
the PC with a USB cable, and then in your Chrome on the PC go to the
following URL: “chrome://inspect”. This will open a Chrome Console that
will be connected to the Android device — which is how I tend to do it
on my Windows machine. Here is a page that explains this last method step-by-step.
You can check out the code for the demo app that controls the bulb in this example here. The code above lives in the connect() function.
Troubleshooting
If no devices show up, make sure that:
- Both Bluetooth and Location Services are turned on. On Android 6, both Bluetooth and Location access are required in order to scan for BLE devices.
- No other app is connected the target device. BLE devices stop advertising their services once some app is connected to them.
- If you still don’t see any device, try restarting chrome, turning Bluetooth off and then on again, or restarting your device.
You can find another example inside the Web Bluetooth standard specification document.
The example shows how to connect to a heart rate monitor device, read
the Service Location Characteristic (which tells you where the sensor is
placed — which body part), and subscribe to notifications from the
Heart Rate Characteristic, meaning you will get an event whenever the
device performs a new measurement. If you want to see a working example,
check out this demo on GitHub.
Interacting with the Internet of Things: Changing the Bulb’s Color
We’ve
seen some code that connects to the bulb and sends it commands, so
let’s now create a function that sets the color given red, green and
blue values:
Note
that the function assumes that we saved the reference to the
characteristic object that we got in the previous step in a global
variable called ledCharacteristic.
We
can connect to the device, and now we have a function with which to
change its color. As discussed int he last post, color component values
are defined as RGB values between 0 and 255. For example, to set the
color to purple, we would use:
setColor(255, 0, 255);
Now
that we have our underlying function, we can add buttons for various
color presets, or create a fully-featured color picker to let the user
set any color he desires. Or we can also…
Add Voice Control!
Since we’ve got the basic app functionality in place, let’s make it more interesting by adding voice control. This will use the Web Speech API. I’ll take a shortcut and use a tiny JavaScript library called annyang which provides a simpler interface to the Speech API.
Using the annyang library is as simple as listing all the voice commands that you want to implement, and then calling the start() method:
As
you can see, adding new commands is pretty straight forward. You can
experiment with adding new colors, an “off” command, or even more
interesting commands such as “random color”, “crossfade”, or “blink
rapidly”.
The
Chrome implementation of the Web Speech API uses the Google Cloud
services for recognizing the speech, so there is a delay of about 1
second until you get the results.
Calling
annyang.start() will request from the user a permission to access their
Microphone, so it can listen to their voice. In the actual app, I’ll
add a microphone button and call this method only after the user pressed
this button. After all, having a web page ask you for permission to use
your mic first thing when you load the page is pretty creepy, don’t you
think?
Finally, you probably noticed that I passed a continuous:true parameter to the start() method. This makes sure the function continuously listens for user commands, and not just the single time.
Making it a Progressive Web App
So
we can control the smart bulb from our browser, but what if we wanted
to control it from our phone, and not only from the browser on our
phone, but from an app on our phone? Enter the Progressive Web App.
In
a nutshell, Progressive Web Apps (PWAs) are websites that look, feel,
and — increasingly — function, like native applications. By taking
advantage of the awesome new capabilities we now have when developing on
the web (like Web Bluetooth!), we can now use things like service
workers to mimic native app capabilities like offline functioning,
notifications, and all sorts of neat stuff.
So since we already have an app to control the bulb, let’s see if we can turn it into a PWA.
To
pick a sample problem: what if I’m offline and want to change the color
of the bulb? Luckily, with PWA I can create a Service Worker that will
define the behavior of the app when the phone is offline.
(For
those of you who’ve been paying attention: you’re right, we won’t have
access to the voice control capability because of the Google Cloud
Speech API dependency, but that doesn’t mean we can’t still build in
some useful behavior!)
To
generate the service worker automatically, I will use a tool called
“sw-precache”. I won’t dive into the details here, but you can read
about it in this great blog post by my friend Wassim Chegam.
Additionally, I’ll add a manifest.json
file to set the icon and app title (for when users add our site to
their homescreens). This also creates a nice splash screen that is
displayed while the app is loading:
Having
both a service worker and an offline manifest file, together with the
fact the the site is served over HTTPS, results in a nice bonus — if a
user visits our web app frequently, he will get prompted automatically
by Chrome to add a shortcut to the app to his device’s home screen:
This feature is called App Install Banners. You can read more about it and the qualifying criteria in here.
Web Bluetooth and the Physical Web
In a previous post, I discussed all the cool things you can do with the Physical Web.
With the Physical Web, you can send a link to your website from a
Bluetooth beacon to a user’s device. With PWA, that link can be to your
web app that looks, feels, and functions like a native app. Then with
Web Bluetooth, you can then speak to the device!
One
interesting feature that is currently being developed is the ability to
hand off a device from the Physical Web to Web Bluetooth. As per the current specs,
if the user opened a link through the Physical Web, a reference to the
device where the link originated from will be available to the web page
through navigator.bluetooth.referringDevice.
This
means that the user won’t have to go through the device selection
dialog and pair with the device again — essentially bridging the gap
between the Physical Web and Web Bluetooth. All a user needs to do is
discover the web link for a nearby device using the Physical Web, then
the Physical Web will hand off the device to your web page once they
open the link, and you will be able to start communicating with the
device directly from that web page.
Pretty cool, right?
Other Notable Web Bluetooth Projects
Security:
always something we want to keep in mind. It isn’t too hard to think up
some good pranks you might want to pull with Web Bluetooth, but at the
same time there’s some more nefarious things the bad guys might want to
try with it, too. Luckily, the guys on the Chrome team are pretty smart,
and they’ve built security considerations into the platform. Jeffrey
Yasskin from the Chrome Team wrote a great post about the Web Bluetooth security model.
Although
it’s still a new technology, there are already some community projects
that take advantage of Web Bluetooth to control various devices. These
are some of my favorites:
- Sphero Ollie
- Web MiP
- Eddystone Beacon Configuration App — configures Physical Web beacons
- Parrot Mini Drone Controller
You can find a list of other Web Bluetooth projects here. And here are some more resources:
p.s.
— if you were worried at all about the security of Web Bluetooth, rest
assured: the Chrome team is already on it. Check out Jeffrey Yasskin’s great post about the Web Bluetooth security model to find out more.
Call to Action: Let’s Push Web Bluetooth Forward!
Build your own demos, share the with the community… make awesome stuff.
Another
small thing you can do to help push Web Bluetooth forward is to vote
for Web Bluetooth on Microsoft Edge. Even if you don’t use it, its
inclusion will help push the standard forward, making life easier for
everyone. You can vote for it up to three times on UserVoice.
If
you happen to find bugs, think of useful features, or have any other
feedback, I have it first hand that the Chrome team wants “Feedback
feedback feedback 😉” You can do so on their GitHub Issues Page.
DON'T FORGET TO SHARE THIS POST
Post a Comment