This demo app demonstrates how easy it is to get an app up and running, which communicates with Bluetooth LE devices! It currently can be used with Chrome browser on iOS and Android, Mac, and Linux. The Windows version of Chrome browser still seems to have some troubles with connecting to a BLE device and this demo won't work with it. However, pre-paired devices such as a FitBit seem to work.
Step 1: Offline Capable PWAIf you have not yet, istall nodejs on your develpment machine: https://nodejs.org/
To generate a stub of our app, I used the angular cli, which you can now install by running:
npm install -g @angular/cli
We are almost done! You can create now a empty app to which we will add the offline capabilities.
ng new my-offline-blle-app
Last step is to add a service worker to our project.
ng add @angular/pwa --project my-offline-blle-app
To pretty up your your app, you can add responsive framework such as bootstrap or google materials.
Link to full fledged guide to pwa with angular by its maker google: https://angular.io/guide/service-worker-getting-started
Step 2: About Web BluetoothWith this demo I used a GATT Server Emulator for Android: nRF Connect for Mobile (https://goo.gl/UpMq4d). After installation, setup a advertiser, adding at least a UserService to it, which is what this demo app uses inside its code. Then, start a GATT Server by enabling the sample configuration.
All the logic for connecting and reading data with Web Bluetooth is inside the app.component.ts file.
First, I check if the Bluetooth api is present. Then start a request with a specific service as filter. "requestDevice" returns a promise that can be chained with the following commands. In the next step we request that service from the server object. Then a specific characteristic and return that for the next chained function where we read the value itself. The last bit converts it into a human readable string. Tada! :-)
public connect() {
var self = this;
var nav: any = navigator;
if (nav.bluetooth && nav.bluetooth.requestDevice) {
nav.bluetooth.requestDevice({ filters: [{ services: [self.service] }] })
.then(device => {
console.log("requestDevice", device);
/* ... */
console.log("device name", device.name);
return device.gatt.connect();
})
.then(server => {
console.log("server", server);
// Getting Battery Service...
return server.getPrimaryService(self.service);
})
.then(service => {
console.log("service", service);
// Getting Characteristic...
return service.getCharacteristic(self.characteristic);
}).then(characteristic => {
console.log("characteristic", characteristic);
// Reading Battery Level...
return characteristic.readValue();
})
.then(value => {
console.log("value", value);
let decoder = new TextDecoder('utf-8');
let name = decoder.decode(value)
this.outputvalue = name;
this.lastupdate = new Date().toJSON();
console.log('value is ' + name);
})
.catch(error => { console.log("webbluetooth error", error); });
}
}
Great samples about how to use Web Bluetooth are lised on: https://googlechrome.github.io/samples/web-bluetooth/
Step 3: DistributionI use a free web app plan on azure to host my code: https://pwablle.azurewebsites.net
The advantage of it is, that we get free SSL out of the box, which is required for Web web Bluetooth to work. It also integrates nicely into Visual Studio Code with a extension.
The cli command...
ng build --prod
... generates all the files needed to distribute your app. It puts the files into the /dist subfolder (or /dist/my-offline-blle-app for some). The content of that folder need to be uploaded to azure. The web.config file contains configuration that is required for azure or iis based hosting only.
I am looking forward to your comments or questions. :-)
Related Linkspwablle (this app):
https://pwablle.azurewebsites.net
Bluetooth LE:
http://blog.bluetooth.com/a-developers-guide-to-bluetooth
Progressive Web Apps:
https://developers.google.com/web/progressive-web-apps
Service Worker:
https://developers.google.com/web/fundamentals/primers/service-workers/
https://serviceworke.rs (Cookbook)
Comments