Espruino:Примеры/BLE и Node-RED с MQTT

Материал из Онлайн справочника
Перейти к навигации Перейти к поиску

Перевод: Максим Кузьмин (Cubewriter) Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.


BLE и Node-RED с MQTT [1]

Простейший способ начать работать с Puck.js и [1]] – это воспользоваться программой EspruinoHub на Raspberry Pi. Она будет служить мостиком между Bluetooth Low Energy и MQTT.

Инструкции по установке и настройке EspruinoHub читайте по этой ссылке.

С чего начать

Установив сервер, подключаемся к Node-RED при помощи HTTP-порта. Например, вот так: «http://raspberry:1880».

Puck.js Node-RED node-red 1.png

Чтобы начать получение MQTT-пакетов:

  • Перетяните в рабочую область входную ноду «mqtt» и выходную ноду «debug», а затем подключите их друг к другу
  • Дважды кликните по ноде «mqtt» и:
    • Убедитесь, что в Server стоит localhost:1883 (при первом использовании Node-RED вам нужно будет добавить новый сервер)
    • Убедитесь, что в Topic стоит /ble/#. Здесь # – это wildcard-символ MQTT
  • Теперь кликните на Deploy справа вверху
  • Убедитесь, что кнопка справа от ноды «debug» имеет ярко зелёный цвет
Puck.js Node-RED node-debug 2.png
  • Кликните на кнопку с тремя полосками справа вверху, а затем на View > Debug messages

Теперь в окне Debug начнут генерироваться сообщения с объявлениями:

Puck.js Node-RED node-debug-msg 3.png

Если также вписать в код для Puck.js функцию NRF.setAdvertising(), то информация, заданная в этой функции, тоже будет показана сообщениях, генерируемых в окне Debug.

Минимизация рассылаемой информации

Часто вам не нужна вся рассылаемая информация, но её можно минимизировать, отредактировав поле Topic во входной ноде «mqtt».

В моём случае это «/ble/advertise/e7:e0:57:ad:36:a2/rssi» (см. вкладку Debug). Это означает, что я получаю информацию о мощности сигнала (RSSI) пакетов, рассылаемых от Puck.js с адресом «e7:e0:57:ad:36:a2».

Чтобы прослушивать все сообщения от «e7:e0:57:ad:36:a2», можно воспользоваться «/ble/advertise/e7:e0:57:ad:36:a2/#», но поскольку мне интересен только RSSI, я оставлю прежний вариант. Поменяйте адрес на тот, что был показан у вас в окне Debug.

Теперь, если нажать Deploy, можно увидеть, что на вкладке Debug будет появляться только RSSI.

Создание графиков данных

Если вы следовали инструкциям для EspruinoHub, то также должны были установить библиотеку для UI.

  • Переместите в рабочую область ноду «chart» из раздела «ui»
  • Подключите её к ноде «mqtt»
  • Дважды кликните по ней и дайте ей какое-нибудь название
  • Теперь кликните на Deploy
  • Теперь, если перейти в браузере по ссылке «http://raspberry:1880/ui», вы увидите график. Чем больше виджетов из «ui» вы добавите в поток Node-RED, тем больше элементов будет в этом окне с графиком

Использование данных

Теперь мы можем воспользоваться этой информацией о мощности сигнала, чтобы выполнить какое-нибудь действие, когда Puck.js приблизится к нам на определённое расстояние (что также изменит мощность сигнала).

  • Найдите подходящее RSSI-значение в сообщениях из вкладки Debug. Помните, что это отрицательное число!
  • Переместите в рабочую область ноду «function», дважды кликните по ней и вставьте в неё код ниже, но замените «-70» на собственное RSSI-значение:
msg.payload = msg.payload > -70;
return msg;
  • Подключите эту ноду между нодами «mqtt» и «debug». Чтобы удалить связь между нодами, кликните на неё и нажмите Delete.
  • Кликните на Deploy. Теперь вместо чисел будут булевы значения – когда Puck.js приблизится на определённое расстояние, значение изменится на true.
  • RSSI-данные могут сильно колебаться, но их можно сгладить при помощи функции «smooth»:
Puck.js Node-RED node-smooth 4.png

Выполнение действий с помощью получаемых данных

Кроме того, имея какие-либо данные, мы можем с их помощью выполнить какое-нибудь действие. Если вы используете Raspberry Pi, то можете перетянуть в рабочую область ноду «rpi gpio» – с её помощью можно менять состояние GPIO-контакта на значение «true», которое мы получили, обработав RSSI-значение.

Или же мы можем отправить электронное письмо, воспользовавшись нодой «email». Но проблема в том, что вы вряд ли захотите отправлять имейл несколько раз в секунду. Как правило, необходимость сделать что-либо появляется только при изменении состояния с одного на другое.

Для этого вам понадобится нода «rbe» (от англ. «Report By Exception», что можно перевести как «сообщить об исключительной ситуации»). Она будет пропускать сообщения дальше по потоку, только если новое значение отличается от предыдущих.

Определение нажатия на кнопку

Puck.js оснащён кнопкой, поэтому очевидно, что мы можем использовать нажатия на неё для активации каких-либо действий. Мы не можем гарантировать получение абсолютно всех пакетов объявлений, отправляемых Puck.js, так что нам нужно будет найти какой-то безошибочный способ определения того, была ли нажата кнопка или нет.

Самый простой – это отправлять число, которое будет увеличиваться с каждым нажатием на кнопку. То есть, если даже какие-то пакеты будут утеряны, EspruinoHub по-прежнему сможет определять нажатия на кнопку, видя изменение в соответствующем значении.

Вот код для Puck.js, с помощью которого это можно сделать:

var pressCount = 0;
setWatch(function() {
  pressCount++;
  NRF.setAdvertising({
    0xFFFF : [pressCount]
  });
}, BTN, { edge:"rising", repeat:true, debounce:50 });

Вместо 0xFFFF можно задать абсолютно любое (даже случайное) значение.

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

Puck.js Node-RED node-button 5.png

В примере выше нода «show toast» будет просто показывать баннер на UI-странице. Этот способ можно использовать для определения любых событий, а не только нажатий на кнопку.

Определение наличия устройства

Мы также можем определять появление и исчезновение (другими словами, отсутствие от него объявлений в течение одной минуты) маяка.

Просто подпишитесь на MQTT-топик «/ble/presence/ад:рес:уст:рой:ст:ва» и будете получать «1» при появлении маяка и «0» при его исчезновении.

Управление Puck.js

Следующий шаг – это отправка сообщения на Puck.js при возникновении какого-то события.

В этот раз мы добавим пару кнопок для запуска событий:

  • Добавляем две ноды «inject»
  • Дважды кликаем по одной из них и задаем в Payload код LED1.set();
  • Дважды кликаем по второй и задаем в Payload код LED1.reset();
  • Добавляем ноду «function» и подключаем к ней обе ноды «inject»
  • Дважды кликаем по ней и пишем в ней код ниже. Он добавит в отправляемые команды символ новой строки (чтобы Puck.js понимал, где заканчивается команда).
msg.payload += "\n";
return msg;
  • Наконец, добавляем выходную ноду «mqtt» и задаем в поле Topic значение «/ble/write/e7:e0:57:ad:36:a2/nus/nus_tx», где «e7:e0:57:ad:36:a2» – это адрес вашего устройства.
Puck.js Node-RED node-nus-tx 6.png

Всё, готово, осталось только кликнуть на Deploy. Теперь, нажимая на кнопки, вы будете включать и выключать светодиод. Помимо прочего, этот метод можно использовать для запуска функций, которые вы до этого задали на Puck.js.

Примечание

Топик задаётся в формате /ble/write/ад:рес:уст:рой:ст:ва/сервис/характеристика, чтобы вам не пришлось передавать данные по Nordic UART на Puck.js. Вы можете задать собственные сервисы и записывать данные напрямую в них. В этом случае формат будет такой:

  • 6e400001b5a3f393e0a9e50e24dcca9e – для 128-битных UUID
  • abcd – для 16-битных UUID

Дополнительно

При помощи модуля «node-red-contrib-ifttt» можно настроить коммуникацию между Node-RED и IFTTT:

  • Залогиньтесь в Raspberry Pi при помощи имени пользователя pi
  • Напечатайте cd .node-red
  • Напечатайте npm install node-red-contrib-ifttt
  • Перезапустите Node-RED при помощи node-red-stop, а затем node-red-start

Теперь у вас есть IFTTT-блок, который можно использовать для запуска IFTTT-событий.

См.также

Ссылки на полезные ресурсы

Внешние ссылки