À propos de l'auteur
Niels est un geek de navigateur qui se prétend lui-même et qui a créé le test HTML5 il y a longtemps. Il est MVP Microsoft, expert en développement Google et conférencier régulier à la…
Pour en savoir plus sur Niels …
Avec les applications Web progressives, vous pouvez désormais utiliser le Web pour créer des applications complètes. Grâce à une quantité énorme de nouvelles spécifications et fonctionnalités, nous pouvons utiliser le Web pour lequel vous aviez besoin d'écrire des applications natives. Cependant, parler aux périphériques matériels était encore un pont trop éloigné jusqu'à présent. Grâce à WebBluetooth, nous pouvons maintenant construire des PWA pouvant contrôler vos lumières, conduire une voiture ou même contrôler un drone.
Avec Progressive Web Apps, le Web se déplace de plus en plus vers les applications natives. Toutefois, avec les avantages supplémentaires inhérents au Web, tels que la confidentialité et la compatibilité entre plates-formes.
Le Web a toujours été fantastique pour parler aux serveurs du réseau, et aux serveurs sur Internet en particulier. Maintenant que le Web évolue vers les applications, nous avons également besoin des mêmes fonctionnalités que les applications natives.
Le nombre de nouvelles spécifications et fonctionnalités mises en œuvre ces dernières années dans les navigateurs est stupéfiant. Nous avons des spécifications pour traiter avec la 3D telles que WebGL et la future WebGPU. Nous pouvons diffuser et générer de l'audio, regarder des vidéos et utiliser la webcam comme périphérique d'entrée. Nous pouvons également exécuter du code à des vitesses presque natives à l'aide de WebAssembly. De plus, bien qu’il s’agisse au départ d’un support exclusivement réseau, le Web a évolué vers une prise en charge hors ligne avec les services services .
C’est formidable et tout, mais un domaine est presque le domaine exclusif des applications natives: communiquer avec des appareils. C’est un problème que nous essayons de résoudre depuis longtemps et que tout le monde a probablement rencontré à un moment donné. Le Web est un excellent moyen de communiquer avec des serveurs, mais pas avec des périphériques . Pensez, par exemple, à la configuration d’un routeur sur votre réseau. Il est probable que vous deviez entrer une adresse IP et utiliser une interface Web via une simple connexion HTTP sans aucune sécurité. C'est juste une mauvaise expérience et une mauvaise sécurité. De plus, comment savoir quelle est la bonne adresse IP?
HTTP est également le premier problème rencontré lorsque nous essayons de créer une application Web progressive qui tente de communiquer avec un appareil. Les PWA sont uniquement HTTPS et les périphériques locaux ne sont toujours que HTTP. Vous avez besoin d'un certificat pour HTTPS et, pour obtenir un certificat, vous avez besoin d'un serveur public avec un nom de domaine (je parle des périphériques de notre réseau local qui sont hors de portée).
Donc, pour de nombreux périphériques , vous avez besoin d’applications natives pour configurer et utiliser les appareils, car celles-ci ne sont pas soumises aux limitations de la plate-forme Web et peuvent offrir une expérience agréable à ses utilisateurs. Cependant, je ne souhaite pas télécharger une application de 500 Mo pour le faire. Peut-être que votre appareil a déjà quelques années et que l'application n'a jamais été mise à jour pour fonctionner sur votre nouveau téléphone. Peut-être souhaitez-vous utiliser un ordinateur de bureau ou un ordinateur portable, et le fabricant n'a créé qu'une application mobile. Ce n'est pas non plus une expérience idéale.
WebBluetooth est une nouvelle spécification mise en œuvre dans Chrome et Samsung Internet qui nous permet de communiquer directement avec les périphériques Bluetooth Low Energy à partir du navigateur. Les applications Web progressives, associées à WebBluetooth, offrent la sécurité et la commodité d'une application Web avec le pouvoir de communiquer directement avec les périphériques.
Bluetooth a une très mauvaise réputation en raison de la portée limitée, de la mauvaise qualité audio et des problèmes d'appariement. Mais, à peu près tous ces problèmes sont une chose du passé. Bluetooth Low Energy est une spécification moderne qui a peu à voir avec les anciennes spécifications Bluetooth à part l'utilisation du même spectre de fréquences. Chaque jour, plus de 10 millions d'appareils sont compatibles Bluetooth. Cela inclut les ordinateurs et les téléphones, mais aussi divers appareils tels que les glucomètres et les glucomètres, les appareils IdO tels que les ampoules électriques et les jouets tels que les voitures télécommandables et les drones.
Lecture recommandée : Basées sur les plates-formes: Un guide pour les chefs de produit
La partie théorique ennuyeuse
Bluetooth n'étant pas une technologie Web, il utilise un vocabulaire qui peut sembler inconnu de nous. Voyons donc comment fonctionne Bluetooth et une partie de la terminologie.
Chaque périphérique Bluetooth est un «périphérique central» ou un «périphérique». Seuls les appareils centraux peuvent établir une communication et ne peuvent communiquer qu'avec des périphériques. Un ordinateur central ou un téléphone portable est un exemple d'appareil central
Un périphérique ne peut pas établir de communication et ne peut communiquer qu'avec un appareil central. De plus, un périphérique ne peut parler qu’à un seul appareil à la fois. Un périphérique ne peut pas communiquer avec un autre périphérique.
Un appareil central peut communiquer avec plusieurs périphériques en même temps et peut relayer des messages s'il le souhaite. Ainsi, un moniteur de fréquence cardiaque ne peut pas communiquer avec vos ampoules, mais vous pouvez écrire un programme qui fonctionne sur un périphérique central qui reçoit votre fréquence cardiaque et allume le voyant rouge si la fréquence cardiaque dépasse un certain seuil.
Parler de WebBluetooth, nous parlons d’une partie spécifique de la spécification Bluetooth appelée Profil d’attribut générique, qui porte l’abréviation très évidente GATT. (Apparemment, GAP était déjà pris.)
Dans le contexte du GATT, nous ne parlons plus de périphériques et de périphériques centraux, mais de clients et de serveurs. Vos ampoules sont des serveurs. Cela peut sembler contre-intuitif, mais cela a du sens si vous y réfléchissez. L’ampoule offre un service, c’est-à-dire une lumière. Tout comme lorsque le navigateur se connecte à un serveur sur Internet, votre téléphone ou votre ordinateur est un client qui se connecte au serveur du GATT dans l'ampoule.
Chaque serveur offre un ou plusieurs services. Certains de ces services font officiellement partie de la norme, mais vous pouvez également définir les vôtres. Dans le cas du moniteur de fréquence cardiaque, un service officiel est défini dans la spécification. Dans le cas de l'ampoule électrique, il n'y en a pas et pratiquement tous les fabricants essaient de réinventer la roue. Chaque service a une ou plusieurs caractéristiques. Chaque caractéristique a une valeur qui peut être lue ou écrite. Pour le moment, il serait préférable de le considérer comme un tableau d'objets, chaque objet ayant des propriétés ayant des valeurs.
Contrairement aux propriétés des objets, les services et les caractéristiques ne sont pas identifiés par une chaîne. Chaque service et caractéristique a un UUID unique qui peut avoir une longueur de 16 ou 128 bits. Officiellement, l’UUID 16 bits est réservé aux normes officielles, mais pratiquement personne ne suit cette règle.
Enfin, chaque valeur est un tableau d'octets. Bluetooth ne contient pas de types de données sophistiqués.
À propos d’une ampoule Bluetooth
Voyons maintenant un appareil Bluetooth: une sphère Mipow Playbulb. Vous pouvez utiliser une application telle que BLE Scanner ou nRF Connect pour vous connecter à l'appareil et voir tous les services et caractéristiques. Dans ce cas, j'utilise l'application BLE Scanner pour iOS.
La première chose que vous voyez lorsque vous vous connectez à l'ampoule est une liste de services. Il existe des systèmes standardisés tels que le service d'informations sur les périphériques et le service sur batterie. Mais il existe aussi des services personnalisés. Je suis particulièrement intéressé par le service avec l'UUID 16 bits de 0xff0f
. Si vous ouvrez ce service, vous pouvez voir une longue liste de caractéristiques. Je n'ai aucune idée de ce que font la plupart de ces caractéristiques, car elles ne sont identifiées que par un UUID et parce qu'elles font malheureusement partie d'un service personnalisé. elles ne sont pas normalisées et le fabricant n'a fourni aucune documentation.
La première caractéristique avec l'UUID de 0xfffc
semble particulièrement intéressante. Il a une valeur de quatre octets. Si nous changeons la valeur de ces octets de 0x00000000
à 0x00ff0000
l'ampoule devient rouge. En le remplaçant par 0x0000ff00
l'ampoule devient verte et 0x000000ff
en bleu. Ce sont des couleurs RVB et correspondent exactement aux couleurs hexadécimales que nous utilisons en HTML et CSS.
Que fait ce premier octet? Eh bien, si nous changeons la valeur en 0xff000000
l'ampoule devient blanche. L'ampoule contient quatre voyants différents et, en modifiant la valeur de chacun des quatre octets, nous pouvons créer toutes les couleurs souhaitées.
L'API WebBluetooth
Il est fantastique de pouvoir utiliser une application native pour modifier le couleur d'une ampoule, mais comment fait-on cela depuis le navigateur? Il s’avère qu’avec les connaissances sur Bluetooth et le GATT que nous venons d’apprendre, c’est relativement simple grâce à l’API WebBluetooth. Il suffit de quelques lignes de code JavaScript pour changer la couleur d’une ampoule.
Passons en revue l’API WebBluetooth.
Connexion à un périphérique
La première chose à faire est de vous connecter à partir du navigateur à l'appareil. Nous appelons la fonction navigator.bluetooth.requestDevice ()
et lui fournissons un objet de configuration. Cet objet contient des informations sur le périphérique que nous voulons utiliser et sur les services qui devraient être disponibles pour notre API.
Dans l'exemple suivant, nous filtrons le nom du périphérique, car nous souhaitons uniquement voir les périphériques contenant le préfixe. PLAYBULB
dans le nom. Nous spécifions également 0xff0f
en tant que service que nous souhaitons utiliser. Puisque la fonction requestDevice ()
renvoie une promesse, nous pouvons attendre le résultat.
let device = attend le navigateur navigator.bluetooth.requestDevice ({
filtres: [
{ namePrefix: 'PLAYBULB' }
],
services facultatifs: [ 0xff0f ]
});
Lorsque nous appelons cette fonction, une fenêtre contenant la liste des périphériques conformes aux filtres que nous avons spécifiés apparaît. Nous devons maintenant sélectionner le périphérique auquel nous voulons nous connecter manuellement. C’est une étape essentielle pour la sécurité et la confidentialité et donne le contrôle à l’utilisateur. L'utilisateur décide si l'application Web est autorisée à se connecter et, bien sûr, à quel appareil elle est autorisée à se connecter. L'application Web ne peut pas obtenir une liste de périphériques ni se connecter sans que l'utilisateur sélectionne manuellement un périphérique.
Une fois que nous avons eu accès au périphérique, nous pouvons nous connecter au serveur du GATT en appelant la fonction connect ()
sur la propriété gatt
et d'attendre le résultat. 19659042] let server = wait device.gatt.connect ();
Une fois que nous avons le serveur, nous pouvons appeler getPrimaryService ()
sur le serveur avec l'UUID du service que nous voulons utiliser comme paramètre et attendre le résultat.
let service = wait server .getPrimaryService (0xff0f);
Appelez ensuite getCharacteristic ()
sur le service avec le paramètre UUID de la caractéristique et attendez à nouveau le résultat.
Nous avons maintenant nos caractéristiques que nous pouvons utiliser pour écrire et lire des données:
let caractéristique = wait service.getCharacteristic (0xfffc);
Écrire des données
Pour écrire des données, nous pouvons appeler la fonction writeValue ()
sur la caractéristique avec la valeur que nous voulons écrire en tant que ArrayBuffer, qui est une méthode de stockage des données binaires. La raison pour laquelle nous ne pouvons pas utiliser un tableau standard est que les tableaux classiques peuvent contenir des données de différents types et même avoir des trous vides.
Comme nous ne pouvons pas créer ou modifier directement un ArrayBuffer, nous utilisons à la place un "tableau typé". Chaque élément d'un tableau typé est toujours du même type et ne comporte aucun trou. Dans notre cas, nous allons utiliser un Uint8Array
qui n'est pas signé et ne peut donc contenir aucun nombre négatif; un entier, donc il ne peut pas contenir de fractions; et il s'agit de 8 bits et ne peuvent contenir que des valeurs comprises entre 0 et 255. En d'autres termes: un tableau d'octets.
character.writeValue (
nouveau Uint8Array ([ 0, r, g, b ])
)
Nous savons déjà comment fonctionne cette ampoule. Nous devons fournir quatre octets, un pour chaque voyant. Chaque octet a une valeur comprise entre 0 et 255 et, dans ce cas, nous souhaitons uniquement utiliser les voyants rouge, vert et bleu. Nous laissons donc le voyant blanc éteint en utilisant la valeur 0.
Reading Data
Pour lire la couleur actuelle de l'ampoule, nous pouvons utiliser la fonction readValue ()
et attendre le résultat.
let value = wait = caractéristique.readValue ();
Soit r = valeur.getUint8 (1);
Soit g = valeur.getUint8 (2);
Soit b = valeur.getUint8 (3);
La valeur que nous récupérons est une vue de données d'un ArrayBuffer et offre un moyen d'extraire les données de l'ArrayBuffer. Dans notre cas, nous pouvons utiliser la fonction getUint8 ()
avec un index comme paramètre pour extraire les octets individuels du tableau.
Getting Notified Of Changes
Enfin, il existe aussi un moyen d’être averti lorsque la valeur d’un périphérique change. Ce n'est pas vraiment utile pour une ampoule électrique, mais pour notre moniteur de fréquence cardiaque, nous avons des valeurs qui changent constamment, et nous ne voulons pas interroger manuellement la valeur actuelle chaque seconde.
character.addEventListener (
'caractéristiquevaluée', e => {
Soit r = e.target.value.getUint8 (1);
Soit g = e.target.value.getUint8 (2);
Soit b = e.target.value.getUint8 (3);
}
)
caractéristique.startNotifications ();
Pour obtenir un rappel chaque fois qu'une valeur change, nous devons appeler la fonction addEventListener ()
sur la caractéristique avec le paramètre caractéristique évaluée
et une fonction de rappel.
Chaque fois que la valeur change, la fonction de rappel est appelée avec un objet événement comme paramètre et nous pouvons obtenir les données à partir de la propriété value de la cible de l'événement. Et, enfin, extrayez à nouveau les octets individuels à partir du DataView de ArrayBuffer.
La bande passante du réseau Bluetooth étant limitée, nous devons démarrer manuellement ce mécanisme de notification en appelant startNotifications ()
. . Sinon, le réseau sera inondé de données inutiles. De plus, comme ces appareils utilisent généralement une batterie, chaque octet que nous n'avons pas à envoyer améliorera définitivement la durée de vie de la batterie de l'appareil, car la radio interne ne doit pas nécessairement être allumée aussi souvent.
Conclusion
Nous avons maintenant dépassé 90% de l'API WebBluetooth. En quelques appels de fonction et envoi de 4 octets, vous pouvez créer une application Web qui contrôle les couleurs de vos ampoules. Si vous ajoutez quelques lignes supplémentaires, vous pouvez même contrôler une voiture miniature ou piloter un drone. Avec de plus en plus d'appareils Bluetooth sur le marché, les possibilités sont infinies.
Ressources supplémentaires
Source link