Mainflux LoRaWAN Tutorial

Manuel Imperiale
Mainflux IoT Platform
8 min readApr 12, 2019



LoRa (Long Range) is a patented digital wireless data communication technology developed by Cycleo of Grenoble, France, and acquired by Semtech in 2012.

LoRa uses license-free sub-gigahertz radio frequency bands like 169 MHz, 433 MHz, 868 MHz (Europe) and 915 MHz (North America). LoRa enables very-long-range transmissions (more than 10 km in rural areas) with low power consumption. The technology is presented in two parts — LoRa, the physical layer and LoRaWAN (Long Range Wide Area Network), the upper layers.


The LoRaWAN specification is a Low Power, Wide Area Networking (LPWAN) protocol designed to wirelessly connect battery operated ‘things’ to the internet in regional, national or global networks, and targets key Internet of Things (IoT) requirements such as bi-directional communication, end-to-end security, mobility and localization services.

LoRa Sever

The LoRa Server project provides open-source components for building LoRaWAN networks. Together they form a ready-to-use solution, including an user-friendly web-interface together with gRPC and REST APIs. Components can also be swapped out for customization or when integrating LoRa Server into existing infrastructures. All components are licensed under the MIT license and can be used for commercial purposes.

LoRa Server is used for connectivity layer. Specially for the LoRa Gateway Bridge service, which abstracts the SemTech packet-forwarder UDP protocol into JSON over MQTT. But also for the LoRa Server service, responsible of the de-duplication and handling of up-link frames received by the gateway(s), handling of the LoRaWAN mac-layer and scheduling of down-link data transmissions. Finally the ChirpStack Application Server service is used to interact with the system.

Mainflux lora-adapter

This adapter sits between Mainflux and LoRa Server and forwards the MQTT messages published by the ChirpStack Application Server to the Mainflux multi-protocol message broker, using the adequate MQTT topics and in the good message format (JSON and SenML), i.e. respecting the APIs of both systems.

Integration flow

1. Provisioning flow / 2. Messaging flow


Go, docker and docker-compose are prerequisites.

Clone Mainflux repository with the following command:

go get

Run Mainflux

Once it’s installed, execute the following command from Mainflux project root to run the docker composition:

docker-compose -f docker/docker-compose.yml up

This will bring up all Mainflux docker containers and inter-connect them in the composition. In this example we will use InfluxDB as message database. So we need to run the docker composition of the addon influxdb-writer. For that, execute this commands from project root:

docker-compose -f docker/addons/influxdb-writer/docker-compose up

Run LoRa Server

Before running lora-adapter you must install and run LoRa Server. First, execute the following command:

go get

Once everything is installed, execute the following command from the LoRa Server project root:

docker-compose up

Troubleshooting: Mainflux and LoRa Server use their own MQTT brokers. By default, those use the standard MQTT port 1883. If you are running both systems on the same machine you must use different ports. You can fix this on Mainflux side configuring the environment variable MF_MQTT_ADAPTER_MQTT_PORT.

LoRa Server setup

Now that both systems are running you must provision your LoRa Server, which offers for integration with external services, a RESTful and gRPC API. The LoRa App Server GUI, which is nice example of integration, offers a graphic interface to manage the system.

We assume that you already have a gateway configured to send messages to your LoRa Server. This means that your physical LoRa gateway send UDP packets to your LoRa-Gateway-Bridge IP(where LoRa Server runs) at port 1700(ensure that this port is open on your machine). This packets are used by LoRa Server to monitor the gateway activity and receive messages.

  • Create an Organization: To add your own Gateways to the network you must have an Organization.
  • Create Network LoRa Server: Set the address of your Network-Server API that is used by LoRa App Server or other custom components interacting with LoRa Server (by default loraserver:8000).
  • Create a Gateways-Profile: In this profile you can select the radio LoRa channels and the LoRa Network Server to use.
  • Create a Service-profile: A service-profile connects an organization to a network-server and defines the features that an organization can use on this Network-Server.
  • Create a Gateway: You must set proper ID in order to be discovered by LoRa Server.

Your gateway will be created and accessible from Gateways page:

If the Gateway have been discovered you should see something like that:

  • Create a LoRa Server Application: This will allows you to create Devices by connecting them to this application. It’s the Mainflux equivalent of connect Devices to channels.
  • Create a Device-Profile: Before creating Devices you must create a Device profile where you will define some parameter as LoRaWAN MAC version (format of the device address) and the LoRaWAN regional parameter (frequency band). This will allow you to create many devices using this profile.
  • Create a Device: Finally, you can create a Device. Edit profile names , select a device-profile and generate your Device key:
  • Activate your Device: You must configure the network session key and application session key of your Device. You can generate and copy them on your device configuration or you can use your own pre-generated keys and set them using the LoRa App Server GUI. Device connect through OTAA. Make sure that LoRa Server device-profile is using same release as device. If MAC version is 1.0.X, application key = app_key and app_eui = deviceEUI. If MAC version is 1.1 or ABP both parameters will be needed, APP_key and Network key.

Your Device will be created an accessible from Applications page:

Run lora-adapter

Once Mainflux and LoRa Server are running and the LoRa Server is provisioned, execute the following command from Mainflux project root to run the lora-adapter:

docker-compose -f docker/addons/lora-adapter/docker-compose.yml up

Troubleshooting: The lora-adapter subscribes to the LoRa Server MQTT broker and will fail if the connection is not established. You must ensure that the environment variable MF_LORA_ADAPTER_MESSAGES_URL is properly configured.

Remark: By default, MF_LORA_ADAPTER_MESSAGES_URL is set as tcp:// in the docker-compose.yml file of the adapter. If you run the composition without configure this variable you will start to receive messages from our demo server.

Provisioning / Route map:

The lora-adapter use Redis database to create a route map between both systems. As in Mainflux we use Channels to connect Things, LoRa Server uses Applications to connect Devices.

The lora-adapter uses the matadata of provision events emitted by Mainflux system to update his route map. For that, you must provision Mainflux Channels and Things with an extra metadata key in the JSON Body of the HTTP request. It must be a JSON object with keys type and app_id or dev_eui. In this case type value must be lora and app_id or dev_eui value must be an existent LoRa Server Application ID or Device EUI.

LoRa Channel:

"name": "<channel name>",
"metadata:": {
"lora": {
"app_id": "<application ID>"

LoRa Thing:

"name": "<thing name>",
"metadata:": {
"lora": {
"dev_eui": "<device EUI>"

Provision over CLI:

Over the Mainflux CLI the following commands will provision the system and create LoRa mappings.

cli channels create '{"name":"myLoRaApp", "metadata": {"lora": { "app_id": "<application ID>"}"}' <user_token>cli things create '{"name":"myLoRaDev", "metadata": {"lora": { "dev_eui": "<device EUI>"}"}' <user_token>

Provision over GUI:

Provisioning can also be done from Mainflux UI. To deploy Mainflux Core services + the UI + use make run command from mainflux/ui repository. The docker container will be exposed at localhost:80. To create the mapping access to Things/Lora page and ensure that the device that you are going to create has proper values (in the following example app_id is 3 and dev_eui is 70b3d5599d2c8a5f).


To receive messages the lora-adapter subscribes to a specific topic of the LoRa Server MQTT broker that the LoRa-Gateways-Bridge service uses to publish decoded UDP packets received from gateways. It verifies app_id and dev_eui of published messages. If the mapping exists it uses corresponding channel ID and thing ID to sign and forward the content of the LoRa message to the Mainflux message broker.

If you followed previous steps and properly provisioned your Mainflux instance incoming messages should being stored in the InfluxDB database by mainflux-influxdb-writer.

Read LoRa messages

To read stored messages you can use the mainflux-grafana docker exposed at localhost:3001 that automatically runs with influxdb-writer docker composition.

Grafana setup:

Using your browser log in Grafana with credentials admin / admin and just add a database of Type InfluxDB using default address http://influxdb:8086. Database, User and Password are mainflux. This values are configurable on the influxdb-writer/docker-compose.yml file.

Finally, you can add different kind of panels to your Dashboard and configure them with different database queries to generate graphs, monitors and many other components. You must select the DB table messages. The parameters of the query are channel and publisher, values where generated on previous Mainflux Things service provision and correspond to channel ID and device ID.

Have fun!