target
Recently, a project is being developed. The requirements of the project are as follows:
On the H5 (based on vue framework) page, call the webluetooth interface through js to read the data transmitted by a Bluetooth device and return to the display.
introduce
background
With the rise of PWA, more and more web services are supported. But one area is almost exclusive to native applications: communication with devices. For a long time, developers have been committed to solving this problem.
The web is excellent for talking to servers, but not for talking to devices
......
So WebBluetooth came into being, which is a new specification that has been implemented on Chrome and Samsung Internet.
WebBluetooth is a new specification that has been implemented in Chrome and Samsung Internet that allows us to communicate directly to Bluetooth Low Energy devices from the browser.
Bluetooth Low Energy (BLE)
Wikipedia - Low Power Bluetooth
Generic Attribute Profile (GATT)
Bluetooth ble: introduction to GATT profile (GATT and GAP)
GAP makes your device visible to other devices and determines whether or how your device can interact with contract equipment.
GATT protocol - general attribute configuration
WebBluetooth API
By using the WebBluetooth API, we only need a few lines of JavaScript to communicate with Bluetooth devices.
The Web Bluetooth API aims to do exactly that with a promise-based API, which allows you to interact with many BLE(Bluetooth Low Energy) enabled devices.
prerequisites
- HTTPS required
- The user needs to give Bluetooth permission and click OK
button.addEventListener('pointerup', function(event) { // Call navigator.bluetooth.requestDevice });
- System requirements, see here for details MDN's Browser compatibility
A subset of the Web Bluetooth API is available in Chrome OS, Chrome for Android 6.0, Mac (Chrome 56) and Windows 10 (Chrome 70)
navigator.bluetooth.requestDevice()
Accept a mandatory object that defines a filter. These filters are used to return only devices that match some published Bluetooth GATT services and / or device names.
Using: Filters
- Services filter
navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] }) .then(device => { /* ... */ }) .catch(error => { console.error(error); });
If the Bluetooth device is not here Service list Inside, we need to provide complete Bluetooth UUID or 16-/32-bit arrangement
navigator.bluetooth.requestDevice({ filters: [{ services: [0x1234, 0x12345678, '99999999-0000-1000-8000-00805f9b34fb'] }] }) .then(device => { /* ... */ }) .catch(error => { console.error(error); });
- Name filter
navigator.bluetooth.requestDevice({ filters: [{ name: 'Francois robot' }], optionalServices: ['battery_service'] // Required to access service later. }) .then(device => { /* ... */ }) .catch(error => { console.error(error); });
- Manufacturer data filter
// Filter Bluetooth devices from Google company with manufacturer data bytes // that start with [0x01, 0x02]. navigator.bluetooth.requestDevice({ filters: [{ manufacturerData: [{ companyIdentifier: 0x00e0, dataPrefix: new Uint8Array([0x01, 0x02]) }] }], optionalServices: ['battery_service'] // Required to access service later. }) .then(device => { /* ... */ }) .catch(error => { console.error(error); });
- No filters
navigator.bluetooth.requestDevice({ acceptAllDevices: true, optionalServices: ['battery_service'] // Required to access service later. }) .then(device => { /* ... */ }) .catch(error => { console.error(error); });
start
Reference [1] gives an example of controlling bulb color through Bluetooth. Our experiment is also based on his ideas and modified, and finally achieve the goal.
1. Connect Bluetooth device
First, we need to connect Bluetooth devices. Here we use navigator bluetooth. Requestdevice() is the interface.
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.error(error); });
2. Write data
3. Read data
navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] }) .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'); }) .then(characteristic => { // Reading Battery Level... return characteristic.readValue(); }) .then(value => { console.log(`Battery percentage is ${value.getUint8(0)}`); }) .catch(error => { console.error(error); });
4. Get information and change (return to display)
navigator.bluetooth.requestDevice({ filters: [{ services: ['heart_rate'] }] }) .then(device => device.gatt.connect()) .then(server => server.getPrimaryService('heart_rate')) .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.error(error); }); function handleCharacteristicValueChanged(event) { const 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 }
5. Disconnect
navigator.bluetooth.requestDevice({ filters: [{ name: 'Francois robot' }] }) .then(device => { // Set up event listener for when device gets disconnected. device.addEventListener('gattserverdisconnected', onDisconnected); // Attempts to connect to remote GATT Server. return device.gatt.connect(); }) .then(server => { /* ... */ }) .catch(error => { console.error(error); }); function onDisconnected(event) { const device = event.target; console.log(`Device ${device.name} is disconnected.`); }