TTN Stack V3 – RPi Gateway Migration

Wie viele andere, benutze ich auch ein Gateway auf Basis des ic880A Konzentrators und einem Raspberry Pi. Als Software verwende ich einen Fork von JP Meijers Balena Gateway Container, welcher auf den Multi-protocol Packet Forwarder von Jac Kersing setzt. Die se Variante ist sehr beliebt und weit verbreitet. Somit geht es hier heute um die Gateway Migration dieser Variante. Da nun der Wechsel des Stacks von V2 auf V3 ansteht, habe ich versucht mein Gateway auch an den V3 Stack anzubinden.

Diese Anleitung zielt also auf Nutzer des Multi-protocol Packet Forwarder ab und somit auch Nutzer des JP Meijers Balena Gateway Container, bzw. dessen Ableitungen davon.

Dieses ist nur ein vorab Test, mit einem Gateway das ich dafür übrig hatte. Ihr solltet aktuell dieses Schritt abwarten. Aktuell werden die Daten von V2 Gateways auch in den V3 Stack übermittelt. Somit gehen keine Daten verloren. Daten von V3 Gateways gehen aber nicht in den V2 Stack. Solltet ihr also euer Gateway zu früh umstellen, hängt ihr alle anderen ab, die noch auf dem V2 Stack arbeiten. Ihr solltet diesen Schritt also in euere Community diskutieren und euch absprechen. Aktuell besteht kein Grund zur Eile.

Der TTN Mapper ist momentan auch noch nicht V3 ready und laut JP ist dieses wohl auch ein größeres Stück an Arbeit. Um es einfacher zu machen, solltet ihr die Gateway ID aus der V2 Konsole in die V3 Konsole übernehmen (also z.B. eui-xxx). Dadurch fällt es JP wohl einfach die Daten passend zu verlinken.

Allgemein gibt es zu dem Thema noch folgenden Eintrag im Forum.

Ein wichtiger Hinweis: TTIGs können aktuell nicht im V3 genutzt werden. Löscht also nicht euer Gateway im V2 Stack, denn ihr könnt es danach nicht wieder einrichten.

Anlegen eiens neuen Gateways

Ihr geht nun auch die Konsole des V3 Stacks und erzeugt ein neune Gateway. Hier vergebt ihr eine Gateway-ID und setzt den entsprechenden Frequenz Plan. Das Thema Gateway-Status überlasse ich euch, Public sollte aber, in hinsicht auf z.B. den TTN Mapper, bessern sein.

v3-stack-add-gateway
v3-stack-add-gateway
v3-stack-add-gateway

Anschließend setzt ihr noch die Position unter Location und erzeugt einen API-Key. Diesen müsst ihr euch kopieren, da wir diesen anschließend auf unserem Gateway eintragen müssen. Wählt individual rights und macht einen Haken bei Link as Gateway to a Gateway Server . Ihr könnt den Key später nicht mehr auslesen, aber jeder Zeit einen neuen erzeugen.

Setzen der Device Variablen – Die eigentliche Gateway Migration

Im Balena Dashboard setzt ihr nun folgende Device Variablen. Ihr habt dabei die Wahl zwischen SERVER_1 bis SERVER_3. Wichtig ist der Punkt SERVER_TTN. Dieder sollte auf false gesetzt werden, da ihr ansonsten euch auch noch mit dem V2 Stack verbindet und so im Dual Stack Betrieb unterwegs seid. Also setzt bitte diesen Punkt, da es ansonsten zu einer erhöhten Netzlast kommt und wer weiß was ansonsten noch schief gehen kann.

Nachdem ihr die Variablen gesetzt habt, wird euer Gateway neu starten und sollte sich danach mit dem V3 Stack verbinden. Damit solltet ihr eine erfolgreiche Gateway Migration durchgeführt haben.

Gateway-Migration

Hier nochmals alle notwendigen Einstellungen als Tabelle:

SERVER_2_ADDRESS eu1.cloud.thethings.network:1881
SERVER_2_DOWNLINKtrue
SERVER_2_ENABLEDtrue
SERVER_2_GWID<Gateway ID laut Konsole>
SERVER_2_GWKEY<your API key>
SERVER_2_TYPEttn
SERVER_TTNfalse

Überprüfen des Status auf der Konsole

Auf der Konsole solltet ihr nun sehen, das euer Gateway connected ist.

v3-gw-console

In der Detailansicht seht ihr auch wieder den Last seen Status, sowie den RX und TX Counter.

v3-gw-console

In der Liveansicht seht ihr die übermittelten LoRa Pakete , aber auch die Gateway Status Meldungen. Diese enthalten interessante Angaben wie Load und Temperatur.

v3-gw-live-view

Mit dieser kleinen Hilfe solltet ihr eure Gateway Migration erfolgreich erledigt haben und euer Gateway an den V3 Stack angebunden sein. Eventuell wird sich hier in der nächsten Zeit noch etwas ändern, da wir erst am Anfang stehen. Eine eventuelle Nutzung des Basic Station Protokolls muss auch noch geklärt werden, supported ist jedenfalls ein RPi mit iC880A.

13 Gedanken zu „TTN Stack V3 – RPi Gateway Migration“

  1. Hallo,

    kann es sein das man hier
    SERVER_2_ADDRESS eu1.cloud.thethings.network:1881

    folgendes einegeben muss: SERVER_2_ADDRESS eu1.cloud.thethings.network

    Gruß

    E_T

    Antworten
  2. servus Björn,
    habe versucht die Migration durchzuführen aber leider kommt dieser Fehler im Log:

    main 09:56:08 INFO: packets received with a CRC error will NOT be forwarded
    main 09:56:08 INFO: packets received with no CRC will NOT be forwarded
    main 09:56:08 INFO: GPS is disabled
    main 09:56:08 INFO: Upstream data is enabled
    main 09:56:08 INFO: Downstream data is enabled
    main 09:56:08 INFO: Ghoststream data is disabled
    main 09:56:08 INFO: Radiostream data is enabled
    main 09:56:08 INFO: Statusstream data is enabled
    main 09:56:08 INFO: Beacon is disabled
    main 09:56:08 INFO: Packet logger is disabled
    main 09:56:08 INFO: Flush output after statistics is disabled
    main 09:56:08 INFO: Flush after each line of output is disabled
    main 09:56:08 INFO: Watchdog is disabled
    main 09:56:08 INFO: Contact email configured to „“
    main 09:56:08 INFO: Description configured to „“
    main 09:56:08 INFO: [Transports] Initializing protocol for 1 servers
    main 09:56:09 ERROR: [TTN] Connection to server „eu1.cloud.thethings.network“ failed, retry in 30 seconds
    main 09:56:45 ERROR: [TTN] Connection to server „eu1.cloud.thethings.network“ failed, retry in 60 seconds
    main 09:57:47 ERROR: [TTN] Connection to server „eu1.cloud.thethings.network“ failed, retry in 120 seconds
    main 09:59:49 ERROR: [TTN] Connection to server „eu1.cloud.thethings.network“ failed, retry in 240 seconds
    main 10:03:52 ERROR: [TTN] Connection to server „eu1.cloud.thethings.network“ failed, retry in 480 seconds
    main 10:11:54 ERROR: [TTN] Connection to server „eu1.cloud.thethings.network“ failed, retry in 480 seconds

    ————-

    Hast du einen Tipp was ich falsch gemacht haben könnte ?

    Noch eine Frage die ich in deiner Anleitung nicht rausgefunden habe: du schreibst man soll Device Variablen anlegen aber als was ? Auswahlmöglichkeiten sind: all service ( hab ich gemacht ) und main ?!

    Und bei mir ist dann noch ein alter Eintrag mehr drin als in deiner Übersicht: GW_RESET_PIN 22

    Grüße Marc 😉

    Antworten
    • Hallo Marc,

      all service oder main ist egal, da interessiert nur wenn du noch weitere Container aktiv hast.
      Du Felder sind als zusätzliche Einträge zu sehen, der GW_RESET_PIN muss drin bleiben, da ansonsten dein Gateway nicht läuft.
      Die Adresse hast du aber mit dem Port angegeben? Also eu1.cloud.thethings.network:1881

      Grüße,
      Björn

      Antworten
      • Vielen Dank für die schnelle Antwort das ist wirklich nicht selbstverständlich. 😉

        Das ist die Adresse: eu1.cloud.thethings.network:1881

        In balena steht: Status Online
        Aber in der Console kommt:

        main 11:51:30 ERROR: [TTN] Connection to server „eu1.cloud.thethings.network“ failed, retry in 480 seconds
        main 11:59:32 ERROR: [TTN] Connection to server „eu1.cloud.thethings.network“ failed, retry in 480 seconds
        main 12:07:35 ERROR: [TTN] Connection to server „eu1.cloud.thethings.network“ failed, retry in 480 seconds
        main 12:15:37 ERROR: [TTN] Connection to server „eu1.cloud.thethings.network“ failed, retry in 480 seconds

        Was könnte noch falsch sein? oder wie bekomme ich das wieder ans laufen ? im V2 ging ja alles super 🙁 Soll ich evtl mal einen neuen Gateway erstellen im V3 ? Wenn ja was muss ich beachten wenn ich einen neuen GW erstelle und nicht die migration von V2 auf V3 machen will?

        Viele Grüße Marc

        Antworten
        • Hi Marc,

          also die Einstellungen musst du für SERVER_1 oder SERVER_2 oder SERVER_3 machen, nicht für SERVER, da dieser speziell für V2 gedacht ist. Du kannst auch beides parallel laufen lassen, also V2 und V3, macht aber keinen Sinn.
          Du musst natürlich in der V3 Console ein Gateway anlegen, damit du auch einen neuen API Key erstellen kannst. Du kannst natürlich auch eine andere Gateway-ID erzeugen.
          Mit den alten Einstellungen sollte dein Gateway wieder auf V2 laufen.

          Grüße,
          Björn

          Antworten
          • nochmal vielen Dank 😉

            Ich habe es jetzt so gemacht:

            1.) Einen neuen GW in V3 erzeugt.
            2.) API: Grant all current and future rights
            3.) Alles für SERVER_1 laut deiner Tabelle konfiguriert.

            Jetzt steht in der Console von Balena:
            ### [DOWNSTREAM] ###
            main # PULL_DATA sent: 0 (0.00% acknowledged)
            main # PULL_RESP(onse) datagrams received: 0 (0 bytes)
            main # RF packets sent to concentrator: 0 (0 bytes)
            main # TX errors: 0
            main ### BEACON IS DISABLED!
            main ### [JIT] ###
            main # INFO: JIT queue contains 0 packets.
            main # INFO: JIT queue contains 0 beacons.
            main ### GPS IS DISABLED!
            main ### [PERFORMANCE] ###
            main # Upstream radio packet quality: 0.00%.
            main ### [ CONNECTIONS ] ###
            main # eu1.cloud.thethings.network: Connected
            main # Semtech status report sent.
            main ##### END #####
            main 10:33:14 INFO: [TTN] eu1.cloud.thethings.network RTT 39
            main 10:33:14 INFO: [TTN] send status success for eu1.cloud.thethings.network
            main 10:33:21 INFO: Disabling GPS mode for concentrator’s counter…
            main 10:33:21 INFO: host/sx1301 time offset=(1634032612s:93541µs) – drift=7µs
            main 10:33:21 INFO: Enabling GPS mode for concentrator’s counter.

            ——

            In der Gateway Übersicht steht: Status: other cluster
            Weis aber nicht was mir das jetzt sagen soll?!

            Weil im The things Stack steht unter overview: last seen now

            Also denke ich er ist online oder?

            Irgendwie finde ich das V3 absolut nicht schön geschweigedenn übersichtlich 🙁

            Grüße Marc

          • Hi,

            ja, sollte nun passen. Ich denke mal die Meldung „other cluster“, wird auch noch verschwinden.

            An V3 muss man sich erst mal gewöhnen, aber dann geht es.

            Grüße,
            Björn

  3. Ok danke dir 😉 darf ich dich noch eine letzte Sache fragen zu V3? Ich habe meine Node die im V2 super lief versucht im V3 zu connecten leider kommt im serial log des arduinos:
    14:02:11.199 -> Starting
    14:02:12.602 -> Humidity: 6060
    14:02:12.640 -> Temperature: 1990
    14:02:12.640 -> BattValue
    14:02:12.682 -> 316
    14:02:12.682 -> battVoltage
    14:02:12.682 -> -42
    14:02:12.736 -> Packet queued
    14:02:12.736 -> 4178: EV_JOINING
    14:02:12.736 -> 5875: EV_TXSTART
    14:02:18.978 -> 399560: Unknown event: 20
    14:02:19.537 -> 433921: EV_TXSTART

    Ich habe die APPEUI im leb format wie in der V2 eingegeben genauso wie die DEVEUI nur der APPKEY in msb format. Und diese sind alle neu aus der V3 erzeugt worden also neue Applikation neue Node. das einzige ich bin mir nicht sicher was ich für eine Lora Wan version auswählen muss ich n nutze die Lmic 4.1.0 Version in der Arduino IDE mit einem Arduino pro mini 3,3v und einem sx1276 Modul.

    Und mir ist aufgefallen eine Sache verstehe ich absolut nicht: in der V3 Console steht unter Applikation:
    0 – API keys

    Für was brauche ich einen Api key der Applikation?

    Grüße Marc

    Antworten
    • Also der JOIN kommt nicht zustande?
      Das Unknown Event ist erst mal egal, ist jedenfalls kein Fehler.
      Die LMIC 4.1 wäre LoRa 1.0.3, glaube ich.

      API Keys brauchst du für Node-RED z.B. damit du per MQTT die Daten abgreifen kannst.

      Grüße,
      Björn

      Antworten
  4. ja der kommt nicht zustande 🙁 ok ich habe die 1.0.3 durch Zufall ausgewählt gehabt 😀

    Ok dann brauche ich die api keys doch für meinen Homeassistant server, danke dir 😉

    Hier mein sketch der früher im v2 lief habe nur die Schlüssel vom v3 übernommen sonst nichts geändert.

    Antworten
  5. #include
    #include
    #include
    #include
    #include
    #include

    //
    // For normal use, we require that you edit the sketch to replace FILLMEIN
    // with values assigned by the TTN console. However, for regression tests,
    // we want to be able to compile these scripts. The regression tests define
    // COMPILE_REGRESSION_TEST, and in that case we define FILLMEIN to a non-
    // working but innocuous value.
    //
    #ifdef COMPILE_REGRESSION_TEST
    # define FILLMEIN 0
    #else
    # warning „You must replace the values marked FILLMEIN with real values from the TTN control panel!“
    # define FILLMEIN (#dont edit this, edit the lines that use FILLMEIN)
    #endif

    // This EUI must be in little-endian format, so least-significant-byte
    // first. When copying an EUI from ttnctl output, this means to reverse
    // the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3,
    // 0x70.
    static const u1_t PROGMEM APPEUI[8]= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}

    // This should also be in little endian format, see above.
    static const u1_t PROGMEM DEVEUI[8]= { *** };
    void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}

    // This key should be in big endian format (or, since it is not really a
    // number but a block of memory, endianness does not really apply). In
    // practice, a key taken from ttnctl can be copied as-is.
    static const u1_t PROGMEM APPKEY[16]= { *** };
    void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);}

    static uint8_t btn_activated[1] = { 0x01};
    static osjob_t sendjob;

    // Schedule TX every this many seconds (might become longer due to duty
    // cycle limitations).
    const unsigned TX_INTERVAL = 60;

    // Pin mapping
    const lmic_pinmap lmic_pins = {
    .nss = 10,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 5,
    .dio = {2, 3, LMIC_UNUSED_PIN},
    };

    //—— Added —————-
    #define LED_YELLOW 8
    #define LED_GREEN 6

    #define DHT_PIN 7
    #define BTN_PIN 9

    // DHT11 or DHT22
    #define DHTTYPE DHT22

    // Initialize dht
    DHT dht(DHT_PIN, DHTTYPE);

    int buttonState = 0; // current state of the button
    int lastButtonState = 0; // previous state of the button

    int BattValue = 0;

    int BattOut = A1; //Voltage Divider INPUT

    //—————————–

    void onEvent (ev_t ev) {
    Serial.print(os_getTime());
    Serial.print(„: „);
    switch(ev) {
    case EV_SCAN_TIMEOUT:
    Serial.println(F(„EV_SCAN_TIMEOUT“));
    break;
    case EV_BEACON_FOUND:
    Serial.println(F(„EV_BEACON_FOUND“));
    break;
    case EV_BEACON_MISSED:
    Serial.println(F(„EV_BEACON_MISSED“));
    break;
    case EV_BEACON_TRACKED:
    Serial.println(F(„EV_BEACON_TRACKED“));
    break;
    case EV_JOINING:
    LMIC_setDrTxpow(DR_SF9,14);
    Serial.println(F(„EV_JOINING“));
    break;
    case EV_JOINED:
    Serial.println(F(„EV_JOINED“));
    {
    u4_t netid = 0;
    devaddr_t devaddr = 0;
    u1_t nwkKey[16];
    u1_t artKey[16];
    LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);
    Serial.print(„netid: „);
    Serial.println(netid, DEC);
    Serial.print(„devaddr: „);
    Serial.println(devaddr, HEX);
    Serial.print(„artKey: „);
    for (int i=0; i<sizeof(artKey); ++i) {
    Serial.print(artKey[i], HEX);
    }
    Serial.println("");
    Serial.print("nwkKey: ");
    for (int i=0; i<sizeof(nwkKey); ++i) {
    Serial.print(nwkKey[i], HEX);
    }
    Serial.println("");
    }
    // Disable link check validation (automatically enabled
    // during join, but because slow data rates change max TX
    // size, we don't use it in this example.

    Antworten

Schreibe einen Kommentar