1. Tentang apa ini?
Dalam codelab yang telah dijelaskan ini, Anda akan mempelajari cara mengontrol lilin tanpa api tanpa LED PLAYBULB tanpa menggunakan apa pun selain JavaScript berkat Web Bluetooth API. Dalam prosesnya, Anda juga akan menggunakan fitur JavaScript ES2015 seperti Class, Fungsi panah, Peta, dan Promise.
Yang akan Anda pelajari
- Cara berinteraksi dengan perangkat Bluetooth di sekitar di JavaScript
- Cara menggunakan Class ES2015, fungsi Panah, Map, dan Promise
Yang Anda butuhkan
- Pemahaman dasar tentang pengembangan web
- Pengetahuan dasar tentang Bluetooth Hemat Energi (BLE) dan Profil Atribut Umum (GATT)
- Editor teks pilihan Anda
- Mac, Chromebook, atau Perangkat Android M dengan Aplikasi Browser Chrome dan kabel USB mikro ke USB.
2. Mainkan terlebih dahulu
Anda mungkin ingin melihat versi final aplikasi yang akan dibuat di https://googlecodelabs.github.io/candle-bluetooth dan bermain dengan perangkat Bluetooth Lilin PLAYBULB yang Anda miliki sebelum benar-benar mendalami codelab ini.
Anda juga bisa melihat saya mengubah warna di https://www.youtube.com/watch?v=fBCPA9gIxlU
3. Memulai persiapan
Download kode contoh
Anda bisa mendapatkan kode contoh untuk kode ini dengan mengunduh zip di sini:
atau dengan meng-clone repo git ini:
git clone https://github.com/googlecodelabs/candle-bluetooth.git
Jika Anda mendownload sumber sebagai zip, mengekstraknya akan memberi Anda folder root candle-bluetooth-master
.
Menginstal dan memverifikasi server web
Meskipun Anda bebas menggunakan server web Anda sendiri, codelab ini dirancang agar berfungsi dengan baik dengan Server Web Chrome. Jika Anda belum menginstal aplikasi tersebut, Anda dapat menginstalnya dari Chrome Web Store.
Setelah menginstal aplikasi Server Web untuk Chrome, klik pintasan Aplikasi pada kolom bookmark:
Pada jendela berikutnya, klik ikon Web Server:
Anda akan melihat dialog ini berikutnya, yang memungkinkan Anda mengonfigurasi server web lokal:
Klik tombol choose folder, dan pilih root repositori yang di-clone (atau tidak diarsipkan). Dengan begitu, Anda dapat menayangkan pekerjaan yang sedang berlangsung melalui URL yang ditandai dalam dialog server web (di bagian URL Server Web).
Di bawah Options, centang kotak di samping "Otomatis tampilkan index.html", seperti yang ditunjukkan di bawah:
Sekarang kunjungi situs Anda di browser web (dengan mengklik Web Server URL yang disorot) dan Anda akan melihat halaman yang terlihat seperti ini:
Jika ingin melihat tampilan aplikasi ini di ponsel Android, Anda harus mengaktifkan Proses debug jarak jauh di Android dan menyiapkan Penerusan port (nomor port secara default adalah 8887). Setelah itu, Anda cukup membuka tab Chrome baru ke http://localhost:8887 di ponsel Android.
Berikutnya
Pada tahap ini, aplikasi web ini belum melakukan banyak hal. Mari mulai menambahkan dukungan Bluetooth.
4. Temukan lilin
Kita akan mulai dengan menulis library yang menggunakan Class ES2015 JavaScript untuk perangkat Bluetooth Lilin PLAYBULB.
Tetap tenang. Sintaksis class tidak memperkenalkan model pewarisan berorientasi objek baru ke JavaScript. Ini hanya menyediakan sintaks yang jauh lebih jelas untuk membuat objek dan menangani pewarisan, seperti yang dapat Anda baca di bawah ini.
Pertama, mari tentukan class PlaybulbCandle
di playbulbCandle.js
dan buat instance playbulbCandle
yang akan tersedia di file app.js
nanti.
playbulbCandle.js
(function() {
'use strict';
class PlaybulbCandle {
constructor() {
this.device = null;
}
}
window.playbulbCandle = new PlaybulbCandle();
})();
Untuk meminta akses ke perangkat Bluetooth di sekitar, kita perlu memanggil navigator.bluetooth.requestDevice
. Karena perangkat Lilin PLAYBULB terus beriklan (jika belum dipasangkan) UUID Layanan GATT Bluetooth konstan yang dikenal dalam bentuk singkatnya sebagai 0xFF02
, kita dapat dengan mudah menentukan konstanta dan menambahkannya ke parameter layanan filter dalam metode connect
publik baru dari class PlaybulbCandle
.
Kita juga akan melacak secara internal objek BluetoothDevice
sehingga kita dapat mengaksesnya nanti jika diperlukan. Karena navigator.bluetooth.requestDevice
menampilkan Promise JavaScript ES2015, kita akan melakukannya dalam metode then
.
playbulbCandle.js
(function() {
'use strict';
const CANDLE_SERVICE_UUID = 0xFF02;
class PlaybulbCandle {
constructor() {
this.device = null;
}
connect() {
let options = {filters:[{services:[ CANDLE_SERVICE_UUID ]}]};
return navigator.bluetooth.requestDevice(options)
.then(function(device) {
this.device = device;
}.bind(this));
}
}
window.playbulbCandle = new PlaybulbCandle();
})();
Sebagai fitur keamanan, menemukan perangkat Bluetooth di sekitar dengan navigator.bluetooth.requestDevice
harus dipanggil melalui gestur pengguna seperti sentuhan atau klik mouse. Itulah mengapa kita akan memanggil metode connect
saat pengguna mengklik "Hubungkan" tombol di file app.js
:
app.js
document.querySelector('#connect').addEventListener('click', function(event) {
document.querySelector('#state').classList.add('connecting');
playbulbCandle.connect()
.then(function() {
console.log(playbulbCandle.device);
document.querySelector('#state').classList.remove('connecting');
document.querySelector('#state').classList.add('connected');
})
.catch(function(error) {
console.error('Argh!', error);
});
});
Menjalankan aplikasi
Pada tahap ini, kunjungi situs Anda di browser web (dengan mengklik URL Server Web yang disorot di aplikasi server web) atau cukup muat ulang halaman yang ada. Klik tombol "Hubungkan" berwarna hijau pilih perangkat di pemilih dan buka konsol Dev Tools favorit dengan pintasan keyboard Ctrl + Shift + J dan perhatikan bahwa objek BluetoothDevice
dicatat dalam log.
Anda mungkin mengalami kesalahan jika Bluetooth nonaktif dan/atau perangkat bluetooth Lilin PLAYBULB nonaktif. Jika demikian, aktifkan dan lanjutkan lagi.
Bonus Wajib
Saya tidak tahu dengan Anda, tapi saya sudah melihat terlalu banyak function() {}
dalam kode ini. Sebagai gantinya, mari kita beralih ke Fungsi Panah JavaScript ES2015 () => {}
. Game ini sangat membantu: Semua kesenangan fungsi anonim, tanpa kesedihan yang mengikat.
playbulbCandle.js
(function() {
'use strict';
const CANDLE_SERVICE_UUID = 0xFF02;
class PlaybulbCandle {
constructor() {
this.device = null;
}
connect() {
let options = {filters:[{services:[ CANDLE_SERVICE_UUID ]}]};
return navigator.bluetooth.requestDevice(options)
.then(device => {
this.device = device;
});
}
}
window.playbulbCandle = new PlaybulbCandle();
})();
app.js
document.querySelector('#connect').addEventListener('click', event => {
playbulbCandle.connect()
.then(() => {
console.log(playbulbCandle.device);
document.querySelector('#state').classList.remove('connecting');
document.querySelector('#state').classList.add('connected');
})
.catch(error => {
console.error('Argh!', error);
});
});
Berikutnya
- Oke... bisakah saya bicara dengan lilin ini atau apa?
- Tentu... langsung ke langkah berikutnya
Pertanyaan Umum (FAQ)
5. Baca sesuatu
Jadi, apa yang Anda lakukan sekarang setelah memiliki BluetoothDevice
yang ditampilkan dari promise navigator.bluetooth.requestDevice
? Mari hubungkan ke Server GATT jarak jauh Bluetooth yang menyimpan definisi layanan dan karakteristik Bluetooth dengan memanggil device.gatt.connect()
:
playbulbCandle.js
class PlaybulbCandle {
constructor() {
this.device = null;
}
connect() {
let options = {filters:[{services:[ CANDLE_SERVICE_UUID ]}]};
return navigator.bluetooth.requestDevice(options)
.then(device => {
this.device = device;
return device.gatt.connect();
});
}
}
Membaca nama perangkat
Di sini kita terhubung ke Server GATT perangkat Bluetooth Lilin PLAYBULB. Sekarang kita ingin mendapatkan Layanan GATT Utama (yang diiklankan sebagai 0xFF02
sebelumnya) dan membaca karakteristik nama perangkat (0xFFFF
) yang dimiliki layanan ini. Hal ini dapat dilakukan dengan mudah dengan menambahkan metode baru getDeviceName
ke class PlaybulbCandle
serta menggunakan device.gatt.getPrimaryService
dan service.getCharacteristic
. Metode characteristic.readValue
benar-benar akan menampilkan DataView
yang cukup kita dekode dengan TextDecoder
.
playbulbCandle.js
const CANDLE_DEVICE_NAME_UUID = 0xFFFF;
...
getDeviceName() {
return this.device.gatt.getPrimaryService(CANDLE_SERVICE_UUID)
.then(service => service.getCharacteristic(CANDLE_DEVICE_NAME_UUID))
.then(characteristic => characteristic.readValue())
.then(data => {
let decoder = new TextDecoder('utf-8');
return decoder.decode(data);
});
}
Mari tambahkan ke app.js
dengan memanggil playbulbCandle.getDeviceName
setelah terhubung dan menampilkan nama perangkat.
app.js
document.querySelector('#connect').addEventListener('click', event => {
playbulbCandle.connect()
.then(() => {
console.log(playbulbCandle.device);
document.querySelector('#state').classList.remove('connecting');
document.querySelector('#state').classList.add('connected');
return playbulbCandle.getDeviceName().then(handleDeviceName);
})
.catch(error => {
console.error('Argh!', error);
});
});
function handleDeviceName(deviceName) {
document.querySelector('#deviceName').value = deviceName;
}
Pada tahap ini, kunjungi situs Anda di browser web (dengan mengklik URL Server Web yang disorot di aplikasi server web) atau cukup muat ulang halaman yang ada. Pastikan Lilin PLAYBULB diaktifkan, lalu klik "Sambungkan" pada halaman dan Anda akan melihat nama perangkat di bawah pemilih warna.
Membaca level baterai
Ada juga karakteristik Bluetooth tingkat baterai standar yang tersedia di perangkat Bluetooth Lilin PLAYBULB yang berisi level baterai perangkat. Artinya, kita dapat menggunakan nama standar seperti battery_service
untuk UUID Layanan GATT Bluetooth, dan battery_level
untuk UUID Karakteristik GATT Bluetooth.
Mari tambahkan metode getBatteryLevel
baru ke class PlaybulbCandle
dan baca level baterai dalam persen.
playbulbCandle.js
getBatteryLevel() {
return this.device.gatt.getPrimaryService('battery_service')
.then(service => service.getCharacteristic('battery_level'))
.then(characteristic => characteristic.readValue())
.then(data => data.getUint8(0));
}
Kita juga perlu memperbarui objek JavaScript options
untuk menyertakan layanan baterai ke kunci optionalServices
karena tidak diiklankan oleh perangkat Bluetooth Lilin PLAYBULB tetapi masih wajib untuk mengaksesnya.
playbulbCandle.js
let options = {filters:[{services:[ CANDLE_SERVICE_UUID ]}],
optionalServices: ['battery_service']};
return navigator.bluetooth.requestDevice(options)
Seperti sebelumnya, mari kita colokkan ini ke app.js
dengan memanggil playbulbCandle.getBatteryLevel
setelah kita memiliki nama perangkat dan menampilkan level baterai.
app.js
document.querySelector('#connect').addEventListener('click', event => {
playbulbCandle.connect()
.then(() => {
console.log(playbulbCandle.device);
document.querySelector('#state').classList.remove('connecting');
document.querySelector('#state').classList.add('connected');
return playbulbCandle.getDeviceName().then(handleDeviceName)
.then(() => playbulbCandle.getBatteryLevel().then(handleBatteryLevel));
})
.catch(error => {
console.error('Argh!', error);
});
});
function handleDeviceName(deviceName) {
document.querySelector('#deviceName').value = deviceName;
}
function handleBatteryLevel(batteryLevel) {
document.querySelector('#batteryLevel').textContent = batteryLevel + '%';
}
Pada tahap ini, kunjungi situs Anda di browser web (dengan mengklik URL Server Web yang ditandai di aplikasi server web) atau cukup muat ulang halaman yang ada. Klik "Hubungkan" pada halaman dan Anda akan melihat nama perangkat dan level baterai.
Berikutnya
- Bagaimana cara mengubah warna bohlam ini? Karena itulah aku di sini!
- Sedikit lagi, aku berjanji...
Pertanyaan Umum (FAQ)
6. Mengubah warna
Mengubah warna semudah menulis kumpulan perintah tertentu ke Karakteristik Bluetooth (0xFFFC
) di Layanan GATT Utama yang diiklankan sebagai 0xFF02
. Misalnya, mengubah Lilin PLAYBULB menjadi merah akan menulis array yang terdiri dari bilangan bulat tanpa tanda tangan 8-bit yang sama dengan [0x00, 255, 0, 0]
dengan 0x00
adalah saturasi putih dan 255, 0, 0
masing-masing adalah nilai merah, hijau, dan biru .
Kita akan menggunakan characteristic.writeValue
untuk benar-benar menulis beberapa data ke karakteristik Bluetooth dalam metode publik setColor
yang baru dari class PlaybulbCandle
. Kita juga akan menampilkan nilai merah, hijau, dan biru yang sebenarnya saat promise terpenuhi sehingga kita dapat menggunakannya di app.js
nanti:
playbulbCandle.js
const CANDLE_COLOR_UUID = 0xFFFC;
...
setColor(r, g, b) {
let data = new Uint8Array([0x00, r, g, b]);
return this.device.gatt.getPrimaryService(CANDLE_SERVICE_UUID)
.then(service => service.getCharacteristic(CANDLE_COLOR_UUID))
.then(characteristic => characteristic.writeValue(data))
.then(() => [r,g,b]);
}
Mari kita update fungsi changeColor
di app.js
untuk memanggil playbulbCandle.setColor
saat "No Effect" tombol pilihan dicentang. Variabel warna r, g, b
global sudah ditetapkan saat pengguna mengklik kanvas pemilih warna.
app.js
function changeColor() {
var effect = document.querySelector('[name="effectSwitch"]:checked').id;
if (effect === 'noEffect') {
playbulbCandle.setColor(r, g, b).then(onColorChanged);
}
}
Pada tahap ini, kunjungi situs Anda di browser web (dengan mengklik URL Server Web yang disorot di aplikasi server web) atau cukup muat ulang halaman yang ada. Klik "Hubungkan" pada halaman dan klik pemilih warna untuk mengubah warna Lilin PLAYBULB sebanyak yang Anda inginkan.
Efek lilin bulan purnama
Jika Anda sudah menyalakan lilin sebelumnya, Anda tahu bahwa lampunya tidak statis. Untungnya, ada karakteristik Bluetooth lain (0xFFFB
) di Layanan GATT Utama yang diiklankan sebagai 0xFF02
yang memungkinkan pengguna menetapkan beberapa efek lilin.
Menyetel "efek lilin" misalnya dapat dicapai dengan menulis [0x00, r, g, b, 0x04, 0x00, 0x01, 0x00]
. Dan Anda juga bisa mengatur
efek berkedip dengan [0x00, r, g, b, 0x00, 0x00, 0x1F, 0x00]
.
Mari kita tambahkan metode setCandleEffectColor
dan setFlashingColor
ke class PlaybulbCandle
.
playbulbCandle.js
const CANDLE_EFFECT_UUID = 0xFFFB;
...
setCandleEffectColor(r, g, b) {
let data = new Uint8Array([0x00, r, g, b, 0x04, 0x00, 0x01, 0x00]);
return this.device.gatt.getPrimaryService(CANDLE_SERVICE_UUID)
.then(service => service.getCharacteristic(CANDLE_EFFECT_UUID))
.then(characteristic => characteristic.writeValue(data))
.then(() => [r,g,b]);
}
setFlashingColor(r, g, b) {
let data = new Uint8Array([0x00, r, g, b, 0x00, 0x00, 0x1F, 0x00]);
return this.device.gatt.getPrimaryService(CANDLE_SERVICE_UUID)
.then(service => service.getCharacteristic(CANDLE_EFFECT_UUID))
.then(characteristic => characteristic.writeValue(data))
.then(() => [r,g,b]);
}
Dan mari kita update fungsi changeColor
di app.js
untuk memanggil playbulbCandle.setCandleEffectColor
saat "Efek Lilin" tombol pilihan dicentang dan playbulbCandle.setFlashingColor
bila "Berkedip" tombol pilihan dicentang. Kali ini, kami akan menggunakan switch
jika Anda tidak keberatan.
app.js
function changeColor() {
var effect = document.querySelector('[name="effectSwitch"]:checked').id;
switch(effect) {
case 'noEffect':
playbulbCandle.setColor(r, g, b).then(onColorChanged);
break;
case 'candleEffect':
playbulbCandle.setCandleEffectColor(r, g, b).then(onColorChanged);
break;
case 'flashing':
playbulbCandle.setFlashingColor(r, g, b).then(onColorChanged);
break;
}
}
Pada tahap ini, kunjungi situs Anda di browser web (dengan mengklik URL Server Web yang disorot di aplikasi server web) atau cukup muat ulang halaman yang ada. Klik "Hubungkan" di halaman dan bereksperimenlah dengan Efek Lilin dan Berkedip.
Berikutnya
- Itu saja? 3 efek lilin yang buruk? Apakah karena itulah saya di sini?
- Ada lebih banyak lagi, tetapi Anda akan menentukan sendiri kali ini.
7. Lakukan upaya lebih
Jadi, inilah kita. Anda mungkin berpikir bahwa ini sudah hampir berakhir tetapi aplikasi ini belum berakhir. Mari kita lihat apakah Anda benar-benar memahami apa yang telah Anda salin-tempel selama codelab ini. Berikut yang ingin Anda lakukan sekarang untuk membuat aplikasi ini tampil menarik.
Menambahkan efek yang tidak ada
Berikut adalah data untuk efek yang hilang:
- Pulse:
[0x00, r, g, b, 0x01, 0x00, 0x09, 0x00]
(Anda mungkin ingin menyesuaikan nilair, g, b
di sana) - Pelangi:
[0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00]
(Penderita epilepsi mungkin ingin menghindari pelangi ini) - Pudar Pelangi:
[0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x26, 0x00]
Ini pada dasarnya berarti menambahkan metode setPulseColor
, setRainbow
, dan setRainbowFade
baru ke class PlaybulbCandle
dan memanggilnya di changeColor
.
Memperbaiki "tidak berpengaruh"
Anda mungkin telah memperhatikan, "tidak ada efek" opsi ini tidak mengatur ulang efek yang sedang berlangsung, ini kecil, namun tetap saja. Mari kita perbaiki. Dalam metode setColor
, Anda harus memeriksa terlebih dahulu apakah suatu efek sedang berlangsung melalui variabel class baru _isEffectSet
dan jika true
, nonaktifkan efek tersebut sebelum menetapkan warna baru dengan data ini: [0x00, r, g, b, 0x05, 0x00, 0x01, 0x00]
.
Tulis nama perangkat
Yang ini mudah! Menulis nama perangkat khusus semudah menulis ke karakteristik nama perangkat Bluetooth sebelumnya. Sebaiknya gunakan metode TextEncoder
encode
untuk mendapatkan Uint8Array
yang berisi nama perangkat.
Kemudian, saya akan menambahkan "input" eventListener
ke document.querySelector('#deviceName')
dan panggil playbulbCandle.setDeviceName
agar lebih praktis.
Saya sendiri menamainya PLAY💡 CANDLE.
8. Selesai.
Yang telah Anda pelajari
- Cara berinteraksi dengan perangkat Bluetooth di sekitar di JavaScript
- Cara menggunakan Class ES2015, fungsi Panah, Map, dan Promise
Langkah Berikutnya
- Pelajari Web Bluetooth API lebih lanjut
- Jelajahi Sampel Bluetooth Web dan Demo resmi
- Lihat kucing pemarah terbang