Web Bluetooth API memungkinkan situs berkomunikasi dengan perangkat Bluetooth.
Bagaimana jika saya sampaikan bahwa situs dapat berkomunikasi dengan perangkat Bluetooth di sekitar dengan cara yang aman dan menjaga privasi? Dengan cara ini, pemantau detak jantung, bernyanyi bola lampu, dan bahkan kura-kura dapat berinteraksi langsung dengan situs.
Hingga saat ini, kemampuan untuk berinteraksi dengan perangkat Bluetooth masih dapat dilakukan hanya untuk aplikasi khusus platform. Web Bluetooth API bertujuan untuk mengubah ini dan membawanya ke {i>browser<i} web.
Sebelum kita mulai
Dokumen ini mengasumsikan bahwa Anda memiliki pengetahuan dasar tentang cara kerja Bluetooth Rendah Energy (BLE) dan Generic Attribute Profile.
Meskipun spesifikasi Web Bluetooth API belum difinalisasi, spesifikasinya penulis secara aktif mencari pengembang yang antusias untuk mencoba API ini dan memberikan masukan tentang spesifikasi dan masukan tentang penerapan.
Sebagian dari Web Bluetooth API tersedia di ChromeOS, Chrome untuk Android 6.0, Mac (Chrome 56) dan Windows 10 (Chrome 70). Ini berarti Anda harus dapat untuk meminta dan menghubungkan ke perangkat Bluetooth Hemat Energi terdekat, Karakteristik Bluetooth baca/tulis, menerima Notifikasi GATT, mengetahui ketika perangkat Bluetooth terputus, dan bahkan membaca dan menulis ke Deskripsi Bluetooth. Lihat tabel Kompatibilitas browser MDN untuk informasi selengkapnya tidak akurat atau tidak sesuai.
Untuk Linux dan versi Windows sebelumnya, aktifkan
Flag #experimental-web-platform-features
di about://flags
.
Tersedia untuk uji coba origin
Untuk mendapatkan umpan balik sebanyak mungkin dari pengembang yang menggunakan web Bluetooth API di lapangan, Chrome telah menambahkan fitur ini sebelumnya di Chrome 53 sebagai uji coba origin untuk ChromeOS, Android, dan Mac.
Uji coba ini berhasil berakhir pada Januari 2017.
Persyaratan keamanan
Untuk memahami konsekuensi keamanan, sebaiknya baca artikel Web Bluetooth Security Postingan model dari Jeffrey Yasskin, software engineer di tim Chrome, yang sesuai dengan spesifikasi Web Bluetooth API.
Khusus HTTPS
Karena API eksperimental ini adalah fitur baru canggih yang ditambahkan ke web, disediakan hanya untuk mengamankan konteks. Ini berarti Anda harus membangun dengan TLS.
Gestur pengguna diperlukan
Sebagai fitur keamanan, menemukan perangkat Bluetooth dengan
navigator.bluetooth.requestDevice
harus dipicu oleh gestur pengguna seperti
dengan satu sentuhan atau klik {i>mouse<i}. 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 tidak
pelajari keduanya, lihat tutorial Promise yang menarik ini. Satu hal lagi,
() => {}
adalah Fungsi panah ECMAScript 2015.
Meminta perangkat Bluetooth
Versi spesifikasi Web Bluetooth API ini memungkinkan situs web, yang berjalan di peran Sentral, untuk terhubung ke Server GATT jarak jauh melalui koneksi BLE. Ini mendukung komunikasi antar perangkat yang mengimplementasikan Bluetooth 4.0 atau yang lebih baru.
Saat situs meminta akses ke perangkat di sekitar menggunakan
navigator.bluetooth.requestDevice
, browser meminta pengguna dengan perangkat
pilihan di mana 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 GATT Bluetooth Layanan Baterai:
navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Jika Layanan GATT Bluetooth Anda tidak ada dalam daftar Bluetooth standar layanan GATT, Anda dapat memberikan UUID Bluetooth lengkap atau Berbentuk 16- atau 32-bit.
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 namePrefix
tombol filter. Perhatikan bahwa dalam kasus ini, Anda juga perlu mendefinisikan
optionalServices
agar dapat mengakses layanan apa pun yang tidak termasuk dalam
filter layanan. Jika tidak, Anda akan mendapatkan pesan {i>error<i}
saat mencoba mengakses
mereka.
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 produsennya
data tertentu yang diiklankan dengan kunci filter manufacturerData
. Kunci ini
adalah array objek dengan kunci ID perusahaan Bluetooth wajib yang diberi nama
companyIdentifier
. Anda juga dapat menyediakan awalan data yang memfilter
data produsen dari perangkat Bluetooth yang memulainya. Perhatikan bahwa Anda akan
juga harus menentukan kunci optionalServices
agar dapat mengakses layanan
tidak disertakan dalam filter layanan. Jika tidak, Anda akan
mendapat pesan {i>error<i} 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); });
{i>Mask<i} juga dapat digunakan dengan awalan data untuk mencocokkan beberapa pola dalam data produsen. Lihat Penjelasan filter data Bluetooth untuk mempelajari banyak lagi.
Filter pengecualian
Opsi exclusionFilters
di navigator.bluetooth.requestDevice()
memungkinkan
Anda akan mengecualikan beberapa perangkat dari pemilih browser. Hal 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 terdekat. Anda juga harus menentukan optionalServices
kunci untuk dapat
mengakses beberapa layanan. Jika tidak, Anda akan menerima pesan 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 Anda lakukan sekarang setelah memiliki BluetoothDevice
? Mari hubungkan ke
Server GATT jarak jauh Bluetooth yang menyimpan layanan dan karakteristik
definisi.
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 termasuk dalam layanan ini. Misalnya, mari coba membaca tingkat pengisian daya saat ini baterai perangkat.
Pada contoh berikutnya, battery_level
adalah Level Baterai standar
Karakteristik.
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 khusus, Anda dapat memberikan atribut
UUID Bluetooth penuh atau bentuk
16- atau 32-bit pendek untuk
service.getCharacteristic
.
Perhatikan bahwa Anda juga dapat menambahkan pemroses peristiwa characteristicvaluechanged
pada
karakteristik data untuk menangani pembacaan nilainya. Lihat Karakteristik Baca
Contoh Nilai yang Diubah untuk melihat cara menangani GATT mendatang secara opsional
notifikasi juga.
…
.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 Energi yang Dikeluarkan ke 0 pada perangkat pemantau detak jantung.
Aku berjanji tidak akan ada sihir di sini. Semuanya dijelaskan dalam artikel Kontrol Detak Jantung Halaman Karakteristik Titik.
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 Pengukuran Detak Jantung perubahan karakteristik pada 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
}
Sampel Notifikasi menunjukkan cara menghentikan notifikasi dengan
stopNotifications()
dan menghapus characteristicvaluechanged
yang ditambahkan dengan benar
pemroses peristiwa.
Memutuskan hubungan dari Perangkat Bluetooth
Untuk memberikan pengalaman pengguna yang lebih baik, Anda mungkin ingin memproses peristiwa koneksi terputus dan undang 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 peristiwa gattserverdisconnected
yang ada
pemroses. Perhatikan bahwa ini TIDAK akan menghentikan komunikasi perangkat Bluetooth jika yang lain
aplikasi sudah berkomunikasi dengan perangkat Bluetooth. Lihat tab Perangkat
Putuskan Koneksi Contoh dan Contoh Sambungan 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 Bluetooth GATT karakteristik.
Mari kita lihat, misalnya, cara membaca deskripsi pengguna terkait pengukuran interval termometer kesehatan perangkat.
Pada contoh di bawah, health_thermometer
adalah layanan Termometer Kesehatan,
measurement_interval
karakteristik Interval Pengukuran, dan
gatt.characteristic_user_description
Deskripsi Karakteristik Pengguna
.
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 dari termometer kesehatan perangkat. Mari kita lihat cara memperbaruinya dan menulis dengan sejumlah nilai.
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 menikmatinya sampel secara maksimal, sebaiknya instal [BLE Peripheral Simulator BLE Aplikasi Android] yang menyimulasikan periferal BLE dengan Layanan Baterai, Detak Jantung Layanan, atau Layanan Termometer Kesehatan.
Pemula
- Info Perangkat - mengambil informasi dasar perangkat dari Perangkat BLE.
- Level Baterai - mengambil informasi baterai dari informasi Baterai iklan Perangkat BLE.
- Reset Energi - mereset energi yang dikeluarkan dari Detak Jantung iklan Perangkat BLE.
- Properti Karakteristik - menampilkan semua properti karakteristik tertentu dari Perangkat BLE.
- Notifikasi - memulai dan menghentikan notifikasi karakteristik dari Perangkat BLE.
- Pemutusan Sambungan Perangkat - putuskan sambungan dan dapatkan notifikasi saat Perangkat BLE terputus setelah menyambungkannya.
- Dapatkan Karakteristik - dapatkan semua karakteristik layanan yang diiklankan dari Perangkat BLE.
- Mendapatkan Deskripsi - dapatkan semua karakteristik' deskripsi layanan yang diiklankan dari Perangkat BLE.
- Filter Data Manufacturer - mengambil informasi dasar perangkat dari Perangkat BLE yang cocok dengan data produsen.
- Filter Pengecualian - mengambil informasi dasar perangkat dari Perangkat BLE yang menampilkan filter pengecualian dasar.
Menggabungkan beberapa operasi
- Karakteristik GAP - dapatkan semua karakteristik GAP Perangkat BLE.
- Karakteristik Informasi Perangkat - dapatkan semua karakteristik Informasi Perangkat dari Perangkat BLE.
- Link Hilang - tetapkan karakteristik Tingkat Pemberitahuan Perangkat BLE (readValue &writeValue).
- Temukan Layanan & Karakteristik - temukan semua layanan utama yang dapat diakses dan karakteristiknya dari Perangkat BLE.
- Sambungan Ulang Otomatis - menghubungkan kembali ke perangkat BLE yang terputus menggunakan algoritma backoff eksponensial.
- Membaca Nilai Karakteristik yang Diubah - membaca level baterai dan mendapatkan notifikasi perubahan dari Perangkat BLE.
- Membaca Deskripsi - membaca semua deskripsi karakteristik layanan dari Perangkat BLE.
- Menulis Deskripsi - tulis ke deskriptor "Deskripsi Pengguna Karakteristik" pada Perangkat BLE.
Lihat Demo Bluetooth Web yang diseleksi dan juga Codelab Bluetooth Web resmi.
Perpustakaan
- web-bluetooth-utils adalah modul npm yang menambahkan beberapa fungsi praktis ke API.
- Shim Web Bluetooth API tersedia dalam noble, BLE Node.js yang paling populer modul pusat. Ini memungkinkan Anda untuk melakukan webpack/browserify noble tanpa perlu untuk server WebSocket atau plugin lainnya.
- angular-web-bluetooth adalah modul untuk Angular yang memisahkan semua boilerplate 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 sudah siap.
- Jika Anda sudah menjadi developer Bluetooth, Web Bluetooth Developer Studio Plugin juga akan membuat kode JavaScript Web Bluetooth untuk Perangkat Bluetooth.
Tips
Halaman Internal Bluetooth tersedia di Chrome di
about://bluetooth-internals
agar Anda dapat memeriksa semua hal di sekitar
Perangkat Bluetooth: status, layanan, karakteristik, dan deskriptor.
Sebaiknya baca juga Cara melaporkan bug Bluetooth Web resmi halaman sebagai proses debug Bluetooth terkadang sulit dilakukan.
Langkah berikutnya
Periksa status penerapan browser dan platform terlebih dahulu untuk mengetahui bagian mana dari Web Bluetooth API sedang diimplementasikan.
Meskipun belum lengkap, berikut sedikit bocoran tentang apa yang bisa diharapkan dalam waktu dekat mendatang:
- Memindai 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.servicechanged
baru peristiwa akan diaktifkan saat karakteristik dan/atau deskriptor ditambahkan atau dihapus dari Layanan GATT Bluetooth.
Menunjukkan dukungan untuk API
Anda berencana menggunakan Web Bluetooth API? Dukungan publik Anda membantu tim Chrome memprioritaskan fitur dan menunjukkan kepada vendor browser lain betapa pentingnya mendukung mereka.
Kirim tweet ke @ChromiumDev menggunakan hashtag
#WebBluetooth
serta beri tahu kami di mana dan bagaimana Anda menggunakannya.
Resource
- Stack Overflow
- Status Fitur Chrome
- Bug Implementasi Chrome
- Spesifikasi Bluetooth Web
- Masalah Spesifikasi di GitHub
- Aplikasi Simulator Periferal BLE
Ucapan terima kasih
Terima kasih kepada Kayce Basques yang telah membaca artikel ini. Banner besar oleh SparkFun Electronics dari Boulder, Amerika Serikat.