How to connect LoRaWAN gateway to Balena cloud
Published: 2021-08-16 21:56:58

Today I attended day 1 of ["The Things Summer Academy"](https://www.thethingsnetwork.org/article/kickstart-your-lorawan-career-with-the-things-summer-academy), so I'm sharing what I have learned here.

On the previous week, I had ordered the "RAK Discover Kit 2" from the [RAK Wireless Store](https://rakwireless.kckb.st/1a378338). It costs around US$170 but this includes the complete set like a Raspberry Pi 4B 4GB with UK power adapter, a 16GB SD card with the default firmware already installed, a RAK2287 LPWAN Concentrator and a RAK2287 Pi Hat. I think it is a good deal compared to buying the parts individually.

If you do decide to buy them separately, just remember to select the SPI version instead of the USB version because that's how the Pi HAT connects. Also, currently the [basicstation](https://github.com/mpous/basicstation/) repository only works with SPI.

According to the guys, "USB is not a good idea as basically there is an SPI to USB to MCU convertor going on - whereas SPI can talk straight to the MCU. LoRaWAN gateways are very timing sensitive so if something is randomly using up USB bandwidth it can throw things off."

I thought I may not be able to receive the parcel in time due to global delivery delay, but I was impressed that the FEDEX guys came and delivered the kit to my place just 1 hour before the workshop starts. I'm happy to have all the parts that I need to start hacking right away!

---

## The Ants

The Pi Hat and gateway concentrator were already attached to the Raspberry Pi out of the box, except the antennas. Before turning the power on, I have to make sure to connect the antennas first because the documentation mentioned that detaching the antenna while powered on [might damage the circuitry](https://docs.rakwireless.com/Product-Categories/WisLink/RAK2287/Quickstart/#antennas).

At first, I was confused which one is the GPS antenna, and which one is the LoRa antenna. Asking one of the guys in the Slack, someone was kind enough to answer,
"The square lozenge is the GPS antenna, while the longer black (coil) is the LoRa antenna, probably also shipped with a frequency label (e.g. 868Mhz) which is the big clue."

The instructor mentioned that the legacy packet forwarder (the default firmware loaded in the SD card) is based on UDP transport protocol, so the data will be unencrypted in transit, and being UDP it means having no reliability mechanism built-in. Thus, the goal of this workshop is to load a custom firmware over the air and manage the deployments via Balena cloud.

---

## The Basic Station

Balena cloud deploys the application into docker containers, and the one I'm deploying is called [basicstation](https://github.com/mpous/basicstation), a secure websocket based implementation of the packet forwarder.

The easiest way is to go to Balena hub and [fork the fleet](https://hub.balena.io/marc6/basicstation-gateway-tts).

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cd9892ai36nda70rvo5o.png)

Since I did not have an account with Balena yet, I simply authorized creating an account via my Github account.

Next, it asks me to give the fleet a name, so I'm naming it "osm-solution". Because this is supposed to be an oh-sem solution! Get it? Awesome!

I'm selecting Raspberry Pi 4 here because that's the device I have:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9arwtlffkohq7lt4wfbt.png)

Clicking the "Advanced" toggle button will reveal the configuration variables. I'm changing the `MODEL` variable value to `SX1302` because the RAK2287 LPWAN gateway concentrator included in the kit is using the SX1302 chipset. I'm also changing the `TTN_REGION` value to `au1` because that's the closest TTN (The Things Network) region in APAC. I leave the default values for the rest of the variables for now.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mzvzur89lnk27iw9iyfl.png)

Then I'm going to add the device to be managed by Balena Cloud. Here I added my home WiFi details so that my Raspberry Pi is able to connect to the internet as soon as it is powered on. 

By the way, did you noticed my home SSID is named "ARPAnet"? How geeky is that?!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cssmmob94p6nh84oc8ye.png)

This will prepare the custom firmware in a zip file ready to be downloaded.

---

## Flash and Burn!

I'm using [Balena Etcher](https://www.balena.io/etcher/) to burn the firmware into the SD card.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/693vulbzapyy3qujht0i.png)

After inserting the micro SD card to the laptop's USB port, I make sure to select the correct disk. Well, you don't want to accidentally `rm -rf` your hard disk, do you?

As for the SD card, the guys said that minimum class 4 is recommended but basically don't skimp on this, get the highest quality branded product like SanDisk Extreme, Kingston or Toshiba, and choose Class 10 if possible. The kit came with Sandisk Ultra 16GB, so that's what I'm going to use here though. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/35mzqu1krdportlwpwad.png)

... finally I can flash myself! Oops, I mean, the card.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19br1pfnzvbstwyplz4z.png)

In the discussion, the guys mentioned that instead of using SD card, we can also boot from USB [SSD stick](https://sg.cytron.io/p-md2-2280-makerdisk-sata-iii-ssd-with-raspberry-pi-os) or eMMC module such as the [RasPiKey](https://thepihut.com/products/raspikey-plug-and-play-emmc-module-for-raspberry-pi). Balena also produces an independent hardware called [Balena Fin](https://www.balena.io/fin/) which uses industrial eMMC and the Pi Compute Module. These alternatives may prove to be more reliable if you plan to deploy the gateways for commercial use. I'm using this for learning and rapid prototyping, so the storage type doesn't really matter at this point in time.

Next, I inserted the flashed SD card into Raspberry Pi and turned the power on. After a while, I can see the device successfully connects to Balena Cloud. Wow, it's really that easy!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k3rnj8mfmk91qqbimza9.png)

Using the dashboard will allow me to easily manage and update multiple gateways remotely. I can also see where the gateway location is, that's pretty cool!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19sy92tf6c2ht8caxyr4.png)

At the Device Summary section, there's the gateway EUI, which is the first 6 bytes of the ethernet MAC address padded into 8 bytes. The EUI is populated into the `TAGS` when the device gets provisioned on Balena cloud for the first time. Copy this value because it will be used next.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qyav8ligjzhyi5qhqlyh.png)

---

## Where the wild things are

Next step would be to connect the gateway to The Things Network. I already had an account created previously when I took The Things Certification last year, so I'm going to simply login into the dashboard.

For the region selection, I chose the "au1" region, because that is what I had defined in the `TTN_REGION` variable previously, remember?

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mn97yumzscjng3uhhiy9.png)

I want to register a new gateway, so I'm choosing that option here:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fkrus45rsxbvngwk6fhi.png)

So I pasted the gateway EUI value that was copied earlier:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e3wziummd7w6l6s6kxvw.png)

Here we have to select the right frequency based on the country the gateway will be used in, so I chose one from the list [here](https://www.thethingsnetwork.org/docs/lorawan/frequencies-by-country/). By the way, the hardware frequency had already been decided when ordering the LPWAN concentrator module from the store. So you can't really choose any other option here anyway, it wouldn't work.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ujoae924hvnu92doemak.png)

The summary page will be shown once the gateway has been successfully registered. 

---

## Security is the key

Next, I'm going to create an API key so that the gateway can securely connect to The Things Network. The "API keys" option can be found at the top or left hand side of the screen. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6qfkbi21e74vcfik2kcc.png)

I'm granting a specific rights as in the screenshot below, then proceed to generate the key:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4xvicrku98xakdsmym37.png)

Let's not forget to copy the API key here!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w9aa0fwnzqcmbz0uk51r.png)

Finally, I return to Balena cloud dashboard and go to the fleet's (or device's) variables settings. The API key is the one represented by the `TC_KEY` variable:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s209f1nop2apql5mdtz9.png)

I paste the API key copied earlier into the `TC_KEY` value:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8rlkngv8j9myk41bonav.png)

When I go back to The Things Network dashboard, I am able to see that the gateway was "Last seen ... ago".

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1fl6uac4z3n35p11pwvk.png)

This shows that the gateway was able to successfully connect to The Things Network, and can now send data uplink and receives downlink data.

---

## Over the air and beyond!

Lastly, I want to practise how to manage the firmware updates OTA (over-the-air). I will be adding changes to the gateway fleets by deploying a new docker container called ["wifi-connect"](https://github.com/balenablocks/wifi-connect).

I create a new folder and pull the ["basicstation"](https://github.com/mpous/basicstation) repository there:

```
mkdir basicstation-wificonnect
cd basicstation-wificonnect
git clone https://github.com/mpous/basicstation
```

Next, I create a `docker-compose.yml` file and paste the following contents. This is based on the `docker-compose.yml` file in the original [wifi-connect](https://github.com/balenablocks/wifi-connect) repository.

```
version: "2.1"

services:
  wifi-connect:
    image: balenablocks/wifi-connect:aarch64
    restart: always
    network_mode: host
    privileged: true
    labels:
      io.balena.features.dbus: "1"
      io.balena.features.firmware: "1"

  basicstation:
    build: ./basicstation
    privileged: true
    restart: always
    network_mode: host
```

Next, I install the Balena CLI tool from [here](https://github.com/balena-io/balena-cli/blob/master/INSTALL.md) and authenticate using the web authorization method:

```
balena login
```

Push the contents of the `basicstation-wificonnect` folder into Balena cloud:

```
balena push <deployment_name>
```

It will take some time to finish:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/883z80mxqgfupdlvca4b.png)

I can see the software updates has been successfully released:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t5jd5j2hsqzmkcsmbktt.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cz3bvh9ffu8rh2l8fti0.png)

Wifi-connect here will check the internet connection every 120 seconds. If it detects that there is no internet connections is unavailable, it will switch the connection to access point mode. The user can then connect to the SSID and configure the WiFi credentials via a captive portal. This is useful when using the gateway outdoors or for mobile deployments.

I can now confirm that the new feature that was added (wifi-connect) is running fine by reviewing the logs:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/owmkgjlk5opti32y3nl3.png)

---

## Summary

In this workshop, I had learned to build my first LoRaWAN gateway with Raspberry Pi, and how to manage the gateway remotely with Balena Cloud. Then I learned how to register the gateway to The Things Network and authenticate it with API key. Finally I learned how to update the gateway software over-the-air.

Stay tuned for day 2 reports tomorrow! (or a few days later, no pressure, haha!)

---

## References

- https://www.balena.io/blog/run-your-private-the-things-stack-network-server-on-a-raspberry-pi-with-balena/
- https://www.balena.io/blog/deploy-a-basics-station-lora-gateway-with-ttn-and-balena/
- https://www.youtube.com/watch?v=h38IFxHG7pA&list=PLM8eOeiKY7JUSpxCAiEr6eViQYwXZVkXy