SlideShare a Scribd company logo
1 of 118
Download to read offline
Bridging the web and the physical world
Kenneth Rohde Christiansen
Web Platform Architect
Hi! I am Kenneth
Danish - happiest people in the world
second most
Smart devices
What makes a thing "smart"?
Devices which are complicated or slow
to use, are they really smart?
➫ Solve a real issue
➫ Be there when you need them
➫ Ease to use, with low friction
I don't want to download your app,
I just want to do stuff
Now! Now! Nowww!
With many devices around usapps don't scale well
Too many icons!
Lack of overview
Lots of updates pending for stuff I never use!
Too many icons!
➫ Lack of overview
➫ Updates pending for stuff I
never use!
Let's look at usages
There are different common usages
- Everyday use turn on the light!
- Occasionally change temperature of my fridge
- Once paying for parking when travelling
Better model?
We want low friction and ease of use
Focus on speed
HTTP 2.0 push, Service Workers, PRPL pattern, streams, scrolling, CSS Houdini,
Compositing …
Fast with Service Worker caching
The web is up to task
https://www.youtube.com/watch?v=Dsv5NT4PYG0
But that can't be web?!
No address bar - super fast - icon on homescreen
We call that experience for
Progressive Web Apps
https://developers.google.com/web/progressive-web-apps/
Great for one-time use
The low friction of the web
Always handy if I want it to be
Add to homescreen
No clutter
Looks and acts like an app
And safe
But...
Copyright Club Skirts Dinah Shore Weekend https://commons.wikimedia.org/wiki/File:White_Diamonds_Party.jpg
Devices live outside the
sandbox
And yes, the web can do that too!
Keep in mind
Users and companies don't care about
how stuff works, it should just work
Two great technologies
But first, it might make sense to listen
You can actually win stuff!
Lars and Coldfront has joined up for a quiz!
More on that later!
WebLight
Advantages
Widely used, Low energy, Wireless
Advantages
Cheap, Easy to use, Beacon functionality
Disadvantages
Security (just radio waves), Not powered,
Stability, Speed
https://www.youtube.com/watch?v=fBCPA9gIxlU
➫ Based on Bluetooth 4+ (Low Energy) GATT protocol
➫ Easy to use, modern web API
➫ Uses promises and typed arrays (ie. Uint8Array etc)
➫ No Classic mode support
➫ Only Central, not Peripheral
Chrome only for now
Drawing by Noa Lee Shaked
An example
HTTPS only
User Gesture required to request device
https://www.youtube.com/watch?v=Fb_Pgf3rCdA
Requesting device
navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
.then(device => { /* ... */ })
.catch(error => { console.log(error); });
navigator.bluetooth.requestDevice({
filters: [{ services: [0x1234, 0x12345678, '99999999-0000-1000-8000-00805f9b34fb'] }]
})
.then(device => { /* ... */ })
.catch(error => { console.log(error); });
You may provide either the full Bluetooth UUID or a short 16- or 32-bit form, if not a standardized service
Standardized services are easy to connect to
Requesting device
navigator.bluetooth.requestDevice({
filters: [{ name: "Kenneth's robot" }],
optionalServices: ['battery_service']
})
.then(device => { /* ... */ })
.catch(error => { console.log(error); });
You can also search by advertized name. Services can be optional, but needs to be listed if you want to access them when
available
BLE Services and Characteristics
GATT (Generic Attribute profile) defines how two BLE devices
transfer data back and forth using concepts known as Services and
Characteristics
➫ Services are logical entities, and contain specific chunks of
data, known as Characteristics
➫ Characteristics encapsulate a single data point
Services and Characterics are identified by 16- or 128 bit UUID's
Characteristic
Characteristic
Characteristic
Characteristic
Characteristic
Service
Service
Profile
BLE Services and Characteristics
In JavaScript you can think of a Service being something like
an object - ie. a collection of properties
Characteristics are similar to properties on an object
Characteristic
Characteristic
Characteristic
Characteristic
Characteristic
Service
Service
Profile
Connect to a device
navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
.then(device => {
// Human-readable name of the device.
console.log(device.name);
// Attempts to connect to remote GATT Server.
return device.gatt.connect();
})
.then(server => { /* ... */ })
.catch(error => { console.log(error); });
When you have a device, you can connect to the GATT (Generic Attributes) server from where you can access
Characteristics
Deal with Characteristics
.then(service => {
// Getting Battery Level Characteristic...
return service.getCharacteristic('battery_level');
})
.then(characteristic => {
// Reading Battery Level...
return characteristic.readValue();
})
.then(value => {
console.log('Battery percentage is ' + value.getUint8(0));
})
readValue() returns a DataView (part of the Typed Array family), so it is easy to extract values from.
Deal with Characteristics
.then(service => service.getCharacteristic('heart_rate_control_point'))
.then(characteristic => {
// Writing 1 is the signal to reset energy expended.
const resetEnergyExpended = Uint8Array.of(1);
return characteristic.writeValue(resetEnergyExpended);
})
.then(_ => {
console.log('Energy expended has been reset.');
})
Writing is easy too!
Deal with Characteristics
.then(service => service.getCharacteristic('heart_rate_measurement'))
.then(characteristic => characteristic.startNotifications())
.then(characteristic => {
characteristic.addEventListener('characteristicvaluechanged', handleCharacteristicValueChanged);
console.log('Notifications have been started.');
})
.catch(error => { console.log(error); });
function handleCharacteristicValueChanged(event) {
var value = event.target.value;
console.log('Received ' + value);
// TODO: Parse Heart Rate Measurement value.
// See https://github.com/WebBluetoothCG/demos/blob/gh-pages/heart-rate-sensor/heartRateSensor.js
}
GATT notifications - subscribe to Characteristics changes
Bootstrapping - aka. how do people find my site from my device
Bluetooth devices can advertize web sites around them!
That is Eddystone
Shows as notifications
Click, and they open
Shows as notifications
Click, and they open
Can be regular sites
No additional Bluetooth
functionality needed
In near future
Clicking on a Physical
Web notification*, will
allow the opened page to
auto connect to device
*Eddystone URL
Get started today! (or tomorrow)
https://developers.google.com/web/updates/2015/07/
interact-with-ble-devices-on-the-web
Advantages
Widely in use, Cheap, Cabled, More Secure,
Fast, Stable, Can power devices
Disvantages
Cabled
Safe and secure
USB has no radio interference
USB connector can be locked behind a hatch
Recall
Users and companies don't care about
how stuff works - it should just work
Bluetooth and USB coexists just fine!
https://medium.com/@kennethrohde/program-a-smart-device-directly-no-install-needed-cd8b29320d76#.nla4jzls9
https://www.youtube.com/watch?v=o7wGt9RfHVA
Nice example showing
➫ A device capable of running JS!
➫ Bootstrapping and auto connect
➫ Device being powered over USB
Three different transfer types
Bulk, Interrupt, Isochronous
Bulk
Bulk transfers are the fastest* but have no guaranteed timing
Printers and most CDC** (e.g serial) use bulk transfers.
* Bulk transfers will use spare un-allocated bandwidth on the bus after all other transactions have been allocated.
If the bus is busy with isochronous and/or interrupt then bulk data may slowly trickle over the bus.
** Communications Device Class
Interrupt
Interrupt transfers have guaranteed maximum latency, or time
between transaction attempts
Mice and keyboards use interrupt transfers.
Isochronous
Isochronous transfers have guaranteed timing but no error
correcting
Streaming audio and video use isochronous transfers
Web USB specific headers
Creates further security and restrictions
Web USB specific headers
➫ Optional
➫ Required for bootstrapping popup
➫ Restrict which sites can access the peripheral
Issues
The Linux modemmanager (enabled by default on most distros) hijacks (claims for 16sec)
CDC devices unless their VID/PID are blacklisted (like the Arduino Leonardo)
Note: Only affects CDC devices
Issues
Windows autoloads drivers for a range of classes, e.g. HID, MSD and CDC (Win 10)
Other Web USB devices additionally requires MS OS descriptors in order to autoload (or
INF file, see below)
Earlier versions (< 10) of Windows, requires a signed "driver", which is basically a signed
INF text file, binding the VIP/PID to usbser.sys (the default USB serial driver)
More info: https://medium.com/@larsgk/web-enabling-legacy-devices-dc3ecb9400ed#.fj7bd1ba3
API example
let device;
navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] })
.then(selectedDevice => {
device = selectedDevice;
return device.open(); // Begin a session.
})
.then(() => device.selectConfiguration(1)) // Select configuration #1 for the device.
.then(() => device.claimInterface(2)) // Request exclusive control over interface #2.
.then(() => device.controlTransferOut({
requestType: 'class',
recipient: 'interface',
request: 0x22,
value: 0x01,
index: 0x02
})) // Ready to receive data
.then(() => device.transferIn(5, 64)) // Waiting for 64 bytes of data from endpoint #5.
.then(result => {
let decoder = new TextDecoder();
console.log('Received: ' + decoder.decode(result.data));
})
.catch(error => { console.log(error); });
In many ways similar in spirit to Web Bluetooth, but of course USB specific
try {
let device = await navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] })
await device.open(); // Begin a session.
await device.selectConfiguration(1)) // Select configuration #1 for the device.
await device.claimInterface(2)) // Request exclusive control over interface #2.
await device.controlTransferOut({
requestType: 'class',
recipient: 'interface',
request: 0x22,
value: 0x01,
index: 0x02
});
// Ready to receive data
let result = device.transferIn(5, 64)) // Waiting for 64 bytes of data from endpoint #5.
let decoder = new TextDecoder();
console.log('Received: ' + decoder.decode(result.data));
}
catch(error) {
console.log(error);
}
Availability
Works in Chrome today on Linux, Mac and Windows
Get started today!
https://developers.google.com/web/updates/2016/03/a
ccess-usb-devices-on-the-web
Wow!
But there is more!
Photo by Andrés Þór
Many companies often need to
track stuff
Bar codes and similar tech
➫ Quickly read and track things and products
➫ Get information about things around you
➫ Quick actions
Bluetooth Beacons might be the best solution
Or even NFC tags!
Or Quick Response codes and barcodes
+ they are cheap and printable
Barcode reader
The Shape Detection API covering barcodes, faces and more: https://wicg.github.io/shape-detection-api/
try {
let barcodeDetector = new BarcodeDetector();
// Assuming |theImage| is e.g. a <img> content, or a Blob.
let detectedCodes = await barcodeDetector.detect(theImage);
for (const barcode of detectedCodes) {
const box = barcode.boundingBox;
console.log(`Barcode ${barcode.rawValue} @(${box.x}, ${box.y}) with size ${box.width}x${box.height}`);
}
} catch(err) {
console.error(`Barcode Detection failed, boo: ${err}`);
}
Behind a flag
In Chrome
NFC reader/writer
The Web NFC API covers reading from and writing to NFC tags: https://w3c.github.io/web-nfc/
try {
await navigator.nfc.push({
data: [{ recordType: "url", data: "https://w3c.github.io/web-nfc/" }]
});
console.log("Message pushed.");
} catch(err) {
console.log("Push failed :-( try again.");
}
Behind a flag
In Chrome
NFC reader/writer
navigator.nfc.watch(message => {
if (message.data[0].recordType == 'empty') {
navigator.nfc.push({
data: [{
recordType: "json",
mediaType: "application/json",
data: { firstName: 'Kenneth' }
}]
});
} else {
console.log(`Read msg written by ${message.url}`;
processMessage(message);
}
});
Behind a flag
In Chrome
function processMessage(message) {
for (let d of message.data) {
if (d.recordType == "json") {
console.log(`Hello ${record.data.firstName}!`);
}
if (d.recordType == "opaque" && d.mediaType == 'image/png') {
const blob = new Blob(d.data, d.mediaType);
const img = document.createElement("img");
img.src = URL.createObjectURL(blob);
img.onload = _ => URL.revokeObjectURL(img.src);
document.querySelector('images').appendChild(img);
}
}
}
}
Pretty cool, even Sir Tim Berners-Lee is excited
https://my-grocery-plan.glitch.me/
https://www.youtube.com/watch?v=rkjr6tveEuw
But what about
Connecting to other devices
to control or receive data
Like Sensorial input
But my already has sensors!
Gimme gimme access pretty pretty please with sugar on top!
Could an API work for
Local and Remote sensors?
Web Platform, Node, IoT?
Find sensors hard?
Read my motion sensors explainer
https://w3c.github.io/motion-sensors/
Gravity Sensor
Absolute Orientation Sensor
Linear
Acceleration
Sensor
Geomagnetic Orientation Sensor
Low pass filter
Sensor fusion
Very easy to use API
Low-level, so you can do your own filters and sensor fusion
const accel = new Accelerometer({ frequency: 50 });
const gyro = new Gyroscope({ frequency: 50 });
gyro.onreading = _ => { … }
accel.start();
gyro.start();
Behind a flag
In Chrome
let timestamp = null;
gyro.onreading = _ => {
let norm = Math.sqrt(accel.x ** 2 + accel.y ** 2) + accel.z ** 2);
let xAccel = (accel.x / norm) * 90;
let yAccel = (accel.y / norm) * -90;
let zAccel = (accel.z / norm);
let xGyro = gyro.x * 180 / Math.PI;
let yGyro = gyro.y * 180 / Math.PI;
let zGyro = gyro.z * 180 / Math.PI;
let dt = timestamp ? ((gyro.timestamp - this.timestamp) / 1000) : 0;
timestamp = gyro.timestamp;
// Complementary filter
// E.g.: new angle = 98% * (current angle + gyro rotation rate) + (2% * Accelerometer angle)
this.alpha = weight * (this.alpha + zGyro * dt) + (1.0 - weight) * zAccel;
this.beta = weight * (this.beta + xGyro * dt) + (1.0 - weight) * xAccel;
this.gamma = weight * (this.gamma + yGyro * dt) + (1.0 - weight) * yAccel;
console.log(`(${this.alpha}, ${this.beta}, ${this.gamma})`);
};
Let's look at a video!
➫ Daydream controller exposed via Web Bluetooth
➫ Exposed as Generic Sensors
➫ Try it https://sensor-compass.appspot.com/
This is the
Daydream
controller
https://www.youtube.com/watch?v=qkvHJf8N7W0
What about
Smart devices?
That is
quite tiny
https://www.youtube.com/watch?v=K0efnqWDrkY
Summary
The web is ready for nice app like experiences
⬤ ⬤ ⬤ ⬤
Summary
You can effortless connect to devices over Bluetooth
and USB
Chrome for now, but expect other browser vendors to follow suit
⬤ ⬤ ⬤ ⬤
Summary
NFC support and barcode readers are coming too!
⬤ ⬤ ⬤ ⬤
Summary
Generic Sensors exposes sensors to the web
Plus the API is easy to replace with custom implementation, say, via Web Bluetooth
⬤ ⬤ ⬤ ⬤
The web is ready,
let's build the future
Follow me on Twitter, where
I will post these slides today
@kennethrohde
https://bit.ly/2iU4KtH
WebLight

More Related Content

What's hot

Don't touch the mobile parts
Don't touch the mobile partsDon't touch the mobile parts
Don't touch the mobile partsFrancesco Fullone
 
Performance on the Yahoo! Homepage
Performance on the Yahoo! HomepagePerformance on the Yahoo! Homepage
Performance on the Yahoo! HomepageNicholas Zakas
 
High Performance JavaScript - WebDirections USA 2010
High Performance JavaScript - WebDirections USA 2010High Performance JavaScript - WebDirections USA 2010
High Performance JavaScript - WebDirections USA 2010Nicholas Zakas
 
Intro To webOS
Intro To webOSIntro To webOS
Intro To webOSfpatton
 
High Performance JavaScript (YUIConf 2010)
High Performance JavaScript (YUIConf 2010)High Performance JavaScript (YUIConf 2010)
High Performance JavaScript (YUIConf 2010)Nicholas Zakas
 
Enough with the JavaScript already!
Enough with the JavaScript already!Enough with the JavaScript already!
Enough with the JavaScript already!Nicholas Zakas
 
High Performance Mobile Web
High Performance Mobile WebHigh Performance Mobile Web
High Performance Mobile WebMorgan Cheng
 

What's hot (7)

Don't touch the mobile parts
Don't touch the mobile partsDon't touch the mobile parts
Don't touch the mobile parts
 
Performance on the Yahoo! Homepage
Performance on the Yahoo! HomepagePerformance on the Yahoo! Homepage
Performance on the Yahoo! Homepage
 
High Performance JavaScript - WebDirections USA 2010
High Performance JavaScript - WebDirections USA 2010High Performance JavaScript - WebDirections USA 2010
High Performance JavaScript - WebDirections USA 2010
 
Intro To webOS
Intro To webOSIntro To webOS
Intro To webOS
 
High Performance JavaScript (YUIConf 2010)
High Performance JavaScript (YUIConf 2010)High Performance JavaScript (YUIConf 2010)
High Performance JavaScript (YUIConf 2010)
 
Enough with the JavaScript already!
Enough with the JavaScript already!Enough with the JavaScript already!
Enough with the JavaScript already!
 
High Performance Mobile Web
High Performance Mobile WebHigh Performance Mobile Web
High Performance Mobile Web
 

Similar to Cold front - bridging the web and the physical world

Mobile tech briefing 2013
Mobile tech briefing 2013Mobile tech briefing 2013
Mobile tech briefing 2013Scotty Logan
 
Webapps development on ubuntu
Webapps development on ubuntuWebapps development on ubuntu
Webapps development on ubuntuXiaoguo Liu
 
openMIC barcamp 11.02.2010
openMIC barcamp 11.02.2010openMIC barcamp 11.02.2010
openMIC barcamp 11.02.2010Patrick Lauke
 
PowerShell: A Language for the Internet of Things #ATLPUG
PowerShell: A Language for the Internet of Things #ATLPUGPowerShell: A Language for the Internet of Things #ATLPUG
PowerShell: A Language for the Internet of Things #ATLPUGTaylor Riggan
 
Fanug - Pragmatic Windows Phone Developer
Fanug - Pragmatic Windows Phone DeveloperFanug - Pragmatic Windows Phone Developer
Fanug - Pragmatic Windows Phone DeveloperSam Basu
 
What's New with Windows Phone - FoxCon Talk
What's New with Windows Phone - FoxCon TalkWhat's New with Windows Phone - FoxCon Talk
What's New with Windows Phone - FoxCon TalkSam Basu
 
Workshop HTML5+PhoneGap by Ivano Malavolta
Workshop HTML5+PhoneGap by Ivano Malavolta Workshop HTML5+PhoneGap by Ivano Malavolta
Workshop HTML5+PhoneGap by Ivano Malavolta Commit University
 
Mobile is slow - Over the Air 2013
Mobile is slow - Over the Air 2013Mobile is slow - Over the Air 2013
Mobile is slow - Over the Air 2013Jon Arne Sæterås
 
Manish Chasta - Securing Android Applications
Manish Chasta - Securing Android ApplicationsManish Chasta - Securing Android Applications
Manish Chasta - Securing Android ApplicationsPositive Hack Days
 
Bruce lawson-over-the-air
Bruce lawson-over-the-airBruce lawson-over-the-air
Bruce lawson-over-the-airbrucelawson
 
IoThings you don't even need to hack
IoThings you don't even need to hackIoThings you don't even need to hack
IoThings you don't even need to hackSlawomir Jasek
 
Petr Dvořák: Mobilní webové služby pohledem iPhone developera
Petr Dvořák: Mobilní webové služby pohledem iPhone developeraPetr Dvořák: Mobilní webové služby pohledem iPhone developera
Petr Dvořák: Mobilní webové služby pohledem iPhone developeraWebExpo
 
WP7 & Azure
WP7 & AzureWP7 & Azure
WP7 & AzureSam Basu
 
Angular js mobile jsday 2014 - Verona 14 may
Angular js mobile   jsday 2014 - Verona 14 mayAngular js mobile   jsday 2014 - Verona 14 may
Angular js mobile jsday 2014 - Verona 14 mayLuciano Amodio
 

Similar to Cold front - bridging the web and the physical world (20)

Mobile tech briefing 2013
Mobile tech briefing 2013Mobile tech briefing 2013
Mobile tech briefing 2013
 
Webapps development on ubuntu
Webapps development on ubuntuWebapps development on ubuntu
Webapps development on ubuntu
 
openMIC barcamp 11.02.2010
openMIC barcamp 11.02.2010openMIC barcamp 11.02.2010
openMIC barcamp 11.02.2010
 
Vodafone Widget Camp
Vodafone Widget CampVodafone Widget Camp
Vodafone Widget Camp
 
Web assembly with PWA
Web assembly with PWA Web assembly with PWA
Web assembly with PWA
 
PowerShell: A Language for the Internet of Things #ATLPUG
PowerShell: A Language for the Internet of Things #ATLPUGPowerShell: A Language for the Internet of Things #ATLPUG
PowerShell: A Language for the Internet of Things #ATLPUG
 
Fanug - Pragmatic Windows Phone Developer
Fanug - Pragmatic Windows Phone DeveloperFanug - Pragmatic Windows Phone Developer
Fanug - Pragmatic Windows Phone Developer
 
GWT and PWA
GWT and PWAGWT and PWA
GWT and PWA
 
What's New with Windows Phone - FoxCon Talk
What's New with Windows Phone - FoxCon TalkWhat's New with Windows Phone - FoxCon Talk
What's New with Windows Phone - FoxCon Talk
 
Workshop HTML5+PhoneGap by Ivano Malavolta
Workshop HTML5+PhoneGap by Ivano Malavolta Workshop HTML5+PhoneGap by Ivano Malavolta
Workshop HTML5+PhoneGap by Ivano Malavolta
 
Mobile is slow - Over the Air 2013
Mobile is slow - Over the Air 2013Mobile is slow - Over the Air 2013
Mobile is slow - Over the Air 2013
 
Manish Chasta - Securing Android Applications
Manish Chasta - Securing Android ApplicationsManish Chasta - Securing Android Applications
Manish Chasta - Securing Android Applications
 
Usb Drive Protector
Usb Drive ProtectorUsb Drive Protector
Usb Drive Protector
 
Bruce lawson-over-the-air
Bruce lawson-over-the-airBruce lawson-over-the-air
Bruce lawson-over-the-air
 
Web Components and PWA
Web Components and PWAWeb Components and PWA
Web Components and PWA
 
IoThings you don't even need to hack
IoThings you don't even need to hackIoThings you don't even need to hack
IoThings you don't even need to hack
 
Petr Dvořák: Mobilní webové služby pohledem iPhone developera
Petr Dvořák: Mobilní webové služby pohledem iPhone developeraPetr Dvořák: Mobilní webové služby pohledem iPhone developera
Petr Dvořák: Mobilní webové služby pohledem iPhone developera
 
- Webexpo 2010
- Webexpo 2010- Webexpo 2010
- Webexpo 2010
 
WP7 & Azure
WP7 & AzureWP7 & Azure
WP7 & Azure
 
Angular js mobile jsday 2014 - Verona 14 may
Angular js mobile   jsday 2014 - Verona 14 mayAngular js mobile   jsday 2014 - Verona 14 may
Angular js mobile jsday 2014 - Verona 14 may
 

More from Kenneth Rohde Christiansen (10)

Progressive Web Apps - deep dive
Progressive Web Apps - deep diveProgressive Web Apps - deep dive
Progressive Web Apps - deep dive
 
New trends on web platform
New trends on web platformNew trends on web platform
New trends on web platform
 
Web Assembly (W3C TPAC presentation)
Web Assembly (W3C TPAC presentation)Web Assembly (W3C TPAC presentation)
Web Assembly (W3C TPAC presentation)
 
Generic sensors for the Web
Generic sensors for the WebGeneric sensors for the Web
Generic sensors for the Web
 
HTML literals, the JSX of the platform
HTML literals, the JSX of the platformHTML literals, the JSX of the platform
HTML literals, the JSX of the platform
 
Web components v1 intro
Web components v1 introWeb components v1 intro
Web components v1 intro
 
WebKit, why it matters (PDF version)
WebKit, why it matters (PDF version)WebKit, why it matters (PDF version)
WebKit, why it matters (PDF version)
 
WebKit, why it matters?
WebKit, why it matters?WebKit, why it matters?
WebKit, why it matters?
 
Qt WebKit going Mobile
Qt WebKit going MobileQt WebKit going Mobile
Qt WebKit going Mobile
 
Connecting Technology for Great Experiences - How does QML and Web fit together?
Connecting Technology for Great Experiences - How does QML and Web fit together?Connecting Technology for Great Experiences - How does QML and Web fit together?
Connecting Technology for Great Experiences - How does QML and Web fit together?
 

Recently uploaded

Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 

Recently uploaded (20)

Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 

Cold front - bridging the web and the physical world

  • 1. Bridging the web and the physical world Kenneth Rohde Christiansen Web Platform Architect
  • 2. Hi! I am Kenneth
  • 3. Danish - happiest people in the world second most
  • 4.
  • 5.
  • 6.
  • 8. What makes a thing "smart"?
  • 9. Devices which are complicated or slow to use, are they really smart?
  • 10. ➫ Solve a real issue ➫ Be there when you need them ➫ Ease to use, with low friction
  • 11.
  • 12. I don't want to download your app, I just want to do stuff
  • 14. With many devices around usapps don't scale well
  • 15. Too many icons! Lack of overview Lots of updates pending for stuff I never use!
  • 16. Too many icons! ➫ Lack of overview ➫ Updates pending for stuff I never use!
  • 17. Let's look at usages
  • 18. There are different common usages - Everyday use turn on the light! - Occasionally change temperature of my fridge - Once paying for parking when travelling
  • 20. We want low friction and ease of use
  • 21.
  • 22.
  • 23. Focus on speed HTTP 2.0 push, Service Workers, PRPL pattern, streams, scrolling, CSS Houdini, Compositing …
  • 24. Fast with Service Worker caching
  • 25.
  • 26. The web is up to task
  • 27.
  • 29. But that can't be web?! No address bar - super fast - icon on homescreen
  • 30. We call that experience for Progressive Web Apps https://developers.google.com/web/progressive-web-apps/
  • 31. Great for one-time use The low friction of the web
  • 32. Always handy if I want it to be Add to homescreen
  • 33. No clutter Looks and acts like an app
  • 35. But... Copyright Club Skirts Dinah Shore Weekend https://commons.wikimedia.org/wiki/File:White_Diamonds_Party.jpg
  • 36. Devices live outside the sandbox
  • 37. And yes, the web can do that too!
  • 38. Keep in mind Users and companies don't care about how stuff works, it should just work
  • 40. But first, it might make sense to listen You can actually win stuff!
  • 41. Lars and Coldfront has joined up for a quiz! More on that later! WebLight
  • 42. Advantages Widely used, Low energy, Wireless
  • 43. Advantages Cheap, Easy to use, Beacon functionality
  • 44. Disadvantages Security (just radio waves), Not powered, Stability, Speed
  • 46.
  • 47. ➫ Based on Bluetooth 4+ (Low Energy) GATT protocol ➫ Easy to use, modern web API ➫ Uses promises and typed arrays (ie. Uint8Array etc) ➫ No Classic mode support ➫ Only Central, not Peripheral Chrome only for now
  • 48.
  • 49. Drawing by Noa Lee Shaked
  • 50. An example HTTPS only User Gesture required to request device
  • 52. Requesting device navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] }) .then(device => { /* ... */ }) .catch(error => { console.log(error); }); navigator.bluetooth.requestDevice({ filters: [{ services: [0x1234, 0x12345678, '99999999-0000-1000-8000-00805f9b34fb'] }] }) .then(device => { /* ... */ }) .catch(error => { console.log(error); }); You may provide either the full Bluetooth UUID or a short 16- or 32-bit form, if not a standardized service Standardized services are easy to connect to
  • 53. Requesting device navigator.bluetooth.requestDevice({ filters: [{ name: "Kenneth's robot" }], optionalServices: ['battery_service'] }) .then(device => { /* ... */ }) .catch(error => { console.log(error); }); You can also search by advertized name. Services can be optional, but needs to be listed if you want to access them when available
  • 54. BLE Services and Characteristics GATT (Generic Attribute profile) defines how two BLE devices transfer data back and forth using concepts known as Services and Characteristics ➫ Services are logical entities, and contain specific chunks of data, known as Characteristics ➫ Characteristics encapsulate a single data point Services and Characterics are identified by 16- or 128 bit UUID's Characteristic Characteristic Characteristic Characteristic Characteristic Service Service Profile
  • 55. BLE Services and Characteristics In JavaScript you can think of a Service being something like an object - ie. a collection of properties Characteristics are similar to properties on an object Characteristic Characteristic Characteristic Characteristic Characteristic Service Service Profile
  • 56. Connect to a device navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] }) .then(device => { // Human-readable name of the device. console.log(device.name); // Attempts to connect to remote GATT Server. return device.gatt.connect(); }) .then(server => { /* ... */ }) .catch(error => { console.log(error); }); When you have a device, you can connect to the GATT (Generic Attributes) server from where you can access Characteristics
  • 57. Deal with Characteristics .then(service => { // Getting Battery Level Characteristic... return service.getCharacteristic('battery_level'); }) .then(characteristic => { // Reading Battery Level... return characteristic.readValue(); }) .then(value => { console.log('Battery percentage is ' + value.getUint8(0)); }) readValue() returns a DataView (part of the Typed Array family), so it is easy to extract values from.
  • 58. Deal with Characteristics .then(service => service.getCharacteristic('heart_rate_control_point')) .then(characteristic => { // Writing 1 is the signal to reset energy expended. const resetEnergyExpended = Uint8Array.of(1); return characteristic.writeValue(resetEnergyExpended); }) .then(_ => { console.log('Energy expended has been reset.'); }) Writing is easy too!
  • 59. Deal with Characteristics .then(service => service.getCharacteristic('heart_rate_measurement')) .then(characteristic => characteristic.startNotifications()) .then(characteristic => { characteristic.addEventListener('characteristicvaluechanged', handleCharacteristicValueChanged); console.log('Notifications have been started.'); }) .catch(error => { console.log(error); }); function handleCharacteristicValueChanged(event) { var value = event.target.value; console.log('Received ' + value); // TODO: Parse Heart Rate Measurement value. // See https://github.com/WebBluetoothCG/demos/blob/gh-pages/heart-rate-sensor/heartRateSensor.js } GATT notifications - subscribe to Characteristics changes
  • 60. Bootstrapping - aka. how do people find my site from my device
  • 61. Bluetooth devices can advertize web sites around them! That is Eddystone
  • 63. Shows as notifications Click, and they open Can be regular sites No additional Bluetooth functionality needed
  • 64. In near future Clicking on a Physical Web notification*, will allow the opened page to auto connect to device *Eddystone URL
  • 65. Get started today! (or tomorrow) https://developers.google.com/web/updates/2015/07/ interact-with-ble-devices-on-the-web
  • 66. Advantages Widely in use, Cheap, Cabled, More Secure, Fast, Stable, Can power devices
  • 68. Safe and secure USB has no radio interference USB connector can be locked behind a hatch
  • 69. Recall Users and companies don't care about how stuff works - it should just work Bluetooth and USB coexists just fine!
  • 71. Nice example showing ➫ A device capable of running JS! ➫ Bootstrapping and auto connect ➫ Device being powered over USB
  • 72. Three different transfer types Bulk, Interrupt, Isochronous
  • 73. Bulk Bulk transfers are the fastest* but have no guaranteed timing Printers and most CDC** (e.g serial) use bulk transfers. * Bulk transfers will use spare un-allocated bandwidth on the bus after all other transactions have been allocated. If the bus is busy with isochronous and/or interrupt then bulk data may slowly trickle over the bus. ** Communications Device Class
  • 74. Interrupt Interrupt transfers have guaranteed maximum latency, or time between transaction attempts Mice and keyboards use interrupt transfers.
  • 75. Isochronous Isochronous transfers have guaranteed timing but no error correcting Streaming audio and video use isochronous transfers
  • 76. Web USB specific headers Creates further security and restrictions
  • 77. Web USB specific headers ➫ Optional ➫ Required for bootstrapping popup ➫ Restrict which sites can access the peripheral
  • 78.
  • 79. Issues The Linux modemmanager (enabled by default on most distros) hijacks (claims for 16sec) CDC devices unless their VID/PID are blacklisted (like the Arduino Leonardo) Note: Only affects CDC devices
  • 80. Issues Windows autoloads drivers for a range of classes, e.g. HID, MSD and CDC (Win 10) Other Web USB devices additionally requires MS OS descriptors in order to autoload (or INF file, see below) Earlier versions (< 10) of Windows, requires a signed "driver", which is basically a signed INF text file, binding the VIP/PID to usbser.sys (the default USB serial driver) More info: https://medium.com/@larsgk/web-enabling-legacy-devices-dc3ecb9400ed#.fj7bd1ba3
  • 81. API example let device; navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] }) .then(selectedDevice => { device = selectedDevice; return device.open(); // Begin a session. }) .then(() => device.selectConfiguration(1)) // Select configuration #1 for the device. .then(() => device.claimInterface(2)) // Request exclusive control over interface #2. .then(() => device.controlTransferOut({ requestType: 'class', recipient: 'interface', request: 0x22, value: 0x01, index: 0x02 })) // Ready to receive data .then(() => device.transferIn(5, 64)) // Waiting for 64 bytes of data from endpoint #5. .then(result => { let decoder = new TextDecoder(); console.log('Received: ' + decoder.decode(result.data)); }) .catch(error => { console.log(error); }); In many ways similar in spirit to Web Bluetooth, but of course USB specific try { let device = await navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] }) await device.open(); // Begin a session. await device.selectConfiguration(1)) // Select configuration #1 for the device. await device.claimInterface(2)) // Request exclusive control over interface #2. await device.controlTransferOut({ requestType: 'class', recipient: 'interface', request: 0x22, value: 0x01, index: 0x02 }); // Ready to receive data let result = device.transferIn(5, 64)) // Waiting for 64 bytes of data from endpoint #5. let decoder = new TextDecoder(); console.log('Received: ' + decoder.decode(result.data)); } catch(error) { console.log(error); }
  • 82. Availability Works in Chrome today on Linux, Mac and Windows
  • 84. Wow! But there is more! Photo by Andrés Þór
  • 85. Many companies often need to track stuff
  • 86. Bar codes and similar tech ➫ Quickly read and track things and products ➫ Get information about things around you ➫ Quick actions
  • 87. Bluetooth Beacons might be the best solution
  • 88. Or even NFC tags!
  • 89. Or Quick Response codes and barcodes + they are cheap and printable
  • 90. Barcode reader The Shape Detection API covering barcodes, faces and more: https://wicg.github.io/shape-detection-api/ try { let barcodeDetector = new BarcodeDetector(); // Assuming |theImage| is e.g. a <img> content, or a Blob. let detectedCodes = await barcodeDetector.detect(theImage); for (const barcode of detectedCodes) { const box = barcode.boundingBox; console.log(`Barcode ${barcode.rawValue} @(${box.x}, ${box.y}) with size ${box.width}x${box.height}`); } } catch(err) { console.error(`Barcode Detection failed, boo: ${err}`); } Behind a flag In Chrome
  • 91. NFC reader/writer The Web NFC API covers reading from and writing to NFC tags: https://w3c.github.io/web-nfc/ try { await navigator.nfc.push({ data: [{ recordType: "url", data: "https://w3c.github.io/web-nfc/" }] }); console.log("Message pushed."); } catch(err) { console.log("Push failed :-( try again."); } Behind a flag In Chrome
  • 92. NFC reader/writer navigator.nfc.watch(message => { if (message.data[0].recordType == 'empty') { navigator.nfc.push({ data: [{ recordType: "json", mediaType: "application/json", data: { firstName: 'Kenneth' } }] }); } else { console.log(`Read msg written by ${message.url}`; processMessage(message); } }); Behind a flag In Chrome function processMessage(message) { for (let d of message.data) { if (d.recordType == "json") { console.log(`Hello ${record.data.firstName}!`); } if (d.recordType == "opaque" && d.mediaType == 'image/png') { const blob = new Blob(d.data, d.mediaType); const img = document.createElement("img"); img.src = URL.createObjectURL(blob); img.onload = _ => URL.revokeObjectURL(img.src); document.querySelector('images').appendChild(img); } } } }
  • 93. Pretty cool, even Sir Tim Berners-Lee is excited
  • 95. But what about Connecting to other devices to control or receive data
  • 97. But my already has sensors! Gimme gimme access pretty pretty please with sugar on top!
  • 98. Could an API work for Local and Remote sensors? Web Platform, Node, IoT?
  • 99.
  • 100. Find sensors hard? Read my motion sensors explainer https://w3c.github.io/motion-sensors/ Gravity Sensor Absolute Orientation Sensor Linear Acceleration Sensor Geomagnetic Orientation Sensor Low pass filter Sensor fusion
  • 101. Very easy to use API Low-level, so you can do your own filters and sensor fusion const accel = new Accelerometer({ frequency: 50 }); const gyro = new Gyroscope({ frequency: 50 }); gyro.onreading = _ => { … } accel.start(); gyro.start(); Behind a flag In Chrome
  • 102. let timestamp = null; gyro.onreading = _ => { let norm = Math.sqrt(accel.x ** 2 + accel.y ** 2) + accel.z ** 2); let xAccel = (accel.x / norm) * 90; let yAccel = (accel.y / norm) * -90; let zAccel = (accel.z / norm); let xGyro = gyro.x * 180 / Math.PI; let yGyro = gyro.y * 180 / Math.PI; let zGyro = gyro.z * 180 / Math.PI; let dt = timestamp ? ((gyro.timestamp - this.timestamp) / 1000) : 0; timestamp = gyro.timestamp; // Complementary filter // E.g.: new angle = 98% * (current angle + gyro rotation rate) + (2% * Accelerometer angle) this.alpha = weight * (this.alpha + zGyro * dt) + (1.0 - weight) * zAccel; this.beta = weight * (this.beta + xGyro * dt) + (1.0 - weight) * xAccel; this.gamma = weight * (this.gamma + yGyro * dt) + (1.0 - weight) * yAccel; console.log(`(${this.alpha}, ${this.beta}, ${this.gamma})`); };
  • 103. Let's look at a video! ➫ Daydream controller exposed via Web Bluetooth ➫ Exposed as Generic Sensors ➫ Try it https://sensor-compass.appspot.com/
  • 109.
  • 110.
  • 111.
  • 112. Summary The web is ready for nice app like experiences ⬤ ⬤ ⬤ ⬤
  • 113. Summary You can effortless connect to devices over Bluetooth and USB Chrome for now, but expect other browser vendors to follow suit ⬤ ⬤ ⬤ ⬤
  • 114. Summary NFC support and barcode readers are coming too! ⬤ ⬤ ⬤ ⬤
  • 115. Summary Generic Sensors exposes sensors to the web Plus the API is easy to replace with custom implementation, say, via Web Bluetooth ⬤ ⬤ ⬤ ⬤
  • 116. The web is ready, let's build the future
  • 117. Follow me on Twitter, where I will post these slides today @kennethrohde