Did you know that your web sites can now talk to actual bluetooth devices around it? With new initiatives like the Physical Web and new APIs like Web Bluetooth, it’s now easier than ever to interact with hardware using nothing but Web technologies. In this talk, you will learn how to broadcast URLs to nearby devices and how to control hardware via bluetooth. All of this using plain old vanilla Javascript.
7. @joel__lord
#JSRemoteConf
Bluetooth
WHY USE IT?
• Named after Harald Bluetooth who was the
Viking king of Denmark between 958 and
970
• It’s present on most cell phones that were
manufactured in this millennium
• Uses a network of 79 bands of radio waves.
• The most recent standard (4.2) has a
theoretical speed of 2.1Mbps and range of
100 meters
• Devices can automatically detect each
other
• Can connect up to 8 devices at once
8. @joel__lord
#JSRemoteConf
Bluetooth
AVAILABLE IN MULTIPLE FLAVORS
• Bluetooth Basic Rate/Enhanced Data Rate (BR/EDR)
• More limited in range
• More suitable for continuous connections
• Bluetooth Low Energy (LE)
• Perfect for brief bursts of data
• Uses very low power
• Cheaper
10. @joel__lord
#JSRemoteConf
Bluetooth
GENERIC ATTRIBUTE PROFILE (GATT)
• A characteristic consists of
• a type (represented by a UUID)
• a value
• a set of properties indicating the operations the characteristic
supports
• a set of permissions relating to security.
11. @joel__lord
#JSRemoteConf
Bluetooth
ADOPTED SPECIFICATIONS
• Battery Service - org.bluetooth.service.battery_service (0x180F)
• battery_level: Read, Notify
• Heart Rate Service – org.bluetooth.service.heart_rate (0x180D)
• heart_rate_measurement: Notify
• body_sensor_location: Read
For more on Bluetooth specs: https://www.bluetooth.com/specifications/gatt
18. @joel__lord
#JSRemoteConf
Physical Web
WHAT WILL YOU NEED
• A URL that you want to broadcast
• Has to resolve to HTTPS and public
• Has to be less than 18 characters
• A phone or device that can receive nearby notifications
19. @joel__lord
#JSRemoteConf
Physical Web
CONFIGURE YOUR PHONE
• First, check that you have an active data
connection as well as Bluetooth and Location
turned on. The notification shade provides an
easy way to check that these requirements are
met.
34. @joel__lord
#JSRemoteConf
Web Bluetooth API
WHAT THE…?
• Available in Chrome 56 and Chrome for Android M
• Lets you:
• Request and connect to nearby Bluetooth devices
• Read and write Bluetooth Characteristics
• Receive GATT Notifications
• Know about disconnects
36. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• You will need a compatible browser
• Understanding of Promises
• A User gesture event
document.querySelector("button").addEventListener("click", _ => {
//User event
});
38. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• First, we need to connect to a device.
• Requires a mandatory service filter
navigator.bluetooth.requestDevice({ filters: [
{ services: ['heart_rate'] }
]})
.then(device => { /* ... */ })
.catch(error => { console.log(error); });
39. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• First, we need to connect to a device.
• Requires a mandatory service filter
navigator.bluetooth.requestDevice({ filters: [
{ services: ['heart_rate'] }
]})
.then(device => { /* ... */ })
.catch(error => { console.log(error); });
40. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• You can see all the devices but you will get an error later if you don’t
add a service filter
navigator.bluetooth.requestDevice({acceptAllDevices: true})
.then(device => { /* ... */ })
.catch(error => { console.log(error); });
41. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• First, we need to connect to a device.
• Requires a mandatory service filter
navigator.bluetooth.requestDevice({ filters: [
{ services: ['heart_rate'] }
]})
.then(device => { /* ... */ })
.catch(error => { console.log(error); });
42. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• First, we need to connect to a device.
• Requires a mandatory service filter
navigator.bluetooth.requestDevice({ filters: [
{ services: ['heart_rate'] }
]})
.then(device => { /* ... */ })
.catch(error => { console.log(error); });
43. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• You can *then* connect to the device and get information about this
device
navigator.bluetooth.requestDevice(options)
.then(device => {
// Human-readable name of the device.
console.log(device.name);
})
.catch(error => { console.log(error); });
44. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• Once you have a device, you can access the GATT server
navigator.bluetooth.requestDevice(options)
.then(device => {
// Attempts to connect to remote GATT Server.
return device.gatt.connect();
})
.then(server => { /* ... */ })
.catch(error => { console.log(error); });
45. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• Once you have a device, you can access the GATT server
navigator.bluetooth.requestDevice(options)
.then(device => {
// Attempts to connect to remote GATT Server.
return device.gatt.connect();
})
.then(server => { /* ... */ })
.catch(error => { console.log(error); });
46. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• And you can now access the service to get the desired characteristic
navigator.bluetooth.requestDevice(options)
.then(device => device.gatt.connect())
.then(server => {
// Getting Battery Service
return server.getPrimaryService('battery_service');
})
.then(service => {
// Getting Battery Level Characteristic.
return service.getCharacteristic('battery_level');
})
.catch(error => { console.log(error); });
47. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• And you can now access the service to get the desired characteristic
navigator.bluetooth.requestDevice(options)
.then(device => device.gatt.connect())
.then(server => {
// Getting Battery Service
return server.getPrimaryService('battery_service');
})
.then(service => {
// Getting Battery Level Characteristic.
return service.getCharacteristic('battery_level');
})
.catch(error => { console.log(error); });
48. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• You can finally read the value of the characteristic
navigator.bluetooth.requestDevice(options)
.then(device => device.gatt.connect())
.then(server => server.getPrimaryService('battery_service'))
.then(service => service.getCharacteristic('battery_level'))
.then(characteristic => {
// Reading Battery Level
return characteristic.readValue();
})
.then(value => {
console.log('Characteristic value: ' + value);
})
.catch(error => { console.log(error); });
49. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• You can finally read the value of the characteristic
navigator.bluetooth.requestDevice(options)
.then(device => device.gatt.connect())
.then(server => server.getPrimaryService('battery_service'))
.then(service => service.getCharacteristic('battery_level'))
.then(characteristic => {
// Reading Battery Level
return characteristic.readValue();
})
.then(value => {
console.log('Characteristic value: ' + value);
})
.catch(error => { console.log(error); });
50. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• When reading the value, it returns a ArrayBuffer which you need to
convert into an int value
navigator.bluetooth.requestDevice(options)
.then(device => device.gatt.connect())
.then(server => server.getPrimaryService('battery_service'))
.then(service => service.getCharacteristic('battery_level'))
.then(characteristic => characteristic.readValue())
.then(value => {
var intVal = value.getUint8(0);
console.log('Battery percentage is ' + intVal);
})
.catch(error => { console.log(error); });
51. @joel__lord
#JSRemoteConf
Web Bluetooth API
GETTING READY
• Or subscribe to the notifications
navigator.bluetooth.requestDevice(options)
.then(device => device.gatt.connect())
.then(server => server.getPrimaryService('battery_service'))
.then(service => service.getCharacteristic('battery_level'))
.then(c => {
// Set up event listener for when characteristic value changes.
c.addEventListener('characteristicvaluechanged', console.log);
})
.catch(error => { console.log(error); });
54. DOCUMENT CONFIDENTIEL, TOUT DROIT RÉSERVÉ
PRESENTED BY
That’s all folks !
JOEL LORD
March 17th, 2017
TWITTER: @JOEL__LORD
GITHUB: HTTP://GITHUB.COM/JOELLORD