Edge computing is a concept where the gateway processes the data itself, takes decisions, acts according to a user-defined logic, and transmits only the necessary data to a central datacenter.
This short step-by-step tutorial demonstrates how to setup your Kerlink gateway to quickly reach a full chain demo level.
This tutorial provides command line instructions as well as JetPorch playbooks.
Playbooks prove to be very usefull to easily deploy needed packages and configurations. Please refer to solution#create-a-playbook to get started with playbooks before going through the following guidelines.
All the following commands are meant to be run as root. You may switch to root user using
sudo su -or prefix all commands withsudoand enter your password.
To replicate our demo setup, you will need:
Demonstration workflow

Bonus: Denoted as followers, other gateways can be configured to forward LoRaWAN frames to the leader gateway. They must be able to reach the leader gateway through the network:
All the Edge logic is integrated in the leader gateway. We will thus install the Chirpstack LNS, as well as NodeRed which proves to be a usefull applicative to experiment with Edge logic. The gateway will also integrate a LoRaWAN forwarder connected to its local LNS.
We provide the step-by-step approach, and a more abstracted example which installs and configures the Chirpstack LNS in a single step. We recommend to first go through the different steps to understand how we demonstrate the integration in our example.
This sample playbook offers a all-in-one solution to deploy on gateways
- name: Disable Network monitoring
groups:
- all
tasks:
- !sd_service
name: "Deactivate Network monitoring"
service: keros-network-monitoring
enabled: false
restart: false
- name: Add chirpstack repository
groups:
- all
tasks:
- !external
use: copycontent
name: "Add chirpstack repository"
params:
dest: "/etc/apt/sources.list.d/chirpstack_4.list"
content: |
deb https://artifacts.chirpstack.io/packages/4.x/deb stable main
- !external
use: copycontent
name: "Exclude chirpstack-mqtt-forwarder"
params:
dest: "/etc/apt/preferences.d/50-chirpstack-mqtt-forwarder"
content: |
Package: chirpstack-mqtt-forwarder
Pin: origin artifacts.chirpstack.io
Pin-Priority: -1
- !shell
name: "Cleanup empty line"
cmd: sed -i '/^$/d' /etc/apt/preferences.d/50-chirpstack-mqtt-forwarder
- !shell
name: "Get chirpstack key"
cmd: curl --fail "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x1ce2afd36dbcca00" -o /tmp/chirpstack_4.asc
- !shell
name: "Add chirpstack key"
cmd: cat /tmp/chirpstack_4.asc | gpg --dearmor --batch --yes > /etc/apt/trusted.gpg.d/chirpstack_4.gpg
- !shell
name: update repo
cmd: apt update
- name: Install chirpstack
groups:
- all
defaults:
apt_packages:
- chirpstack-sqlite
- sqlite3
- mosquitto
- mosquitto-clients
- redis
- zram
tasks:
- !apt
name: Install packages
package: "{{ item }}"
with:
items: apt_packages
- !shell
name: Allow external gateway
cmd: printf "\n[gateway]\n allow_unknown_gateways=true\n" >> /etc/chirpstack/chirpstack.toml
- !shell
name: Create SQLite database folder
cmd: mkdir -p /var/lib/chirpstack && chown chirpstack:chirpstack /var/lib/chirpstack/
- !shell
name: Configure SQLite DB
cmd: printf "\n[sqlite]\n path=\"sqlite:///var/lib/chirpstack/chirpstack.sqlite\"\n" >> /etc/chirpstack/chirpstack.toml
- !sd_service
name: Start chirpstack
service: chirpstack-sqlite
enabled: true
restart: true
- !shell
name: Add local gateway
cmd: sleep 5 && sqlite3 /var/lib/chirpstack/chirpstack.sqlite "INSERT INTO gateway (gateway_id, tenant_id, created_at, updated_at, last_seen_at, name, description, latitude, longitude, altitude, stats_interval_secs, tls_certificate, tags, properties) VALUES (X'$EUI64', (SELECT id FROM tenant LIMIT 1), datetime('now'), datetime('now'), NULL, 'local gateway', 'self', 0.0, 0.0, 0.0, 30, NULL, '{}', '{}'); "
- name: Allow http-alt connection
groups:
- all
tasks:
- !external
use: copycontent
name: "Open firewall for chirpstack"
params:
dest: "/etc/iptables/iptables.d/chirpstack.rules"
content: |
*filter
-A INPUT -p tcp --dport http-alt -j ACCEPT
COMMIT
- !sd_service
name: Reload firewall
service: iptables
enabled: true
restart: true
- name: Setup a follower gateway
groups:
- all
defaults:
mqtt:
topic: "eu868"
server: "localhost:1883"
tasks:
- !shell
name: update repo
cmd: apt update
- !sd_service
name: "Activate lorafwd"
service: lorafwd
enabled: true
started: true
restart: true
- !apt
name: Install chirpstack-mqtt-forwarder
package: chirpstack-mqtt-forwarder
- !template
name: Configure chirpstack-mqtt-forwarder
src: /usr/share/chirpstack-mqtt-forwarder/template.hb
dest: /etc/chirpstack-mqtt-forwarder/chirpstack-mqtt-forwarder.toml
- !sd_service
name: Restart chirpstack-mqtt-forwarder
service: chirpstack-mqtt-forwarder
enabled: true
restart: true
- name: Allow mqtt to listen on local interface
groups:
- all
tasks:
- !shell
name: allow include dir for mosquitto
cmd: mkdir -p /etc/mosquitto/conf.d/ && echo "include_dir /etc/mosquitto/conf.d/" >> /etc/mosquitto/mosquitto.conf
- !external
use: copycontent
name: add rule to listen on local interface
params:
dest: "/etc/mosquitto/conf.d/local.conf"
content: |
listener 1883 0.0.0.0
allow_anonymous true
- !sd_service
name: Reload mosquitto
service: mosquitto
enabled: true
restart: true
If lorafwd service is not activated, you need to enable and start it.
systemctl enable lorafwd.service --now
- name: Enable lorafwd
groups:
- all
tasks:
- !sd_service
name: "Activate lorafwd"
service: lorafwd
enabled: true
started: true
restart: true
For embedded configuraton, disabling network monitoring prevents gateway from automatic reboot in case of the gateway is not connected to internet.
systemctl disable keros-network-monitoring.service --now
- name: Disable Network monitoring
groups:
- all
tasks:
- !sd_service
name: "Disable Network monitoring"
service: keros-network-monitoring
enabled: false
restart: false
We will use Chirpstack as the embedded LNS. Chirpstack is available from its own repository, and is directly installable in KerOS 6.
Execute the following sample to add the Chirpstack repository in KerOS apt source.
cat > /etc/apt/sources.list.d/chirpstack_4.list << EOF
deb https://artifacts.chirpstack.io/packages/4.x/deb stable main
EOF
cat > /etc/apt/preferences.d/50-chirpstack-mqtt-forwarder << EOF
Package: chirpstack-mqtt-forwarder
Pin: origin artifacts.chirpstack.io
Pin-Priority: -1
EOF
# cleanup empty line
sed -i '/^$/d' /etc/apt/preferences.d/50-chirpstack-mqtt-forwarder
curl --fail "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x1ce2afd36dbcca00" -o /tmp/chirpstack_4.asc
cat /tmp/chirpstack_4.asc | gpg --dearmor --batch --yes -o /etc/apt/trusted.gpg.d/chirpstack_4.gpg
apt update
- name: Add chirpstack repository
groups:
- all
tasks:
- !external
use: copycontent
name: "Add chirpstack repository"
params:
dest: "/etc/apt/sources.list.d/chirpstack_4.list"
content: |
deb https://artifacts.chirpstack.io/packages/4.x/deb stable main
- !external
use: copycontent
name: "Exclude chirpstack-mqtt-forwarder"
params:
dest: "/etc/apt/preferences.d/50-chirpstack-mqtt-forwarder"
content: |
Package: chirpstack-mqtt-forwarder
Pin: origin artifacts.chirpstack.io
Pin-Priority: -1
- !shell
name: "Cleanup empty line"
cmd: sed -i '/^$/d' /etc/apt/preferences.d/50-chirpstack-mqtt-forwarder
- !shell
name: "Get chirpstack key"
cmd: curl --fail "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x1ce2afd36dbcca00" -o /tmp/chirpstack_4.asc
- !shell
name: "Add chirpstack key"
cmd: cat /tmp/chirpstack_4.asc | gpg --dearmor --batch --yes > /etc/apt/trusted.gpg.d/chirpstack_4.gpg
- !shell
name: update repo
cmd: apt update
Execute the following sample to install Chirpstack.
apt install --yes chirpstack-sqlite sqlite3 mosquitto mosquitto-clients redis zram
printf "\n[gateway]\n allow_unknown_gateways=true\n" | tee -a /etc/chirpstack/chirpstack.toml
- name: Install chirpstack
groups:
- all
defaults:
apt_packages:
- chirpstack-sqlite
- sqlite3
- mosquitto
- mosquitto-clients
- redis
- zram
tasks:
- !apt
name: Install packages
package: "{{ item }}"
with:
items: apt_packages
- !shell
name: Allow external gateway
cmd: printf "\n[gateway]\n allow_unknown_gateways=true\n" >> /etc/chirpstack/chirpstack.toml
Chirpstack LNS is using sqlite as a database.
Execute the following sample to create a database, and configure it to accept Chirpstack connection.
mkdir -p /var/lib/chirpstack && chown -R chirpstack:chirpstack /var/lib/chirpstack/
printf "\n[sqlite]\n path=\"sqlite:///var/lib/chirpstack/chirpstack.sqlite\"\n" >> /etc/chirpstack/chirpstack.toml
systemctl enable chirpstack-sqlite --now
sleep 5 && sqlite3 /var/lib/chirpstack/chirpstack.sqlite "INSERT INTO gateway (gateway_id, tenant_id, created_at, updated_at, last_seen_at, name, description, latitude, longitude, altitude, stats_interval_secs, tls_certificate, tags, properties) VALUES (X'$EUI64', (SELECT id FROM tenant LIMIT 1), datetime('now'), datetime('now'), NULL, 'local gateway', 'self', 0.0, 0.0, 0.0, 30, NULL, '{}', '{}'); "
- name: Setup sqlite for chirpstack
groups:
- all
tasks:
- !shell
name: Create SQLite database folder
cmd: mkdir -p /var/lib/chirpstack && chown -R chirpstack:chirpstack /var/lib/chirpstack/
- !shell
name: Configure SQLite DB
cmd: printf "\n[sqlite]\n path=\"sqlite:///var/lib/chirpstack/chirpstack.sqlite\"\n" >> /etc/chirpstack/chirpstack.toml
- !sd_service
name: Start chirpstack
service: chirpstack-sqlite
enabled: true
restart: true
- !shell
name: Add local gateway
cmd: sleep 5 && sqlite3 /var/lib/chirpstack/chirpstack.sqlite "INSERT INTO gateway (gateway_id, tenant_id, created_at, updated_at, last_seen_at, name, description, latitude, longitude, altitude, stats_interval_secs, tls_certificate, tags, properties) VALUES (X'$EUI64', (SELECT id FROM tenant LIMIT 1), datetime('now'), datetime('now'), NULL, 'local gateway', 'self', 0.0, 0.0, 0.0, 30, NULL, '{}', '{}'); "
Chirpstack LNS provides a web interface listening on port 8080. If we want to access it, we need to open this port to allow connection.
Security consideration:
This is for demonstration purpose. Do not use as this in a production environment.
Execute the following sample to configure the firewall.
cat > /etc/iptables/iptables.d/chirpstack.rules << EOF
*filter
-A INPUT -p tcp --dport http-alt -j ACCEPT
COMMIT
EOF
# cleanup empty line
sed -i '/^$/d' /etc/iptables/iptables.d/chirpstack.rules
systemctl restart iptables
- name: Allow http-alt connection
groups:
- all
tasks:
- !external
use: copycontent
name: "Open firewall for chirpstack"
params:
dest: "/etc/iptables/iptables.d/chirpstack.rules"
content: |
*filter
-A INPUT -p tcp --dport http-alt -j ACCEPT
COMMIT
- !sd_service
name: Reload firewall
service: iptables
enabled: true
restart: true
The leader gateway also integrates a LoRaWAN forwarder connected to its local LNS.
Execute the following sample to install and configure
chirpstack-mqtt-forwarder.
Make sure to adapt the MQTT topic to match your LoRaWAN region, cf. chirpstack-mqtt-forwarder configuration
apt update
apt install chirpstack-mqtt-forwarder
# Adapt topic_prefix if needed (us915_0,as923,...)
cat > leader_config.toml << EOF
[mqtt]
topic_prefix = "eu868"
server = "tcp://localhost:1883"
EOF
# cleanup empty line
sed -i '/^$/d' leader_config.toml
conflex -t -o chirpstack-mqtt-forwarder.toml -T /usr/share/chirpstack-mqtt-forwarder/template.hb leader_config.toml
mv -f chirpstack-mqtt-forwarder.toml /etc/chirpstack-mqtt-forwarder/chirpstack-mqtt-forwarder.toml
systemctl enable chirpstack-mqtt-forwarder --now
mkdir -p /etc/mosquitto/conf.d/
echo "include_dir /etc/mosquitto/conf.d/" | tee -a /etc/mosquitto/mosquitto.conf
cat > local.conf << EOF
listener 1883 0.0.0.0
allow_anonymous true
EOF
# cleanup empty line
sed -i '/^$/d' local.conf
mv local.conf /etc/mosquitto/conf.d/
systemctl enable mosquitto --now
- name: Setup the leader gateway
groups:
- all
defaults:
mqtt:
topic: "eu868"
server: "localhost:1883"
tasks:
- !shell
name: update repo
cmd: apt update
- !apt
name: Install chirpstack-mqtt-forwarder
package: chirpstack-mqtt-forwarder
- !template
name: Configure chirpstack-mqtt-forwarder
src: /usr/share/chirpstack-mqtt-forwarder/template.hb
dest: /etc/chirpstack-mqtt-forwarder/chirpstack-mqtt-forwarder.toml
- !sd_service
name: Restart chirpstack-mqtt-forwarder
service: chirpstack-mqtt-forwarder
enabled: true
restart: true
- name: Allow mqtt to listen on local interface
groups:
- all
tasks:
- !shell
name: allow include dir for mosquitto
cmd: mkdir -p /etc/mosquitto/conf.d/ && echo "include_dir /etc/mosquitto/conf.d/" >> /etc/mosquitto/mosquitto.conf
- !external
use: copycontent
name: add rule to listen on local interface
params:
dest: "/etc/mosquitto/conf.d/local.conf"
content: |
listener 1883 0.0.0.0
allow_anonymous true
- !sd_service
name: Reload mosquitto
service: mosquitto
enabled: true
restart: true
The interface is available from your gateway webui#hostname-url on the 8080 port.
Example:
- A Wirnet™ iFemtoCell has a board ID of 704BEc1234AB (and 7276FF00391234AB as EUI64)
- Chirpstack LNS interface URL is http://klk-wifc-1234AB.local:8080
Please refer to Chirpstack LNS documentation for more details.
At this stage, your gateway should now be visible in the "Gateways" menu



Join your end-device !
In "Gateways > TLS certificate" and "Applications > Integrations > MQTT integration" sections, the button for generating a certificate doesn't work by default.


Notice:
to sign client-certificates for gateways and the application MQTT integration please refer to Chirpstack TLS documentation for more details.
In this demo, we use node-red to implement the specific logic of our edge solution.
Node-red requires additional ressources. Prior to install the application, you need to enable swap memory, cf. FAQ: how to enable swap memory
Execute the following sample to install node-red application
apt update
apt install node-red
systemctl enable node-red --now
- name: Deploy node-red service
groups:
- all
tasks:
- !apt
package: node-red
- !sd_service
name: Start node-red
service: node-red
enabled: true
restart: true
To connect to node-red web interface, we need to open the node-red port.
Security consideration:
This is for demonstration purpose. Do not use as this in a production environment.
cat > node-red.rules << EOF
*filter
-A INPUT -p tcp --dport 1880 -j ACCEPT
COMMIT
EOF
# cleanup empty line
sed -i '/^$/d' node-red.rules
mv node-red.rules /etc/iptables/iptables.d/
systemctl restart iptables
- name: Allow node-red connection
groups:
- all
tasks:
- !external
use: copycontent
name: "Open firewall for node-red"
params:
dest: "/etc/iptables/iptables.d/node-red.rules"
content: |
*filter
-A INPUT -p tcp --dport 1880 -j ACCEPT
COMMIT
- !sd_service
name: Reload firewall
service: iptables
enabled: true
restart: true
The interface is now available from your gateway webui#hostname-url on the 1880 port.
Example:
- A Wirnet™ iFemtoCell has a board ID of 704BEc1234AB (and 7276FF00391234AB as EUI64)
- NodeRed interface URL is http://klk-wifc-1234AB.local:1880/
In the following demonstration flow, you will find an MQTT registration to get all uplink messages from our LoRaWAN test device, unpack the data, and trigger a ntfy notification when the device transmits a message following a push on its test button.
You will also find an example of a downlink message from the gateway to the device. A click on the left square next to the "on" and "off" boxes will respectively provision a downlink command in Chirpstack LNS to enable or disable the LED of our test device.

Import our example into node-red and get started:
Please refer to node-red documentation on how to import a node-red flow.
You will have to adapt the logic to your setup:
- According to your LoRaWAN device payload format
- With your Chirpstack Application ID in the downlink logic
[
{
"id": "193fbdbd9c664d13",
"type": "tab",
"label": "Flow 1",
"disabled": false,
"info": "",
"env": []
},
{
"id": "f381210bac9b8559",
"type": "subflow",
"name": "ntfy",
"info": "set msg.payload to content\nset msg.topic to topic",
"category": "",
"in": [
{
"x": 60,
"y": 80,
"wires": [
{
"id": "340242d93be4e1bd"
}
]
}
],
"out": [
{
"x": 580,
"y": 80,
"wires": [
{
"id": "937457591f52cf96",
"port": 0
}
]
}
],
"env": [],
"meta": {},
"color": "#DDAA99"
},
{
"id": "9b5169040f2e5f61",
"type": "mqtt-broker",
"name": "",
"broker": "127.0.0.1",
"port": "1883",
"clientid": "",
"autoConnect": true,
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willPayload": "",
"willMsg": {},
"userProps": "",
"sessionExpiry": ""
},
{
"id": "340242d93be4e1bd",
"type": "function",
"z": "f381210bac9b8559",
"name": "function 1",
"func": "msg.url = \"https://ntfy.sh/\" + msg.topic\nmsg.headers = {};\nmsg.headers['X-Title'] = 'Kerlink Demo';\nmsg.headers['Icon'] = 'https://www.kerlink.com/wp-content/themes/ci_kerlink/images/favicon.ico'\nmsg.headers['Tags'] = 'rotating_light'\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 200,
"y": 80,
"wires": [
[
"937457591f52cf96"
]
]
},
{
"id": "937457591f52cf96",
"type": "http request",
"z": "f381210bac9b8559",
"name": "",
"method": "POST",
"ret": "txt",
"paytoqs": "ignore",
"url": "",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 390,
"y": 80,
"wires": [
[]
]
},
{
"id": "6bcf54eee5b8dcca",
"type": "mqtt in",
"z": "193fbdbd9c664d13",
"name": "wal-e message up",
"topic": "application/+/device/7076ff004d040032/event/up",
"qos": "2",
"datatype": "auto-detect",
"broker": "9b5169040f2e5f61",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 190,
"y": 240,
"wires": [
[
"27629ab6b4f065d7"
]
]
},
{
"id": "27629ab6b4f065d7",
"type": "function",
"z": "193fbdbd9c664d13",
"name": "wal-e data unpack",
"func": "const buf = Buffer.from(msg.payload.data, 'base64');\nvar newpayload = {}\nnewpayload.version = buf.readInt16LE(0)\nnewpayload.eventsrc = buf.readInt16LE(2)\nnewpayload.temp = (buf.readInt16LE(4)*0.1)\nnewpayload.hum = (buf.readInt16LE(6)*0.1)\nnewpayload.volt = (buf.readInt16LE(8)/1000.0)\nnewpayload.data = Buffer.from(msg.payload.data, 'base64').toString('hex');\nmsg.payload = newpayload\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 410,
"y": 240,
"wires": [
[
"bedb6d28236f99dd"
]
]
},
{
"id": "bedb6d28236f99dd",
"type": "switch",
"z": "193fbdbd9c664d13",
"name": "",
"property": "payload.eventsrc",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "0",
"vt": "str"
},
{
"t": "eq",
"v": "1",
"vt": "str"
},
{
"t": "eq",
"v": "2",
"vt": "str"
},
{
"t": "else"
}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 590,
"y": 240,
"wires": [
[],
[],
[
"d142ee8d2ab53e58"
],
[]
]
},
{
"id": "d142ee8d2ab53e58",
"type": "change",
"z": "193fbdbd9c664d13",
"name": "",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "button alert",
"tot": "str"
},
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "kerlinkdemo",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 780,
"y": 300,
"wires": [
[
"e7dcbc0b61ccc662"
]
]
},
{
"id": "e7dcbc0b61ccc662",
"type": "subflow:f381210bac9b8559",
"z": "193fbdbd9c664d13",
"name": "ntfy",
"x": 950,
"y": 300,
"wires": [
[]
]
},
{
"id": "a8ef637d8c6bad1c",
"type": "inject",
"z": "193fbdbd9c664d13",
"name": "trigger manually",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "kerlinkdemo",
"payload": "nodered alert",
"payloadType": "str",
"x": 560,
"y": 300,
"wires": [
[
"d142ee8d2ab53e58"
]
]
},
{
"id": "94180ba5574c08a5",
"type": "mqtt out",
"z": "193fbdbd9c664d13",
"name": "wal-e message down",
"topic": "application/4b1cc342-885d-43de-98a7-eb91aae07d88/device/7076ff004d040032/command/down",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "9b5169040f2e5f61",
"x": 440,
"y": 420,
"wires": []
},
{
"id": "7e968cb850874d2b",
"type": "inject",
"z": "193fbdbd9c664d13",
"name": "on",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"devEui\":\"7076ff004d040032\",\"confirmed\":false,\"fPort\":1,\"data\":\"AQ==\"}",
"payloadType": "json",
"x": 250,
"y": 380,
"wires": [
[
"94180ba5574c08a5"
]
]
},
{
"id": "707146799641ee9c",
"type": "inject",
"z": "193fbdbd9c664d13",
"name": "off",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"devEui\":\"7076ff004d040032\",\"confirmed\":false,\"fPort\":1,\"data\":\"AA==\"}",
"payloadType": "json",
"x": 250,
"y": 460,
"wires": [
[
"94180ba5574c08a5"
]
]
}
]
ntfy (pronounced notify) is a simple HTTP-based pub-sub notification service. It allows you to send notifications to your phone or desktop via scripts from any computer, and/or using a REST API.
As a demonstration, we are here using it to send notification from the gateway directly to your end-user device.
In our example we use the
kerlinkdemotopic, but please feel free to adapt the topic to your needs.
Security consideration:
This is for demonstration purpose. Do not use as this in a production environment.
The "Follower" gateway is a gateway which is essentially forwarding collected LoRaWAN frames to a leader gateway hosting the LNS.
If you wish to connect another gateway as a follower, you need to open the MQTT port in the leader gateway.
Execute the following sample in the leader gateway to configure the firewall.
cat > mosquitto.rules << EOF
*filter
-A INPUT -p tcp --dport 1883 -j ACCEPT
COMMIT
EOF
# cleanup empty line
sed -i '/^$/d' mosquitto.rules
mv mosquitto.rules /etc/iptables/iptables.d/
systemctl restart iptables
- name: Allow mqtt conection
groups:
- all
tasks:
- !external
use: copycontent
name: "Open firewall for mosquitto"
params:
dest: "/etc/iptables/iptables.d/mosquitto.rules"
content: |
*filter
-A INPUT -p tcp --dport 1883 -j ACCEPT
COMMIT
- !sd_service
name: Reload firewall
service: iptables
enabled: true
restart: true
Execute the sample from this section edge-computing#install-the-lorawan-forwarder in the Follower gateway.
apt update
systemctl enable lorafwd.service --now
apt install chirpstack-mqtt-forwarder
# Adapt LEADER_IP_ADDR to Hostname or IP of your leader gateway
# LEADER_IP_ADDR=myLeaderGW
# Adapt topic_prefix if needed (us915_0,as923,...)
cat > leader_config.toml << EOF
[mqtt]
topic_prefix = "eu868"
server = "tcp://${LEADER_IP_ADDR:=localhost}:1883"
EOF
# cleanup empty line
sed -i '/^$/d' leader_config.toml
conflex -t -o chirpstack-mqtt-forwarder.toml -T /usr/share/chirpstack-mqtt-forwarder/template.hb leader_config.toml
mv chirpstack-mqtt-forwarder.toml /etc/chirpstack-mqtt-forwarder/chirpstack-mqtt-forwarder.toml
systemctl enable chirpstack-mqtt-forwarder --now
- name: Setup a follower gateway
groups:
- all
defaults:
mqtt:
topic: "eu868"
server: "localhost:1883"
tasks:
- !shell
name: update repo
cmd: apt update
- !sd_service
name: "Activate lorafwd"
service: lorafwd
enabled: true
started: true
restart: true
- !apt
name: Install chirpstack-mqtt-forwarder
package: chirpstack-mqtt-forwarder
- !template
name: Configure chirpstack-mqtt-forwarder
src: /usr/share/chirpstack-mqtt-forwarder/template.hb
dest: /etc/chirpstack-mqtt-forwarder/chirpstack-mqtt-forwarder.toml
- !sd_service
name: Restart chirpstack-mqtt-forwarder
service: chirpstack-mqtt-forwarder
enabled: true
restart: true
Make sure to specify the leader "server": Replace "localhost" by your leader gateway address in our playbook sample, for example with "klk-wifc-XXXXXX:1883.