Статьи

Приложения с поддержкой Bluetooth Beacon с BlueCats и PhoneGap

Маяки BLE — это технология, которая вдохновляет меня быть разработчиком сегодня. Мало того, что есть так много возможностей, любой разработчик может начать разработку прямо сейчас . Не предварительный заказ, не все еще находящийся в разработке продукт, не Kickstarter … Маяки Bluetooth уже используются! В этой статье мы рассмотрим, как начать работу с маяками BLE, связывающими облачную платформу маяка BlueCats и API с PhoneGap.

Что такое маяки BLE?

BLE означает Bluetooth Low Energy и относится к технологии беспроводной сети Bluetooth, которая была разработана для работы с гораздо меньшим энергопотреблением и гораздо меньшей стоимостью. Только эти два фактора сделали его идеальным для ряда новых подключенных устройств, включая носимые устройства, интеллектуальные системы домашней автоматизации и наиболее интересный для нас в этой статье — маяки.

Маяки — это устройства Bluetooth, которые можно разместить практически где угодно, чтобы отслеживать местоположение пользователя в этом пространстве. Они могут быть повсюду в здании, на рекламном щите, в транспортном средстве … почти везде, где полезно знать, где находятся ваши пользователи. Примеры потенциального использования в приложении для смартфона:

  • Мобильное приложение, посвященное экскурсиям по музею, которое может определить местонахождение каждого пользователя в музее и предоставить им соответствующий контент
  • Интерактивные рекламные щиты, которые изменяются или перемещаются, когда пользователи с приложением находятся поблизости!
  • Умная система автоматизации телефона, которая знает, в какой комнате вы находитесь, и управляет определенными вещами соответственно

Как вписываются BlueCats Beacons?

Маяки BlueCats — это маяки BLE, которые поставляются с легкодоступным API (доступным на Android, iOS и PhoneGap) и облачной платформой для управления ими. Несколько недель назад я имел удовольствие встретиться с несколькими парнями, работающими над маяками BlueCats, и разговор с ними вызвал у меня жажду попробовать! Я, честно говоря, не мог поверить, насколько готова технология была внедрена.

Демо

Я попробовал маяки BlueCats, собрав простой прототип PhoneGap, который использовал их API для внедрения некоторых функций, основанных на местоположении. Я построил прототип таймера обратного отсчета, предназначенного для того, чтобы напоминать зависимым от компьютера душам, таким как я, каждые 30 минут вставать с компьютера и передвигаться.

В отличие от обычных таймеров обратного отсчета, этот использует мощные маяки BlueCats, чтобы узнать, действительно ли вы встали и переехали в другую комнату. Как только таймер отключается, пользователь должен встать и пройти в другую комнату с определенным маяком, чтобы сбросить таймер. В качестве дополнительного бонуса, как только они возвращаются на свой компьютер, USB-маяк распознает, что они вернулись, и автоматически перезапускает таймер для них.

Подготовка нашего приложения PhoneGap

Для начала давайте подготовим наше демонстрационное приложение PhoneGap, используя обычные команды PhoneGap. Если у вас еще нет PhoneGap, установите его с помощью этой команды npm:

sudo npm install -g phonegap 

Затем мы создадим наше базовое приложение для этой демонстрации. Я назвал это «BreakEnforcer», но вы можете называть это как хотите. Когда мы запустим приведенную ниже команду, PhoneGap установит все наши основы.

 phonegap create BreakEnforcer 

Подготовьте наше приложение BlueCats

Если вы новичок в BlueCats и ищете хороший способ начать работу, в этой демонстрации используются маяки BlueCats из пакета BlueCats StarterPack .

Чтобы начать работу с платформой BlueCats, вам необходимо настроить учетную запись BlueCats. Вы можете зарегистрировать StarterPack на странице настройки BlueCats StarterPack .

После настройки учетной записи перейдите на панель управления BlueCats и войдите в систему.

Отсюда вы увидите панель управления, которая выглядит примерно так:

Панель управления BlueCats

Нажмите ссылку «Приложения» с левой стороны, чтобы перейти на панель мониторинга приложений, а затем нажмите «Создать новое приложение».

Здесь мы можем ввести данные нашего приложения. Я назвал свое приложение «Break Enforcer».

Выберите платформу, на которой вы будете тестировать свое приложение. Я выбрал Android, так как именно это я и буду тестировать. Однако, поскольку мы используем Phonegap, должно быть достаточно просто воссоздать приложение для остальных позже. Затем нажмите «Создать приложение».

Форма создания приложения BlueCats

Добавление нашего приложения BlueCats в PhoneGap

В BlueCats есть плагин PhoneGap, который мы будем использовать для добавления всех функций маяка BlueCats. Чтобы включить его в наше приложение PhoneGap, выполните следующую команду в каталоге BreakEnforcer (или как вы назвали свое приложение):

 phonegap plugin add https://github.com/bluecats/bluecats-phonegap.git 

Если вы перейдете в папку plugins своего приложения PhoneGap, вы найдете папку com.bluecats.beacons с нашей функциональностью BlueCats.

Наш Кодекс

Весь код для этой демонстрации доступен на GitHub для просмотра и адаптации к вашим собственным созданиям маяков! Я объясню основные области кода и как они работают.

Примечание: весь наш код здесь аккуратно заключен в пространство имен app , поэтому при вызове функций и тому подобного вам нужно помнить об этом.

Весь наш код начинается с функции initialize() . Он запускает две функции, bindEvents() и initCountdownTimer() . bindEvents() нашу функцию маяка, в то время как initCountdownTimer() фокусируется на наших функциях таймера.

 initialize: function() { this.bindEvents(); this.initCountdownTimer(); }, 

Я сохранил их относительно отдельно, поэтому, если вы используете это как базовую линию для совершенно другого приложения, не должно быть слишком сложно поменять биты таймера на свои собственные.

Наши функции маяка

Для функциональности маяка мы будем использовать структуру, очень похожую на пример plugins/com.bluecats.beacons/Samples/HelloBeacons/index.js который вы найдете в папке плагинов BlueCats. Их установка довольно чиста, и я подумал, что лучше оставаться последовательным! Наш пример немного более упорядочен, так как мы не будем использовать все функции в примере приложения. Мы будем сосредоточены на отслеживании того, когда мы достигнем маяков. Также можно отслеживать, когда мы отходим от них, или определять, какой маяк находится ближе всего к нам — наше приложение не будет беспокоиться об этом.

Вернуться к коду! В bindEvents() мы настраиваем наш прослушиватель событий, который прослушивает, когда наш телефон / планшет готов. Мы отслеживаем это через событие deviceready .

 document.addEventListener('deviceready', this.onDeviceReady, false); 

На deviceready запущены две функции, связанные с маяком. Мы рассмотрим каждый ниже.

 onDeviceReady: function() { app.receivedEvent('received'); app.watchBeacons(); }, 

Функция receivedEvent() функция, которая отвечает на три разных события, связанных с маяком. Это выглядит так:

 receivedEvent: function(event) { var parentElement = document.getElementById('deviceready'), listeningElement = parentElement.querySelector('.listening'), receivedElement = parentElement.querySelector('.received'); listeningElement.setAttribute('style', 'display:none;'); receivedElement.setAttribute('style', 'display:block;'); if (event == 'apptokenrequired') { receivedElement.innerHTML = 'App token not set' } else if (event == 'bluecatspurring') { // We are on the look out for beacons receivedElement.setAttribute('style', 'display:none;'); }; console.log('Received Event: ' + event); }, 

Первоначально он .listening два наших элемента сообщения: .listening и .received . Затем он скрывает элемент .listening и в игру вступают три типа наших событий:

  • 'received' — хотя наш код .received receivedEvent() напрямую не ссылается на эту строку события, при первоначальной отправке через нее наш элемент .received в нашем приложении .received видимым. Это элемент, который говорит «Устройство готово» по умолчанию.
  • 'apptokenrequired' — это переключает наш элемент .received чтобы сказать “Токен приложения не установлен”.
  • 'bluecatspurring' — это передается, когда наше приложение с готовностью ищет маяки. Когда он делает это, мы очищаем сообщение, поэтому наше наблюдение за маяками выполняется тонко.

Если мы onDeviceReady() на нашу onDeviceReady() , другая функция, которая запускается для наших маяков, — это watchBeacons() . Это настраивает наше приложение для наблюдения за маяками BlueCats через SDK.

Мы начнем с объявления переменной с именем watchIdForEnterBeacon которую мы будем использовать для назначения «идентификатора наблюдения», который ссылается на наш наблюдатель маяка. Это дает нам переменную для очистки, если мы хотим прекратить просмотр маяков с помощью вызова SDK с именем com.bluecats.beacons.clearWatch .

 var watchIdForEnterBeacon = null; 

Далее у нас есть тест, чтобы убедиться, что вы добавили в приложение токен. Если у вас его нет, он запустит receivedEvent() и отобразит ошибку. В производственной среде вы можете снять эту проверку, поскольку к тому времени вы вряд ли пропустили этот шаг. Это была умная проверка, добавленная в пример командой BlueCats, которая мне понравилась и была там!

 if (blueCatsAppToken == 'BLUECATS-APP-TOKEN') { //BlueCats app token hasn't been configured app.receivedEvent('apptokenrequired'); return; } 

Затем у нас есть два набора опций, которые мы можем использовать для настройки работы нашего наблюдения за маяками. Во-первых, sdkOptions — это параметры, которые мы можем передать в com.bluecats.beacons.startPurringWithAppToken() API com.bluecats.beacons.startPurringWithAppToken() . Это то, что запускает BlueCats SDK и начинает искать устройства Bluetooth, поэтому эти параметры относятся к этому. Тот, что в моем примере выглядит так:

 var sdkOptions = { useLocalStorage: true }; 

По сути, мы запрашиваем кэширование маяков с нашей учетной записи BlueCats, если у нас нет доступа к Интернету. Все потенциальные варианты включают в себя:

  • trackBeaconVisits — должны ли мы регистрировать каждое посещение наших маяков в API BlueCats? (Правда или ложь)
  • useLocalStorage — наше локальное кэширование маяка, как использовано выше (логическое значение).
  • cacheAllBeaconsForApp — Должны ли мы кэшировать все маяки при запуске? (Правда или ложь)
  • discoverBeaconsNearby — Должны ли мы кэшировать маяки, обнаруженные устройством? (Правда или ложь)
  • cacheRefreshTimeIntervalInSeconds — как часто проверять изменения API в секундах.

Далее у нас есть beaconWatchOptions которые мы будем использовать в функции com.bluecats.beacons.watchEnterBeacon() в API. Это то, что наблюдает и реагирует на каждый раз, когда мы попадаем в зону действия маяка, так что эти опции относятся к этому.

В нашем коде мы устанавливаем для параметраimumTriggerIntervalInSeconds minimumTriggerIntervalInSeconds 5 чтобы уменьшить частоту выполнения обратных вызовов. Я думал, что по умолчанию запускать его каждую секунду будет слишком часто для этого приложения, поскольку мы не будем слишком часто переходить на новые маяки.

У нас также есть пустая опция filter . У меня не было необходимости фильтровать маяки, которые найдет приложение, однако отсутствие этого пустого JSON вызвало ошибку, поэтому я оставил здесь пустой объект.

 var beaconWatchOptions = { minimumTriggerIntervalInSeconds: 5, filter: {} }; 

Все потенциальные варианты включают в себя:

  • minimumTriggerIntervalInSeconds — минимальное количество секунд между обратными вызовами, как использовано выше.
  • repeatCount — как часто триггер должен иметь возможность повторяться. Мы хотим, чтобы это всегда происходило каждый раз, когда мы входим в радиус действия маяка, поэтому мы не устанавливаем это, однако, если вы хотите ограничить это, вот место.
  • В рамках filter мы имеем следующее:
    • minimumProximity и maximumProximity — минимальное и максимальное расстояние, на которое мы хотим инициировать эти вызовы. Для них может быть задана строка из 'BC_PROXIMITY_IMMEDIATE' (~ <0,5 м), 'BC_PROXIMITY_NEAR' (~ <3 м), 'BC_PROXIMITY_FAR' (~> 3 м) и 'BC_PROXIMITY_UNKNOWN' .
    • минимальная minimumAccuracy — минимальное расстояние в метрах (по умолчанию 0).
    • maximumAccuracy — максимальное расстояние в метрах (по умолчанию неограниченное).
    • sitesNamedsitesNamed массив сайтов, которые вы определили в своей учетной записи SDK, которые вы хотите использовать в приложении (например, ['Fortress of Solitude', 'Batcave', 'The Watchtower'] .
    • categoriesNamed — введите массив категорий, которые вы определили в своей учетной записи SDK, которые вы хотите использовать в приложении (например, ['Memorial Statue', 'Bat-Poles'] ).

Затем у нас есть com.bluecats.beacons.startPurringWithAppToken() из API BlueCats, который запускает наш BlueCats SDK, как упоминалось ранее. Мы даем ему наши blueCatsAppToken и sdkOptions определенные выше, вместе с purringSuccess() обратного вызова purringSuccess() только она готова к доступу к маякам, и logError() если происходит ошибка.

 com.bluecats.beacons.startPurringWithAppToken( blueCatsAppToken, purringSuccess, logError, sdkOptions ); 

Наша purringSuccess() запускает событие 'bluecatsspurring' которое вы запомните ранее. Он также запускает watchBeaconEntry() котором мы watchBeaconEntry() далее.

 function purringSuccess() { app.receivedEvent('bluecatspurring'); watchBeaconEntry(); } 

watchBeaconEntry() выполняет самые захватывающие фрагменты нашего приложения — оно отслеживает маяки BlueCats и реагирует на них. Сначала он проверяет, есть ли у нас уже идентификатор для watchIdForEnterBeacon . Если так, мы сначала очищаем это.

 function watchBeaconEntry() { if (watchIdForEnterBeacon != null) { com.bluecats.beacons.clearWatch(watchIdForEnterBeacon); }; 

Затем мы настраиваем часы- com.bluecats.beacons.watchEnterBeacon() используя com.bluecats.beacons.watchEnterBeacon() из API BlueCats. Это будет работать, когда мы пересекаемся с маяком. В нем есть функция обратного вызова, которая может получить доступ к watchData из маяка, который мы нашли.

 watchIdForEnterBeacon = com.bluecats.beacons.watchEnterBeacon( function(watchData){ // Our response will be here 

С нашими watchData мы получим массив маяков внутри watchData.filteredMicroLocation.beacons . Каждый элемент в этом массиве имеет весь спектр информации о маяке. Существует много потенциальной информации, если вам нужен весь список, см. Раздел информации о маяках BlueCats PhoneGap на странице GitHub.

В нашем приложении мы сосредоточены на одной вещи — названии маяка. Я назвал свой маяк, подключенный через USB, «USBeecon», а мой маяк в другой комнате — «BeaconBeta» (у меня было еще два, которые я назвал «BeaconAlpha» и «BeaconGamma», но мне понравился цвет «BeaconBeta» для этого ). Скорее всего, у вас будут собственные имена для маяков, измените код ниже, чтобы соответствовать им.

Мы используем библиотеку Underscore.js для поиска по каждому элементу в массиве маяков и смотрим, есть ли у маяка какое-либо имя. Если у маяка есть имя «BeaconBeta», то оно должно быть в нашей комнате отдыха, и пользователю необходимо встать и двигаться к нему. В этом случае breakRoomBeacon имеет значение true . Если у маяка есть имя «USBeecon», то для computerBeacon устанавливается значение true .

 var breakRoomBeacon = _.find(watchData.filteredMicroLocation.beacons, function(beacon) { return beacon.name == 'BeaconBeta'; }); var computerBeacon = _.find(watchData.filteredMicroLocation.beacons, function(beacon) { return beacon.name == 'USBeecon'; }); 

Следующий бит кода относится к нашему объекту timer который хранит информацию о нашем таймере. Я расскажу об этом позже в этой статье, но в основном — в ней есть переменная с именем state которая отслеживает состояние нашего таймера (например, идет ли обратный отсчет, истек ли он, находимся ли мы на остановке… и т. Д.) ,

Если срок его действия истек, и мы находимся у маяка в нашей комнате отдыха, мы запускаем app.runBreakMode() который app.runBreakMode() наше приложение в режим прерывания:

 // Room was entered, break successful if (app.timer.state == 'expired' && breakRoomBeacon) { app.runBreakMode(); } 

Если у нас был перерыв и мы вернулись к USB-маяку нашего компьютера, мы запустим app.startCountdownTimer() чтобы снова запустить app.startCountdownTimer() отсчета.

 // Back at the computer else if (app.timer.state == 'breaksuccess' && computerBeacon) { app.startCountdownTimer(); } 

Чтобы завершить нашу com.bluecats.beacons.watchEnterBeacon() , нашей второй и третьей переменными являются наша logError() и наши beaconWatchOptions мы установили ранее.

 }, logError, beaconWatchOptions); } 

Наша logError() довольно проста и просто выполняет основной консольный журнал:

 function logError() { console.log('Error occurred watching beacons'); } 

Вот и вся наша функциональность маяка! Далее мы быстро пройдемся по функциям таймера. Мы не будем вдаваться в подробности по таймеру, так как основное внимание уделяется нашим маякам. Функции таймера в основном работают с (new Date).getTime() и (new Date).getTime() / перезапускают / останавливают наш таймер на этом.

Наши функции таймера

Основная переменная под названием timer которую мы использовали ранее при обнаружении маяка, — это наш объект, который знает все о настройках и состоянии нашего таймера.

 timer: { targetDuration: (1 * 60 * 1000), // Minutes * 60 * 1000 initialCount: 0, currentCount: 0, targetCount: 0, timeout: null, elem: null, toggleButton: null, restartButton: null, message: null, expired: false, state: '' }, 

Объяснение каждого из них должно дать хороший обзор того, как работает таймер:

  • targetDuration — устанавливает в миллисекундах, как долго мы хотим, чтобы таймер отсчитывал. У меня это как (30 * 60 * 1000) , который устанавливает его на 30 минут.
  • initialCount — когда мы запускаем наш таймер обратного отсчета, мы устанавливаем его на время, которое происходит в тот момент.
  • currentCount — каждый раз, когда мы проверяем, какое время для нашего таймера обратного отсчета (каждые полсекунды), мы сохраняем это время в этой переменной.
  • targetCount — в этой переменной мы добавляем нашу targetDuration к нашему initialCount чтобы узнать время initialCount отсчета.
  • timeout — для запуска каждого тика таймера обратного отсчета мы используем setTimeout() . Мы запускаем это каждые полсекунды (если есть небольшая задержка и PhoneGap не может работать ровно каждую секунду). Каждые полсекунды мы сверяем текущее время с запланированным временем и обновляем таймер. Мы храним ссылку на этот тайм-аут, чтобы очистить его в этой переменной. Примечание. Это может привести к разряду батареи и, безусловно, может быть оптимизировано в будущей версии (или в собственном приложении, которое может отслеживать время в фоновом режиме).
  • elem — Наш фактический таймер, который мы обновляем с последним временем обратного отсчета, оставлял каждый тик.
  • toggleButton и restartButton — это две наши кнопки, которые запускают наш таймер и перезапускают наш таймер.
  • message — элемент, используемый для отображения сообщений под таймером.
  • expired — логическое значение, истекшее время таймера или нет.
  • state — состояние нашего таймера, это может быть:
    • 'ready' — наш таймер готов начать.
    • 'running' — наш таймер работает.
    • 'enforcer' — наш таймер отсчитал до тридцати минут и хочет, чтобы наш пользователь сделал перерыв.
    • 'breaksuccess' — наш таймер видел, как мы 'breaksuccess' в другую комнату с маяком, и снова счастлив.

Остальная часть кода таймера должна быть достаточно app.countdown() , app.countdown() запускается каждые 500 миллисекунд для обратного отсчета таймера. Если он заканчивается, он устанавливает состояние 'enforcer' и требует, чтобы наш пользователь встал и вошел в другую комнату. ,

app.setTimerState() используется часто и настраивает наше приложение в зависимости от состояния, в котором находится наш таймер. Функциональность наших кнопок, независимо от того, появляются они или нет, сообщение нашего приложения под таймером и класс, применяемый к общему приложению для стилизации этих различных состояний, здесь обрабатываются.

Тестирование нашего приложения с поддержкой BLE Beacon

PhoneGap имеет приложение для разработчиков, которое позволяет проводить локальное тестирование на iOS, Android и Windows Phone. Я не смог заставить его работать с BlueCats, что, по моему мнению, связано с тем, что BlueCats требует стороннего плагина. Тестирование приложений Bluetooth в эмуляторе Android также не будет работать, так как эмулятор не поддерживает Bluetooth. Поэтому, чтобы протестировать наше приложение, нам нужно использовать реальное устройство Android.

Мы расскажем об основах PhoneGap для Android, однако, если вы хотите получить больше информации или хотите разрабатывать на другой платформе, ознакомьтесь с Руководствами по платформе PhoneGap (хотя этапы компиляции и все должны быть очень похожими) ,

Мы добавляем Android в качестве платформы для нашего приложения с помощью этой команды:

 phonegap platform add android 

После успешного запуска мы запускаем команду PhoneGap для создания нашего приложения с использованием Cordova:

 phonegap build android 

Если вы получите сообщение об ошибке, которое говорит о том, что uses-sdk:minSdkVersion 7 cannot be smaller than version 10 declared in library , вам необходимо обновить config.xml . Линия:

 <preference name="android-minSdkVersion" value="7" /> 

Должно быть:

 <preference name="android-minSdkVersion" value="10" /> 

Затем подключите ваше устройство Android через USB (убедитесь, что параметры USB Debugging и Developer включены ) и запустите:

 phonegap run android 

Теперь вы должны увидеть, как работает ваше приложение, и уметь протестировать прототип вашего приложения-маяка!

Break Enforcer Running App

BlueCats и Break Enforcer в действии

BlueCats и Break Enforcer в действии

Вывод

Получение приложений, подключенных к маякам Bluetooth, было намного проще и более готово для крупных корпоративных проектов, чем я ожидал, было возможно до открытия маяков BlueCats! Их SDK делает разработку с использованием маяков BLE совершенно безболезненной, это простое приложение-прототип было лишь верхушкой айсберга.

Если вы хотите узнать больше о возможностях BlueCats PhoneGap SDK, посетите их страницу GitHub . Если вы предпочитаете попробовать разработку в оригинальном виде, на их странице для разработчиков есть все, что вам нужно!

Я всегда очень хочу видеть и слышать о творениях, которые люди делают из демо-кода, если вы делаете что-то великое с маяками BlueCats, дайте мне знать! Оставьте заметку в комментариях или свяжитесь со мной в Твиттере ( @thatpatrickguy ), я хотел бы проверить это!