Sigfox wide-area, low power devices with Ubidots IoT Application Development platfrom makes for a simple to integrate IoT solution all the way from hardware to the end-user's experience. Built applications in Ubidots to track and monitor assets (cars, busses, trash cans, or even your golf-bag) across long ranges.
By completing this tutorial, following each step closely, you will be able to communicate data from the Sigox backend to Ubidots when the data can be put to work as a solution. This integration will require the UbiFunctions addon, a feature tool of Ubidots IoT Application Development platform that allows users to great a custom API or endpoint for their application.
Requirements
Ubidots Account with an IoT Entrepreneur license o greater.
Any Sigfox Device (Already transmitting data to Sigfox Backend)
1. Understanding Sigfox Messages
If you are not already familiar with Sigfox and the Sigfox Backend, we recommend to check this Sigfox Technology Overview before proceeding much further with this guide.
Let's begin by looking at the messages structure of a Sigfox device. As you might already know, the Sigfox network allows to send (uplink) up to 12 bytes per message with a maximum number of 140 messages per day.
At this point, it's important to clarify that Sigfox devices transmit data in different payload structures depending on the device manufacturer. It is suggested to review the datasheet provided by the manufacturer in order to understand the coded payload and its structure and how it should be decoded prior to be posted to Ubidots.
For testing purposes, let's assume that your Sigfox Device is going to send the data using the following sample payload structure to Ubidots:
Sample data from Sigfox Device:
4fc1b6c81cc23c5514
Where are the bytes? And, how do we understand the payload?
0x4F
- Temperature - Bytes #0 (1 byte)0xC1B6C81C
- Latitude - Bytes #1 - #4 (4 bytes)0xC23C5514
- Longitude - Bytes #5 - #9 (4 bytes)
Total of bytes = 9
If you already don't see it, let me highlight that the device is sending temperature and coordinates data to Ubidots. This data is interpreted, understood, and securely decoded by the Sigfox backend.
Now assuming that the data above is received in the Sigfox Backend, it's time to setup a Callback. The Sigfox Callback is the feature that when used properly can relay data to Ubidots Cloud using the HTTP protocol.
For this guide, we are going to send basic parameters such as the device id and the data received in bytes to Ubidots. Then, using the UbiFunctions feature will parse and decode the payload structure into an Ubidots-supported data structure. Now based on this, the body of the callback should have the following structure:
{
"device_id": "{device}",
"data":"{data}"
}
Now, with a basic understanding of a Sigfox payload, let's now look at how to configure the UbiFunction to decode the payload coming from Sigfox, plus how to setup the callback in Sigfox's backend to ensure data securely reaches your Ubidots account.
2. UbiFunctions Configuration
IMPORTANT NOTE: This guide assumes that your Sigfox Device is able to transmit data to the Sigfox Backend.
Note: An UbiFunction is a Node.js or Python cloud function executed when a GET or POST request is made in the Function's URL, as illustrated below.
1. Go to UbiFunctions module by going to your Ubidots account –> Devices –> Functions.
NOTE: If you cannot see the "Functions" module in your account's menu, you will need to enable the $29/month add-on in the billing section of your account.
2. Click the blue "+" icon in the upper-right corner to create a new function:
3. By default, every Ubifunction is populated with a sample code. Now you need to configure the function in order to make it work best for your needs.
The default configurations for the function are as shown below:
To begin, assign the name desired for your UbiFunction. We recommend using the format "Brand-Reference", i.e. "Sigfox-Suntech", "Sigfox-Oyster" or "Sigfox-Thinxtra". For this example, we are going to assign "Sigfox-Device" as the name.
Then, select POST as HTTP Method, and select between NodeJS 10, Python 3.6 or Python 3.7 as Runtime. For this example, we’ve chosen NodeJS 10. Thus far, your resulting Function setup should look like as follows:
4. Now is time to deploy the UbiFunction in order to generate the API endpoint URL which is going to be used to transmit the data from the Sigfox Backend to Ubidots.
To deploy it click on "Make it live":
Now the resulting URL endpoint will look a little something like this:
IMPORTANT NOTE: Keep this URL Endpoint in your clipboard as you will use it when setting the Sigfox callback.
5. Erase the default code located in the UbiFunction editor, then copy and paste the below sample code. After pasting, be sure to assign your Ubidots TOKEN where indicated:
var request = require('request-promise');
/* Assign your Ubidots TOKEN */
var token = "YOUR-UBIDOTS-TOKEN-HERE";
var url_Base = "https://industrial.api.ubidots.com";
/**************************************************
POST Request to Ubidots *
*************************************************/
async function ubidotsPost(token, device_label, data) {
var options = {
method: 'POST',
url: url + '/api/v1.6/devices/' + device_label,
body: data,
json: true,
headers: {
'Content-Type': 'application/json',
'X-Auth-Token': token
}
};
return request.post(options);
}
/**************************************************
* MAIN FUNCTION *
+************************************************/
async function main(args){
console.log(args);
/* Save device ID of the Sigfox Device */
var device_id = args.device_id;
/* Save data received from Sigfox */
var buf = new Buffer(args.data, 'hex');
/* Parse the incoming data */
var temp = buf.readInt8(0);
var lat = buf.readFloatBE(1);
var lng = buf.readFloatBE(5);
/* Uncomment lines below to debug the values decoded */
/*
console.log(temp);
console.log(lat);
console.log(lng);
/
/* Build body to be POST at Ubidots */
var payload = {"temperature": temp, "position": {"value":"1", "context":{"lat": lat, "lng":lng}}};
/* Make POST request to Ubidots */
var post_response = await ubidotsPost(url_Base, token, device_id, payload);
/* Pass Ubidots' API response to the functions' response */
return post_response;
}
– Sample Code Breakdown and Explanation
1. First of all, we need to set the function that will send the data to Ubidots by executing a HTTP POST request. To this, we will use ‘request-promise’ that is a simple HTTP request client for NodeJS.
async function ubidotsPost(url, token, device_label, data) {
var options = {
method: 'POST',
url: url + '/api/v1.6/devices/' + device_label,
body: data,
json: true,
headers: {
'Content-Type': 'application/json',
'X-Auth-Token': token
}
};
return request.post(options);
}
2. The main function is in charge of receiving data from the Sigfox Backend. As you may have noted, the argument of the main function is ‘args
’; this argument will contain the body of the callback configured in the Sigfox Backend.
async function main(args) {
// Receive and Parse data to be Posted at Ubidots
}
REMINDER: The sample body of the callback is going to be the one below:
{
"device_id": "{device}",
"data":"{data}"
}
Now, inside the main function we need to manage the data received. This part of the code is going to be different depending on the hardware and its data structure payload.
Assuming our sample data (Temp and Coordinates) is on the Sigfox Backend, we will now look at how to decode the payload into an Ubidots supported format, using the UbiFunctions engine to transform/parse the data.
2.1. The below portion of the sample code, takes the parameters received from the Sigfox Callback and assigns the device_id as a temporary variable and the hex data as a hex buffer.
/* Save device ID of the Sigfox Device */
var device_id = args.device_id;
/* Save data received from Sigfox */
var buf = new Buffer(args.data, 'hex')
The variable device_id is an unique identifier (Sigfox Device ID) per device, assigned by the Sigfox backend, and based on the underlying piece of hardware sending the sensor data.
Note: Since the Sigfox ID is unique, multiple devices can be deployed using the same UbiFunction as it will be assigend as the device label in Ubidots.
2.2. Then, the variable ‘buf’ have to be parsed to get the desired variables. To this, you need to split the bytes based on the datasheet from the device's manufacturer.
In this case, the structure used in this tutorial is:
0x4F - Temperature - Bytes #0 (1 byte)
0xC1B6C81C - Latitude - Bytes #1 - #4 (4 bytes)
0xC23C5514 - Longitude - Bytes #5 - #9 (4 bytes)
Accordingly, the bytes are to be split in the following portion of the sample code. Remember that depending on your hardware, this is where your code will reflect the data you wish to POST in the payload to Ubidots.
/* Parse the incoming data */
var temp = buf.readInt8(0);
var lat = buf.readFloatBE(1);
var lng = buf.readFloatBE(5);
2.3. [OPTIONAL] In order to debug and verify the decoded variables, please uncomment the following portion of code.
/*
console.log(temp);
console.log(lat);
console.log(lng);
*/
2.4. With the values already decoded by Ubifunctions, it's time to build the JSON body of the HTTP Request to be POST in your Ubidots Account, according to our API documentation.
Please note that based on the Sigfox hardware used in your Application, you must modify the following portion of the sample code to fit the variable label and values to be sent:
/* Build body to be POST at Ubidots */
var payload = {
"temperature": temp,
"position": {
"value":"1",
"context":{
"lat": lat,
"lng": lng
}
}
};
As you might have noted above, the body contains a variable called temperature with a value of "temp", plus a variable called position with the respective coordinates (latitude and longitude) assigned as the context of the variable.
For additional details on how to handle values, context, or timestamps keys please refer to the
Ubidots REST API Reference.
2.5. Now, it’s time to call the ubidotPost function, which is the function that will send execute the POST request, thus sending the data to your Ubidots account.
/* Make POST request to Ubidots */
var post_response = await ubidotsPost(url_Base, token, device_id, payload);
2.6. To finish let's talk about the last portion of the main function. This portion of code will return the status of the request:
return post_response;
At this point, if everything is properly configured you will get the following 201 successful response:
{
"position":[{"status_code":201}],
"temperature":[{"status_code":201}]
}
If you get a different response code, please refer to our API documentation in order to know its meaning.
3. Now that you have a better idea what the code provided is doing, it's time to save the changes, and deploy it. To do so, just press the "Make it live" button.
With the changes already saved, let's setup the Sigfox Callback to start receiving the data at the Ubidots Cloud.
3. Setting up the Sigfox callback to Ubidots
The management of the data between Sigfox and Ubidots requires a "Callback".
The Sigfox hardware will read sensors and send the values (message) to a Sigfox Base Station to be forwarded to the Sigfox Backend. At this point, your data is already in the cloud (on the internet), so now it's time to make this message valuable using an IoT Application Enablement platform like Ubidots using Sigfox Callback.
Sigfox Callbacks use HTTP requests to transmit data bi-directionally with any cloud service. In this case, we are going to show how to configure the Sigfox Callback to transmit the data to Ubidots.
1. To start with, access to the Sigfox Backend where the hardware is transmitting data.
2. Go to the Device section and select the Device Type of the registered device:
3. Next, verify your device information and select "CALLBACKS" from the menu on the left-hand side of the page, as shown below:
Sigfox callbacks allow you to report data to an external system like Ubidots. To setup a callback to Ubidots API, use the following parameters:
Type:
DATA
-UPLINK
Channel:
URL
Custom payload config: Leave it in blank
Url pattern: This is the URL generated by the UbiFunction in the steps above
https://parse.ubidots.com/prv/ubidots-tutorials/sigfox-device
Use HTTP method:
POST
Header: Leave it in blank
Content Type:
application/json
Body:
{
"device_id": "{device}",
"data":"{data}"
}
After configuring the callback, it should look like this:
IMPORTANT NOTE: In order to avoid authentication issues between the Sigfox callback and Ubidots, make sure to check the “SEND SNI” option.
Once you've verified the callback, press "OK".
At this point, the data is going to be decoded based on the code already configured in the Ubifunctions engine, then post the data to your Ubidots account.
IMPORTANT DEPLOYMENT NOTE: Ubidots and Sigfox communicate via either URL or Batch URL (used for large deployments). This tutorial explains the standard URL channel. If you have a large scale sensor network, please contact sales@ubidots.com to receive additional information for Batch URL integrations.
4. Checking data integration
With the Ubifunction and Sigfox Callback already configured, after the hardware updates a new value, you will notice that a new device was automatically created in your Ubidots account. If the device already exists, it will be updated.
Go to the Device section of your Ubidots account and confirm that the new device(s) were created.
[TIP] - Don't like the Sigfox Device ID as your device's name in your Ubidots display? Don't worry! You can change the name to a more friendly one, but the device label will be stay as the Sigfox Device ID to never get confused which device is which. Reference to Ubidots Help Center for more on Device Labels and Device Name changes in Ubidots.
2. [OPTIONAL] If desired or needed, you are able to see the logs for each Ubifunction triggered. To find the logs, simply press the "envelop" icon located in the control bar of the function you're looking to track
As you can see below, the logs provide both the time of execution and output values received from the Function.