Web Bluetooth API memungkinkan situs berkomunikasi dengan perangkat Bluetooth.
Bagaimana jika saya katakan bahwa situs web dapat berkomunikasi dengan perangkat Bluetooth di sekitar dengan cara yang aman dan menjaga privasi? Dengan cara ini, pemantau detak jantung, menyanyikan bohlam, dan bahkan kura-kura dapat berinteraksi langsung dengan situs web.
Hingga saat ini, kemampuan untuk berinteraksi dengan perangkat Bluetooth hanya memungkinkan aplikasi khusus platform. Web Bluetooth API bertujuan untuk mengubah ini dan juga membawanya ke browser web.
Sebelum kita mulai
Dokumen ini mengasumsikan bahwa Anda memiliki pengetahuan dasar tentang cara kerja Bluetooth Hemat Energi (BLE) dan Profil Atribut Generik.
Meskipun spesifikasi Web Bluetooth API belum diselesaikan, penulis spesifikasi secara aktif mencari developer yang antusias untuk mencoba API ini dan memberikan masukan terkait spesifikasi dan masukan terkait implementasi.
Sebagian Web Bluetooth API tersedia di ChromeOS, Chrome untuk Android 6.0, Mac (Chrome 56), dan Windows 10 (Chrome 70). Ini berarti Anda akan 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 deskripsi Bluetooth. Lihat tabel Kompatibilitas browser MDN untuk informasi selengkapnya.
Untuk Linux dan Windows versi sebelumnya, aktifkan
flag #experimental-web-platform-features
di about://flags
.
Tersedia untuk uji coba origin
Untuk mendapatkan masukan sebanyak mungkin 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 ini telah berhasil berakhir pada Januari 2017.
Persyaratan keamanan
Untuk memahami konsekuensi keamanan, saya merekomendasikan postingan Web Bluetooth Security Model dari Jeffrey Yasskin, software engineer di tim Chrome, yang mengerjakan spesifikasi Web Bluetooth API.
Khusus HTTPS
Karena API eksperimental ini adalah fitur canggih baru yang ditambahkan ke web, API ini hanya tersedia untuk konteks yang aman. Ini berarti Anda harus mempertimbangkan TLS.
Gestur pengguna diperlukan
Sebagai fitur keamanan, menemukan perangkat Bluetooth dengan
navigator.bluetooth.requestDevice
harus dipicu oleh gestur pengguna seperti
sentuhan atau klik mouse. Kita berbicara tentang mendengarkan peristiwa pointerup
, click
, dan touchend
.
button.addEventListener('pointerup', function(event) {
// Call navigator.bluetooth.requestDevice
});
Memahami kode
Web Bluetooth API sangat bergantung pada Promise JavaScript. Jika Anda belum
familier dengannya, lihat tutorial Promise yang bermanfaat ini. Satu hal lagi, () => {}
adalah Fungsi Panah ECMAScript 2015.
Meminta perangkat Bluetooth
Versi spesifikasi Web Bluetooth API ini memungkinkan situs, yang berjalan dengan peran Pusat, untuk terhubung ke Server GATT jarak jauh melalui koneksi BLE. Dukungan ini mendukung komunikasi antar-perangkat 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 dengan pemilih
perangkat tempat mereka dapat memilih satu perangkat atau membatalkan permintaan.
Fungsi navigator.bluetooth.requestDevice()
mengambil objek wajib yang
menentukan filter. Filter ini digunakan untuk hanya menampilkan 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 format 16 atau 32-bit singkat.
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 harus menentukan kunci optionalServices
agar dapat mengakses layanan apa pun yang tidak disertakan dalam filter layanan. Jika tidak, Anda akan mendapatkan pesan error 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
khusus produsen yang diiklankan dengan kunci filter manufacturerData
. Kunci ini
adalah array objek dengan kunci ID perusahaan Bluetooth wajib bernama
companyIdentifier
. Anda juga dapat menyediakan awalan data yang memfilter
data produsen dari perangkat Bluetooth yang dimulai dengannya. Perhatikan bahwa Anda juga harus menentukan kunci optionalServices
agar dapat mengakses layanan apa pun yang tidak disertakan dalam filter layanan. Jika tidak, Anda akan menerima pesan error
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); });
Mask 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 alat pilih 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); });
Jangan menggunakan filter
Terakhir, sebagai ganti filters
, Anda dapat menggunakan tombol acceptAllDevices
untuk menampilkan semua
perangkat Bluetooth di sekitar. Anda juga harus menentukan kunci optionalServices
agar dapat mengakses beberapa layanan. Jika tidak, Anda akan mendapatkan pesan {i>error<i}
saat mencoba mengaksesnya.
navigator.bluetooth.requestDevice({
acceptAllDevices: true,
optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Menghubungkan ke perangkat Bluetooth
Jadi, apa yang Anda lakukan setelah memiliki BluetoothDevice
? Mari kita hubungkan ke Server GATT jarak jauh 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 dari perangkat Bluetooth jarak jauh. Sekarang kita ingin mendapatkan Layanan GATT Utama dan membaca karakteristik yang dimiliki layanan ini. Misalnya, mari kita coba membaca tingkat pengisian daya baterai perangkat saat ini.
Pada contoh sebelumnya, battery_level
adalah Karakteristik Tingkat Baterai
standar.
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 Anda 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 Baca Contoh Perubahan Nilai Karakteristik untuk mengetahui cara menangani notifikasi GATT mendatang 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 semudah membacanya. Kali ini, mari kita gunakan Titik Kontrol Detak Jantung untuk mereset nilai kolom Energi Dibelanjakan ke 0 pada perangkat pemantau detak jantung.
Saya berjanji tidak ada keajaiban di sini. Semuanya dijelaskan di halaman Karakteristik Poin Kontrol Detak Jantung.
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 diberi tahu 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 koneksi terputus dan mengundang pengguna untuk terhubung 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. Perlu diketahui bahwa tindakan ini TIDAK akan menghentikan komunikasi perangkat Bluetooth jika aplikasi
lain sudah berkomunikasi dengan perangkat Bluetooth. Lihat Contoh
Pemutusan Koneksi Perangkat dan Contoh Penyambungan Ulang Otomatis untuk mempelajari lebih lanjut.
Membaca dan menulis ke deskriptor Bluetooth
Deskripsi GATT Bluetooth adalah atribut yang mendeskripsikan nilai karakteristik. Anda dapat membaca dan menulisnya dengan cara yang mirip dengan karakteristik GATT Bluetooth.
Mari kita lihat misalnya cara membaca deskripsi pengguna tentang interval pengukuran termometer kesehatan perangkat.
Pada contoh di bawah ini, health_thermometer
adalah layanan Termometer Kesehatan,
measurement_interval
karakteristik Interval Pengukuran, dan
gatt.characteristic_user_description
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 mengupdatenya 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 Bluetooth Web di bawah telah berhasil diuji. Untuk menikmati sampel ini secara maksimal, sebaiknya instal [Aplikasi Android Peripheral Simulator BLE] yang menyimulasikan periferal BLE dengan Layanan Baterai, Layanan Detak Jantung, atau Layanan Termometer Kesehatan.
Pemula
- Info Perangkat - mengambil informasi perangkat dasar dari Perangkat BLE.
- Level Baterai - mengambil informasi baterai dari BLE Perangkat yang mengiklankan informasi Baterai.
- Reset Energi - reset energi yang dikeluarkan dari Iklan Detak Jantung Perangkat BLE.
- Properti Karakteristik - menampilkan semua properti karakteristik tertentu dari Perangkat BLE.
- Notifikasi - memulai dan menghentikan notifikasi karakteristik dari Perangkat BLE.
- Pemutusan Koneksi Perangkat - putuskan koneksi dan dapatkan notifikasi dari pemutusan Perangkat BLE setelah menghubungkannya.
- Dapatkan Karakteristik - dapatkan semua karakteristik layanan yang diiklankan dari Perangkat BLE.
- Dapatkan Deskripsi - dapatkan 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 dilengkapi filter pengecualian dasar.
Menggabungkan beberapa operasi
- Karakteristik GAP - mendapatkan semua karakteristik GAP dari Perangkat BLE.
- Karakteristik Informasi Perangkat - dapatkan semua karakteristik Informasi Perangkat dari Perangkat BLE.
- Kehilangan Link - menetapkan karakteristik Tingkat Pemberitahuan pada Perangkat BLE (readValue & writeValue).
- Temukan Layanan & Karakteristik - temukan semua layanan utama yang dapat diakses dan karakteristiknya dari Perangkat BLE.
- Penyambungan Ulang Otomatis - menghubungkan kembali ke perangkat BLE yang terputus menggunakan algoritma backoff eksponensial.
- Baca Nilai Karakteristik yang Diubah - baca level baterai dan dapatkan notifikasi tentang perubahan dari Perangkat BLE.
- Membaca Deskripsi - membaca semua deskripsi karakteristik layanan dari Perangkat BLE.
- Tulis Deskripsi - tulis ke deskripsi "Deskripsi Pengguna Karakteristik" pada Perangkat BLE.
Lihat juga Demo Bluetooth Web pilihan dan Codelab Bluetooth Web resmi kami.
Library
- web-bluetooth-utils adalah modul npm yang menambahkan beberapa fungsi praktis ke API.
- Shim Web Bluetooth API tersedia di noble, modul pusat Node.js BLE yang paling populer. Hal ini memungkinkan Anda membuat webpack/browserify mulia tanpa perlu server WebSocket atau plugin lainnya.
- angular-web-bluetooth adalah modul untuk Angular yang memisahkan semua boilerplate yang diperlukan untuk mengonfigurasi Web Bluetooth API.
Alat
- Mulai Menggunakan Bluetooth Web adalah Aplikasi Web sederhana yang akan menghasilkan semua kode boilerplate JavaScript untuk mulai berinteraksi dengan perangkat Bluetooth. Masukkan nama perangkat, layanan, karakteristik, tentukan propertinya, dan Anda siap memulai.
- Jika Anda sudah menjadi developer Bluetooth, Plugin Web Bluetooth Developer Studio juga akan menghasilkan kode JavaScript Bluetooth Web untuk perangkat Bluetooth Anda.
Tips
Halaman Internal Bluetooth tersedia pada Chrome di
about://bluetooth-internals
sehingga Anda dapat memeriksa semua hal tentang
perangkat Bluetooth di sekitar: status, layanan, karakteristik, dan deskripsi.
Sebaiknya Anda juga melihat halaman resmi Cara melaporkan bug Bluetooth Web karena terkadang men-debug Bluetooth terkadang sulit.
Langkah selanjutnya
Periksa status implementasi browser dan platform terlebih dahulu untuk mengetahui bagian dari Web Bluetooth API yang saat ini diterapkan.
Meskipun masih belum lengkap, berikut sedikit bocoran tentang apa yang akan segera tersedia dalam waktu dekat:
- Pemindaian iklan BLE di sekitar
akan terjadi dengan
navigator.bluetooth.requestLEScan()
. - Peristiwa
serviceadded
baru akan melacak Layanan GATT Bluetooth yang baru ditemukan, sedangkan peristiwaserviceremoved
akan melacak yang dihapus. Peristiwaservicechanged
baru akan diaktifkan saat karakteristik dan/atau deskripsi apa pun 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 mendukung fitur tersebut.
Kirim tweet ke @ChromiumDev menggunakan hashtag
#WebBluetooth
dan beri tahu kami di mana dan bagaimana Anda menggunakannya.
Referensi
- Stack Overflow
- Status Fitur Chrome
- Bug Implementasi Chrome
- Spesifikasi Bluetooth web
- Masalah Spesifikasi di GitHub
- Aplikasi Peripheral Simulator BLE
Ucapan terima kasih
Terima kasih kepada Kayce Basques yang telah meninjau artikel ini. Banner besar oleh SparkFun Electronics dari Boulder, AS.