In diesem Projekt wird ein kleiner Test der LORA -Übertragungstechnologie durchgeführt, um Informationen zu sammeln, die von der CTIC Foundation verwendet werden können. Informationen werden von einem endgültigen Gerät (Knoten oder Kunde) gesendet. Diese Informationen werden von einem Gateway -Gerät gesammelt, was wiederum an einen Server weiterleitet, um es zu speichern.
Lora ist eine drahtlose Technologie (wie WLAN, Bluetooth, LTE, Sigfox oder Zigbee), die eine Art von Semtech verwendet.
Derzeit wird die Technologie von der Alliance Lora verwaltet, die alle Hardware -Hersteller zertifiziert, die mit dieser Technologie arbeiten möchten.
LORA hat eine hohe Interferenz , eine hohe Empfindlichkeit, Daten zu erhalten (-168 dB), einen sehr geringen Verbrauch (das Gerät kann ein Jahrzehnt mit einer einzigen Batterie dauern) und einen Bereich von 10 bis 20 km (je nachdem, ob direktes Sehen oder Topologie des Landes verfügbar ist). Andererseits finden wir eine sehr niedrige Datenübertragung (bis zu 255 Bytes).
All dies macht diese Transfertechnologie für große Entfernungen oder IoT -Netzwerke nützlich, die keinen Zugang zu elektrischem Strom benötigen oder keinen Zugang haben.
Lora arbeitet bei kostenlosen Frequenzen (diese sind in Europa 868 MHz , 916 MHz in Amerika oder 433 MHz in Asien).
Wir können mit den Geräten über Loremac (auch durch Lora bekannt) oder durch Lorawan kommunizieren.
LORAMAC : Wird verwendet, um zwei Geräte miteinander zu kommunizieren.
Lorawan : Wird verwendet, um ein Netzwerk von Geräten zu kommunizieren. In diesem Ansatz erscheint die Abbildung des Gateways (Gerät, das die Informationen eines oder mehrerer Geräte sammelt und an den Server weiterleitet). In Lorawan müssen die Informationen gefiltert werden, um zu wissen, welche Geräte Sie auf das Gateway hören sollten und welche zu ignorieren sind, aber dies wird später gesehen. Dieser Ansatz verwendet eine Star -Topologie.
Andererseits gibt es in Lorawan auch drei Arten von endgültigen Geräten oder Knoten :
*In den Beispielen unterstützt nur Knoten der Klasse A und B (unterstützt von der verwendeten Bibliothek), aber nur der Typ A. wird nur implementiert
Wenn das freie Frequenzband in Europa (868 MHz) verwendet wird, müssen einige Einschränkungen berücksichtigt werden:
In jedem Frequenzband gibt es mehrere Kanäle oder Unterbänder, im Fall des Europäischen (868 MHz) finden wir 10 Kanäle, die von 0 bis 9 nummeriert sind. Zum Beispiel im Amerikaner (915 MHz) können wir bis zu 64 finden.
Das Senden von Informationen über den einen oder anderen Kanal ist eine Aufgabe, die Bibliotheken normalerweise ermöglichen.
In einigen End-Evices ist es möglich, den Datenausgang oder den Gerätebrachter zu ändern.
Der Datenheim und der SpreadingFactor sind verwandt: Ein Datenausgang von 0 gibt einen SF12 an und ein Datenausgang von 5 zeigt einen SF7 an. Alle mit einer Frequenz von 125 kHz mit der folgenden Ausnahme: Ein Datenaterat von 6 zeigt einen SF7 mit 250 kHz an.
Zwei Geräte (einer für den Knoten und eine für das Gateway, die auch WLAN -Konnektivität haben müssen) und ein zugehöriges Konto in TTS ( das Things -Netzwerk ) oder ChirpStack (in der Lage sein, einen eigenen Server zu Hause zu verwenden). In diesem Beispiel werden sowohl Loremac- als auch Lorawan -Beispiele, die einen Arduino -Knoten und ein Pycom -Gateway verwenden.
Zu Beginn reicht es aus, das Repository zu klonen:
git clone https://github.com/Javieral95/Getting_Started_With_LoRa.git
Und laden Sie dann die entsprechenden Projekte auf die Geräte hoch
Warum zwei IDes? Einfache Pymakr -Erweiterung funktioniert kaum im Visual Studio Code. Nutzen Sie den Arbeitsbereich, der am bequemsten ist.
Beide Geräte haben eine antera Lora mit ihnen verbunden.
HINWEIS : Der Code für einen Arduinomkr1300 (mehr für die Verwendung wie Lora End-Device) und Codes, um einen Pysense oder Pytrack als End-Evex zu verwenden, ist auch in den Repos enthalten.

Das Loramac -Beispiel (befindet sich im Homonym -Ordner) ist funktionell, ein Arduino -Endgerät und ein Pycom -Gateway zu verwenden.
Der Knoten sendet nur Hardcode -Informationen und das Gateway stellt nur eine Verbindung zu Lora und WiFi her, empfängt die Pycom -Informationen und druckt die gelesenen Daten (obwohl er die Funktion des Sendens der Daten an das Netzwerk implementiert hat).
Die Verwendung eines Netzwerkservers wird mit ausgegeben.
Um mehr zu erfahren, können Sie auf den Ordner /Loramac zugreifen.
Für die Verwendung dieser Beispiele (die funktionale Verwendung eines Arduino -Endgeräts und eines Pycom -Gateways) ist ein Server erforderlich, um die Daten zu visualisieren. In diesem Beispiel wurde die Verwendung von The Things Network und ChirpStack (zuvor als Loraserver bekannt) behandelt.
Um mehr zu erfahren, können Sie auf den Ordner /Lorawan zugreifen und diese Dokumentation weiterhin konsultieren.
In Lorawan gibt es zwei Arten der Authentifizierung:
*In den Beispielen im Moment wird nur OTAA gemacht.
Wie bereits erwähnt, benötigen wir einen Server. In diesem Beispiel wurde eine kostenlose Version des Things Network, ein ChirpStack -Server von Pycom und eine andere zu Hause bereitgestellte Server verwendet.
Es ist die zuverlässigste, sichere und besser dokumentierte Alternative. Alles zeigt jedoch an, dass es aufhören wird, offen zu sein (es gibt eine Grenze von 50 Knoten pro Anwendung).
Das Erstellen einer Anwendung ist einfach, greifen Sie auf das Menü zu und klicken Sie auf die Schaltfläche +. Sobald wir den Namen der Anwendung, eine eindeutige ID und eine Beschreibung angegeben haben.
Wenn die Anwendung erstellt wird, können wir endgültige Geräte (Knoten) hinzufügen, die auf die Schaltfläche +klicken.
Gateways sind Geräte, die für das Versenden von Verkehrsmitteln verantwortlich sind, die aus mehreren endgültigen Geräten (zu mehreren Anwendungen) und an den Server weiterleiten. Das Erstellen eines Gateways ist ebenfalls einfach. Klicken Sie auf die Schaltfläche + und füllen Sie das Formular aus, das auf die folgenden Konzepte achtet:
Um die Daten lesen zu können, die der Knoten an den Server gesendet hat, müssen wir die Nutzlast im Fall von TTN für jedes Gerät auf der Registerkarte Nutzlastformatter erledigen. Wir wählen, wie Formatierer die JavaScript -Option eingeben und:
function Decoder(bytes, port) {
// Decode plain text; for testing only
return {
myTestValue: String.fromCharCode.apply(null, bytes)
};
}
arduino_ttn_decoder.js Es ist festgestellt, dass alle hexadezimalen Adressen des Networks -Netzwerks im Bürgermeister sind. Es ist nicht wichtig, dass die Geräte die Geräte programmieren, aber in früheren Versionen wurden Fehler erlitten.
Dies ist die Open -Source -Alternative, sie ist noch in der Entwicklung und ihre Dokumentation ist nicht so gut. Es funktioniert jedoch und ermöglicht es, dass der Server gestartet wird.
Pycom bietet einen ChirpStack -Server an, um Ihr Gateway -Gerät zu verbinden.
Die Anwendung ähnelt dem im Abschnitt des Things Network ausführlichen.
Sie müssen zu den Geräteprofilen des Serverabschnitts wechseln, sobald IT-Zugriff auf das Interesse (in diesem Fall OTAA) zugreifen und die Versionen ändern:
Greifen Sie zum Erstellen eines Gateways auf denselben Namen zu und klicken Sie auf die Schaltfläche +. Füllen Sie das Formular aus, das besondere Aufmerksamkeit auf das Feld Gateway ID (64 Bit in Hexadezimal, das das Gateway identifiziert), ChirpStack für Sie erzeugen, aber der Mac des Geräts wird normalerweise verwendet (wenn Sie es nicht im Abschnitt kennen, der das Gateway -Pycom erklärt, wird es detailliert als das Erhalten des Gateway -Pycoms erläutert.
Sie können den Rest der Standardwerte hinterlassen.
Um die Daten zu lesen, die der Knoten an den Server gesendet hat, muss die Nutzlast entschlüsselt werden. Im Fall von ChirpStack werden wir dies für jedes Gerätsprofil im Gerätetupfer auf das Profil zugreifen, das uns interessiert (in diesem Fall OTAA), und wir zugreifen auf die Codec -Registerkarte Codec:
Wir wählen in den benutzerdefinierten Decipt -Codec -Funktionen und:
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 Es ist festgestellt, dass alle hexadezimalen Adressen von Chirpstack in minuskulären sind. Es ist nicht wichtig, dass die Geräte programmieren, aber in früheren Versionen wurden Fehler erlitten.
ChirpStack bietet eine OpenSource -Alternative, um unseren eigenen privaten Server in Lorawan zu starten, und ermöglicht es uns, diese auf einfache Weise und durch Container zu tun.
Aus diesem Grund ist ein anderes Repository, das dem Gründer von Chirpstack (Brocar) gehört, das diese Operation ermöglicht: Chirpstack-Docker wurde im vorliegenden Repository kloniert. Wir finden es im Ordner chirpstack-docker .
ChirpStack verfügt über verschiedene Komponenten in seiner Architektur, um den Service in der Lage zu machen, zu operieren. Sie sind die folgenden:

Die Möglichkeit, den Server in Form von Containern anzuzeigen, ermöglicht es uns, einen Großteil der Architekturkomponenten abstrahieren. Sie sind jedoch nachstehend beschrieben:
Vor der Bereitstellung müssen alle erforderlichen Parameter in den in der Konfigurationsplatine gespeicherten Konfigurationsdateien konfiguriert werden.
Sie können die folgende offizielle Dokumentation konsultieren:
Hinweis: Die Konfigurationsdateien sind empfindlich gegenüber leeren Leerzeichen oder leeren Zeilen (sie wurden im Moskitonetz gefunden), überprüfen Sie die Dateien und beseitigen, um Fehler zu vermeiden.
Wie bereits erwähnt, ist der Einsatz in Containern einfach und befindet sich im Verzeichnis chirpstack-docker .
Sobald die erforderlichen bereits konfiguriert sind, reicht es aus, um in das Verzeichnis chirpstack-docker platziert zu werden und starten:
docker-compose up
Mit der Standardkonfiguration können Sie in lokaler Richtung auf den Server zugreifen: 8080 . Der Benutzer ist Administrator und das Administratorkennwort .
Fügen wir die grundlegende Konfiguration hinzu:
Sobald der Server konfiguriert wurde, müssen wir unsere Gateways registrieren und Anwendungen erstellen, um unsere endgültigen Geräte aufzuzeichnen. Dieser Vorgang wird analog zu dem im vorherigen Abschnitt dieser Dokumentation erläuterten: ChirpStack (LORA Server) durchgeführt.
Darüber hinaus muss die Funktion, die die empfangenen Informationen decodiert und codiert, angezeigt werden, sie wird auch im vorherigen Abschnitt erläutert.
Der Code, der zum Starten des Gateways verwendet wird, ist unten in einem Pycom (FIPY mit PyTrack) aufgeführt. Dieser Code befindet sich in Lorawan/Lorapycomgateway .
Die Nanogateway -PY -Bibliothek wurde verwendet, mit der Gateway in Minuten gestartet werden kann.
Nano-Gateway wandelt ein Pycom-Gerät in ein einfaches Gateway um, das nur auf einen Frequenzband (monochanaler) Kanal hört , um mehr Bands in Pycom zu hören. Es ist möglich, dass es für ein kommerzielles Gateway erforderlich ist.
In der Konfigurationsdatei alles, was zum Anpassen des Gateways erforderlich ist:
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
Hinweis: Wenn Sie Ihr Gateway ohne Internetverbindung an ein lokales Netzwerk verbinden, wird bei der Synchronisierung der Uhren ein Fehler zurückgegeben. Sie können aus dem Schritt aussteigen, der die folgenden Codezeilen in der Start- (Selbst-) Funktion der nanogateway.py -Datei unter Beweis stellt, wie das folgende Beispiel zeigt:
# 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")
Es werden keine Hauptdateifunktionen verwendet. Es ist nur erforderlich, das Gateway wie folgt zu starten, und wirkt bereits.
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)
Das Pycom hält das rote Licht, bis es sich anschließen kann, und hört nach Geräten der Geräte zu, die seine grüne LED blinkt.
Das Folgende ist detailliert, um den Klassenknoten A mit Arduino zu bedienen.
Die Theorie verwendet alle im Frequenzband verfügbaren Kanäle. Später wird nur eine (nicht empfohlen) eine Art Kraft gesehen.
Die McCi Arduino Lorawan Library wurde verwendet, mit der Sie viele Aspekte der Lora -Kommunikation abstrahieren können. Es wurde vom Platformio Library Manager installiert.
Grundsätzlich ist der Code, der für den Arduino -Client verwendet wird, derjenige, der im Beispiel der Bibliothek ttn-otaa.ino zu finden ist, mit Ausnahme einer Änderung.
Die Konfiguration erfolgt in zwei verschiedenen Dateien:
Die gesamte Konfiguration im Zusammenhang mit Lorawan, wie oben angegeben, ist in der Datei lorawan.cpp angegeben. Zu Beginn des Dokuments ist detailliert, dass Daten angezeigt werden sollten: app_eui , dev_eui und app_key (Auge zum unten angegebenen Format).
Dann das Beispiel in 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};
Unter der gesamten Schlüsselkonfiguration können wir in der Datei loraWan.cpp auswählen, ob flache Text oder Daten aus dem Temperatur- und Feuchtigkeitssensor gesendet werden sollen. Dekomiert die gewünschte Option:
/******* 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);
Abhängig von den gesendeten Informationen muss eine Dekodierung oder eine andere Funktion verwendet werden, wie in den Abschnitten des Dings Network und ChirpStack angegeben.
Wie bereits gesehen, kann die Nano-Gateway -Pycom-Platte nur auf einem Kanal lesen, während das Arduino-Finale-Gerät auf allen Bandkanälen ausstrahlen kann (z. B. in der europäischen Band gibt es 10 Kanäle). Obwohl es nicht empfohlen wird (die 1%-Regel kann verletzt werden) kann gezwungen werden, nur einen Kanal zu verwenden, und eine Häufigkeit nur aufgrund von Entwicklungs- und Testproblemen.
Zu diesem Zweck ist es erforderlich, den Bibliothekscode zu ändern, insbesondere die lorabase_eu868.h (im Fall der Verwendung der europäischen Frequenz) und die gewünschte Frequenz zur Ausgabe als Follows (Beobachten Sie, wie alle Werte hartcodiert wurden, um die Frequenz 868.MHz anzuzeigen):
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
};
Die folgende Funktion sollte auch zu Beginn der Funktion von Lora ( Lorawan_startjob () aufgerufen werden:
// 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);
}
Der Kanal und das zu konfigurierte Daterat befinden sich am Anfang der Datei in den Zeilen (standardmäßig: Kanal 0 und die gewünschte Datenstelle des Spreading -Faktors 7, dessen Wert 5 ist):
/******* 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).
Dies würde den Verlust von Paketen erheblich reduzieren lassen, obwohl es immer noch einige gibt, die das Gateway nicht erhält.
Kopieren Sie das Projekt einfach auf Ihre Arduino -Platte.
Die Buchhandlung arbeitet nach Ereignissen. In diesem Fall ist die Authentifizierung (wenn Sie abgeschlossen sind, die Schlüssel in der Konsole) und die Datenversuche.
Das Ereignis, in dem Daten gesendet werden, wird in der void ONET -Funktion (ev_t ev) der Lorawan.cpp -Datei (ev_t ev) erfolgt . Beachten Sie, dass das Ereignis das "RX -Fenster" enthält. Zu diesem Zeitpunkt hört das Gerät an.
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;
Die Funktion in derselben Datei, in der detailliert werden, welche Daten gesendet werden, ist do_send (Kommentar oder Dekoment der Zeilen, die die Informationen codieren, wenn Sie flache Text senden möchten):
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.
}
Hinweis : Es wurde ein Fehler erlitten, der den Knoten daran hinderte, Rückpakete zu empfangen. Daher war es unmöglich, das Gerät vor dem Server zu authentifizieren. Es wurde in der Customer -Setup () (insbesondere in der Funktion lorawan_startjob () der Lorawan.cpp -Datei) hinzugefügt, die den maximalen Taktfehler um 10%erhöht:
LMIC_setClockError(MAX_CLOCK_ERROR * 10 / 100);
Sowohl ChirpStack als auch The Things Network bieten eine Reihe von Integrationen an, um die Daten zu senden, die unser Server an andere Dienste empfängt. Zum Beispiel: Wir können die Daten an eine Einflussdatenbank senden, MQTT verwenden, eine Verbindung zu AWS -Diensten oder Azure herstellen ...
In diesem Abschnitt wird ein praktischer Fall zu sehen, in dem wir die Integration von HTTP (Webhooks in the Things Network) und MQTT verwenden können, um die Daten zu senden, die unsere Geräte senden und dass unser Server eine eigene Anwendung erhält.
Zu Zugang zu Integrationen:
Im Falle der Verwendung von Chirpstack sind wir interessiert
In beiden Servern funktioniert diese Integration auf ähnliche Weise: Startet jedes Mal ein Ereignis, wenn ein Anwendungsgerät Informationen sendet (im Fall von TTN müssen wir das Uplink -Nachrichtenfeld markieren), und mit diesen Informationen wird eine Postp -HTTP -Anforderung an die von uns angegebene URL gestartet.
Hinweis: Eine gute Praxis, entweder um zu überprüfen, ob das Ereignis korrekt gestartet wird, oder um das Datenformat zu visualisieren, besteht darin, auf den Post -Bin -Dienst zuzugreifen, in dem wir einen Bin erstellen können (temporäre URL, um Anforderungen zu erhalten).
Hinweis 2: Wenn die Anwendung, auf die Sie starten, die Petition in Localhost und auf dem ChirpStack -Server (auf dokierte Weise wie in dieser Dokumentation gezeigt) untergebracht ist, müssen Sie die URL wie folgt angeben:
http://host.docker.internal:PUERTO/uri
Diese Dokumentation deckt nur die Verwendung von ChirpStack ab und TTN wird nicht so dokumentiert, dass Daten gesendet werden (sie hat ein anderes Format in der Petition).
Wenn die Daten mit den Beispielen dieses Repositorys (Ordner Decoders-Integrations ) dekodiert wurden, erhalten wir eine Körperschaft in der Anfrage, die wie folgt ähnelt:
{
"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 ist das von unserer Decoder -Funktion zurückgegebene Objekt.
Zum Lesen zu lesen, beispielsweise in einer JavaScript-Anwendung, reicht es aus, etwas Ähnliches wie folgt zu tun (mehr in der Datei /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;
Wenn wir nicht MQTTS (MQTT mit TLS) verwenden, ist es nicht erforderlich, über die Server -Webanwendung auf eine Integration zugreifen zu können.
In diesem Beispiel werden wir unsere Anwendung an das Thema unterschreiben, an das unser endgültiges Gerät die Daten sendet.
Wenn unsere Anwendung zu Hause und den ChirpStack -Server ebenfalls gestartet wird (wie in dieser Dokumentation angedockt), ist der Broker -Host die IP des WSL -Computers. Um diese Daten zu kennen, werden wir starten:
wsl hostname -I
Sie müssen auch einige Konfigurationen vornehmen, indem Sie die folgenden Befehle starten (1883 ist der Port von Mosquitto, falls ein anderer Modify verwendet wird):
netsh interface portproxy add v4tov4 listenport=1883 listenaddress=0.0.0.0 connectport=1883 connectaddress=127.0.0.1
Wir können MQTT verwenden, da es im Beispiel von Docker mit dem anonymen Parameter mit TRU -Wert (ohne eine Art Kennwort oder eine Liste von Benutzern verwendet wird) oder eine Liste von Benutzern (jeweils mit den Themen, die lesen oder schreiben können) mit ihren jeweiligen Passwörtern (wie in der folgenden Dokumentation angegeben) konfigurieren.
Dazu starten wir die folgenden Befehle (wir können sie von WSL aus starten). Jeder von ihnen wird uns auffordern, für jeden Benutzer ein Kennwort vorzustellen (in diesem Beispiel wurde Pass für alle verwendet):
# 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
Dadurch wird die passwd -Datei erstellt, die alle Benutzer und Kennwörter enthält. Wir können jetzt eine ACLS -Liste in einer homonymen Datei konfigurieren, wie dies Folgendes:
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/#
Jetzt müssen wir die Serverkonfiguration ändern, um diese Anmeldeinformationen zu verwenden, indem wir die in /chirpstack-docker/configuration eingereichten Dateien ändern:
[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
In diesem Beispiel werden wir eine NodeJS -Anwendung verwenden, um eine Verbindung zu unserem lokalen ChirpStack -Server herzustellen. Der gesamte Code finden Sie in der Datei /Decoders-Integrations/arduino_Chirpstack_mqtt_Integration.js .
Zuerst müssen wir das MQTT -Paket installieren
npm install mqtt --save
Mit ihm können wir uns bereits mit dem Broker verbinden:
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
})
Und abonnieren Sie das gewünschte Thema (der # Charakter ist eine mehrstufige Wildcard. Dies bedeutet, dass wir jeden Subtoper lesen, während der Charakter + eine einstufige Wildcard ist).
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";
Wir werden die folgenden Ereignisse dafür verwenden:
//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).