Web Bluetooth API, web sitelerinin Bluetooth cihazlarla iletişim kurmasına olanak tanır.
Web sitelerinin yakındaki Bluetooth cihazlarla güvenli ve gizliliği koruyarak iletişim kurabileceğini söyleseydik? Bu sayede, kalp atış hızı monitörleri, şarkı söyleyen ampuller ve hatta kaplumbağalar bile doğrudan bir web sitesiyle etkileşime geçebilir.
Şimdiye kadar Bluetooth cihazlarla etkileşim kurma özelliği yalnızca platforma özel uygulamalarda kullanılabiliyordu. Web Bluetooth API, bu durumu değiştirmeyi ve web tarayıcılarına da getirmeyi amaçlar.
Başlamadan önce
Bu belgede, Bluetooth Düşük Enerji (BLE) ve Generic Attribute Profile'ın işleyiş şekliyle ilgili temel bilgilere sahip olduğunuz varsayılmaktadır.
Web Bluetooth API spesifikasyonu henüz tamamlanmamış olsa da spesifikasyon yazarları, bu API'yi denemek ve spesifikasyon hakkında geri bildirimde bulunmak ve uygulama hakkında geri bildirimde bulunmak için hevesli geliştiriciler aramaktadır.
Web Bluetooth API'nin bir alt kümesi ChromeOS, Android 6.0 için Chrome, Mac (Chrome 56) ve Windows 10'da (Chrome 70) kullanılabilir. Bu sayede yakındaki Bluetooth Düşük Enerji cihazlarına istek gönderebilir ve bağlanabilir, Bluetooth özelliklerini okuyabilir/yazabilir, GATT bildirimleri alabilir, Bluetooth cihazının bağlantısının kesildiğini öğrenebilir, hatta Bluetooth tanımlayıcılarını okuyup yazabilirsiniz. Daha fazla bilgi için MDN'nin Tarayıcı uyumluluğu tablosuna bakın.
Linux ve Windows'un önceki sürümlerinde about://flags'de #experimental-web-platform-features işaretini etkinleştirin.
Kaynak denemelerinde kullanılabilir
Chrome, Web Bluetooth API'yi sahada kullanan geliştiricilerden mümkün olduğunca fazla geri bildirim almak için bu özelliği daha önce Chrome 53'e ChromeOS, Android ve Mac için kaynak denemesi olarak eklemişti.
Deneme süresi Ocak 2017'de başarıyla sona erdi.
Güvenlik şartları
Güvenlik açısından yapılan değişiklikleri anlamak için Chrome ekibinde Web Bluetooth API spesifikasyonu üzerinde çalışan yazılım mühendisi Jeffrey Yasskin'in Web Bluetooth Security Model (Web Bluetooth Güvenlik Modeli) başlıklı gönderisini incelemenizi öneririz.
Yalnızca HTTPS
Bu deneysel API, web'e eklenen güçlü bir yeni özellik olduğundan yalnızca güvenli bağlamlarda kullanılabilir. Bu nedenle, TLS'yi göz önünde bulundurarak geliştirme yapmanız gerekir.
Kullanıcı hareketi gerekiyor
Güvenlik özelliği olarak, navigator.bluetooth.requestDevice ile Bluetooth cihaz keşfi, dokunma veya fare tıklaması gibi kullanıcı hareketiyle tetiklenmelidir. pointerup, click ve touchend etkinliklerini dinlemekten bahsediyoruz.
button.addEventListener('pointerup', function(event) {
// Call navigator.bluetooth.requestDevice
});
Koda erişme
Web Bluetooth API, JavaScript Promises'e büyük ölçüde bağlıdır. Bu kavramlara aşina değilseniz Promises eğitimine göz atın. Bir diğer nokta ise ECMAScript 2015 ok işlevleri.() => {}
Bluetooth cihaz isteğinde bulunma
Web Bluetooth API spesifikasyonunun bu sürümü, Central rolünde çalışan web sitelerinin BLE bağlantısı üzerinden uzak GATT sunucularına bağlanmasına olanak tanır. Bluetooth 4.0 veya sonraki sürümleri uygulayan cihazlar arasındaki iletişimi destekler.
Bir web sitesi navigator.bluetooth.requestDevice kullanarak yakındaki cihazlara erişim istediğinde tarayıcı, kullanıcıya bir cihaz seçiciyle istemde bulunur. Kullanıcı bu seçiciyi kullanarak bir cihaz seçebilir veya isteği iptal edebilir.
navigator.bluetooth.requestDevice() işlevi, filtreleri tanımlayan zorunlu bir nesne alır. Bu filtreler, yalnızca bazı reklamı yapılan Bluetooth GATT hizmetleriyle ve/veya cihaz adıyla eşleşen cihazları döndürmek için kullanılır.
Hizmet filtresi
Örneğin, Bluetooth GATT Battery Service reklamı yapan Bluetooth cihazları istemek için:
navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Ancak Bluetooth GATT Hizmetiniz standartlaştırılmış Bluetooth GATT hizmetleri listesinde yer almıyorsa tam Bluetooth UUID'yi veya kısa 16 ya da 32 bitlik bir formu sağlayabilirsiniz.
navigator.bluetooth.requestDevice({
filters: [{
services: [0x1234, 0x12345678, '99999999-0000-1000-8000-00805f9b34fb']
}]
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Ad filtresi
Ayrıca, name filters anahtarıyla reklamı yapılan cihaz adına veya namePrefix filters anahtarıyla bu adın bir önekine göre Bluetooth cihazları da isteyebilirsiniz. Bu durumda, hizmet filtresine dahil olmayan hizmetlere erişebilmek için optionalServices anahtarını da tanımlamanız gerektiğini unutmayın. Aksi takdirde, daha sonra bu dosyalara erişmeye çalıştığınızda hata mesajı alırsınız.
navigator.bluetooth.requestDevice({
filters: [{
name: 'Francois robot'
}],
optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Üretici verileri filtresi
Ayrıca, manufacturerData filtre anahtarıyla reklamı yapılan üreticiye özel verilere göre Bluetooth cihazları da isteyebilirsiniz. Bu anahtar, companyIdentifier adlı zorunlu bir Bluetooth şirket tanımlayıcısı anahtarına sahip nesneler dizisidir. Ayrıca, Bluetooth cihazlardaki üretici verilerini filtreleyen bir veri öneki de sağlayabilirsiniz. Hizmet filtresine dahil olmayan hizmetlere erişebilmek için optionalServices anahtarını da tanımlamanız gerektiğini unutmayın. Aksi takdirde, daha sonra bu dosyalara erişmeye çalıştığınızda hata alırsınız.
// 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); });
Üretici verilerindeki bazı kalıpları eşleştirmek için maske, veri önekiyle birlikte de kullanılabilir. Daha fazla bilgi edinmek için Bluetooth veri filtreleri açıklayıcı başlıklı makaleyi inceleyin.
Hariç tutma filtreleri
navigator.bluetooth.requestDevice() bölümündeki exclusionFilters seçeneği, bazı cihazları tarayıcı seçiciden hariç tutmanıza olanak tanır. Daha geniş bir filtreyle eşleşen ancak desteklenmeyen cihazları hariç tutmak için kullanılabilir.
// 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); });
Filtre yok
Son olarak, yakındaki tüm Bluetooth cihazları göstermek için filters yerine acceptAllDevices tuşunu kullanabilirsiniz. Bazı hizmetlere erişebilmek için optionalServices anahtarını da tanımlamanız gerekir. Aksi takdirde, daha sonra bu dosyalara erişmeye çalıştığınızda hata mesajı alırsınız.
navigator.bluetooth.requestDevice({
acceptAllDevices: true,
optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Bluetooth cihaza bağlanma
Peki, BluetoothDevice sahibi olduğunuzda ne yapmanız gerekir? Hizmet ve özellik tanımlarını içeren Bluetooth uzaktan kumanda GATT sunucusuna bağlanalım.
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); });
Bluetooth Karakteristiği Okuma
Burada, uzak Bluetooth cihazının GATT sunucusuna bağlanıyoruz. Şimdi birincil GATT hizmeti almak ve bu hizmete ait bir özelliği okumak istiyoruz. Örneğin, cihazın pilinin mevcut şarj seviyesini okumayı deneyelim.
İlerideki örnekte battery_level, standartlaştırılmış pil seviyesi özelliğidir.
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); });
Özel bir Bluetooth GATT özelliği kullanıyorsanız service.getCharacteristic için tam Bluetooth UUID'sini veya kısa 16 ya da 32 bitlik bir biçimi sağlayabilirsiniz.
Değerini okumak için bir özelliğe characteristicvaluechanged etkinlik dinleyicisi de ekleyebilirsiniz. Yaklaşan GATT bildirimlerini isteğe bağlı olarak nasıl işleyeceğinizi görmek için Read Characteristic
Value Changed Sample'a göz atın.
…
.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);
}
Bluetooth Karakteristiğine Yazma
Bluetooth GATT Karakteristiği'ne yazmak, onu okumak kadar kolaydır. Bu kez, nabız monitörü cihazında Harcanan Enerji alanının değerini sıfırlamak için kalp atış hızı kontrol noktasını kullanalım.
Burada sihir olmadığını garanti ederim. Tüm bunlar Kalp Atış Hızı Kontrolü Noktası Karakteristikleri sayfasında açıklanmaktadır.
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); });
GATT bildirimleri alma
Şimdi de cihazda nabız ölçümü özelliği değiştiğinde nasıl bildirim alacağımıza bakalım:
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
}
Bildirim Örneği, stopNotifications() ile bildirimleri nasıl durduracağınızı ve eklenen characteristicvaluechanged etkinlik işleyicisini nasıl düzgün şekilde kaldıracağınızı gösterir.
Bluetooth cihazının bağlantısını kesme
Daha iyi bir kullanıcı deneyimi sunmak için bağlantı kesme etkinliklerini dinleyebilir ve kullanıcıyı yeniden bağlanmaya davet edebilirsiniz:
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.`);
}
Web uygulamanızın Bluetooth cihazıyla bağlantısını kesmek için device.gatt.disconnect() numaralı telefonu da arayabilirsiniz. Bu işlem, mevcut gattserverdisconnected etkinlik dinleyicilerini tetikler. Başka bir uygulama Bluetooth cihazla iletişim kuruyorsa bu işlemin Bluetooth cihaz iletişimini DURDURMAYACAĞINI unutmayın. Daha ayrıntılı bilgi için Device
Disconnect Sample (Cihaz Bağlantısını Kesme Örneği) ve Automatic Reconnect Sample (Otomatik Yeniden Bağlanma Örneği) sayfalarına göz atın.
Bluetooth tanımlayıcılarını okuma ve yazma
Bluetooth GATT tanımlayıcıları, bir karakteristik değeri tanımlayan özelliklerdir. Bluetooth GATT özelliklerine benzer şekilde okuyabilir ve yazabilirsiniz.
Örneğin, cihazın sağlık termometresinin ölçüm aralığına ait kullanıcı açıklamasının nasıl okunacağını inceleyelim.
Aşağıdaki örnekte health_thermometer, Sağlık Termometresi hizmeti, measurement_interval Ölçüm Aralığı özelliği ve gatt.characteristic_user_description Özellik Kullanıcı Açıklaması tanımlayıcısıdır.
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); });
Cihazın sağlık termometresinin ölçüm aralığıyla ilgili kullanıcı açıklamasını okuduğumuza göre, şimdi bunu nasıl güncelleyeceğimizi ve özel bir değer yazacağımızı görelim.
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); });
Örnekler, demolar ve codelab'ler
Aşağıdaki tüm Web Bluetooth örnekleri başarıyla test edilmiştir. Bu örneklerden en iyi şekilde yararlanmak için [BLE Peripheral Simulator Android App] uygulamasını yüklemenizi öneririz. Bu uygulama, Pil Hizmeti, Kalp Atış Hızı Hizmeti veya Sağlık Termometresi Hizmeti ile bir BLE çevre birimini simüle eder.
Başlangıç düzeyi
- Cihaz Bilgileri: BLE cihazından temel cihaz bilgilerini alma.
- Pil Seviyesi: Pil bilgilerini yayınlayan bir BLE cihazından pil bilgilerini alma.
- Enerjiyi Sıfırla: BLE cihazının kalp atış hızı reklamından harcanan enerjiyi sıfırlar.
- Karakteristik Özellikler: Bir BLE cihazındaki belirli bir karakteristiğin tüm özelliklerini gösterir.
- Bildirimler: BLE cihazından gelen karakteristik bildirimleri başlatma ve durdurma.
- Cihaz bağlantısı kesildi: Bağlandıktan sonra BLE cihazının bağlantısı kesildiğinde bağlantıyı kesebilir ve bildirim alabilirsiniz.
- Get Characteristics (Özellikleri Al): BLE cihazından reklamı yapılan bir hizmetin tüm özelliklerini alır.
- Get Descriptors: Bir BLE cihazından reklamı yapılan hizmetin tüm özellik tanımlayıcılarını alır.
- Üretici Veri Filtresi: Üretici verileriyle eşleşen bir BLE cihazından temel cihaz bilgilerini alın.
- Hariç tutma filtreleri: Temel hariç tutma filtreleri içeren bir BLE cihazından temel cihaz bilgilerini alma.
Birden fazla işlemi birleştirme
- GAP Özellikleri: Bir BLE cihazının tüm GAP özelliklerini alın.
- Cihaz Bilgisi Özellikleri: Bir BLE cihazının tüm Cihaz Bilgisi özelliklerini alır.
- Bağlantı Kaybı: BLE cihazının uyarı düzeyi özelliğini ayarlayın (readValue ve writeValue).
- Hizmetleri ve Özellikleri Keşfetme: Bir BLE cihazından erişilebilen tüm birincil hizmetleri ve özelliklerini keşfedin.
- Otomatik Yeniden Bağlanma: Üstel geri çekilme algoritması kullanarak bağlantısı kesilen bir BLE cihazına yeniden bağlanın.
- Read Characteristic Value Changed: Pil seviyesini okuyun ve BLE cihazındaki değişikliklerden haberdar olun.
- Read Descriptors: Bir hizmetin tüm karakteristik tanımlayıcılarını BLE cihazından okur.
- Yazma tanımlayıcısı: Bir BLE cihazındaki "Karakteristik Kullanıcı Açıklaması" tanımlayıcısına yazma.
Ayrıca, seçilmiş Web Bluetooth demolarımıza ve resmi Web Bluetooth Codelab'lerimize de göz atın.
Kütüphaneler
- web-bluetooth-utils, API'ye bazı kolaylık işlevleri ekleyen bir npm modülüdür.
- En popüler Node.js BLE merkezi modülü olan noble'da bir Web Bluetooth API shim'i mevcuttur. Bu sayede, WebSocket sunucusu veya başka eklentilere gerek kalmadan noble'ı webpack/browserify yapabilirsiniz.
- angular-web-bluetooth, Web Bluetooth API'yi yapılandırmak için gereken tüm standart kodları ortadan kaldıran bir Angular modülüdür.
Araçlar
- Get Started with Web Bluetooth, Bluetooth cihazla etkileşim kurmaya başlamak için gereken tüm JavaScript standart kodunu oluşturan basit bir web uygulamasıdır. Bir cihaz adı, hizmet veya özellik girin, özelliklerini tanımlayın ve kullanmaya başlayın.
- Zaten bir Bluetooth geliştiricisiyseniz Web Bluetooth Developer Studio Eklentisi, Bluetooth cihazınız için Web Bluetooth JavaScript kodunu da oluşturur.
İpuçları
Chrome'da Bluetooth Internals sayfası bulunur.about://bluetooth-internals Bu sayfada, yakındaki Bluetooth cihazlarla ilgili her şeyi (durum, hizmetler, özellikler ve tanımlayıcılar) inceleyebilirsiniz.
Bluetooth'ta hata ayıklama bazen zor olabileceğinden resmi Web Bluetooth hatalarını bildirme sayfasını da incelemenizi öneririz.
Sırada ne var?
Web Bluetooth API'nin hangi bölümlerinin şu anda uygulandığını öğrenmek için önce tarayıcı ve platform uygulama durumunu kontrol edin.
Henüz tamamlanmamış olsa da yakın gelecekte sizi nelerin beklediğine dair bir önizleme:
- Yakındaki BLE reklamları taranırken
navigator.bluetooth.requestLEScan()kullanılır. - Yeni
serviceaddedetkinliği, yeni keşfedilen Bluetooth GATT hizmetlerini izlerkenserviceremovedetkinliği, kaldırılan hizmetleri izler. Bir Bluetooth GATT hizmetine herhangi bir özellik ve/veya tanımlayıcı eklendiğinde ya da kaldırıldığında yeni birservicechangedetkinlik tetiklenir.
API'ye desteğinizi gösterme
Web Bluetooth API'yi kullanmayı planlıyor musunuz? Herkese açık desteğiniz, Chrome ekibinin özellikleri önceliklendirmesine yardımcı olur ve diğer tarayıcı satıcılarına bu özelliklerin desteklenmesinin ne kadar önemli olduğunu gösterir.
#WebBluetooth hashtag'ini kullanarak @ChromiumDev hesabına tweet gönderin
ve nerede, nasıl kullandığınızı bize bildirin.
Kaynaklar
- Stack Overflow
- Chrome Özellik Durumu
- Chrome'da uygulama hataları
- Web Bluetooth spesifikasyonu
- GitHub'daki spesifikasyon sorunları
- BLE Peripheral Simulator App
Teşekkür
İnceleme için Kayce Basques'e teşekkür ederiz.