let's get physical
TRANSCRIPT
www.spiria.com
Let’s Get Physical
Presented By
JOEL LORD
JS Remote ConfMarch 15th, 2017
www.spiria.com
Let’s Get Physical
Presented By
JOEL LORD
JS Remote ConfMarch 15th, 2017
@joel__lord#JSRemoteConf
JOEL LORDAboot me, eh?
• Javascript Junkie• Tinkerer• Technology enthusiast
@joel__lord#JSRemoteConf
Agenda
• What is Bluetooth• The Physical Web• Web Bluetooth API• Demos, code and lots of fun!
@joel__lord#JSRemoteConf
Agenda
• What is Bluetooth• The Physical Web• Web Bluetooth API• Demos, code and lots of fun!
What’s the fuss about?BLUETOOTH, BLE, PHYSICAL WEB
@joel__lord#JSRemoteConf
BluetoothWHY 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
@joel__lord#JSRemoteConf
BluetoothAVAILABLE 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
@joel__lord#JSRemoteConf
The Generic Attributes (GATT) define a hierarchical data structure that is exposed to connected Bluetooth LE devices.
@joel__lord#JSRemoteConf
BluetoothGENERIC 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.
@joel__lord#JSRemoteConf
BluetoothADOPTED 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
What’s that?PHYSICAL WEB
@joel__lord#JSRemoteConf
The Physical Web is an open approach to enable quick and seamless interactions with physical objects and locations.
@joel__lord#JSRemoteConf
Physical WebEDDYSTONE BEACONS
• An easy way to broadcast a URL• Makes it easy to interact with objects• Only requires something that can broadcast over Bluetooth (BLE)
@joel__lord#JSRemoteConf
Physical WebPOSSIBLE BEACONS
• Ready to use beacons
@joel__lord#JSRemoteConf
Physical WebPOSSIBLE BEACONS
• Ready to use beacons• Your own laptop
@joel__lord#JSRemoteConf
Physical WebPOSSIBLE BEACONS
• Ready to use beacons• Your own laptop• And, of course, a little touch of
Javascript
@joel__lord#JSRemoteConf
Physical WebWHAT 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
@joel__lord#JSRemoteConf
Physical WebCONFIGURE 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.
@joel__lord#JSRemoteConf
Physical WebCONFIGURE YOUR PHONE
• Swipe down on the notification shade when you first encounter a beacon. You will receive a notification alerting you about nearby web pages.
@joel__lord#JSRemoteConf
Physical WebCONFIGURE YOUR PHONE
• Tap on the notification to opt into future Nearby notifications. Opting in will take you to a list of nearby URLs
@joel__lord#JSRemoteConf
Physical WebCONFIGURE YOUR PHONE
• When you are near a beacon in the future, you will see a notification informing you of nearby URLs.
@joel__lord#JSRemoteConf
Physical WebSTILL NOT WORKING?
• Try to download the application ”Physical Web” from the Play Store
@joel__lord#JSRemoteConf
Physical WebAS FOR IPHONES?
• Dunno…
Try it and let me know: iOS
@joel__lord#JSRemoteConf
Physical WebBROADCAST THAT URL
• You will need• Compatible Bluetooth 4.0 USB adapter
(Macbook Pro)• NodeJs• See full list of requirements
@joel__lord#JSRemoteConf
Physical WebBROADCAST THAT URL
[SYS:~ jlord$ npm install eddystone-beacon
@joel__lord#JSRemoteConf
Physical WebBROADCAST THAT URL
var beacon = require("eddystone-beacon");var options = {
name: "MyBeacon" }; var url = "https://goo.gl/SuTBBh";
beacon.advertiseUrl(url, options);
@joel__lord#JSRemoteConf
Physical WebBROADCAST THAT URL
var beacon = require("eddystone-beacon");var options = {
name: "MyBeacon"};var url = "https://goo.gl/SuTBBh";
beacon.advertiseUrl(url, options);
@joel__lord#JSRemoteConf
Physical WebBROADCAST THAT URL
var beacon = require("eddystone-beacon"); var options = {
name: "MyBeacon" }; var url = "https://goo.gl/SuTBBh";
beacon.advertiseUrl(url, options);
@joel__lord#JSRemoteConf
Physical WebBROADCAST THAT URL
var beacon = require("eddystone-beacon"); var options = {
name: "MyBeacon" }; var url = "https://goo.gl/SuTBBh";
beacon.advertiseUrl(url, options);
@joel__lord#JSRemoteConf
Physical WebBROADCAST THAT URL
var beacon = require("eddystone-beacon");var options = {
name: "MyBeacon"};var url = "https://goo.gl/SuTBBh";
beacon.advertiseUrl(url, options);
@joel__lord#JSRemoteConf
Physical WebTADA!
• You should see the notification on your phone• It’s really just that simple!
Web Bluetooth API
@joel__lord#JSRemoteConf
Web Bluetooth APIWHAT 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
@joel__lord#JSRemoteConf
Web Bluetooth APIWHAT THE…?
• Still experimental• Full specs here• Only Google implementing it so far• Security is a big concern
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING READY
• You will need a compatible browser• Understanding of Promises• A User gesture event
document.querySelector("button").addEventListener("click", _ => {//User event
});
@joel__lord#JSRemoteConf
Web Bluetooth APILET’S GET CODING
• Heart Beat Sensor
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING 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); });
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING 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); });
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING 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); });
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING 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); });
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING 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); });
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING 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); });
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING 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); });
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING 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); });
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING 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 Servicereturn server.getPrimaryService('battery_service');
}).then(service => { // Getting Battery Level Characteristic.return service.getCharacteristic('battery_level');
}) .catch(error => { console.log(error); });
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING 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 Servicereturn server.getPrimaryService('battery_service');
}) .then(service => {// Getting Battery Level Characteristic.return service.getCharacteristic('battery_level');
}).catch(error => { console.log(error); });
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING 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 Levelreturn characteristic.readValue();
}).then(value => { console.log('Characteristic value: ' + value);
}) .catch(error => { console.log(error); });
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING 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); });
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING 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); });
@joel__lord#JSRemoteConf
Web Bluetooth APIGETTING 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); });
Show me the real stuff !
QUESTIONS?
DOCUMENT CONFIDENTIEL, TOUT DROIT RÉSERVÉ
PRESENTED BY
That’s all folks !
JOEL LORDMarch 17th, 2017
TWITTER: @JOEL__LORDGITHUB: HTTP://GITHUB.COM/JOELLORD