iBeacon, youBeacon, weBeacon
Abdou nous a introduit dans cet article la technologie iBeacon dans ses grandes lignes. Si vous ne l'avez pas encore lu, je vous invite à le faire avant de lire celui-ci. Nous allons maintenant aller un peu plus loin pour comprendre concrètement comment iBeacon peut nous être utile, et quelles sont ses limitations. Il est important de bien saisir que iBeacon est une technologie permettant à un émetteur de signaler sa propre présence, et rien de plus. Ce n’est pas un protocole d’échange, l'émetteur ne sait pas si un récepteur est entré ou sorti de son périmètre et il ne peut pas échanger de messages particuliers avec lui. Il n’est qu’une balise (beacon en anglais) qui émet une transmission à sens unique, et il ne fait qu’annoncer (advertise) qui il est, à la manière d'un phare qui s'identifie par son signal sans savoir si le moindre navire est à sa portée. Par conséquent, toute l’intelligence de la mise en oeuvre d'iBeacon réside dans la pertinence de la localisation de la balise et dans le code de l’application qui l’écoute. Pour une meilleure compréhension de l'article, nous utiliserons le mot iBeacon pour désigner la technologie, et le mot balise pour désigner l'appareil. L'application à l'écoute du signal sera désignée comme récepteur.
La Balise
Qui peut être balise ?
Pour les développeurs iOS, le plus immédiat pour tester la technologie est probablement de concevoir une application iBeacon sur un device Apple. Tous les devices implémentant BLE (iPad 3+, iPhone 4S+, iPad mini+, iPod touch 5+) sont capables de fonctionner en tant que balise. Il suffit pour cela de faire appel aux frameworks CoreLocation et CoreBluetooth. Ensuite, quelques lignes de code suffisent à émettre une annonce iBeacon avec un UUID, une valeur majeure et une valeur mineure. Dans le code suivant, on suppose que les conditions requises sont vérifiées (la classe appelante implémente le protocole CBPeripheralManagerDelegate, l'activation du Bluetooth a été vérifiée, le device assure le BLE...) :
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"318FDEAA-64DD-4448-88B4-2CD462CF68BE"];
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:1 minor:1 identifier:@"beacon1-region"];
NSDictionary *beaconDictionary = [beaconRegion peripheralDataWithMeasuredPower:nil];
CBPeripheralManager *peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil options:nil];
[peripheralManager startAdvertising:beaconPeripheralData];
Bien sûr, il serait dommage de limiter son iPad à la transmission iBeacon. Pour un usage plus pérenne, plus économique et moins encombrant, on préférera utiliser des devices dédiés à la transmissions iBeacon. Une fois acquis, ceux-ci ne demandent qu'à être allumés pour émettre leur signal. L'UUID et les valeurs majeure et mineure peuvent ensuite être changés.
Enfin, il est possible de concevoir soi-même sa balise iBeacon à l'aide de n'importe quel autre appareil implémentant BLE. Par exemple, à partir d'un Raspberry Pi couplé à une clé Bluetooth 4.0, on peut installer les outils nécessaires et configurer son système pour qu'il diffuse une identification conformément au format iBeacon.
Chacune de ces solutions présente ses caractéristiques propres (autonomie, fréquence de l'annonce, portée de la diffusion, capacités de personnalisation, consommation électrique...), et il convient de bien considérer son besoin avant d'en choisir une.
Que fait la balise ?
Concrètement, une balise iBeacon diffuse à travers la technologie BLE un ensemble d’octets qui permettent - De définir le format du message - D'identifier la balise Pour illustrer le contenu du message envoyé, disséquons la ligne de commande appelée pour émettre un signal iBeacon depuis un device linux (en l’occurrence, un Raspberry Pi). La ligne de commande est celle-ci :
hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 **31 8F DE AA 64 DD 44 48 88 B4 2C D4 62 CF 68 BE** 00 01 00 01 C5 00
hcitool
: On fait ici appel à la commande hcitool issue de Bluez, une boite à outils Buetooth pour Linux. Cette commande permet de configurer la connexion Bluetooth.-i hci0
: On indique le nom de l’appareil Bluetooth sur lequel on souhaite appliquer la configurationcmd
: La commande suivante doit être envoyée à l'appareil0x08 0x0008
: Ces octets désignent le groupe de commandes bluetooth 0x08, c’est-à-dire "LE Controller Commands”, au sein duquel il faut exécuter la commande spécifique 0x0008, c’est à dire “LE Set Advertising Data”. C’est cette commande qui va nous permettre d’émettre un signal en Low Energy. Le contenu du signal émis devra se conformer au format iBeacon pour être identifiable par les devices “à l’écoute”.1E
: Indique le nombre d’octets significatifs à prendre en compte dans la commande. Pour un signal iBeacon, elle vaut 30, donc les 30 prochains octets sont significatif. Le maximum pour ce type de commande est de 31 octet (1F).02 01 1A 1A FF 4C 00 02 15
: Ensemble d’octets fixe spécifique à la technologie iBeacon. Ils contiennent un certain nombre d’informations comme des flags Bluetooth ou l’indication d’un signal spécifique du constructeur Apple.**31 8F DE AA 64 DD 44 48 88 B4 2C D4 62 CF 68 BE**
: Ici commencent les informations d’identification de la balise. Ces 16 octets constituent l’UUID de proximité, c’est-à-dire l’identifiant unique des balises rattachées à une certaine entité (une entreprise, un magasin, un constructeur…). Un UUID peut être généré très simplement à l'aide de la ligne de commandeuuidgen
sur Mac.00 01
: Les 2 octets de la valeur majeure, pour désigner un groupe de balises au sein de l’entité (toutes les balises de la boutique des Champs Elysées, du 2eme étage, de la zone électroménagers…)00 01
: Les 2 octets de la valeur mineure, pour désigner de façon unique une balise au sein d’un groupe (la balise de la porte d’entrée, du rayon appareils photos, de la caisse numéro 3…)C5
: La force du signal bluetooth à 1m de l'appareil en complément à 2, c'est-à-dire -59dBm dans notre cas.00
: pour compléter jusqu’à 31 octets, non transmis pour économie d’énergie
De tous ces éléments, il n'y en a finalement que 3 qui nous intéressent vraiment d'un point de vue fonctionnel : l'UUID, la valeur majeure et la valeur mineure. Ces 3 éléments combinés identifient une région. Sa surface est définie par la balise au centre et la portée de l'émetteur.
Le récepteur
Qui peut être récepteur ?
Bien sûr, le récepteur privilégié pour une application localisée par iBeacon reste les appareils Apple, puisque la technologie a été conçue par eux. On peut objecter qu'iBeacon repose sur une transmission BLE, et que n'importe quel appareil capable de recevoir du BLE pourrait exploiter le signal. C'est vrai, mais l'intérêt des appareils Apple est qu'iOS7 lui-même interprète le signal. Il est donc capable de réveiller une application et de publier un message alors que l'application n'est qu'en arrière plan, ou que le device est en veille. Et depuis iOS7.1, il est même possible d'afficher une notification locale alors que l'application ne tourne pas en background (après redémarrage du device, par exemple). D'autre part, le SDK d'iOS inclut des librairies facilitant largement la détection de signaux iBeacon.
Il est toutefois à noter que Radius Networks a développé un SDK Android pour répliquer un fonctionnement identique sur une application Android.
Que fait le récepteur ?
Comme on l'a précisé en introduction, c'est dans le récepteur que se situe toute l'intelligence de la localisation. Tout comme le capitaine d'un bateau reconnait un phare à son signal et adapte sa navigation en conséquence, l'application doit identifier la balise qu'elle détecte et restituer le comportement correspondant. Dans le contexte d'une application iOS, le SDK propose 2 niveaux de détection d'une région. Le "monitoring" (pour détecter la présence) et le "ranging" (pour estimer la distance). L'application peut commencer à "monitorer" la présence d'un ensemble de régions par les lignes suivantes (ici aussi, on réduit le code à l'essentiel, en supposant tous les pré-requis vérifiés).
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"318FDEAA-64DD-4448-88B4-2CD462CF68BE"];
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"corporate-region"];
[locationManager startMonitoringForRegion:beaconRegion];
La région est ici définie par l'UUID uniquement. Quelles que soient leurs valeurs majeure et mineure, les balises identifiées par cet UUID seront donc écoutées. On pourrait réduire le spectre du monitoring en précisant une valeur majeure, ou une valeur majeure et une valeur mineure. En revanche, on ne pourrait pas élargir le spectre pour détecter toute balise iBeacon sans connaitre son UUID. Le SDK ne le permet pas.
Le monitoring défini par le framework CoreLocation permet au delegate d'être alerté dès que le device entre ou sort d'une région identifiée par l'UUID. Les 2 méthodes du delegate sont (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
et (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
. L'information (entrée ou sortie du périmètre d'une balise) peut être exploitée même si l'application ne tourne pas (ni en foreground, ni en background) avec l'affichage d'une notification locale.
Pour obtenir une information plus précise sur la proximité de la balise, on fait intervenir l'outil de ranging. On appelle pour cela la méthode (void)startRangingBeaconsInRegion:(CLBeaconRegion *)region
(généralement depuis la méthode delegate (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
). La méthode delegate (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
est alors appelée régulièrement avec en argument les balises détectées dans la région scrutée :
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
for (CLBeacon *beacon in beacons)
{
// Exploiter les valeurs de beacon.proximityUUID, beacon.major, beacon.minor, beacon.proximity, beacon.rssi
}
}
Les informations contenues dans ces objets CLBeacon permettent d'identifier précisément les balises à portées du device. Il appartient ensuite à l'application d'exploiter au mieux ces données. Elle doit pour ce faire être lancée et en foreground. L'information de proximité (qui peut prendre les valeurs immédiate, proche, lointaine ou inconnue), de même que le RSSI (Received Signal Strength Indication) ne permettent qu'une estimation de la distance qui sépare le récepteur de la balise. Leur fiabilité est donc relative, et il appartient au concepteur de l'application d'en tenir compte.
Conclusion
On l'a vu, il est important d'être conscient des limitations de la technologie iBeacon pour bien appréhender ses usages. L'aspect unilatéral de la transmission d'identification et la précision relative de l'estimation de distance d'une balise sont des facteurs souvent sous-estimés.
Si l'on souhaite localiser précisément son client dans un magasin pour l'orienter au mieux dans son parcours, il faudra acquérir plusieurs balises et le localiser de façon plus précise en utilisant la triangulation. En revanche, si on n'a pas besoin d'une précision fine, par exemple pour souhaiter la bienvenue à un client entrant dans le magasin, une balise unique est suffisante, mais il faudra bien réfléchir à son positionnement en fonction de sa portée et de la configuration physique de la boutique. L'application réceptrice doit par ailleurs être bien conçue pour déclencher les actions adéquates selon les signaux reçus. Par exemple, la réception du signal de l'entrée du magasin pourra afficher une notification sur le téléphone pour encourager l'utilisateur à lancer l'application, l'arrivée à proximité de la balise d'un rayon en promotion pourra ouvrir un écran spécifique aux offres actuelles, l'entrée dans la région des caisses pourra orienter le client vers la caisse la moins fréquentée, etc. D'autre part, si on souhaite déclencher un véritable échange d'informations lorsqu'un mobile arrive à proximité d'une balise iBeacon, on se pourra se reposer sur un bon vieux back-end. Ainsi, lorsque le client entre dans la région des caisses, l'application pourra ouvrir un écran connecté à une solution de paiement mobile.
L'iBeacon est donc une technologie prometteuse, et si les cas d'usage dans le cadre d'une balise fixe sont déjà nombreux, dans le cadre du retail notamment, on peut aussi imaginer de nombreux cas d'usage de balises mobiles, associées à un moyen de transport (trains, voitures...) ou a des personnes, puisque même un iphone peut faire office de balise.