Take flight with a PWA

by Carl Vuorinen / @cvuorinen

Carl Vuorinen

@cvuorinen
cvuorinen
cvuorinen.net

citydevlabs.fi/rekry

WHAT?



Control drone with Bluetooth Web API
Taking input from Device Orientation API


  • Using RxJS to map input to output

But, WHY?

Goal: Controller that anyone could
just pick up and start flying
(without any prior experience)

Parrot Mini Drones


parrot.com/drones

Disclaimer

THE PRESENTER SHALL NOT BE LIABLE FOR ANY CUT FINGERS, LOST DRONES, BROKEN WINDOWS, OR ANY OTHER INCIDENTAL, INDIRECT, PUNITIVE, SPECIAL OR CONSEQUENTIAL DAMAGES WHATSOEVER ARISING OUT OF USAGE OF THESE CODE EXAMPLES OR THE PROGRESSIVE WEB APP WITHOUT PROPER SUPERVISION, EVEN IF THE PRESENTER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

Web Bluetooth API


Usages

Web Bluetooth API


Browser support:


caniuse.com/web-bluetooth

Web Bluetooth API


navigator.bluetooth.requestDevice(options)
  .then(device => { /* ... */ })
  .catch(error => { console.log(error) })

Web Bluetooth API


Web Bluetooth API


navigator.bluetooth.requestDevice(options)
  .then(device => device.gatt.connect())
  .then(server => { /* ... */ })
  .catch(error => { console.log(error) })

The Generic Attributes (GATT) define a hierarchical data structure
that is exposed to connected Bluetooth Low Energy (LE) devices.

Web Bluetooth API


navigator.bluetooth.requestDevice(options)
  .then(device => device.gatt.connect())
  .then(server => server.getPrimaryService('battery_service'))
  .then(service => { /* ... */ })
  .catch(error => { console.log(error) })

Web Bluetooth API


navigator.bluetooth.requestDevice(options)
  .then(device => device.gatt.connect())
  .then(server => server.getPrimaryService('battery_service'))
  .then(service => service.getCharacteristic('battery_level'))
  .then(characteristic => { /* ... */ })
  .catch(error => { console.log(error) })
Are we there yet?

Web Bluetooth API


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 => { /* ... */ })
  .catch(error => { console.log(error) })

Web Bluetooth API


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 => {
    console.log('Battery percentage is ' + value.getUint8(0))
  })
  .catch(error => { console.log(error) })
value comes in a DataView object (binary ArrayBuffer)

Web Bluetooth API


navigator.bluetooth.requestDevice(options)
  .then(device => device.gatt.connect())
  .then(server => server.getPrimaryService('heart_rate'))
  .then(service => service.getCharacteristic('heart_rate_control_point'))
  .then(characteristic => characteristic.writeValue(Uint8Array.of(1)))
  .then(_ => {
    console.log('Value has been written.')
  })
  .catch(error => { console.log(error) })
value comes in a DataView object (binary ArrayBuffer)

Web Bluetooth Security


  • HTTPS only
  • User Gesture Required
    (touch/mouse click)

Parrot Bluetooth API

write('fa00', 'fa0b', [4, ++fa0b, 0, 4, 1, 0, 0x32, 0x30,
  0x31, 0x34, 0x2D, 0x31, 0x30, 0x2D, 0x32, 0x38, 0x00]);
???

Device Orientation API

DEMO

THE END


Questions?


@cvuorinen

Links