Этот проект стремится провести небольшой тест технологии передачи LORA для сбора информации, которая может использоваться Фондом CTIC. Информация будет отправлена с окончательного устройства (узла или клиента), эта информация будет собрана устройством шлюза, и эта, в свою очередь, пересылает его на сервер для его хранения.
Lora - это беспроводная технология (такая как Wi -Fi, Bluetooth, LTE, Sigfox или Zigbee), которая использует тип радиочастотной модуляции, запатентованной Semtech.
В настоящее время технология управляет Альянсом Лора, которая сертифицирует все аппаратное производство, которое стремится работать с этой технологией.
Лора имеет высокую допустимость к помехам , высокая чувствительность к получению данных (-168 дБ), очень низкое потребление (устройство может длиться десятилетие с одним батареей) и диапазоном от 10 до 20 км (в зависимости от того, доступно ли прямое зрение или топология земли). С другой стороны, мы находим очень низкую передачу данных (до 255 байтов).
Все это делает эту технологию передачи полезным для больших расстояний или сетей IoT, которые не нуждаются или не имеют доступа к электрическому току.
Лора работает на свободных частотах (например, в Азии на 868 МГц , 916 МГц в Америке или 433 МГц в Азии), которые, собирая не -необходимый, чтобы иметь поставщика электрической сети и поставщика телекоммуникаций (мы используем радиоприемность), позволяет эмит и отправлять информацию без риска.
Мы можем общаться с устройствами через Loremac (также известный через Лору) или Лораваном.
Loramac : используется для передачи двух устройств друг с другом с точкой точки, один отправляет информацию, а другой собирает ее (или наоборот).
Лораван : используется для передачи сети устройств. При таком подходе появляется фигура шлюза (устройство, которое собирает информацию одного или нескольких устройств и направляет ее на сервер). В Лораване информация должна быть отфильтрована, чтобы узнать, какие устройства вы должны слушать шлюз, а какие игнорировать, но это будет видно позже. Этот подход использует звездную топологию.
С другой стороны, в Лораване есть также три типа окончательных устройств или узлов :
*В примерах только поддержка узлов класса A и B (поддерживаемая используемой библиотекой), но только тип A. реализуется только
Если используется бесплатная полоса частот в Европе (868 МГц), необходимо учитывать некоторые ограничения:
В каждой частотной полосе существует несколько каналов или подполосков, в случае европейского (868 МГц) мы находим 10 каналов, пронумерованных от 0 до 9. Но, например, в американском (915 МГц) мы можем найти до 64.
Отправка информации через тот или иной канал - это задача, которую библиотеки обычно облегчают использовать.
В некоторых конечных показах можно изменить дату-сертификат или распределитель устройства.
Связаны Datarrate и FressingFactor: Datarrate 0 указывает SF12, а Datarrate 5 указывает SF7. Все на частоте 125 кГц, имеющих следующее исключение: данные 6 указывает на SF7 с 250 кГц.
Два устройства (одно для узла и одно для шлюза, которые также должны иметь подключение к Wi -Fi) и связанная с этим учетная запись в TTS ( The Things Network ) или ChirpStack (способность использовать свой собственный сервер дома). В этом примере и Loremac, и Lorawan примеры, которые используют узел Arduino и шлюз Pycom.
Для начала этого достаточно, чтобы клонировать репозиторий:
git clone https://github.com/Javieral95/Getting_Started_With_LoRa.git
А затем загрузите соответствующие проекты на устройства
Почему два IDE? Простое расширение Pymakr едва работает в коде Visual Studio. Не стесняйтесь использовать рабочее место, которое является наиболее удобным.
Оба устройства имеют подключенную к ним антеру.
Примечание . Код для Arduinomkr1300 (более подготовленный для использования, такого как Lora End-Device) и коды для использования Pysense или Pytrack в качестве конечного эвекса также включены в репо.

Пример Loramac (найдена в папке Homomony) функциональны, используя финальное устройство Arduino и шлюз Pycom.
Узел отправляет только информацию о жестком коде, а шлюз подключается только к LORA и WiFi, получает информацию PYCOM и печатает чтение данных (хотя он реализовал функцию отправки данных в сеть).
Использование сетевого сервера распределяется.
Чтобы узнать больше, вы можете получить доступ к папке /Loramac .
Для использования этих примеров (которые являются функциональными, используя окончательное устройство Arduino и шлюз Pycom), для визуализации данных необходим сервер. В этом примере было рассмотрено использование вещей и чирпстака (ранее известного как Loraserver).
Чтобы узнать больше, вы можете получить доступ к папке /Lorawan , а затем продолжить консультировать эту документацию.
В Лораване есть два типа аутентификации:
*В примерах на данный момент производится только OTAA.
Как упоминалось ранее, нам понадобится сервер. Для этого примера использовалась бесплатная версия Tehing Network, сервер ChirpStack, принадлежащий Pycom и другой развернутой дома.
Это самая надежная, безопасная и лучшая задокументированная альтернатива. Тем не менее, все указывает на то, что оно перестанет быть открытым (существует предел 50 узлов на приложение).
Создание приложения просто, доступ к меню и нажмите кнопку +. Как только мы указываем имя приложения, уникальный идентификатор и описание.
Когда приложение создано, мы можем добавить окончательные устройства (узлы) нажимать на кнопку +.
Ворота - это устройства, которые несут ответственность за отправку трафика, который поступает из нескольких окончательных устройств (принадлежащих к нескольким приложениям) и направляется на сервер. Создать шлюз также проста, нажмите кнопку + и заполните форму, обращая внимание на следующие концепции:
Чтобы иметь возможность читать данные, которые узел отправил на сервер, необходимо декодировать полезную нагрузку, в случае TTN мы сделаем это для каждого устройства, на вкладке «Форматиры полетной нагрузки» . Мы выбираем, как формат введите опцию JavaScript и:
function Decoder(bytes, port) {
// Decode plain text; for testing only
return {
myTestValue: String.fromCharCode.apply(null, bytes)
};
}
arduino_ttn_decoder.js Установлено, что все шестнадцатеричные адреса сети вещей находятся в мэре, не важно при программировании устройств, но ошибки были понесены в прошлых версиях.
Это альтернатива с открытым исходным кодом, она все еще находится в разработке, и его документация не так хороша. Тем не менее, он работает и позволяет запустить сервер.
Pycom предлагает сервер ChirpStack для подключения устройства Gateway.
Приложение аналогично подробно в разделе сети вещей.
Вы должны перейти к разработке устройств раздела сервера, один раз в ИТ-доступ к профилю, который интересует (OTAA в данном случае) и изменяют версии:
Чтобы создать шлюз, получить доступ к одному имени и нажмите кнопку +. Заполните форму, уделяющую особое внимание идентификационному поле Gateway (64 бита в шестнадцатеричном, который идентифицирует Gateway), вы можете заставить Chirpstack генерировать их для вас, но Mac устройства обычно используется (если вы не знаете его в разделе, который объясняет шлюз pycom, он будет подробно описан в качестве получения).
Вы можете оставить остальные значения по умолчанию.
Чтобы прочитать данные, которые узел отправил на сервер, необходимо декодировать полезную нагрузку, в случае CHIRPStack мы сделаем это для каждого профиля устройства, в Device Propiles_ Мы получаем доступ к профилю, который интересует нас (в данном случае OTAA), и мы получаем доступ к вкладке CODEC :
Мы выбираем в пользовательских функциях кодека Decipt и:
function Decode(fPort, bytes) {
var tempObj = new Object();
tempObj.data=bytes;
tempObj.decodedData = String.fromCharCode.apply(null, bytes);
tempObj.message = "Informacion recibida del nodo";
return tempObj;
}
arduino_chirpstark_decoder.js Установлено, что все шестнадцатеричные адреса ChirpStack находятся в руках, не важно при программировании устройств, но ошибки были пострадали в прошлых версиях.
Chirpstack предоставляет альтернативу OpenSource для запуска нашего собственного частного сервера в Лораване и позволяет нам делать это простым способом и через контейнеры.
Вот почему еще один репозиторий, принадлежащий основателю Chirpstack (Brocar), который позволяет этой операции: в настоящем репозитории был клонирован Chirpstack-Docker. Мы находим его в папке chirpstack-docker .
Chirpstack имеет различные компоненты в своей архитектуре, чтобы сделать услугу, способной работать, они являются следующими:

Способ отображения сервера в виде контейнеров позволяет нам абстрагировать большую часть компонентов архитектуры, однако они подробно описаны ниже:
Перед развертыванием все необходимые параметры должны быть настроены в файлах конфигурации, хранящиеся в плате конфигурации .
Вы можете проконсультироваться с следующей официальной документацией:
Примечание. Файлы конфигурации чувствительны к пустым пространствам или пустым линиям (они были найдены в сети комаров), проверяют файлы и устраняют, чтобы избежать ошибок.
Как уже упоминалось ранее, развертывание в контейнерах простое и расположено в каталоге chirpstack-docker .
После того, как необходимое уже настроено, этого достаточно, чтобы быть помещенным в каталог и запуск Chirpstack-Docker :
docker-compose up
С помощью конфигурации по умолчанию вы можете получить доступ к серверу в локальном направлении: 8080 . Пользователь будет администратором и паролем администратора .
Давайте начнем добавлять базовую конфигурацию:
Как только сервер будет настроен, нам придется зарегистрировать наши шлюзы и создать приложения для записи наших окончательных устройств. Этот процесс проводится аналогично тем, что объясняется в предыдущем разделе этой документации: Chirpstack (Lora Server).
Кроме того, функция, которая декодирует и кодирует полученную информацию, должна быть указана, она также объясняется в предыдущем разделе.
Код, используемый для запуска шлюза, подробно описан ниже в Pycom (Fipy с питрантом). Этот код находится в Lorawan/LorapyComgateway .
Была использована библиотека PY Nanogateway , которая позволяет запустить шлюз за считанные минуты.
Nano-Gateway преобразует устройство Pycom в простой шлюз, который слушает только канал полосы частот (моноханал) , чтобы прослушать больше полос в Pycom, возможно, что это необходимо для коммерческого шлюза.
В файле конфигурации все необходимо для настройки шлюза:
WIFI_MAC = ubinascii.hexlify(machine.unique_id()) #.toUpper() para TTS
SERVER = 'loraserver.pycom.io' #(or url of your server)
GATEWAY_ID = WIFI_MAC[:6] + "ffff" + WIFI_MAC[6:12] #Minusculas: Chirpstack
NTP = "es.pool.ntp.org"
NTP_PERIOD_S = 3600
#WiFi settings (change it)
WLAN_SSID = "MyAwesomeWiFi" #"pycom-wifi"
WLAN_PASS = "CheckOutThisGoodPassword" #"securepassword"
WLAN_TIMEOUT_MS = 180000
### LoRaWAN for EU868 ###
LORA_FREQUENCY = 868500000
#Spreading Factor: (Higher value in SF=More distance but less speed transmision)
LORA_GW_DR = "SF7BW125" # DR_5,Can change in range: SF7 to SF15 (SF7B250 also exists)
LORA_NODE_DR = 5 #5 (6 uses 250Khz) for SF7, 4 for SF6.. all using 125Khz
###
def get_gateway_id():
print("Your gateway_id is: {}".format(GATEWAY_ID)) #The gateway is b'THIS_STRING'
return GATEWAY_ID
Примечание. Если вы подключите свой шлюз к локальной сети без подключения к Интернету, он вернет ошибку при синхронизации часов. Вы можете выйти из шага, комментируя следующие строки кода в функции начала (самостоятельно) файла nanogateway.py , как показывает следующий пример:
# get a time sync
self._log('Syncing time with {} ...', self.ntp_server)
#self.rtc.ntp_sync(self.ntp_server, update_period=self.ntp_period)
#while not self.rtc.synced():
# utime.sleep_ms(50)
self._log("RTC NTP sync complete")
Несколько основных функций файлов не используются, необходимо только запустить шлюз следующим образом и уже будет работать.
def init_loraWAN_gateway():
print("Initializing LoRaWAN nano Gateway")
nanogw = NanoGateway(
id=config.GATEWAY_ID,
frequency=config.LORA_FREQUENCY,
datarate=config.LORA_GW_DR,
ssid=config.WLAN_SSID,
password=config.WLAN_PASS,
server=config.SERVER,
port=config.PORT,
ntp_server=config.NTP,
ntp_period=config.NTP_PERIOD_S
)
print("Ok! Now you have a LoRaWAN Gateway! Lets start it, wait . . .")
pycom.rgbled(0xAA0000)
nanogw.start()
nanogw._log('. . . Yeah! Nano gateway is connected and running, enjoy the log:')
pycom.rgbled(0x000000)
PYCOM будет держать красный свет, пока ему не удастся подключиться, как только слушают устройства устройств, будут пропускать зеленый светодиод.
Ниже подробно описано для управления узлом класса А с использованием Arduino.
Теория использует все каналы, доступные в полосе частот, позже будет видны способ силы (не рекомендуется).
Использовалась библиотека McCi Arduino Lorawan , которая позволяет вам абстрагировать многие аспекты общения Lora. Он был установлен Platerio Library Manager.
По сути, код, используемый для клиента Arduino, является тем, что найдено в примере библиотеки ttn-otaa.ino , за исключением некоторой модификации.
Конфигурация изготовлена в двух разных файлах:
Вся конфигурация, связанная с Лораваном, как указано выше, указана в файле lorawan.cpp . В начале документа подробно описано, что данные должны быть указаны: app_eui , dev_eui и app_key (глазу на формат, указанный ниже).
Тогда пример в ChirpStack:
static const u1_t PROGMEM APPEUI[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static const u1_t PROGMEM DEVEUI[8] = {0x7b, 0x6b, 0xff, 0x2c, 0x7b, 0x2c, 0x19, 0x5a};
static const u1_t PROGMEM APPKEY[16] = {0xbd, 0x21, 0x5a, 0x82, 0xb2, 0xf7, 0x92, 0xf3, 0xc7, 0xcb, 0xb2, 0x88, 0xc7, 0x55, 0x33, 0xe7};
Под всей конфигурацией ключа, в файле loraWan.cpp , мы можем выбрать, отправлять ли плоский текст или данные из датчика температуры и влажности. Декомирует желаемый вариант:
/******* Send data config *******/
// Use this to send a Hello world in plain text
// static uint8_t mydata[] = "Hello World!";
// Use this to send sensor data
const int neededBytes = 4; // 4 bytes: 2 for temperature and 2 for humidity, can change this value
static byte mydata[neededBytes];
static LoraEncoder encoder(mydata);
В зависимости от отправленной информации необходимо использовать декодирование или другую функцию, как указано в разделах вещей сети и чирпстака.
Как видно ранее, табличка Pycom Nano-Gateway может читать только на канале, в то время как финальное устройство Arduino может транслировать на всех каналах группы (например, в европейской группе есть 10 каналов). Хотя это не рекомендуется (правило 1%может быть нарушено) может быть вынуждено использовать только канал и частоту только из -за проблем разработки и тестирования.
Для этого необходимо изменить код библиотеки, в частности, lorabase_eu868.h (в случае использования европейской частоты) и заставляя желаемую частоту выпускать следующее (наблюдать, как все значения были жестко кодированы, чтобы нарушить частоту 868.MHZ):
enum {
EU868_F1 = 868500000, // g1 SF7-12
EU868_F2 = 868500000, // g1 SF7-12 FSK SF7/250
EU868_F3 = 868500000, // g1 SF7-12
EU868_F4 = 868500000, // g2 SF7-12
EU868_F5 = 868500000, // g2 SF7-12
EU868_F6 = 868500000, // g3 SF7-12
EU868_J4 = 868500000, // g2 SF7-12 used during join
EU868_J5 = 868500000, // g2 SF7-12 ditto
EU868_J6 = 868500000, // g2 SF7-12 ditto
};
enum {
EU868_FREQ_MIN = 868500000,
EU868_FREQ_MAX = 868500000
};
Следующая функция также должна быть вызвана в начале функции lora ( lorawan_startjob () :
// Define the single channel and data rate (SF) to use
void disableChannels(int selectedChannel, int dr)
{
// Disable all channels, except for the one defined above.
// ONLY FOR TESTING AND DEVELOPING!
for (int i = 0; i < 9; i++)
{ // For EU; for US use i<71
if (i != selectedChannel)
{
LMIC_disableChannel(i);
}
}
// Set data rate (SF) and transmit power for uplink
LMIC_setDrTxpow(dr, 14);
}
Канал и датерат, подлежащие настроению, находятся в начале файла, в строках (по умолчанию: канал 0 и желаемый дат данных о распространении коэффициента 7, значение которого составляет 5):
/******* Channel config (only change if you want to uses a single channel) *******/
const int channel = 0; // Use if you want to use only one Band's Channel.
const int dr = DR_SF7; // Use if you want to use a specific datarate (The spreading factor mark the dr's value).
Это позволило бы значительно уменьшить потерю пакетов, хотя все еще есть некоторые, которые шлюз не получает.
Просто скопируйте проект на свою плиту Arduino.
Книжный магазин работает по событиям, в данном случае наиболее важной будет аутентификация (когда вы завершите, вы увидите ключи в консоли) и доставку данных.
Событие, в котором отправляются данные, будет EV_TXCOMPLETE в функции void OneVent (ev_t EV) файла lorawan.cpp , наблюдая, что событие включает в себя «окно RX», в это время устройство слушает.
case EV_TXCOMPLETE:
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
if (LMIC.txrxFlags & TXRX_ACK)
Serial.println(F("Received ack"));
if (LMIC.dataLen)
{
Serial.print(F("Received "));
Serial.print(LMIC.dataLen);
Serial.println(F(" bytes of payload"));
}
// Schedule next transmission
os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), do_send);
break;
Функция, в том же файле, где будет подробно описано, какие данные отправляются, является do_send (комментарий или деформация строк, которые кодируют информацию, если вы хотите отправить плоский текст):
void do_send(osjob_t *j)
{
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND)
{
Serial.println(F("OP_TXRXPEND, not sending"));
}
else
{
// Leer datos de sensor y codificar (Libreria LoRa_Serialization).
am2315_readedData data = readAM2315Data();
encoder.writeTemperature(data.temp);
encoder.writeHumidity(data.hum);
// Comentar las dos lineas "encoder" para enviar texto plano
// Send packet
LMIC_setTxData2(1, mydata, sizeof(mydata), 0);
if (isLoopRunning)
{
freq = String(LMIC.freq);
Serial.println("-->Packet queued using freq = " + freq);
// Prepare upstream data transmission at the next possible time.
printSensorInfoInDisplay(data.temp, data.hum);
printLoraSentInDisplay(freq);
}
}
// Next TX is scheduled after TX_COMPLETE event.
}
ПРИМЕЧАНИЕ . Была потерпеть ошибку, которая не позволила узел принять задних пакетов, поэтому было невозможно аутентифицировать устройство перед сервером. Он был добавлен в настройку клиента () (более конкретно в функции lorawan_startjob () файла lorawan.cpp ) следующей строки кода, которая увеличивает максимальную ошибку часов на 10%:
LMIC_setClockError(MAX_CLOCK_ERROR * 10 / 100);
Как Chirpstack, так и The Things Network предлагают серию интеграций для отправки данных, которые наш сервер получает в другие службы. Например: мы можем отправить данные в базу данных влияния, использовать MQTT, подключиться к службам AWS или Azure ...
В этом разделе будет видно практическое обоснование, в котором мы можем использовать интеграцию HTTP (WebHooks в сети вещей) и MQTT для отправки данных, которые отправляют наши устройства и что наш сервер получает собственное приложение.
Чтобы получить доступ к интеграции:
В случае использования chirpstack нам интересно
На обоих серверах эта интеграция работает аналогичным образом: запускает событие каждый раз, когда устройство приложения отправляет информацию (в случае TTN мы должны отмечать окно сообщений восходящей линии связи ), и, с этой информацией, поступирование HTTP -запроса Post -Type выпускается на URL, который мы указываем.
Примечание. Хорошая практика, чтобы убедиться, что событие запускается правильно, либо для визуализации формата данных - это доступ к службе Postbin, где мы можем создать корзину (временный URL -адрес для получения запросов).
ПРИМЕЧАНИЕ2: Если приложение, на которое вы запустите петицию, размещено в Localhost , а на сервере Chirpstack также (в докеризированном виде, как показано в этой документации), вам придется указать URL следующим образом:
http://host.docker.internal:PUERTO/uri
Эта документация только охватывает использование чирпстака, а TTN не задокументирована для отправки данных (у нее другой формат в петиции).
Если данные были декодированы примерами этого репозитория (папка Decoders-Integrations ), мы получим тело в запросе, аналогичном следующему:
{
"applicationID": 0,
"applicationName": "Name",
"deviceName": "DeviceName",
"devEUI": "BYTES_EUI",
"txInfo": [Object object],
"adr": true,
"dr": 5,
"fCnt": 24,
"fPort": 1,
"data": "DATA_WITHOUT_DECODE",
"objectJSON": {
"data":"DATA_WITHOUT_DECODE==",
"decodedData":{
"humidity":37,"temperature":23
},
"message":"Informacion recibida del nodo"
},
"tags": [Object object],
"confirmedUplink": false,
"devAddr": "BYTES_DEV_ADDR"
}
ObjectJson - это объект, возвращаемый нашей функцией декодера .
Чтобы прочитать его, например, в приложении JavaScript было бы достаточно, чтобы сделать что-то похожее на следующее (подробнее в файле /Decoders-Integrations/arduino_Chirpstack_Http_Integration.js )
const { deviceName, objectJSON, devAddr} = req.body;
var sensorData = JSON.parse(objectJSON);
//devAddr esta codificado!
var temperature = sensorData.decodedData.temperature;
var humidity = sensorData.decodedData.humidity;
На самом деле, если мы не используем MQTTS (MQTT с TLS), не потребуется доступ к какой -либо интеграции из веб -приложения сервера.
В этом примере мы подписам наше приложение на тему, на которую наше окончательное устройство отправит данные.
Если наше приложение будет запущено дома, а также сервер ChirpStack также (Dockerized, как мы показали в этой документации), хост брокера станет IP на машине WSL. Чтобы узнать эти данные, мы запустим:
wsl hostname -I
Вам также придется создать некоторые конфигурации, запустив следующие команды (1883 год - это порт комара, если его используется другое изменение):
netsh interface portproxy add v4tov4 listenport=1883 listenaddress=0.0.0.0 connectport=1883 connectaddress=127.0.0.1
Мы можем использовать MQTT, поскольку он поступает в примере Docker, с анонимным параметром со значением TRU (без использования какого -либо типа пароля или списка пользователей) или мы можем настроить список пользователей (каждый со темами, которые могут читать или писать) с их соответствующими паролями (как указано в следующей документации).
Для этого мы запустим следующие команды (мы можем запустить их из WSL ), каждый из них попросит нас представить пароль для каждого пользователя (в этом примере проход использовался для всех):
# Create a password file, with users chirpstack_gw, chirpstack_ns, chirpstack_as, bob and nodeApp
sudo mosquitto_passwd -c /etc/mosquitto/passwd chirpstack_gw
sudo mosquitto_passwd /etc/mosquitto/passwd chirpstack_ns
sudo mosquitto_passwd /etc/mosquitto/passwd chirpstack_as
sudo mosquitto_passwd /etc/mosquitto/passwd bob
sudo mosquitto_passwd /etc/mosquitto/passwd nodeApp
# Optional, Secure the password file
sudo chmod 600 /etc/mosquitto/passwd
Это создаст файл passwd , который будет содержать все пользователи и пароли, теперь мы можем настроить список ACL в домоничном файле, как следующее:
user chirpstack_gw
topic write gateway/+/event/+
topic read gateway/+/command/+
user chirpstackns
topic read gateway/+/event/+
topic write gateway/+/command/+
user chirpstack_as
topic write application/+/device/+/event/+
topic read application/+/device/+/command/+
user bob
topic read application/123/device/+/event/+
topic write application/123/device/+/command/+
user nodeApp
topic read application/+/device/#
topic write application/+/device/#
Теперь мы должны изменить конфигурацию сервера, чтобы использовать эти учетные данные, изменяя файлы, помещенные в /chirpstack-docker/configuration :
[application_server.integration.mqtt]
server="tcp://mosquitto:1883"
username="chirpstack_as"
password="pass"
[integration.mqtt.auth.generic]
servers=["tcp://mosquitto:1883"]
username="chirpstack_gw"
password="pass"
[network_server.gateway.backend.mqtt]
server="tcp://mosquitto:1883"
username="chirpstack_ns"
password="pass"
listener 1883
password_file /mosquitto/config/passwd
acl_file /mosquitto/config/acls
allow_anonymous false
mosquitto:
image: eclipse-mosquitto:2
ports:
- 1883:1883
volumes:
- ./configuration/eclipse-mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf
- ./configuration/eclipse-mosquitto/passwd:/mosquitto/config/passwd
- ./configuration/eclipse-mosquitto/acls:/mosquitto/config/acls
В этом примере мы будем использовать приложение Nodejs для подключения к нашему локальному локальному серверу Chirpstack. Весь код можно найти в файле /Decoders-Integrations/arduino_Chirpstack_mqtt_Integration.js .
Во -первых, нам придется установить пакет MQTT
npm install mqtt --save
С ним мы уже можем подключиться к брокеру:
var mqtt = require('mqtt')
const host = 'WSL_IP'
const port = '1883' //or your port
const clientId = 'mqtt_NodeApp_' + Math.random().toString(16).slice(3)
const connectUrl = 'mqtt://' + host + ':' + port;
const client = mqtt.connect(connectUrl, {
clientId,
clean: true,
//username: "nodeApp", //Descomentar si usamos contraseñas y acls
//password: "pass", //Colocar el usuario y contraseña correspondiente
connectTimeout: 4000,
reconnectPeriod: 1000,
debug: true
})
И подписаться на желаемую тему (персонаж # - это многоуровневая подстановочная зона, это означает, что мы читаем любой субтоп, в то время как персонаж + представляет собой одноуровневое подстановка).
const chirpstackApplicationID = 1; //Check url, for example: http://localhost:8080/#/organizations/1/applications. /1/ is the ID
const chirpstackDeviceID = "DEV_EUI";
const chirpstackReadAppTopic = "application/" + chirpstackApplicationID + "/device/#";
const chirpstackWriteAppTopic = "application/" + chirpstackApplicationID + "/device/"+chirpstackDeviceID+"/EXAMPLE";
Мы будем использовать следующие события для этого:
//Evento al conectarse
client.on('connect', function () {
console.log("Connected")
client.subscribe(chirpstackReadAppTopic, function (err) {
if (!err) {
console.log("Subscribed to topic: "+chirpstackReadAppTopic)
//client.publish(chirpstackWriteAppTopic, 'Hello mqtt') //Podemso enviar un mensaje para debugear
}
else {
console.log("Error in connection:")
console.log(err)
}
})
})
//Evento al recibir un mensaje
client.on('message', function (topic, message) {
// El mensaje es un buffer, convertimos a String.
var stringMsg = message.toString();
console.log(topic + " - " + stringMsg)
insertSensorEntry_Mqtt(topic, stringMsg); //Funcion que lee el mensaje e inserta en base de datos
})
En ambos servidores (Chirpstack y The Things Network) la integración tiene por nombre MQTT , eso sí, antes de realizar ninguna integración debemos configurar los certificados.
A continuación se documentará como realizar la integración con MQTT en un servidor local de Chirpstack (para más info revisar el apartado ChirpStack privado en local de esta documentación).
Antes de generar los certificados, debemos tener instalado CFSSL & CFSSLJSON. Tras ello, clonaremos el siguiente repositorio propiedad del creador de Chirpstack y seguiremos los pasos de su documentación: Chirpstack-Certificates.
NOTA: Si se usa Windows, instalar los pre-requisitos en la máquina WSL pues se necesitará hacer uso del comando make .
Colocamos la carpeta certs generada con el proyecto Chirpstack-Certificates en nuestro proyecto Chirpstack-Docker . Después modificados el archivo docker-compose.yml para añadir a cada contenedor el volumen que contendrá los certificados correspondientes.
Seguimos siguiendo la documentación del proyecto Chirpstack-Certificates para realizar todas las modificaciones pertinentes en la configuración del servidor:
Como hemos visto anteriormente, el evento que se lanza al recibir un mensaje llama a una función que lee el mensaje recibido y lo descodifica.
El formato del mensaje recibido (si hemos usado los descodificadores del ejemplo) es una cadena de texto con el siguiente contenido:
{"applicationID":"1","applicationName":"APP_NAME","deviceName":"DEV_NAME","devEUI":"DEV_ADDRESS", "txInfo":{"frequency":868500000,"dr":5},"adr":true,"fCnt":2, "fPort":1,"data":"DATA","object":{"data":"DATA","decodedData":{"humidity":0,"temperature":-327},"message":"Informacion recibida del nodo"}}
Y es lo que buscamos leer en la siguiente función:
function insertSensorEntry_Mqtt(topic, msg){
console.log("INSERTAMOS DATO DE SENSOR RECIBIDO POR MQTT EN TOPICO: "+topic);
const parseMsg = JSON.parse(msg); //Recordar haber hecho un ToString al buffer antes!
var deviceName = parseMsg.deviceName;
var devAddr = parseMsg.devEUI; //No codificado
var temperature = parseMsg.object.decodedData.temperature;
var humidity = parseMsg.object.decodedData.humidity;
var success = true;
}
object es el objeto retornado por nuestra función Decoder .
Como bien se sabe, la tasa de transferencia de LoRA es muy baja, lo que provoca una gran perdida de paquetes y una enorme latencia cuando se envía información:
Algunos expertos indican que es necesario cierta distancia entre los dispositivos (30m y preferiblemente algún obstaculo entre ellos) para que la comunicación sea más fluida. No ha sido probado y solo se ha lanzado con las dos tarjetas en un extremo cada una de un piso.
Por otro lado se hace uso de versiones antiguas de LoRaWAN (1.0.2 y 1.0.3) que tienen problemas de seguridad que se solventan en parte en las siguientes versiones (1.0.4 y 1.1.0, esta última también implementa re-conectividad en caso de desconectarse de la red LoRaWAN), pero no se dispone de librerias para trabajar con ellas.
Esto no quita que esta técnología pueda ser muy interesante y útil en el futuro debido a no depender de proveedores externos (de comunicaciones y electricidad), siendo una opción ecónomica y muy llamativa para utilizar en proyectos IoT de grandes ciudades o entornos rurales.
Este proyecto ha sido realizado para la Fundación CTIC, su uso es libre y no es necesarío ningún crédito en su uso (Revisar las licencia de las librerias utilizadas).