Web Bluetooth API memungkinkan situs berkomunikasi dengan perangkat Bluetooth.
Bagaimana jika saya memberi tahu Anda bahwa situs dapat berkomunikasi dengan perangkat Bluetooth di sekitar dengan cara yang aman dan menjaga privasi? Dengan cara ini, monitor detak jantung, bohlam lampu yang bisa bernyanyi, dan bahkan kura-kura dapat berinteraksi langsung dengan situs.
Hingga saat ini, kemampuan untuk berinteraksi dengan perangkat Bluetooth hanya tersedia untuk aplikasi khusus platform. Web Bluetooth API bertujuan untuk mengubah hal ini dan membawanya ke browser web juga.
Sebelum kita mulai
Dokumen ini mengasumsikan bahwa Anda memiliki pengetahuan dasar tentang cara kerja Bluetooth Hemat Energi (BLE) dan Generic Attribute Profile.
Meskipun spesifikasi Web Bluetooth API belum final, penulis spesifikasi secara aktif mencari developer yang antusias untuk mencoba API ini dan memberikan masukan tentang spesifikasi dan masukan tentang implementasi.
Sebagian kecil Web Bluetooth API tersedia di ChromeOS, Chrome untuk Android 6.0, Mac (Chrome 56), dan Windows 10 (Chrome 70). Artinya, Anda dapat meminta dan menghubungkan ke perangkat Bluetooth Hemat Energi di sekitar, membaca/menulis karakteristik Bluetooth, menerima Notifikasi GATT, mengetahui kapan perangkat Bluetooth terputus, dan bahkan membaca dan menulis ke deskriptor Bluetooth. Lihat tabel Kompatibilitas browser MDN untuk mengetahui informasi selengkapnya.
Untuk Linux dan Windows versi sebelumnya, aktifkan tanda
#experimental-web-platform-features di about://flags.
Tersedia untuk uji coba origin
Untuk mendapatkan sebanyak mungkin masukan dari developer yang menggunakan Web Bluetooth API di lapangan, Chrome sebelumnya telah menambahkan fitur ini di Chrome 53 sebagai uji coba origin untuk ChromeOS, Android, dan Mac.
Uji coba telah berhasil berakhir pada Januari 2017.
Persyaratan keamanan
Untuk memahami pertimbangan keamanan, saya merekomendasikan postingan Web Bluetooth Security Model dari Jeffrey Yasskin, seorang software engineer di tim Chrome, yang mengerjakan spesifikasi Web Bluetooth API.
Khusus HTTPS
Karena API eksperimental ini adalah fitur baru canggih yang ditambahkan ke web, API ini hanya tersedia untuk konteks aman. Artinya, Anda harus membangun dengan mempertimbangkan TLS.
Diperlukan gestur pengguna
Sebagai fitur keamanan, penemuan perangkat Bluetooth dengan
navigator.bluetooth.requestDevice harus dipicu oleh gestur pengguna seperti
sentuhan atau klik mouse. Kita membahas cara memproses peristiwa
pointerup, click, dan touchend.
button.addEventListener('pointerup', function(event) {
// Call navigator.bluetooth.requestDevice
});
Mempelajari kode
Web Bluetooth API sangat mengandalkan Promise JavaScript. Jika Anda belum
terbiasa dengan Promise, lihat tutorial Promise yang bagus ini. Satu hal lagi, () => {} adalah Fungsi panah ECMAScript 2015.
Meminta perangkat Bluetooth
Spesifikasi Web Bluetooth API versi ini memungkinkan situs, yang berjalan dalam peran Central, terhubung ke Server GATT jarak jauh melalui koneksi BLE. API ini mendukung komunikasi antarperangkat yang menerapkan Bluetooth 4.0 atau yang lebih baru.
Saat situs meminta akses ke perangkat di sekitar menggunakan
navigator.bluetooth.requestDevice, browser akan meminta pengguna memilih perangkat di pemilih perangkat atau membatalkan permintaan.
Fungsi navigator.bluetooth.requestDevice() mengambil objek wajib yang
menentukan filter. Filter ini digunakan untuk menampilkan hanya perangkat yang cocok dengan beberapa layanan GATT Bluetooth yang diiklankan dan/atau nama perangkat.
Filter layanan
Misalnya, untuk meminta perangkat Bluetooth yang mengiklankan Layanan Baterai GATT Bluetooth:
navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Namun, jika Layanan GATT Bluetooth Anda tidak ada dalam daftar layanan GATT Bluetooth standar, Anda dapat memberikan UUID Bluetooth lengkap atau bentuk 16 atau 32 bit yang disingkat.
navigator.bluetooth.requestDevice({
filters: [{
services: [0x1234, 0x12345678, '99999999-0000-1000-8000-00805f9b34fb']
}]
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Filter nama
Anda juga dapat meminta perangkat Bluetooth berdasarkan nama perangkat yang diiklankan dengan kunci filter name, atau bahkan awalan nama ini dengan kunci filter namePrefix. Perhatikan bahwa dalam hal ini, Anda juga perlu menentukan kunci
optionalServices agar dapat mengakses layanan apa pun yang tidak disertakan dalam
filter layanan. Jika tidak, Anda akan mendapatkan error nanti saat mencoba mengaksesnya.
navigator.bluetooth.requestDevice({
filters: [{
name: 'Francois robot'
}],
optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Filter data produsen
Anda juga dapat meminta perangkat Bluetooth berdasarkan data spesifik produsen yang diiklankan dengan kunci filter manufacturerData. Kunci ini
adalah array objek dengan kunci Bluetooth company identifier wajib bernama
companyIdentifier. Anda juga dapat memberikan awalan data yang memfilter data produsen dari perangkat Bluetooth yang diawali dengan awalan tersebut. Perhatikan bahwa Anda juga perlu menentukan kunci optionalServices agar dapat mengakses layanan apa pun yang tidak disertakan dalam filter layanan. Jika tidak, Anda akan mendapatkan error nanti saat
mencoba mengaksesnya.
// 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); });
Masker juga dapat digunakan dengan awalan data untuk mencocokkan beberapa pola dalam data produsen. Lihat Penjelasan filter data Bluetooth untuk mempelajari lebih lanjut.
Filter pengecualian
Opsi exclusionFilters di navigator.bluetooth.requestDevice() memungkinkan
Anda mengecualikan beberapa perangkat dari pemilih browser. Filter ini dapat digunakan untuk mengecualikan perangkat yang cocok dengan filter yang lebih luas, tetapi tidak didukung.
// Request access to a bluetooth device whose name starts with "Created by".
// The device named "Created by Francois" has been reported as unsupported.
navigator.bluetooth.requestDevice({
filters: [{
namePrefix: "Created by"
}],
exclusionFilters: [{
name: "Created by Francois"
}],
optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Tidak ada filter
Terakhir, alih-alih filters, Anda dapat menggunakan tombol acceptAllDevices untuk menampilkan semua perangkat Bluetooth di sekitar. Anda juga perlu menentukan kunci optionalServices
untuk dapat mengakses beberapa layanan. Jika tidak, Anda akan mendapatkan error nanti saat mencoba mengaksesnya.
navigator.bluetooth.requestDevice({
acceptAllDevices: true,
optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Menyambungkan ke perangkat Bluetooth
Jadi, apa yang akan Anda lakukan setelah memiliki BluetoothDevice? Mari terhubung ke
Server GATT remote Bluetooth yang menyimpan definisi layanan dan karakteristik.
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); });
Membaca Karakteristik Bluetooth
Di sini kita terhubung ke Server GATT perangkat Bluetooth jarak jauh. Sekarang kita ingin mendapatkan Layanan GATT Utama dan membaca karakteristik yang termasuk dalam layanan ini. Misalnya, mari kita coba membaca tingkat pengisian daya baterai perangkat saat ini.
Dalam contoh di bawah, battery_level adalah Karakteristik Tingkat Baterai yang distandardisasi.
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); });
Jika menggunakan karakteristik GATT Bluetooth kustom, Anda dapat memberikan
UUID Bluetooth lengkap atau bentuk 16 atau 32 bit singkat ke
service.getCharacteristic.
Perhatikan bahwa Anda juga dapat menambahkan pemroses peristiwa characteristicvaluechanged pada karakteristik untuk menangani pembacaan nilainya. Lihat Read Characteristic
Value Changed Sample untuk melihat cara menangani notifikasi GATT
yang akan datang secara opsional.
…
.then(characteristic => {
// Set up event listener for when characteristic value changes.
characteristic.addEventListener('characteristicvaluechanged',
handleBatteryLevelChanged);
// Reading Battery Level…
return characteristic.readValue();
})
.catch(error => { console.error(error); });
function handleBatteryLevelChanged(event) {
const batteryLevel = event.target.value.getUint8(0);
console.log('Battery percentage is ' + batteryLevel);
}
Menulis ke Karakteristik Bluetooth
Menulis ke Karakteristik GATT Bluetooth sama mudahnya dengan membacanya. Kali ini, mari kita gunakan Heart Rate Control Point untuk mereset nilai kolom Energy Expended menjadi 0 di perangkat pemantau detak jantung.
Saya berjanji tidak ada sihir di sini. Semuanya dijelaskan di halaman Heart Rate Control Point Characteristic.
navigator.bluetooth.requestDevice({ filters: [{ services: ['heart_rate'] }] })
.then(device => device.gatt.connect())
.then(server => server.getPrimaryService('heart_rate'))
.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.');
})
.catch(error => { console.error(error); });
Menerima notifikasi GATT
Sekarang, mari kita lihat cara mendapatkan notifikasi saat karakteristik Pengukuran Detak Jantung berubah di perangkat:
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
}
Contoh Notifikasi menunjukkan cara menghentikan notifikasi dengan
stopNotifications() dan menghapus pemroses peristiwa characteristicvaluechanged
yang ditambahkan dengan benar.
Memutuskan Sambungan dari Perangkat Bluetooth
Untuk memberikan pengalaman pengguna yang lebih baik, Anda dapat memproses peristiwa pemutusan koneksi dan meminta pengguna untuk menghubungkan kembali:
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.`);
}
Anda juga dapat memanggil device.gatt.disconnect() untuk memutuskan koneksi aplikasi web dari perangkat Bluetooth. Tindakan ini akan memicu pemroses
peristiwa gattserverdisconnected yang ada. Perhatikan bahwa komunikasi perangkat Bluetooth TIDAK akan berhenti jika aplikasi lain sudah berkomunikasi dengan perangkat Bluetooth. Lihat Contoh Pemutusan Koneksi Perangkat dan Contoh Koneksi Ulang Otomatis untuk mempelajari lebih lanjut.
Membaca dan menulis ke deskriptor Bluetooth
Deskriptor GATT Bluetooth adalah atribut yang mendeskripsikan nilai karakteristik. Anda dapat membaca dan menulisnya dengan cara yang sama seperti karakteristik GATT Bluetooth.
Misalnya, mari kita lihat cara membaca deskripsi pengguna tentang interval pengukuran termometer kesehatan perangkat.
Dalam contoh di bawah, health_thermometer adalah layanan Termometer Kesehatan,
measurement_interval adalah karakteristik Interval Pengukuran, dan
gatt.characteristic_user_description adalah deskriptor Deskripsi Pengguna Karakteristik.
navigator.bluetooth.requestDevice({ filters: [{ services: ['health_thermometer'] }] })
.then(device => device.gatt.connect())
.then(server => server.getPrimaryService('health_thermometer'))
.then(service => service.getCharacteristic('measurement_interval'))
.then(characteristic => characteristic.getDescriptor('gatt.characteristic_user_description'))
.then(descriptor => descriptor.readValue())
.then(value => {
const decoder = new TextDecoder('utf-8');
console.log(`User Description: ${decoder.decode(value)}`);
})
.catch(error => { console.error(error); });
Setelah membaca deskripsi pengguna tentang interval pengukuran termometer kesehatan perangkat, mari kita lihat cara memperbarui dan menulis nilai kustom.
navigator.bluetooth.requestDevice({ filters: [{ services: ['health_thermometer'] }] })
.then(device => device.gatt.connect())
.then(server => server.getPrimaryService('health_thermometer'))
.then(service => service.getCharacteristic('measurement_interval'))
.then(characteristic => characteristic.getDescriptor('gatt.characteristic_user_description'))
.then(descriptor => {
const encoder = new TextEncoder('utf-8');
const userDescription = encoder.encode('Defines the time between measurements.');
return descriptor.writeValue(userDescription);
})
.catch(error => { console.error(error); });
Contoh, demo, dan codelab
Semua contoh Web Bluetooth di bawah telah berhasil diuji. Untuk menikmati contoh ini sepenuhnya, sebaiknya Anda menginstal [Aplikasi Android BLE Peripheral Simulator] yang menyimulasikan perangkat periferal BLE dengan Layanan Baterai, Layanan Detak Jantung, atau Layanan Termometer Kesehatan.
Pemula
- Info Perangkat - mengambil informasi perangkat dasar dari Perangkat BLE.
- Tingkat Baterai - mengambil informasi baterai dari Iklan Perangkat BLE yang mengiklankan informasi Baterai.
- Reset Energi - mereset energi yang dikeluarkan dari Iklan Perangkat BLE Detak Jantung.
- Properti Karakteristik - menampilkan semua properti karakteristik tertentu dari Perangkat BLE.
- Notifikasi - memulai dan menghentikan notifikasi karakteristik dari Perangkat BLE.
- Putuskan Sambungan Perangkat - putuskan sambungan dan dapatkan notifikasi dari pemutusan sambungan Perangkat BLE setelah terhubung ke perangkat tersebut.
- Get Characteristics - mendapatkan semua karakteristik layanan yang diiklankan dari Perangkat BLE.
- Get Descriptors - mendapatkan semua deskripsi karakteristik layanan yang diiklankan dari Perangkat BLE.
- Filter Data Produsen - mengambil informasi perangkat dasar dari Perangkat BLE yang cocok dengan data produsen.
- Filter Pengecualian - mengambil informasi perangkat dasar dari Perangkat BLE yang menampilkan filter pengecualian dasar.
Menggabungkan beberapa operasi
- Karakteristik GAP - mendapatkan semua karakteristik GAP Perangkat BLE.
- Karakteristik Informasi Perangkat - mendapatkan semua karakteristik Informasi Perangkat dari Perangkat BLE.
- Link Loss - menetapkan karakteristik Tingkat Pemberitahuan Perangkat BLE (readValue & writeValue).
- Discover Services & Characteristics - menemukan semua layanan utama yang dapat diakses dan karakteristiknya dari Perangkat BLE.
- Koneksi Ulang Otomatis - menghubungkan kembali ke perangkat BLE yang terputus menggunakan algoritma backoff eksponensial.
- Read Characteristic Value Changed - membaca level baterai dan mendapatkan notifikasi perubahan dari Perangkat BLE.
- Baca Deskriptor - membaca semua deskriptor karakteristik layanan dari Perangkat BLE.
- Write Descriptor - menulis ke deskriptor "Characteristic User Description" di Perangkat BLE.
Lihat juga Demo Web Bluetooth pilihan dan Codelab Web Bluetooth resmi kami.
Perpustakaan
- web-bluetooth-utils adalah modul npm yang menambahkan beberapa fungsi praktis ke API.
- Shim Web Bluetooth API tersedia di noble, modul pusat BLE Node.js yang paling populer. Hal ini memungkinkan Anda memaketkan/menggabungkan noble tanpa memerlukan server WebSocket atau plugin lainnya.
- angular-web-bluetooth adalah modul untuk Angular yang mengabstraksi semua boilerplate yang diperlukan untuk mengonfigurasi Web Bluetooth API.
Alat
- Mulai Menggunakan Web Bluetooth adalah Aplikasi Web sederhana yang akan membuat semua kode boilerplate JavaScript untuk mulai berinteraksi dengan perangkat Bluetooth. Masukkan nama perangkat, layanan, karakteristik, tentukan propertinya, dan Anda siap menggunakannya.
- Jika Anda sudah menjadi developer Bluetooth, Plugin Web Bluetooth Developer Studio juga akan membuat kode JavaScript Web Bluetooth untuk perangkat Bluetooth Anda.
Tips
Halaman Bluetooth Internals tersedia di Chrome di
about://bluetooth-internals sehingga Anda dapat memeriksa semua hal tentang perangkat Bluetooth di sekitar: status, layanan, karakteristik, dan deskriptor.
Sebaiknya Anda juga melihat halaman Cara melaporkan bug Web Bluetooth resmi karena proses men-debug Bluetooth terkadang sulit.
Langkah berikutnya
Periksa status penerapan browser dan platform terlebih dahulu untuk mengetahui bagian mana dari Web Bluetooth API yang saat ini diterapkan.
Meskipun masih belum lengkap, berikut cuplikan singkat tentang hal-hal yang akan hadir dalam waktu dekat:
- Memindai iklan BLE di sekitar
akan terjadi dengan
navigator.bluetooth.requestLEScan(). - Peristiwa
serviceaddedbaru akan melacak Layanan GATT Bluetooth yang baru ditemukan, sedangkan peristiwaserviceremovedakan melacak layanan yang dihapus. Peristiwaservicechangedbaru akan diaktifkan saat karakteristik dan/atau deskriptor ditambahkan atau dihapus dari Layanan GATT Bluetooth.
Menunjukkan dukungan untuk API
Apakah Anda berencana menggunakan Web Bluetooth API? Dukungan publik Anda membantu tim Chrome memprioritaskan fitur dan menunjukkan kepada vendor browser lain betapa pentingnya dukungan untuk fitur tersebut.
Kirim tweet ke @ChromiumDev menggunakan hashtag
#WebBluetooth
dan beri tahu kami di mana dan bagaimana Anda menggunakannya.
Resource
- Stack Overflow
- Status Fitur Chrome
- Bug Penerapan Chrome
- Spesifikasi Web Bluetooth
- Masalah Spesifikasi di GitHub
- Aplikasi BLE Peripheral Simulator
Ucapan terima kasih
Terima kasih kepada Kayce Basques yang telah meninjau.