TTN Gateways Monitoring – TGM

TTN version: TTNv3
System: 64-bit
Last updated: June 28, 2024

For gateways monitoring, we use an open-source time series database InfluxDB and an open-source analytical and interactive visualization web application Grafana. Gateway data is loaded from The Things Stack using our TGM. The TGM makes a GET requests, parses the data received in the response, and then stores the data (number of uplinks and downlinks, times – last uplink received at, last downlink received at and last status received at) in the InfluxDB database.

TTN Gateways monitoring dashboard

 

Prepare

  • Raspberry Pi 4/5 or Linux server
  • The Things Stack with active gateways

 

Raspberry Pi OS setup and Docker installation

Raspberry Pi OS setup
  1. From https://www.raspberrypi.com/software/ download Raspberry Pi Imager and install it.
  2. Insert the microSD card into the computer.
  3. Run Raspberry Pi Imager.
  4. Click on CHOOSE OS.
  5. Click on Raspberry Pi OS (other).
  6. Click on Raspberry Pi OS Lite (64-bit).
  7. Click on CHOOSE STORAGE.
  8. Select the inserted microSD card on which you want to install Raspberry Pi OS.
  9. Click on Next.
  10. Would you like to apply OS customisation settings? – EDIT SETTINGS.
  11. Set hostname.
  12. Set username and password. (we recommend a 17-digit password containing lower and upper case letters, numbers and symbols)
  13. If you will use WiFi – Configure wireless LAN. (optional)
  14. Set locale settings.
  15. Click on tab SERVICES.
  16. If you will be connecting remotely via SSH – Enable SSH – Use password authentication. (optional)
  17. Click on SAVE.
  18. Click on YES.
  19. Click on YES.
  20. Click on CONTINUE.
  21. Insert the microSD card into the Raspberry Pi.
  22. Turn on the Raspberry Pi.

 

Remote connection via SSH (optional)
  1. Connect to your router and find the IP address of your Raspberry Pi.
  2. From a Windows PC, you can connect using Command Prompt (CMD) or PuTTY.
  3. On Windows PC open Command Prompt (CMD).
  4. Type ssh -p port username@IP_Address (for example: ssh -p 22 loravsb@192.168.1.120).
  5. Type your password.

 

Post-installation steps
  1. Update, upgrade and reboot Raspberry Pi. This will ensure that any security vulnerabilities are patched:
    $ sudo apt update
    $ sudo apt full-upgrade
    $ sudo reboot
  2. Connect again via SSH.
  3. Use a different port for SSH and disable root login. First, open the SSH configuration file with a text editor:
    $ sudo nano /etc/ssh/sshd_config
    
  4. Locate the line with Port 22 and change it to the desired port number (for example, change the port to 2222). Locate the line with PermitRootLogin and change its value to no (this will disable root login via SSH):
    Port 2222
    PermitRootLogin no
    
    
  5. Save the changes and exit the text editor.
  6. Restart the SSH service to apply the changes:
    $ sudo systemctl restart ssh
    
  7. Log out and connect again via SSH on the new port.
  8. Install and configure the built-in firewall, ufw, to limit incoming and outgoing network connections. In the sudo ufw limit 2222/tcp rule, change port 2222 to port you have chose for SSH above.
    $ sudo apt install ufw
    $ sudo ufw default deny incoming
    $ sudo ufw default deny outgoing
    $ sudo ufw limit 2222/tcp
    $ sudo ufw allow out 123/udp
    $ sudo ufw allow out to any port 53
    $ sudo ufw allow out to any port 80
    $ sudo ufw allow out to any port 443
    $ sudo ufw enable
    

    Note: Firewall rules will have no effect on ports opened by Docker.

  9. Reboot Raspberry Pi:
    $ sudo reboot

 

Docker
  1. Connect again via SSH.
  2. Install the latest Docker version using the convenience script provided by docker:
    $ curl -fsSL https://get.docker.com -o get-docker.sh
    $ sudo sh get-docker.sh
    $ sudo groupadd docker
    $ sudo usermod -aG docker $USER
    $ newgrp docker
    $ sudo systemctl enable docker.service
    $ sudo systemctl enable containerd.service

For more information on Docker installation, see https://docs.docker.com/engine/install/.

 

TTS API key

  1. In TTS -> YourUsername -> Personal API keys click on + Add API key.
  2. Write something in the Name.
  3. Select Grant individual rights.
  4. Check List gateways the user is collaborator of.
  5. Click on button Create API key.
  6. Click the Copy to Clipboard button and save the key somewhere safe for later use.
  7. In the section below, you will use the API key.

 

Option 1: InfuxDB v1.8.10, Grafana and TGM 1 setup

If you want to deploy the new Grafana, InfluxDB v1.8.10 and TGM 1, follow the instructions in this section.

  1. Clone the repository with TGM 1 and go to the created directory:
    $ git clone https://github.com/OndrejKnebl/tgm_1.git
    $ cd tgm_1
  2. Create internal Docker networks:
    $ sudo docker network create myNetworkIandG
    $ sudo docker network create myNetworkIandM
  3. Run this command to edit the docker-compose.yml file:
    $ sudo nano docker-compose.yml
  4. Copy and paste the API key you got previously saved to the TTN_PERSONAL_API_KEY variable.
  5. Replace the values ​​of the following variables with your values and save the docker-compose.yml file:
    INFLUXDB_DB,
    INFLUXDB_ADMIN_USER,
    INFLUXDB_ADMIN_PASSWORD,
    INFLUXDB_WRITE_USER,
    INFLUXDB_WRITE_USER_PASSWORD,
    INFLUXDB_READ_USER,
    INFLUXDB_READ_USER_PASSWORD,
    DB_USERNAME,
    DB_PASSWORD,
    DB_NAME,
    DB_MEASUREMENT
  6. Build the image:
    $ sudo docker compose build
  7. Now, you can start it running in the background with the following command:
    $ sudo docker compose up -d

 

Grafana setup

  1. Now you can visit your Grafana web application from a browser in your internal network at http://IP_AddressOfServer:3000 (for example 192.168.1.120:3000).
  2. Log in with username admin and password admin.
  3. Change your Grafana account password.
  4. Click on Connections -> Data sources -> Add data source.
  5. Choose InfluxDB.
  6. Query Language = InfluxQL
  7. URL = http://influxdb:8086
  8. Database = ttnGateways
  9. User = myNewReadUser
  10. Password = myNewReadUserPassword
  11. HTTP Method = GET
  12. Click on Save & test
  13. Continue with the “Grafana dashboard setup” section below.

 

Option 2: InfuxDB v2, Grafana and TGM 2 setup

If you want to deploy the new Grafana, InfluxDB v2 and TGM 2, follow the instructions in this section.

  1. Clone the repository with TGM 2 and go to the created directory:
    $ git clone https://github.com/OndrejKnebl/tgm_2.git
    $ cd tgm_2
  2. Create internal Docker networks:
    $ sudo docker network create myNetworkIandG
    $ sudo docker network create myNetworkIandM
  3. Build the image:
    $ sudo docker compose build
  4. Now, you can start it running with the following command:
    $ sudo docker compose up
  5. Now you can visit your InfluxDB web application from a browser in your internal network at http://IP_AddressOfServer:8086 (for example 192.168.1.120:8086).
  6. Click on GET STARTED.
  7. Setup your Initial User – Username, Password, Organization and Bucket.
  8. Click on CONTINUE.
  9. Click on QUICK START.
  10. In the left menu, click Load data -> API Tokens -> + GENERATE API TOKEN -> Custom API Token.
  11. Write something to Description.
  12. Click on Buckets and check the Read box next to the previously created bucket.
  13. Click on GENERATE.
  14. Click on the COPY TO CLIPBOARD button and save the key somewhere safe for later use in Grafana.
  15. Click on cross button.
  16. Click on + GENERATE API TOKEN -> Custom API Token.
  17. Write something to Description.
  18. Click on Buckets and check the Write box next to the previously created bucket.
  19. Click on GENERATE.
  20. Click on the COPY TO CLIPBOARD button and save the key somewhere safe for later use in docker-compose.yml file for TGM.
  21. Click on cross button.
  22. Logout from your InfluxDB web application.
  23. In the terminal with container outputs running, press Ctrl+C.
  24. Run this command to edit the docker-compose.yml file:
    $ sudo nano docker-compose.yml
  25. Copy and paste the TTN API key you got previously saved to the TTN_PERSONAL_API_KEY variable.
  26. Replace the values ​​of the following variables with your values and save the docker-compose.yml file:
    DB_WRITE_TOKEN,
    DB_ORG,
    DB_BUCKET
  27. Now, you can start it running in the background with the following command:
    $ sudo docker compose up -d
  28. Continue with the “Grafana dashboard setup” section below.

 

Grafana setup

  1. Now you can visit your Grafana web application from a browser in your internal network at http://IP_AddressOfServer:3000 (for example 192.168.1.120:3000).
  2. Log in with username admin and password admin.
  3. Change your Grafana account password.
  4. Click on Connections -> Data sources -> Add data source.
  5. Choose InfluxDB.
  6. Query Language = InfluxQL
  7. URL = http://influxdb2:8086
  8. Database = myBucket
  9. User = myInitialUser
  10. Password = myReadToken
  11. HTTP Method = GET
  12. Click on Save & test
  13. Continue with the “Grafana dashboard setup” section below.

 

Grafana dashboard setup

  1. Click on Dashboards -> New -> New Dashboard.
  2. Choose + Add visualization -> influxdb.
  3. In the FROM line click on select measurement and select GW (InfliuxDB v2 – your Bucket).
  4. Click on + and select host::tag.
  5. Click on select tag value and select your gateway.
  6. In the SELECT line click on value and select for example uplink_count.
  7. Then change mean() to last().
  8. In the GROUP BY line change fill(null) to fill(none).
  9. You can change the Type, Title, Unit, Display name, Color scheme and many more in the menu on the right.
  10. Next, click on Save.
  11. Continue like this for the other panels and gateways.TTN Gateways monitoring panel
  12. If you want to display the increase in the number of Downlinks/Uplinks since the last data collection, it is necessary to write the query manually.
  13. In the settings of the newly added blank panel, press the pencil symbol and put the query with uplink or downlink count in the field.
  14. An example of creating a query to determine the difference is shown below:
    SELECT difference_value 
    FROM (
    SELECT difference(last("uplink_count")) AS difference_value 
    FROM "GW" 
    WHERE ("host"::tag = 'tts-vsb-gw002') AND $timeFilter 
    GROUP BY time($__interval) fill(none)
    ) 
    WHERE difference_value >= 0