The ChirpStack open-source LoRaWAN Network Server stack provides open-source components for LoRaWAN networks. Together they form a ready-to-use solution including an user-friendly web-interface for device management and APIs for integration.
Following this guide, you will be able to decode the data from ChirpStack and forward it to Ubidots.
Requirements
An active ChirpStack account.
LoRaWAN gateway and devices already transmitting data to ChirpStack.
1. Integration Workflow
To upstream the data located in ChirpStack server to Ubidots, it is necessary to make an HTTP cloud-to-cloud integration. This integration requires to convert the ChirpStack output JSON format into an Ubidots-compatible. The process of parsing the data can be achieved using the Ubidots Functions as a Service (FaaS) module, called UbiFunctions, where the ChirpStack’s native JSON format is taken and transformed into an Ubidots API compatible one.
2. Ubidots UbiFunction Decoder Setup
Follow the steps below to create and launch the UbiFunction which will handle ChirpStack’s native JSON format conversion into an Ubidots-compatible one:
Step 1: Go to the Functions module found under the Devices tab.
Step 2: Click the “+” icon or select the button “Create Function” to create a new UbiFunction in your account.
Step 3: Assign a name to the UbiFunction, e.g., “ChirpStack Integration”. Then, assign POST as the HTTP Method and choose Python or NodeJS as runtime programming language. Press the blue button called “Make it live” and the HTTPs endpoint URL will be generated.
NOTE: Leave the “Time-based trigger” option disabled.
Step 4: Copy and paste the code below into the Ubidots Function's code editor. Please select the code accordingly with the runtime programming language.
Python:
import requests
import time
import base64
import json
BASE_URL = "https://industrial.api.ubidots.com"
REQUESTS_FUNCTIONS = {"get": requests.get, "post": requests.post}
def main(args):
print(args)
token = args.get("token")
device_label = get_device_label(args)
payload = json.loads(args.get("objectJSON"))
req = update_device(device_label, payload, token)
return {"status_code": req.status_code, "res": req.json()}
def get_device_label(data):
label_b64 = base64.b64decode(data.get("devEUI"))
return label_b64.hex()
def update_device(device, payload, token):
url = "{}/api/v1.6/devices/{}".format(BASE_URL, device)
headers = {"X-Auth-Token": token, "Content-Type": "application/json"}
req = create_request(url, headers, payload, attempts=5, request_type="post")
return req
def create_request(url, headers, data, attempts, request_type):
"""
Function to create a request to the server
"""
request_func = REQUESTS_FUNCTIONS.get(request_type)
kwargs = {"url": url, "headers": headers}
if request_type == "post":
kwargs["json"] = data
try:
req = request_func(**kwargs)
print("[INFO] Request result: {}".format(req.text))
status_code = req.status_code
time.sleep(1)
while status_code >= 400 and attempts < 5:
req = request_func(**kwargs)
print("[INFO] Request result: {}".format(req.text))
status_code = req.status_code
attempts += 1
time.sleep(1)
return req
except Exception as e:
print("[ERROR] There was an error with the request, details:")
print(e)
return None
NodeJS:
const axios = require('axios');
async function main(args) {
console.log(args);
// Get token
var token = args.token;
// Get Device Label
var label = args.devEUI;
// Decode data
var buff = Buffer.from(label, 'base64');
var device_label = buff.toString('hex');
console.log(device_label);
var payload = args.objectJSON;
console.log(payload);
// Send the payload to Ubidots
var response = await ubidots_request(token, device_label, payload);
// Log Ubidots response to the console
console.log(response);
// Pass Ubidots' API response as the function's reponse
return response;
}
// This function builds an HTTP POST request to Ubidots
async function ubidots_request(token, device_label, payload) {
let config = {
method: 'post',
url: 'https://industrial.api.ubidots.com/api/v1.6/devices/' + device_label,
data: payload,
headers: {
'Content-Type': 'application/json',
'X-Auth-Token': token
}
}
const response = await axios.request(config);
return response.data;
}
Step 5: Copy the “HTTPS Endpoint URL” by clicking the “Copy” icon and save it for later.
3. ChirpStack HTTP Integration
Once the UbiFunction is setup, you can proceed to complete the integration to start forwarding data to Ubidots. Please follow the next steps that will guide you through this process:
Step 1: Click “Applications” and select the option “CREATE”.
Step 2: Enter an Application name, Application description and select the service-profile. Then click the button “CREATE APPLICATION”.
Step 3: Go to the newly created Application and enter the tab “INTEGRATIONS”.
Step 4: Choose the HTTP option and enter the following information:
- Payload marshaler: JSON
- Headers: “X-Auth-Token”: Your Token.
- Endpoints: HTTPS Endpoint URL saved from the last section.
After completing this process, you will be able to start seeing your ChirpStack devices getting created in your Ubidots account and reporting data as it becomes available.