Interfejs Web Bluetooth API umożliwia witrynom komunikowanie się z urządzeniami Bluetooth.
Co zrobić, jeśli strony mogą komunikować się z urządzeniami Bluetooth w pobliżu? w bezpieczny sposób z zachowaniem prywatności? Dzięki temu monitory pracy serca, śpiewają, żarówki, a nawet żółwie mogą wchodzić w bezpośrednią interakcję ze stroną internetową.
Do tej pory można było obsługiwać urządzenia Bluetooth w przypadku aplikacji działających na określonych platformach. Interfejs Web Bluetooth API ma to zmienić pojawia się również w przeglądarkach.
Zanim zaczniemy
W tym dokumencie zakładamy, że wiesz już trochę o tym, jak Bluetooth Low Energia (BLE) i ogólny profil atrybutów działają.
Chociaż specyfikacja interfejsu Web Bluetooth API nie została jeszcze opracowana, autorzy aktywnie szukają entuzjastycznych programistów, którzy chcieliby wypróbować ten interfejs API. prześlij opinię o specyfikacji i o implementacji.
Część interfejsu Web Bluetooth API jest dostępna w ChromeOS, Chrome na Androida 6.0, Mac (Chrome 56) i Windows 10 (Chrome 70). Oznacza to, że możesz być w stanie aby wysyłać żądania i łączyć się z urządzeniami Bluetooth Low Energy w pobliżu; odczyt/zapis charakterystyki Bluetooth, otrzymywanie powiadomień GATT, informacje gdy urządzenie Bluetooth zostaje odłączone, a nawet odczytuje i zapisuje dane na Deskryptory Bluetooth Więcej informacji znajdziesz w tabeli MDN na temat zgodności z przeglądarką. i informacjami o nich.
W systemie Linux i starszych wersjach systemu Windows włącz
Flaga #experimental-web-platform-features
w: about://flags
.
Dostępne w przypadku testowania origin
Aby uzyskać jak najwięcej opinii od programistów korzystających z internetu Interfejs API Bluetooth w tej sekcji, Chrome dodał wcześniej tę funkcję do Chrome wersji 53 jako okresu próbnego origin dla ChromeOS, Androida i Maca.
Okres próbny zakończył się w styczniu 2017 roku.
Wymagania dotyczące bezpieczeństwa
Aby poznać zalety zabezpieczeń, polecam artykuł Web Bluetooth Security Post o modelu napisany przez Jeffreya Yasskina, inżyniera oprogramowania w zespole Chrome nad specyfikacją interfejsu Web Bluetooth API.
Tylko HTTPS
Ten eksperymentalny interfejs API to nowa, zaawansowana funkcja dodana do internetu, dlatego udostępniane tylko w bezpiecznych kontekstach. Oznacza to, że Pamiętaj o TLS.
Wymagany gest użytkownika
W ramach funkcji zabezpieczeń wykrywanie urządzeń Bluetooth
Funkcja navigator.bluetooth.requestDevice
musi być wywoływana gestem użytkownika, w ten sposób:
po kliknięciu lub kliknięciu myszy. Mówimy o słuchaniu
Zdarzenia pointerup
, click
i touchend
.
button.addEventListener('pointerup', function(event) {
// Call navigator.bluetooth.requestDevice
});
Zapoznaj się z kodem
Web Bluetooth API w znacznym stopniu opiera się na obietnicach JavaScriptu. Jeśli nie jesteś
zapoznaj się z tym świetnym samouczkiem. I jeszcze jedno,
() => {}
to funkcje strzałek ECMAScript 2015.
Żądanie urządzeń Bluetooth
Ta wersja specyfikacji interfejsu Web Bluetooth API zezwala na witryny działające w główną rolę, czyli łączenie się ze zdalnymi serwerami GATT przez połączenie BLE. it obsługuje komunikację między urządzeniami z Bluetooth 4.0 lub nowszym.
Gdy strona prosi o dostęp do urządzeń w pobliżu za pomocą
navigator.bluetooth.requestDevice
, przeglądarka prosi użytkownika na urządzeniu
wyboru, w którym można wybrać jedno urządzenie lub anulować prośbę.
Funkcja navigator.bluetooth.requestDevice()
przyjmuje obowiązkowy obiekt, który
definiuje filtry. Te filtry służą tylko do wyświetlenia tylko tych urządzeń, które spełniają określone kryteria
reklamowanych usług GATT Bluetooth i/lub nazwy urządzenia.
Filtr usług
Na przykład, aby zażądać urządzeń Bluetooth reklamujących GATT Bluetooth Serwis baterii:
navigator.bluetooth.requestDevice({ filters: [{ services: ['battery_service'] }] })
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Jeśli Twoja usługa Bluetooth GATT nie znajduje się na liście ustandaryzowanych usług Bluetooth GATT, możesz jednak podać pełny identyfikator UUID Bluetooth Format 16- lub 32-bitowy.
navigator.bluetooth.requestDevice({
filters: [{
services: [0x1234, 0x12345678, '99999999-0000-1000-8000-00805f9b34fb']
}]
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Filtr nazwy
Możesz też zażądać urządzeń Bluetooth na podstawie reklamowanej nazwy urządzenia
z kluczem name
lub nawet prefiksem tej nazwy z kluczem namePrefix
. W tym przypadku musisz też określić
optionalServices
, aby uzyskać dostęp do usług niezawartych w
filtr usługi. Jeśli tego nie zrobisz, później podczas próby uzyskania dostępu pojawi się błąd
.
navigator.bluetooth.requestDevice({
filters: [{
name: 'Francois robot'
}],
optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Filtr danych producenta
Można też poprosić o zezwolenie na urządzenia Bluetooth w zależności od producenta
określonych danych reklamowanych za pomocą klucza manufacturerData
. Ten klucz
to tablica obiektów z wymaganym kluczem identyfikatora firmy Bluetooth o nazwie
companyIdentifier
Możesz też podać prefiks danych, który filtruje
dane producenta z urządzeń Bluetooth, które od nich zaczynają. Pamiętaj, że
trzeba też zdefiniować klucz optionalServices
, aby uzyskać dostęp do usług
nie uwzględniono w filtrze usługi. Jeśli tego nie zrobisz, później pojawi się błąd,
dostęp do nich.
// 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); });
Maski można też używać z prefiksem danych, aby dopasować niektóre wzorce w danych producenta. Zapoznaj się z wyjaśnieniem filtrów danych Bluetooth, aby dowiedzieć się więcej. i innych.
Filtry wykluczania
Opcja exclusionFilters
w tabeli navigator.bluetooth.requestDevice()
pozwala
możesz wykluczyć niektóre urządzenia z selektora przeglądarki. Może służyć do wykluczania
które pasują do szerszego filtra, ale nie są obsługiwane.
// 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); });
Brak filtrów
Na koniec, zamiast filters
, możesz użyć klawisza acceptAllDevices
, aby wyświetlić wszystkie
urządzenia Bluetooth w pobliżu. Musisz także określić optionalServices
klucz, aby mieć dostęp do niektórych usług. Jeśli tego nie zrobisz, później pojawi się błąd
podczas próby uzyskania do nich dostępu.
navigator.bluetooth.requestDevice({
acceptAllDevices: true,
optionalServices: ['battery_service'] // Required to access service later.
})
.then(device => { /* … */ })
.catch(error => { console.error(error); });
Nawiązywanie połączenia z urządzeniem Bluetooth
Co możesz zrobić, gdy masz już BluetoothDevice
? Połączmy się z
Zdalny serwer GATT Bluetooth, na którym jest przechowywana usługa i charakterystyka
definicji.
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); });
Odczytuj cechy Bluetooth
Tutaj łączymy się z serwerem GATT zdalnego urządzenia Bluetooth. Teraz chcesz uzyskać podstawową usługę GATT i odczytać cechę, która należy do tę usługę. Spróbujmy na przykład poznać bieżący poziom naładowania baterii urządzenia.
W przykładzie poniżej battery_level
to standaryzowany poziom baterii
Cecha.
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); });
Jeśli używasz niestandardowej właściwości GATT Bluetooth, możesz podać parametr
pełny identyfikator UUID Bluetooth albo krótki 16- lub 32-bitowy format
service.getCharacteristic
Pamiętaj, że możesz też dodać detektor zdarzeń characteristicvaluechanged
do
do obsługi odczytu jej wartości. Sprawdź cechy czytania
Przykładowe dane o zmianie wartości, które pokazują, jak opcjonalnie obsługiwać przyszłe GATT
jak również powiadomienia.
…
.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);
}
Zapisz w charakterze Bluetooth
Zapisywanie danych w charakterze GATT Bluetootha jest równie łatwe jak czytanie. Tym razem użyjmy punktu kontrolnego tętna, by zresetować wartość zużytej energii na 0 na pulsie.
Obiecuję, że nie ma tu magii. Wszystko zostało wyjaśnione w sekcji Kontrola tętna Strona Cecha punktu.
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); });
Otrzymywanie powiadomień GATT
Zobaczmy teraz, jak otrzymać powiadomienie po pomiarze tętna. zmian cech charakterystycznych na urządzeniu:
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
}
Przykład powiadomień pokazuje, jak wyłączyć powiadomienia z
stopNotifications()
i prawidłowo usuń dodany element: characteristicvaluechanged
detektora zdarzeń.
Rozłączanie z urządzeniem Bluetooth
Aby zadbać o wygodę użytkowników, możesz nasłuchiwać zdarzeń rozłączenia i poproś go o ponowne połączenie:
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.`);
}
Możesz też wywołać device.gatt.disconnect()
, by odłączyć aplikację internetową od
Urządzenie Bluetooth. Spowoduje to aktywowanie istniejącego zdarzenia gattserverdisconnected
słuchaczom. Pamiętaj, że NIE spowoduje to przerwania komunikacji z urządzeniem Bluetooth, jeśli inna
Aplikacja komunikuje się już z urządzeniem Bluetooth. Sprawdź urządzenie
Odłącz próbkę i próbkę automatycznego ponownego połączenia, aby dowiedzieć się więcej.
Odczyt i zapis w deskryptorach Bluetooth
Deskryptory GATT Bluetooth to atrybuty opisujące wartość charakterystyczną. Można je odczytywać i zapisywać w podobny sposób jak w GATT Bluetooth dla niektórych cech produktu.
Przyjrzyjmy się np. temu, jak odczytać opis pomiaru podany przez użytkownika między termometrem zdrowotnym urządzenia.
W poniższym przykładzie health_thermometer
to usługa termometru zdrowotnego,
measurement_interval
charakter interwału pomiaru oraz
gatt.characteristic_user_description
Opis użytkownika
deskryptor.
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); });
Po przeczytaniu opisu przez użytkownika interwału pomiaru termometru zdrowotnego urządzenia, zobaczmy, jak go zaktualizować i napisać własną .
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); });
Przykłady, wersje demonstracyjne i ćwiczenia z programowania
Wszystkie poniższe przykłady Web Bluetooth zostały przetestowane. Ciesz się zalecamy zainstalowanie [BLE Peripheral Simulator] Android App Store], który symuluje urządzenie peryferyjne BLE z usługą baterii, pomiarem tętna lub serwisu termometru zdrowotnego.
Początkujący
- Informacje o urządzeniu – pobieranie podstawowych informacji o urządzeniu z urządzenia BLE.
- Poziom baterii – pobiera informacje o baterii z urządzenia BLE wyświetlającego informacje o baterii.
- Resetuj energię – zresetuj energię wydaną przez urządzenie BLE wyświetlające wskaźniki tętna.
- Właściwości charakterystyczne – wyświetlanie wszystkich właściwości określonych cech urządzenia BLE.
- Powiadomienia – uruchamianie i zatrzymywanie powiadomień o charakterze z urządzenia BLE.
- Odłączanie urządzenia – rozłącz urządzenie BLE i otrzymuj powiadomienie o jego rozłączeniu po połączeniu z nim.
- Uzyskaj cechy – pozwala uzyskać wszystkie cechy reklamowanej usługi z urządzenia BLE.
- Pobierz deskryptory – uzyskaj wszystkie cechy” deskryptory reklamowanej usługi z urządzenia BLE.
- Filtr danych producenta – pobiera z urządzenia BLE podstawowe informacje o urządzeniu zgodne z danymi producenta.
- Filtry wykluczania – pobieranie podstawowych informacji o urządzeniu z urządzenia BLE obejmujące podstawowe filtry wykluczania.
Łączenie kilku operacji
- GAP Characteristics (Charakterystyka GAP) – pozwala uzyskać wszystkie cechy GAP urządzenia BLE.
- Charakterystyka informacji o urządzeniu – pobieranie wszystkich informacji o urządzeniu z BLE.
- Utrata połączenia – ustaw charakterystykę poziomu alertu urządzenia z BLE (readValue &writeValue).
- Odkryj usługi i Cechy – informacje o wszystkich dostępnych usługach podstawowych i ich cechach dostępnych na urządzeniu BLE.
- Automatyczne ponowne łączenie – ponownie nawiąż połączenie z odłączonym urządzeniem BLE za pomocą algorytmu ponowienia „wykładniczego”.
- Zmiana wartości charakteru odczytu – odczytuje poziom baterii i otrzymuj powiadomienia o zmianach z urządzenia BLE.
- Odczytaj deskryptory – odczyt wszystkich deskryptorów usługi z urządzenia BLE.
- Wpisz deskryptor – zapisz w deskryptorze „Characterists User description” (Opis charakterystyczny użytkownika) na urządzeniu BLE.
Sprawdź też nasze wyselekcjonowane wersje demonstracyjne Web Bluetooth i oficjalne ćwiczenia z programowania Web Bluetooth.
Biblioteki
- web-bluetooth-utils to moduł npm, który zapewnia dodatkowe wygodne funkcje interfejs API.
- Podkładka Web Bluetooth API jest dostępna w noble, najpopularniejszym środowisku Node.js BLE z modułu centralnego. Pozwala to na tworzenie pakietów internetowych/przeglądarek szlachetnych bez konieczności dla serwera WebSocket lub innych wtyczek.
- angular-web-bluetooth to moduł narzędzia Angular, który wyodrębnia wszystkie potrzebne do skonfigurowania interfejsu Web Bluetooth API.
Narzędzia
- Pierwsze kroki z Web Bluetooth to prosta aplikacja internetowa, która wygeneruje stały kod JavaScript, by zacząć interakcję z urządzeniem Bluetooth. Wpisz nazwę urządzenia, usługę, charakterystykę, określ jego właściwości oraz Wszystko gotowe.
- Jeśli jesteś już programistą Bluetooth, Web Bluetooth Developer Studio Wtyczka wygeneruje też kod JavaScript Web Bluetooth dla Urządzenie Bluetooth.
Wskazówki
Strona Wewnętrzne Bluetooth znajdziesz w Chrome na:
about://bluetooth-internals
, aby przeglądać wszystko w pobliżu
Urządzenia Bluetooth: stan, usługi, parametry i deskryptory.
Zalecamy też zapoznanie się z oficjalnym artykułem na temat zgłaszania błędów przez Web Bluetooth. ponieważ debugowanie Bluetootha może być czasem trudne.
Co dalej?
Najpierw sprawdź stan implementacji przeglądarki i platformy, aby dowiedzieć się, które interfejsu Web Bluetooth API jest obecnie wdrażany.
Chociaż nie zostało ono jeszcze do końca gotowe, zobacz zdrapek o tym, czego można się spodziewać w niedalekiej przyszłości przyszłe:
- Skanuję w poszukiwaniu reklam BLE w pobliżu
będzie dotyczyć
navigator.bluetooth.requestLEScan()
. - Nowe zdarzenie
serviceadded
będzie śledzić nowo wykryte usługi GATT Bluetooth aserviceremoved
zdarzenie – śledzenie usuniętych. Nowyservicechanged
jest wywoływane po dodaniu właściwości lub deskryptora zostało usunięte z usługi GATT Bluetooth.
Pokaż wsparcie dla interfejsu API
Czy planujesz korzystanie z interfejsu API Web Bluetooth? Twoje publiczne wsparcie pomaga zespołowi Chrome nadaje priorytet funkcjom i pokazuje innym dostawcom przeglądarek, jak ważne jest ich wsparcie.
Wyślij tweeta na adres @ChromiumDev, używając hashtagu
#WebBluetooth
.
i daj nam znać, gdzie i jak go używasz.
Zasoby
- Stack Overflow
- Stan funkcji Chrome
- Błędy w implementacji Chrome
- Specyfikacja Web Bluetooth
- Problemy ze specyfikacją w GitHubie
- Aplikacja symulatora urządzeń peryferyjnych BLE
Podziękowania
Dziękujemy Kayce Basques za przeczytanie tego artykułu. Baner powitalny: SparkFun Electronics z Boulder, USA.