Bluetooth cihazlarla JavaScript üzerinden iletişim kurma

Web Bluetooth API, web sitelerinin Bluetooth cihazlarla iletişim kurmasına olanak tanır.

François Beaufort
François Beaufort

Web sitelerinin yakındaki Bluetooth cihazlarla iletişim kurabileceğini söylesem ne olur? nasıl koruyabilir? Böylece nabız takip eder, şarkı söyler ampuller ve hatta kaplumbağalar bir web sitesiyle doğrudan etkileşime girebilir.

Şimdiye kadar Bluetooth cihazlarla etkileşimde bulunulabiliyor. yalnızca platforma özgü uygulamalar için geçerlidir. Web Bluetooth API, bunu değiştirmeyi ve aynı zamanda web tarayıcılarına da getirir.

Başlamadan önce

Bu dokümanda, Bluetooth Düşük Bluetooth kalitesi ile ilgili bazı temel bilgilere sahip olduğunuz varsayılır Enerji (BDE) ve Genel Özellik Profili çalışır.

Web Bluetooth API spesifikasyonu henüz kesinleşmemiş olsa da spesifikasyon yazarlar etkin bir şekilde bu API'yi deneyen coşkulu geliştiriciler arıyorlar ve spesifikasyonlarla ilgili geri bildirim ve uygulamayla ilgili geri bildirim sağlayın.

Web Bluetooth API'nin bir alt kümesi; ChromeOS ve Android için Chrome'da kullanılabilir. 6.0, Mac (Chrome 56) ve Windows 10 (Chrome 70). Bu da müzakere etme becerilerinizi yakındaki Bluetooth Düşük Enerji cihazlarını istemek ve bağlamak için okuma/yazma Bluetooth özellikleri, GATT bildirimlerini alma, bilme Bluetooth cihazın bağlantısı kesildiğinde, hatta cihazda okuma ve yazma işlemi yaptığınızda Bluetooth tanımlayıcıları. Daha fazla bilgi için MDN'nin Tarayıcı uyumluluğu tablosuna bakın ekleyebilirsiniz.

Linux ve Windows'un önceki sürümlerinde about://flags bölgesinde #experimental-web-platform-features işareti.

Kaynak denemeleri için kullanılabilir

Web'i kullanan geliştiricilerden mümkün olduğunca fazla geri bildirim almak için Chrome, alanda Bluetooth API'yi eklemişti. 53'ü ChromeOS, Android ve Mac için kaynak deneme sürümü olarak kullanabilirsiniz.

Deneme süresi Ocak 2017'de başarıyla sona erdi.

Güvenlik şartları

Güvenlik açısından ödün vermeden Web Bluetooth Security'nin Chrome ekibinde yazılım mühendisi olan Jeffrey Yasskin'in yaptığı model gönderisi, web Bluetooth API spesifikasyonu üzerinde çalışıyoruz.

Yalnızca HTTPS

Bu deneysel API, web'e eklenen güçlü ve yeni bir özellik olduğundan, yalnızca güvenli bağlamlarda kullanılabilir. Bu, ekibiniz için TLS'yi göz önünde bulundurun.

Kullanıcı hareketi gerekli

Bir güvenlik özelliği olarak, navigator.bluetooth.requestDevice, şu şekilde bir kullanıcı hareketiyle tetiklenmelidir: tıklama veya fare tıklaması şeklinde olabilir. İnsanların sizi dinlemekten pointerup, click ve touchend etkinlikleri.

button.addEventListener('pointerup', function(event) {
  // Call navigator.bluetooth.requestDevice
});

Kodu öğrenin

Web Bluetooth API büyük ölçüde JavaScript Vaatleri'ne dayanır. Google hakkında bilgi edinmek istiyorsanız bu harika Promises eğitimine göz atın. Bir şey daha var. () => {}, ECMAScript 2015 ok işlevleridir.

Bluetooth cihazları isteme

Web Bluetooth API spesifikasyonunun bu sürümü, web sitelerine izin vererek ve Merkezi rolü için, BDE bağlantısı üzerinden uzak GATT sunucularına bağlanırsınız. Google Bluetooth 4.0 veya sonraki sürümleri uygulayan cihazlar arasındaki iletişimi destekler.

Bir web sitesi, navigator.bluetooth.requestDevice, tarayıcı kullanıcıdan cihazı ister cihazı seçebileceği veya isteği iptal edebileceği bir seçiciye dokunun.

Bluetooth cihaz kullanıcı istemi.

navigator.bluetooth.requestDevice() işlevi, şu koşulları karşılayan zorunlu bir nesne alır: , filtreleri tanımlar. Bu filtreler yalnızca bazı eşleşen cihazları döndürmek için kullanılır Bluetooth GATT hizmetleri ve/veya cihaz adı.

Hizmet filtresi

Örneğin, Bluetooth GATT'yi tanıtan Bluetooth cihazlarını istemek için Pil Hizmeti:

navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
.then(device => { /* … */ })
.catch(error => { console.error(error); });

Bluetooth GATT Hizmetiniz standartlaştırılmış Bluetooth GATT hizmetlerinden yararlanabilmeniz için tam Bluetooth UUID'yi veya 16 veya 32 bit form.

navigator.bluetooth.requestDevice({
  filters: [{
    services: [0x1234, 0x12345678, '99999999-0000-1000-8000-00805f9b34fb']
  }]
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });

Ad filtresi

Bluetooth cihazları, reklamı yapılan cihaz adına göre de isteyebilirsiniz name filtre anahtarını, hatta bu adın namePrefix önekini içeren bir ön eki kullanın Filtreler tuşu. Bu durumda, anahtar kelimeleri de tanımlamanız gerekeceğini unutmayın. optionalServices anahtarının bulunduğu sürümü kullanmaya devam edebilirsiniz. hizmet filtresinden yararlanın. Aksi takdirde daha sonra erişmeye çalıştığınızda hata mesajı alırsınız. gerekir.

navigator.bluetooth.requestDevice({
  filters: [{
    name: 'Francois robot'
  }],
  optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });

Üretici veri filtresi

Üreticiye bağlı olarak Bluetooth cihazları da isteyebilirsiniz. manufacturerData filtre anahtarıyla reklamı yapılan belirli veriler. Bu anahtar adlı zorunlu Bluetooth şirket tanımlayıcı anahtarına sahip bir nesne dizisidir companyIdentifier. Veri ön eki de sağlayarak üretici verileri ile ilgili verileri kullanır. Bu işlemin ardından herhangi bir hizmete erişebilmek için optionalServices anahtarını da tanımlamanız gerekir bir hizmet filtresine dahil değildir. Aksi halde daha sonra erişmeye çalışın.

// 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); });

Maskeler, aynı zamanda belirli kalıplarla eşleştirmek için bir veri önekiyle birlikte de üretici verileri. Öğrenmek için Bluetooth veri filtreleri açıklayıcısına göz atın daha fazla.

Hariç tutma filtreleri

navigator.bluetooth.requestDevice() içindeki exclusionFilters seçeneği şunları sağlar: bazı cihazları tarayıcı seçiciden hariç tutarsınız. Hariç tutmak için kullanılabilir daha geniş bir filtreyle eşleşen ancak desteklenmeyen cihazlar

// 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 kullanmayın

Son olarak, tüm reklam öğelerini göstermek için filters yerine acceptAllDevices anahtarını kullanabilirsiniz yakındaki Bluetooth cihazları. Ayrıca, optionalServices anahtarını kullandığınızdan emin olun. Aksi takdirde daha sonra hata mesajı alacaksınız erişmeye ç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

BluetoothDevice sahibi olduğunuza göre şimdi ne yapacaksınız? Şimdi Hizmeti ve özellikleri barındıran Bluetooth uzak GATT Sunucusu tanımlar.

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 özelliğini oku

Burada, uzak Bluetooth cihazının GATT sunucusuna bağlanıyoruz. Şimdi Birincil GATT Hizmeti almak ve bu hizmeti kullanabilirsiniz. Örneğin, şimdiye kadar yer alan mevcut harcama seviyesini piline bağlı.

Yukarıdaki örnekte battery_level, standartlaştırılmış Pil Düzeyi'dir Özellik.

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, tam Bluetooth UUID veya 16 ya da 32 bit service.getCharacteristic

Ayrıca characteristicvaluechanged etkinlik işleyicisi ekleyebileceğinizi de karakteristik bir özellik olduğunu hatırlatalım. Daha fazla bilgi için Okuma Özelliğine Yakında kullanıma sunulacak GATT'nin nasıl ele alınacağını öğrenmek için Değer Değişikliği Örneği'ni inceleyin bildirimleri de kullanabilirsiniz.


.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);
}

Bir Bluetooth özelliğine yaz

Bir Bluetooth GATT özelliğine yazmak, onu okumak kadar kolaydır. Bu sefer Tüketilen Enerjinin değerini sıfırlamak için Nabız Kontrol Noktası'nı kullanalım değerini 0 olarak ayarlayın.

Yemin ederim burada sihir yok. Tüm bunları Nabız Kontrolü Puan Özellikleri sayfası.

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 bildirimlerini alma

Şimdi de Nabız Ölçümü gerçekleştiğinde nasıl bildirim alacağınızı inceleyelim. yeni bir e-posta alırsınız:

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() ve eklenen characteristicvaluechanged öğelerini düzgün şekilde kaldırın yardımcı olur.

Bluetooth Cihazın bağlantısını kesme

Daha iyi bir kullanıcı deneyimi sağlamak için bağlantı kesintileriyle ilgili etkinlikleri dinlemek isteyebilirsiniz. ve kullanıcıyı yeniden bağlantı kurmaya davet edin:

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.`);
}

Ayrıca, device.gatt.disconnect() numaralı telefonu arayarak web uygulamanızın Bluetooth cihaz. Bu işlem mevcut gattserverdisconnected etkinliğini tetikler yardımcı olur. Başka bir Bluetooth cihazı varsa Bluetooth cihazı iletişimini Bluetooth cihazıyla zaten iletişim kuruyor. Cihaza göz atın. Daha ayrıntılı bilgi edinmek için Sample ve Otomatik Yeniden Bağlanma Örneği bağlantısını kesin.

Bluetooth tanımlayıcılarını okuma ve bu tanımlayıcılara yazma

Bluetooth GATT tanımlayıcıları, belirli bir değeri tanımlayan özelliklerdir. Bunları Bluetooth GATT'ye benzer şekilde okuyup yazabilirsiniz. özellikler.

Örneğin, kullanıcı düzeyinde ölçümün kullanıcı açıklamasının nasıl okunacağına bakalım. cihazın sağlık termometresinin aralığına göre ayarlanır.

Aşağıdaki örnekte health_thermometer Sağlık Termometresi hizmetidir, measurement_interval Ölçüm aralığı özelliği ve gatt.characteristic_user_description Özel Kullanıcı Açıklaması açıklayıcı olarak değiştirin.

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); });

Şimdi GCLID'nin ölçüm aralığının kullanıcı açıklamasını okuduğumuza göre, bir bakalım. Şimdi, bu termometrenin nasıl güncelleneceğine ve değer.

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 özelliklerden tam olarak anlamak için [BLE Çevre Birimi Simülatörü'nü kurmanızı öneririm. Android App] içeren bir BDE çevre birimini simüle eden bir Pil Hizmeti, hizmet veya Sağlık Termometresi Hizmeti.

Başlangıç düzeyi

  • Cihaz Bilgileri - Bir BDE cihazından temel cihaz bilgilerini alın.
  • Pil Seviyesi - Pil bilgilerini tanıtan bir BDE cihazından pil bilgilerini alın.
  • Enerjiyi Sıfırla: Bir BDE cihazından harcanan enerjiyi sıfırlayın.
  • Karakter Özellikleri: Bir BDE Cihazındaki belirli bir özelliğin tüm özelliklerini gösterir.
  • Bildirimler - Bir BDE cihazından gelen karakteristik bildirimleri başlatın ve durdurun.
  • Cihazın bağlantısını kesme: BDE cihazına bağlandıktan sonra cihazın bağlantısının kesilmesi ve bağlantısının kesilmesiyle ilgili bildirim alın.
  • Özellikleri Alma: Bir BDE cihazından, reklamı yapılan hizmetin tüm özelliklerini öğrenin.
  • Tanımlayıcıları Al: tüm özellikleri getir' bir BDE cihazından reklamı yapılan hizmetin tanımlayıcıları.
  • Üretici Veri Filtresi: Üretici verileriyle eşleşen bir BDE cihazından temel cihaz bilgilerini alma.
  • Hariç Tutma Filtreleri - Temel hariç tutma filtrelerini içeren bir BDE cihazından temel cihaz bilgilerini alma.

Birden çok işlemi birleştirme

Seçilmiş Web Bluetooth Demolarımıza ve resmi Web Bluetooth Codelab'lerimize de göz atın.

Kütüphaneler

  • web-bluetooth-utils, cihazınıza bazı kolaylık işlevleri ekleyen bir npm modülüdür. API.
  • En popüler Node.js BDE'si olan noble'da bir Web Bluetooth API dolgusu mevcuttur merkezi modüldür. Bu da, ihtiyaç duymadan asil web paketi/tarayıcı oluşturmanıza olanak tanır veya diğer eklentiler için geçerlidir.
  • angle-web-bluetooth, tüm öğeleri soyutlayan Açısal için bir modüldür Web Bluetooth API'yi yapılandırmak için gereken ortak metin.

Araçlar

  • Get Started with Web Bluetooth (Web Bluetooth'u Kullanmaya Başlayın) JavaScript ortak metin kodunu eklemeniz gerekir. Bir cihaz adı, hizmet, özellik girin, özelliklerini tanımlayın artık bir sorun yok.
  • Zaten bir Bluetooth geliştiricisiyseniz, Web Bluetooth Geliştirici Stüdyosu Eklenti, tarayıcınız için web Bluetooth JavaScript kodunu da Bluetooth cihaz.

İpuçları

Chrome'da Bluetooth Internals sayfasını şu adreste bulabilirsiniz: about://bluetooth-internals adlı yeri seçerek etraftaki her şeyi inceleyebilirsiniz Bluetooth cihazlar: durum, hizmetler, özellikler ve tanımlayıcılar.

Chrome'da Bluetooth hatalarını ayıklamak için kullanılan dahili sayfanın ekran görüntüsü
Bluetooth cihazlarında hata ayıklamaya ilişkin Chrome dahili sayfası.

Ayrıca, resmi Web Bluetooth hatalarını bildirme Bluetooth hata ayıklama sayfasını ziyaret etmek bazen zor olabilmektedir.

Sırada ne var?

Hangi kısımların bulunduğunu öğrenmek için önce tarayıcı ve platform uygulama durumunu kontrol edin web Bluetooth API'si şu anda uygulanmaktadır.

Henüz tamamlanmamış olsa da yakın gelecekte karşılaşabileceğiniz durumlara dair gelecek:

  • Yakındaki BDE reklamlarını tarama navigator.bluetooth.requestLEScan() ile birlikte gerçekleşecek.
  • Yeni keşfedilen Bluetooth GATT hizmetleri yeni bir serviceadded etkinliğiyle izlenecek serviceremoved etkinliği ise kaldırılanları izler. Yeni bir servicechanged etkinlik, herhangi bir özellik ve/veya tanımlayıcı eklendiğinde ya da Bluetooth GATT Hizmeti'nden kaldırıldı.

API'ye desteğinizi gösterin

Web Bluetooth API'yi kullanmayı planlıyor musunuz? Herkese açık desteğiniz Chrome ekibine yardımcı olur ve diğer tarayıcı tedarikçilerine söz konusu özellikleri desteklemenin ne kadar önemli olduğunu gösterir.

Hashtag'i kullanarak @ChromiumDev hesabına tweet gönderin #WebBluetooth ve nerede ve nasıl kullandığınızı bize bildirin.

Kaynaklar

Teşekkür

Bu makaleyi incelediği için Kayce Basques'e teşekkür ederiz. Lokomotif resim: Boulder, ABD'den SparkFun Electronic.