Pengantar WebBluetooth

Diterbitkan: 2022-03-10
Ringkasan cepat Dengan Aplikasi Web Progresif, kini Anda dapat menggunakan web untuk membuat aplikasi lengkap. Berkat sejumlah besar spesifikasi dan fitur baru, kami dapat melakukan berbagai hal dengan web yang Anda gunakan untuk menulis aplikasi asli. Namun, berbicara dengan perangkat keras masih merupakan jembatan yang terlalu jauh sampai sekarang. Berkat WebBluetooth, kini kami dapat membuat PWA yang dapat mengontrol lampu Anda, mengendarai mobil, atau bahkan mengontrol drone.

Dengan Progressive Web Apps, web semakin dekat dengan aplikasi asli. Namun, dengan manfaat tambahan yang melekat pada web seperti privasi dan kompatibilitas lintas platform.

Web secara tradisional sangat bagus untuk berbicara dengan server di jaringan, dan ke server di Internet secara khusus. Sekarang web bergerak menuju aplikasi, kami juga membutuhkan kemampuan yang sama dengan yang dimiliki aplikasi asli.

Jumlah spesifikasi dan fitur baru yang telah diterapkan dalam beberapa tahun terakhir di browser sangat mengejutkan. Kami memiliki spesifikasi untuk menangani 3D seperti WebGL dan WebGPU yang akan datang. Kami dapat melakukan streaming dan menghasilkan audio, menonton video, dan menggunakan webcam sebagai perangkat input. Kami juga dapat menjalankan kode dengan kecepatan hampir asli menggunakan WebAssembly. Selain itu, meskipun awalnya hanya media jaringan, web telah beralih ke dukungan offline dengan pekerja layanan.

Itu bagus dan semuanya, tetapi satu area hampir menjadi domain eksklusif untuk aplikasi asli: berkomunikasi dengan perangkat. Itu adalah masalah yang telah lama kami coba pecahkan, dan itu adalah sesuatu yang mungkin pernah dihadapi semua orang pada satu titik. Web sangat baik untuk berbicara dengan server, tetapi tidak untuk berbicara dengan perangkat . Pikirkan, misalnya, mencoba mengatur router di jaringan Anda. Kemungkinan Anda harus memasukkan alamat IP dan menggunakan antarmuka web melalui koneksi HTTP biasa tanpa keamanan apa pun. Itu hanya pengalaman yang buruk dan keamanan yang buruk. Selain itu, bagaimana Anda tahu apa alamat IP yang benar?

Lebih banyak setelah melompat! Lanjutkan membaca di bawah ini

HTTP juga merupakan masalah pertama yang kami hadapi saat mencoba membuat Aplikasi Web Progresif yang mencoba berbicara dengan perangkat. PWA hanya HTTPS, dan perangkat lokal selalu hanya HTTP. Anda memerlukan sertifikat untuk HTTPS, dan untuk mendapatkan sertifikat, Anda memerlukan server yang tersedia untuk umum dengan nama domain (saya berbicara tentang perangkat di jaringan lokal kami yang tidak terjangkau).

Jadi untuk banyak perangkat, Anda memerlukan aplikasi asli untuk mengatur perangkat dan menggunakannya karena aplikasi asli tidak terikat pada batasan platform web dan dapat menawarkan pengalaman yang menyenangkan bagi penggunanya. Namun, saya tidak ingin mengunduh aplikasi 500 MB untuk melakukan itu. Mungkin perangkat yang Anda miliki sudah berumur beberapa tahun, dan aplikasi tidak pernah diperbarui untuk berjalan di ponsel baru Anda. Mungkin Anda ingin menggunakan komputer desktop atau laptop, dan pabrikan hanya membuat aplikasi seluler. Juga bukan pengalaman yang ideal.

WebBluetooth adalah spesifikasi baru yang telah diterapkan di Chrome dan Samsung Internet yang memungkinkan kita berkomunikasi langsung ke perangkat Bluetooth Low Energy dari browser. Aplikasi Web Progresif dalam kombinasi dengan WebBluetooth menawarkan keamanan dan kenyamanan aplikasi web dengan kekuatan untuk berbicara langsung dengan perangkat.

Bluetooth memiliki nama yang sangat buruk karena jangkauan terbatas, kualitas audio yang buruk, dan masalah pemasangan. Tapi, hampir semua masalah itu adalah masa lalu. Bluetooth Low Energy adalah spesifikasi modern yang tidak ada hubungannya dengan spesifikasi Bluetooth lama , selain menggunakan spektrum frekuensi yang sama. Lebih dari 10 juta perangkat dikirimkan dengan dukungan Bluetooth setiap hari. Itu termasuk komputer dan telepon, tetapi juga berbagai perangkat seperti monitor detak jantung dan glukosa, perangkat IoT seperti bola lampu dan mainan seperti mobil dan drone yang dapat dikendalikan dari jarak jauh.

Bacaan yang disarankan : Memahami Platform Berbasis API: Panduan Untuk Manajer Produk

Bagian Teori yang Membosankan

Karena Bluetooth sendiri bukanlah teknologi web, ia menggunakan beberapa kosakata yang mungkin tampak asing bagi kita. Jadi mari kita bahas cara kerja Bluetooth dan beberapa terminologinya.

Setiap perangkat Bluetooth adalah 'Perangkat pusat' atau 'Periferal'. Hanya perangkat pusat yang dapat memulai komunikasi dan hanya dapat berbicara dengan periferal. Contoh perangkat pusat adalah komputer atau telepon seluler.

Sebuah periferal tidak dapat memulai komunikasi dan hanya dapat berbicara dengan perangkat pusat. Selain itu, periferal hanya dapat berbicara dengan satu perangkat pusat pada saat yang bersamaan. Sebuah periferal tidak dapat berbicara dengan periferal lain.

telepon di tengah, berbicara dengan beberapa periferal, seperti drone, mainan robot, monitor detak jantung, dan bola lampu
Perangkat pusat dapat berbicara dengan beberapa periferal. (Pratinjau besar)

Perangkat pusat dapat berbicara dengan beberapa periferal secara bersamaan dan dapat menyampaikan pesan jika diinginkan. Jadi monitor detak jantung tidak dapat berbicara dengan bola lampu Anda, namun, Anda dapat menulis program yang berjalan pada perangkat pusat yang menerima detak jantung Anda dan mengubah lampu menjadi merah jika detak jantung melebihi ambang batas tertentu.

Ketika kita berbicara tentang WebBluetooth, kita berbicara tentang bagian spesifik dari spesifikasi Bluetooth yang disebut Generic Attribute Profile, yang memiliki singkatan GATT yang sangat jelas. (Tampaknya, GAP sudah diambil.)

Dalam konteks GATT, kita tidak lagi berbicara tentang perangkat pusat dan periferal, tetapi klien dan server. Bola lampu Anda adalah server. Itu mungkin tampak kontra-intuitif, tetapi sebenarnya masuk akal jika Anda memikirkannya. Bola lampu menawarkan layanan, yaitu cahaya. Sama seperti ketika browser terhubung ke server di Internet, ponsel atau komputer Anda adalah klien yang terhubung ke server GATT di bola lampu.

Setiap server menawarkan satu atau lebih layanan. Beberapa dari layanan tersebut secara resmi merupakan bagian dari standar, tetapi Anda juga dapat menentukan layanan Anda sendiri. Dalam hal monitor detak jantung, ada layanan resmi yang ditentukan dalam spesifikasi. Dalam hal bola lampu, tidak ada, dan hampir setiap pabrikan mencoba menemukan kembali roda. Setiap layanan memiliki satu atau lebih karakteristik. Setiap karakteristik memiliki nilai yang dapat dibaca atau ditulis. Untuk saat ini, akan lebih baik untuk menganggapnya sebagai array objek, dengan setiap objek memiliki properti yang memiliki nilai.

hierarki layanan dan karakteristik dibandingkan dengan konstruksi yang lebih dikenal dari JavaScript - server mirip dengan array objek, layanan ke objek dalam array itu, karakteristik ke properti objek itu dan keduanya memiliki nilai
Hirarki layanan dan karakteristik yang disederhanakan. (Pratinjau besar)

Tidak seperti properti objek, layanan dan karakteristik tidak diidentifikasi oleh string. Setiap layanan dan karakteristik memiliki UUID unik yang panjangnya bisa 16 atau 128 bit. Secara resmi, UUID 16 bit dicadangkan untuk standar resmi, tetapi hampir tidak ada yang mengikuti aturan itu. Akhirnya, setiap nilai adalah array byte. Tidak ada tipe data mewah di Bluetooth.

Melihat Lebih Dekat Bola Lampu Bluetooth

Jadi mari kita lihat perangkat Bluetooth yang sebenarnya: Mipow Playbulb Sphere. Anda dapat menggunakan aplikasi seperti BLE Scanner, atau nRF Connect untuk terhubung ke perangkat dan melihat semua layanan dan karakteristik. Dalam hal ini, saya menggunakan aplikasi BLE Scanner untuk iOS.

Hal pertama yang Anda lihat saat menyambungkan ke bola lampu adalah daftar layanan. Ada beberapa yang standar seperti layanan informasi perangkat dan layanan baterai. Tetapi ada juga beberapa layanan kustom. Saya sangat tertarik dengan layanan dengan UUID 16 bit 0xff0f . Jika Anda membuka layanan ini, Anda dapat melihat daftar karakteristik yang panjang. Saya tidak tahu apa yang dilakukan sebagian besar karakteristik ini, karena mereka hanya diidentifikasi oleh UUID dan sayangnya mereka merupakan bagian dari layanan kustom; mereka tidak distandarisasi, dan pabrikan tidak memberikan dokumentasi apa pun.

Karakteristik pertama dengan UUID 0xfffc tampaknya sangat menarik. Ini memiliki nilai empat byte. Jika kita mengubah nilai byte ini dari 0x00000000 menjadi 0x00ff0000 , bola lampu berubah menjadi merah. Mengubahnya menjadi 0x0000ff00 mengubah bola lampu menjadi hijau, dan 0x000000ff menjadi biru. Ini adalah warna RGB dan sesuai persis dengan warna hex yang kita gunakan dalam HTML dan CSS.

Apa yang dilakukan byte pertama itu? Nah, jika kita mengubah nilainya menjadi 0xff000000 , bola lampu menjadi putih. Bola lampu berisi empat LED yang berbeda, dan dengan mengubah nilai masing-masing dari empat byte, kita dapat membuat setiap warna yang kita inginkan.

API WebBluetooth

Sungguh luar biasa bahwa kita dapat menggunakan aplikasi asli untuk mengubah warna bola lampu, tetapi bagaimana kita melakukannya dari browser? Ternyata dengan pengetahuan tentang Bluetooth dan GATT yang baru saja kita pelajari, ini relatif mudah berkat WebBluetooth API. Hanya perlu beberapa baris JavaScript untuk mengubah warna bola lampu.

Mari kita membahas API WebBluetooth.

Menghubungkan ke Perangkat

Hal pertama yang perlu kita lakukan adalah menghubungkan dari browser ke perangkat. Kami memanggil fungsi navigator.bluetooth.requestDevice() dan menyediakan fungsi dengan objek konfigurasi. Objek itu berisi informasi tentang perangkat mana yang ingin kita gunakan dan layanan mana yang harus tersedia untuk API kita.

Dalam contoh berikut, kami memfilter nama perangkat, karena kami hanya ingin melihat perangkat yang berisi awalan PLAYBULB di namanya. Kami juga menentukan 0xff0f sebagai layanan yang ingin kami gunakan. Karena fungsi requestDevice() mengembalikan sebuah janji, kita bisa menunggu hasilnya.

 let device = await navigator.bluetooth.requestDevice({ filters: [ { namePrefix: 'PLAYBULB' } ], optionalServices: [ 0xff0f ] });

Saat kita memanggil fungsi ini, sebuah jendela muncul dengan daftar perangkat yang sesuai dengan filter yang telah kita tentukan. Sekarang kita harus memilih perangkat yang ingin kita sambungkan secara manual. Itu adalah langkah penting untuk keamanan dan privasi dan memberikan kontrol kepada pengguna. Pengguna memutuskan apakah aplikasi web diizinkan untuk terhubung, dan tentu saja, ke perangkat mana yang diizinkan untuk terhubung. Aplikasi web tidak bisa mendapatkan daftar perangkat atau terhubung tanpa pengguna secara manual memilih perangkat.

browser Chrome dengan jendela yang perlu digunakan pengguna untuk terhubung ke perangkat, dengan bola lampu terlihat di daftar perangkat
Pengguna harus terhubung secara manual dengan memilih perangkat. (Pratinjau besar)

Setelah kita mendapatkan akses ke perangkat, kita dapat terhubung ke server GATT dengan memanggil fungsi connect() pada properti gatt perangkat dan menunggu hasilnya.

 let server = await device.gatt.connect();

Setelah kami memiliki server, kami dapat memanggil getPrimaryService() di server dengan UUID layanan yang ingin kami gunakan sebagai parameter dan menunggu hasilnya.

 let service = await server.getPrimaryService(0xff0f);

Kemudian panggil getCharacteristic() pada layanan dengan UUID karakteristik sebagai parameter dan sekali lagi menunggu hasilnya.

Kami sekarang memiliki karakteristik kami yang dapat kami gunakan untuk menulis dan membaca data:

 let characteristic = await service.getCharacteristic(0xfffc);

Menulis Data

Untuk menulis data, kita dapat memanggil fungsi writeValue() pada karakteristik dengan nilai yang ingin kita tulis sebagai ArrayBuffer, yang merupakan metode penyimpanan untuk data biner. Alasan kita tidak dapat menggunakan array biasa adalah karena array biasa dapat berisi data dari berbagai jenis dan bahkan dapat memiliki lubang kosong.

Karena kami tidak dapat membuat atau memodifikasi ArrayBuffer secara langsung, kami menggunakan 'array yang diketik' sebagai gantinya. Setiap elemen dari array yang diketik selalu bertipe sama, dan tidak memiliki lubang. Dalam kasus kami, kami akan menggunakan Uint8Array , yang tidak ditandatangani sehingga tidak dapat berisi angka negatif apa pun; bilangan bulat, sehingga tidak dapat berisi pecahan; dan itu adalah 8 bit dan hanya dapat berisi nilai dari 0 hingga 255. Dengan kata lain: array byte.

 characteristic.writeValue( new Uint8Array([ 0, r, g, b ]) );

Kita sudah tahu bagaimana bola lampu ini bekerja. Kami harus menyediakan empat byte, satu untuk setiap LED. Setiap byte memiliki nilai antara 0 dan 255, dan dalam hal ini, kami hanya ingin menggunakan LED merah, hijau dan biru, jadi kami membiarkan LED putih mati, dengan menggunakan nilai 0.

Membaca Data

Untuk membaca warna bola lampu saat ini, kita dapat menggunakan fungsi readValue() dan menunggu hasilnya.

 let value = await characteristic.readValue(); let r = value.getUint8(1); let g = value.getUint8(2); let b = value.getUint8(3);

Nilai yang kami dapatkan kembali adalah DataView dari ArrayBuffer, dan ia menawarkan cara untuk mengeluarkan data dari ArrayBuffer. Dalam kasus kami, kami dapat menggunakan fungsi getUint8() dengan indeks sebagai parameter untuk mengeluarkan byte individual dari array.

Mendapatkan Pemberitahuan Perubahan

Terakhir, ada juga cara untuk mendapatkan notifikasi saat nilai perangkat berubah. Itu tidak terlalu berguna untuk bola lampu, tetapi untuk monitor detak jantung kami, kami memiliki nilai yang terus berubah, dan kami tidak ingin melakukan polling nilai saat ini secara manual setiap detik.

 characteristic.addEventListener( 'characteristicvaluechanged', e => { let r = e.target.value.getUint8(1); let g = e.target.value.getUint8(2); let b = e.target.value.getUint8(3); } ); characteristic.startNotifications();

Untuk mendapatkan callback setiap kali suatu nilai berubah, kita harus memanggil fungsi addEventListener() pada karakteristik dengan parameter characteristicvaluechanged dan fungsi callback. Setiap kali nilai berubah, fungsi panggilan balik akan dipanggil dengan objek peristiwa sebagai parameter, dan kita bisa mendapatkan data dari properti nilai dari target peristiwa. Dan, terakhir ekstrak byte individu lagi dari DataView dari ArrayBuffer.

Karena bandwidth pada jaringan Bluetooth terbatas, kita harus memulai mekanisme notifikasi ini secara manual dengan memanggil startNotifications() pada karakteristik. Jika tidak, jaringan akan dibanjiri oleh data yang tidak perlu. Selain itu, karena perangkat ini biasanya menggunakan baterai, setiap byte yang tidak perlu kita kirim pasti akan meningkatkan masa pakai baterai perangkat karena radio internal tidak perlu sering dinyalakan.

Kesimpulan

Kami sekarang telah menggunakan lebih dari 90% WebBluetooth API. Hanya dengan beberapa panggilan fungsi dan mengirim 4 byte, Anda dapat membuat aplikasi web yang mengontrol warna bola lampu Anda. Jika Anda menambahkan beberapa baris lagi, Anda bahkan dapat mengontrol mobil mainan atau menerbangkan drone. Dengan semakin banyak perangkat Bluetooth yang masuk ke pasar, kemungkinannya tidak terbatas.

Sumber Daya Lebih Lanjut

  • Bluetooth.rocks! Demo | (Kode sumber di GitHub)
  • “Spesifikasi Bluetooth Web,” Grup Komunitas Bluetooth Web
  • Buka Registri GATT Kumpulan dokumentasi tidak resmi untuk layanan Atribut Generik untuk perangkat Bluetooth Hemat Energi.