Ловимо повідомлення з допомогою маячків

Привіт, мене звуть Ілля Гарах, у мене є власна студія, де я керую мобільного та веб-розробкою, паралельно розвиваю і просуваю кілька стартапів. Про Bluetooth-маячки вперше я почув з чергової презентації Apple, і на той момент вся ідея здалася сумнівною і заплутаною. Пізніше ми з колегами повернулися до теми маячків: інтерактивна реакція на пересування і висока точність позиціонування в приміщеннях виглядали дуже привабливо.


Стаття автора Іллі Гараха, в рамках конкурсу <a href=«special.habrahabr.ru/google/lab>Device Lab від Google».

Але наліт радості був затьмарений обмеженнями пристроїв, адже з BLE (Bluetooth з низьким енергоспоживанням) на той момент вміли працювати тільки нові Айфони і останні версії пристроїв на Android, тому дане рішення складно було просунути як робочий для широкої аудиторії. Згодом відсоток пристроїв, що підтримують BLE істотно зріс, тому на початку 2016 ми закупили ibeacon-маяки для тестування. З цього все і почалося.

Якщо ви не в курсі, ibeacon — це протокол (формат) взаємодії з BLE придуманий Apple. На ринку є багато виробників маяків, які передають дані в цьому форматі. Першим маяком, який потрапив у мої руки був ibeacon-маяк від фірми «iBecom».


Його доставили в поштовому конверті, без будь-яких інструкцій (власне, як і будь-які інші маяки), і що з ним робити далі я не уявляв. Почалася довга переписка з технічною підтримкою «iBecom», в ході якої з'ясувалося, що налаштувати маяк можна тільки через додаток для iPhonne (при цьому треба було надіслати запити на реєстрацію в якомусь їхньому внутрішньому порталі), а власники Android-пристроїв можуть завантажити будь-який додаток для управління маяками з «Play Market». Проходити квести з iPhone мені захотілося; програми для Android дійсно бачили маяк, але жодне з них не дозволяло його налаштовувати, питання: «Так і повинно бути?» залишилося невирішеним.

До речі, всі додатки показували різні відстані до маяка: від 1 до 10 метрів, хоча маяк лежав у кількох сантиметрах від телефону. Це настільки розчулювало, і я почав шукати відгуки про реальних впроваджень. З'ясувалося, що позиціонування відмінно працює в тестових кімнатах, а в реальних умовах сила сигналу залежить не тільки від батареї і відстані, а також від стін, перегородок, і взагалі всього, що знаходиться в приміщень. Тому навіть якщо у вас буде натикано багато маяків, і ви будете знати їх координати, то стриангулировать і точно визначити розташування телефону швидше за все не вдасться. Ця задача вирішується створенням «карти сигналів» для мікро-локацій: розставляєте маяки, берете пристрій і ходите по місцевості, у кожній невеликій зоні скануєте маяки, прочитаєте силу їх сигналів, все це справа як-небудь хешируете, отриманий хеш буде ідентифікувати мікро-зону.

Невеликий відступ
Ми не займаємося нативної мобільного розробкою, а використовуємо Cordova. У Cordova є свої плюси, є багато мінусів і обмежень, а так само треба вміти її готувати, але в певних випадках плюсів більше (для нас). Тому тут і далі мова буде йти виключно про Cordova.
Так от, для Cordova був і є готовий плагін для роботи з ibeacon. Він легко встановився і досить швидко вдалося зібрати перше тестове додаток. Телефон цілком стабільно отлавливал наближення до маячку і вихід із зони видимості». Не пам'ятаю точних характеристик «iBecom» маяка, але зазвичай заявляють, що маяк ловиться на 10 метрів (а деякі на 50 і більше). Мій телефон «втрачав» маяк в одній кімнаті при видаленні від нього приблизно на 4 метри.
Ще одна цікава особливість полягала в тому, що для лову маяка необхідно вказувати його UUID (дізнатися UUID можна за допомогою будь-якої програми для роботи з BLE і маяками, UUID так само можна змінити, але для цього потрібен софт від виробника)

var beaconRegion = new cordova.plugins.locationManager.BeaconRegion('someMyld', '00000000-0000-0000-0000-000000000000');
cordova.plugins.locationManager.startMonitoringForRegion(beaconRegion);

beaconRegion = new cordova.plugins.locationManager.BeaconRegion ( 'someMyId2' , '00000000-0000-0000-0000-000000000123');
cordova.plugins.locationManager.startMonitoringForRegion(beaconRegion);

І так далі в циклі. Повідомлення про маяку повернеться в ваш коллбек. Таким чином, вам заздалегідь треба знати UUID всіх своїх маяків, а зробити broadcast пошук неможливо (забігаючи трохи вперед — broadcast все ж можливий, хоч і через… одне місце).

Погравшись з ibeacon ми зрозуміли, що в цілому його можна використовувати як додаткову «фічу» і ловити «клієнта», коли він близько підходить до маяка, наприклад, сідає за стіл або підходить до товару. Використовувати маяки для позиціонування в приміщеннях нам здалося технічно можливим, але аж надто важким заняттям. Ну, і звичайно «клієнт» повинен встановити собі ваш додаток.

У підсумку ми впровадили цей плагін в режимі тесту в реальне додаток і все пройшло гладко, нічого не зламалося і не стало конфліктувати (якщо ви не знайомі з Cordova, то проблеми з кривими і конфліктуючими плагінами — це те, на що постійно доводиться витрачати час при розробці, ми з любов'ю називаємо цю проблему «Cordova Plugin Hell»). Переконавшись, що все працює, я поставив галочку напроти ibecon і з чистою совістю відклав маяк на майбутнє.

Eddystone
Зовсім недавно я дізнався, що крім ibeacon існують і інші протоколи роботи маяків. Мова звичайно йде про Eddystone, який придумав Google, а так само Altbeacon, який придумав співтовариство. Це повернуло мене до думок про маяків та їх можливості, а побачивши пост на Хабре про можливості протестувати Eddystone маяки, я не зміг пройти мимо і подав заявку на участь. І вже через кілька тижнів на моєму столі лежав eddystone-маяк від виробника Accent System.


Якщо ви не в курсі, то формат Eddystone включає в себе більше даних, ніж iBeacon, який, по суті передає тільки 16-байтовий UUID, а так само два числа (major і minor values), а зловити ці дані можна тільки у вашому додатку. Eddystone дозволяє маяка працювати в різних режимах: так само як і iBeacon передати UUID (в eddystone він називається UID), передавати URL (який вшитий безпосередньо в маяк, і ви можете налаштовувати), телеметрію (мета-дані маяка, теплота), а так само режим передачі EUID і циклічної його зміни.

Основний шик полягає в тому, що телефони на Android, які підтримують BLE, вміють ловити Eddystone c URL автоматично — вам не треба ставити додаткових додатків. Просто включаєте Bluetooth, підходите до маяка і ловіть повідомлення про те, що телефон знайшов посилання.

iPhone без милиць чужі технології розуміти не хочуть, але можуть ловити URL, якщо встановлений браузер Google Chrome.

Звичайно, я відразу захотів перевірити цю фічу. На сайті виробника я знайшов посилання на додаток Play Market, яке можна використовувати для конфігурування маяка. Маяк знайшовся, без особливих проблем я перевів його в режим конфігурування (необхідно витягнути і вставити назад батарею, і протягом 30 секунд маяк переходить в Dev режим). Прописав URL, все зберіг і став чекати, що буде далі. І нічого не сталося.

Зрозуміло, на допомогу прийде великий Google. Я поліз читати про Google Beacon Dashboard (це хмарна панель управління маяками), про Google Proximity API і NearBy API. З'ясувалося, що з допомогою спеціального мобільного додатку (Google Beacon Tool) треба зловити бекон і зареєструвати його в хмару, після чого у бекона через веб-інтерфейс можна налаштувати і URL, і багато інших параметрів (атачменти, прив'язка до карти тощо). Все це непогано підірвала мозок і грунтовно заплутало, але приблизно через півдня вивчення мінлива я почав розуміти, що до чого.

Отже:

  • Google Proximity API — це API (Java), за допомогою якого ви можете підключитися до eddystone бекону і сконфігурувати його (грубо кажучи якийсь бекенд);
  • NearBy API — це API (Java), з допомогою якого телефон клієнта зможе отримувати дані з хмари Гугла про маяках;
  • Google Beacon Dashboard — власне саме хмара, через веб можна налаштовувати маяки;
  • Google Beacon Tool — мобільний додаток від Гугла для лову маяків та реєстрації в хмарі;
  • А так само у самого Eddystone маяка можна налаштувати URL;
  • Саме вшитий в маяк URL і буде ловитися телефоном, навіть без установки додатків;
Основна мета Google Beacon Dashboard і NearBy API — впровадити маяки і управляти їх параметрами через веб, не розробляючи свій бек-енд для цього. А Google Proximity API використовується, якщо вам потрібно впровадити управління маяками в свій проект.

Проблема полягала в тому, що мій телефон вперто не хотів ловити маяк з URL. Виявилося, що у мене була заборона на пошук публічних посилань, які можна прибрати в налаштуваннях Google у вашому Android-девайсі (саме налаштування Google, а не системи, і якщо ви ще там не повзали, то знайдете багато цікавого).


З цією проблемою розібралися. Заради інтересу я перевірив телефони всіх найближчих колег і знайомих: ні в кого такої фігні не було і після включення Bluetoothа, всі девайси відразу спіймали посилання. Списали все на дивацтва налаштування мого девайса.

Далі я спробував зареєструвати Eddystone-маяк в хмарі Google, але Google Beacon Tool вперто не знаходило Eddystone, хоча iBeacon (від «iBecom») знайшовся відразу, і з ним проблем не було. Після великої кількості марних спроб я написав в саппорт виробнику «Accent Systems» (до речі, якщо ви збираєтеся рясно впроваджувати саме ці маяки, врахуйте, що само собою по-російськи ніхто там не говорить). Відповідь від «Accent Systems» я отримав через 3-4 робочих дня, що на мій скромний погляд зовсім не швидко.

У відповідь мені надіслали посилання на Dropbox, де я міг завантажити нову версію програми для конфігурування маяка і нову документацію. Новий додаток перепрошило маяк, Beacon Tool його нарешті знайшла. Варто відзначити, що вся ця історія зі скачуванням програми з незрозумілих посилань виглядає принаймні сумнівно для серйозного виробника пристроїв (і, до речі, партнером Google).

Згідно нової документації від «Accent Systems» їх eddystone маяки можуть одночасно вести мовлення як 4 звичайних eddystone і 2 ibeacon.


На практиці ж мені так і не вдалося змусити працювати слоти, крім першого. До речі, усвідомлення цього факту зайняло досить багато часу, тому що спершу я налаштовував 3-ий слот і довго не міг зрозуміти чому нічого не працює.

Таким чином, мій Eddystone маяк міг мовити одночасно як ibeacon і як eddystone (в будь-якому режимі), тобто 1+1 замість заявлених 4+2 одночасних слотів.

Програмуємо тестове додаток
Після того як з Eddystone маяком вдалося налагодити стабільну роботу пора розробити тестове додаток. Як я вже написав раніше — все будемо робити на Cordova.

Шукаємо плагіни для роботи з eddystone для Cordova і відразу знаходимо . Це плагін від компанії Evothings, яка займається розробкою і постачанням різних рішень для BLE пристроїв.

Фінальний варіант мого тестового додатку я залив на гитхаб.


Не вдаючись у деталі нашої внутрішньої кухні, приклад зроблений на базі нашого внутрішнього каркаса додатків, який працює на F7 Framework і RequireJS. Весь код основний перебуває тут.

Я додав плагін (cordova-plugin-eddystone), скопіював їх приклад, сбилдил додаток і запустив на телефоні.

Невеликий відступ для тих, хто хоче використовувати Cordova. Ми не билдим додатки локально, замість цього розгорнуто білд-сервер в Digital Ocean. Все це може бути інтегровано з вашим CI-рішенням або кустарними-скриптами. В результаті при пуше білд-сервер сповіщається, pull-іт зміни і запускає білд. Весь процес ретельно коментується нашим ботом в Slack (з текстом з комітів), тому всі завжди в курсі, що билдится, і коли все готове для встановлення. Загалом, нескладно налаштувати зворотний зв'язок і через ADB автоматично встановлювати додатках на телефон.

Тестувати ж основну логіку Cordova додатків можна в браузері, тому що по суті додаток — це звичайний веб-сайт. Ми знайшли цей підхід дуже зручним, адже не треба турбуватися про оточеннях, версіях Java, Cordova, які Android Target встановлені, а білд-сервер піднімається з снапшота за 1 хвилину. Звичайно, це історія про Андроїд, адаптація, білд і продакшен для ios відрізняються.

Якщо ви вирішите піти цим шляхом рекомендую додати в білд видалення і додавання платформи, це позбавить вас від багатьох проблем з плагінами.


Так от, після білду прикладу, я відразу підключив дебагер (через chrome://inspect) та побачив, що хоч приклад і працює без помилок, але беконов він не знаходить. І це абсолютно нормально для Cordova — плагіни дуже часто не працюють як треба. Я почав вивчати плагін cordova-plugin-eddystone і виявив код, який запускає BLE сканування.

// The device object given in this callback is reused by easyble.
// Therefore we can store data in it and expect to have the data still be there
// on the next callback with the same device.
evothings.easyble.startScan(
// Scan for Eddystone Service UUID.
// This enables background scanning on iOS (and Android).
['0000FEAA-0000-1000-8000-00805F9B34FB'], function(device)
{
// A device might be an Eddystone if it has advertisementData... var ad = device.advertisementData; if(lad) return;
// With serviceData...
var sd = ad.kCBAdvDataServiceData;
if(lsd) return;
// And the 0xFEAA service.

Магічне число 0000FEAA-0000-1000-8000-00805F9B34FB — це ідентифікатор Eddystone-маяків. Воно передається в інші методи плагіна і в підсумку йде в Java плагін. Вивчаємо вихідний код методу evothings.easyble.startScan і розуміємо, що передавати ідентифікатор необов'язково. Прибираємо його і дивимося, що відбувається — плагін ловить маяки, то, що потрібно!

Більше того, тепер плагін ловить всі BLE пристрої, в тому числі і не маяки. І це чудово, хай ловить, а ми вже якось вирішимо, що робити з цими даними.

Невеликий відступ для тих, хто хоче використовувати Cordova. Підключіть свій телефон за USB, дозвольте налагодження відкрийте Google Chrome chrome://inspect і виберіть свій додаток. Ви можете налагоджувати його як звичайний сайт, а так само прямо на льоту змінювати JS-код.

Ок, роблю форк плагіна і починаю вносити зміни.


Першим ділом, прибираємо рядок
['0000FEAA-0000-1000-8000-00805F9B34FB']
.

Бачу, що тепер плагін ловить і ibeacon, але відкидає його на подальшу валідацію. Читаю документацію за форматом ibeacon і eddystone. Всі маяки шлють Scan Record, який містить всі дані. В base64 це виглядає якось так:

AgEGGv9MAAIVoHxcqFnrTqiZVjC3duD+3AAEAAS7DBbw/1/r3V649LuVAQAAAAAAAAAAAAAAAAAAAAAaaaa=


Конвертуємо в шестнадатиричную систему:



І читаємо опис Scan record для ibeacon формату:



Бачимо, що 6-8 байти (х4с000215) — це константи, після яких йде UUID ibeacon-а. Парсим scan record, знаходимо ці 4 байти і вважаємо наступні 16 байт. Потім конвертуємо всі в рядок до формату типу:

a07c5ca8-59eb-4ea8-9956-30b776e0fedc
https://github.com/garakh/cordova-eddystone/blob/master/js/eddystone-plugin.js#L534 і далі по коду).

Допиливаю інші дрібниці і валідації, запускаю, перевіряю — все працює як треба, тепер крім eddystone плагін ловить і ibeacon. При цьому не треба ставити заздалегідь UUID ibeacon, адже плагін ловить все.

Пушу плагін та приступаю до впровадження Eddystone в реальне додаток.

Продакшен
Саме час познайомити вас з одним з стартапів, в яких я беру активну участь.
Лоя — лояльність як сервіс. Лоя дає бізнесу можливість легко і швидко впровадити програми лояльності, надаючи дашборд з аналітикою, API та інші інструменти.

Одна з фішок — бізнес може замовити собі мобільний додаток, де клієнти зможу накопичувати бали і отримувати подарунки. А якщо бізнес хоче зробити швидкий старт, то може пропонувати своїм клієнтам спільне рішення: клієнтське прикладення Лоя, в якому присутні і всі інші компанії.

Саме у нього ми і будемо додавати підтримку Eddystone. Для того, щоб не ускладнювати проектуємо простий алгоритм роботи з маяками:

  1. Додаток ловить маяк, збирає дані: MAC адреса, URL, UUID, NID+BID (це EUID у eddystone);
  2. Відправляє дані на сервер;
  3. Сервер перевіряє, чи є такий бекон у якої-небудь компанії;
  4. Якщо бекон є, то повертає текст повідомлення, яке відобразимо на екрані, а так само шолом PUSH, мало телефон в кишені;
  5. Якщо додаток ловить Eddstone URL, то на сервері валидируется MAC адресу маяка, і якщо все ок, то відкриваємо сторінку з цим URL.
    До речі, якщо у клієнта не буде встановлено нашого додатка, він все одно побачить URL, тому що Eddstone рулить.
Алгоритм для компанії:

  1. Купують маяк;
  2. За допомогою будь утиліти з'ясовують його дані (UUID, MAC тощо);
  3. Вказують рекламне повідомлення (в нашому веб-дашборде) або конфігурують маяк в режимі Eddystone URL;
  4. Розміщують маяк в магазині;
  5. Проходять поряд покупці бачать URL або пуш нотифікацію, якщо встановлено наше додаток;
Ок, отже, додаємо в дашборд управління маяками:


До речі, фронтенд у нас працює на Angular 1.х, RequierJS, Bower, Gulp. Бекенд: PHP Phalcon, MongoDB. Чудова зв'язка випробувана на багатьох проектах. Дописуємо серверний API і переходимо до програмування мобільного додатку. Т. до. все вже перевірено, то додаємо наш форкнутый плагін і насолоджуємося ловом беконов.

Фінальне відео і реліз
  • Тест ibeacon (підносимо бекон — мабуть повідомлення);
  • Тест eddystone URL (підносимо бекон — відкривається сторінка);
  • Билдим реліз і заливаємо в Play Market;
Тобто, не всі пристрої підтримують BLE тримаємо в маркеті кілька версій. Версія 0.1.0 з підтримкою беконов (буде працювати на Android 5+) і 0.0.8 без підтримки (буде працювати 4-х версіях Андроїда).

Висновок
Було витрачено близько 30 людино-годин на вивчення і тестування та 5 годин на інтеграцію в бойове додаток, розробку бек-енду і реліз. Робота з маячками в мережі досі висвітлена бідно і заплутано. Доводиться спілкуватися з саппортом виробників маячків, і за їх відповідям розумієш, що у самих виробників це працює не сильно краще.

Використовувати маячки для indoor-навігації, на мій погляд можна, але поки що досить сумнівно, так і впроваджується з великими трудовитратами. Маячок від Accent Systems так і не запрацював на всіх слотах.

Батарея маячка від iBecom померла десь через 6 місяців (маяк просто лежав на столі), хоча заявлено мало не 2-3 роки роботи.

Eddystone URL — на мій погляд дуже перспективна штука, не вимагає наявності спеціальних додатків і єдине, що працювало з коробки без шаманства.
У порівнянні Eddystone і iBeacon — eddystone однозначно виграє. Не бачу ніякого сенсу купувати ibeacon маяки, які стоять так само, працюють точно також криво, а в плані функціональності відстають на кілька років.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.