Sigfox wide-area, low power devices with Ubidots IoT Application Development platform makes for a simple to integrate IoT solution all the way from hardware to the end-user's experience.

By following the steps provided is this tutorial, you will be able to handle and send downlink message to your Sigfox Device from Ubidots. This integration will require the UbiFunctions addon, a featured tool of Ubidots IoT Application Development platform that allows users to great a custom APIs or endpoints for their applications.

If you desire to learn how to manage Uplink messages from the Sigfox Backend to Ubidots, please refer to this guide. :)

Requirements

Step-by-Step

  1. Understanding Sigfox Messages
  2. UbiFunctions configuration
    – Sample Code, Breakdown, and Explanation
  3. Setting up the Sigfox callback to Ubidots 
  4. Checking data integration
  5. Summary

1. Understanding Sigfox Messages

If you are not familiar with Sigfox and the Sigfox Backend, we recommend you checking out this Sigfox Technology Overview before proceeding much further with this guide.

Sigfox allows devices to perform 2-way communication meaning you are able to send uplink messages and also receive downlink messages to/from Ubidots.  

A Downlink message can be transmitted at any time within the limitations of the number of requests based on the Sigfox Subscription; the highest connectivity plan allows 4 downlink messages with a max size of 8 bytes.

Based on this, applications requiring downlink messages are suggested to do so sparingly and sporadically. 

To send a Downlink message to Ubidots, the data will be processes according to the below data-path diagram:

To begin, the Sigfox Device must request to the network that a downlink message be sent. 

In this request, the device transmits an uplink message containing a downlink flag to the Sigfox backend. This flag in the uplink message is in charge of requesting a downlink message from a third party platfrom. 

Then, the Sigfox backend will push the uplink message to Ubidots by using a callback configured to handle data in BIDIR (bidirectional) which is pointing to the URL API endpoint generated by function we will create later in this tutorial with the UbiFunctions engine

At this point, because the uplink was sent with an uplink flag, the same callback configured will also be expecting a data object to be returned to the device from Ubidots. This data object will contain the Sigfox Device ID and therefore will know which hardware will receive the message.

The Sigfox Callback is one feature that when used properly can relay data back and forth to/from Ubidots using an HTTP Request.

For reference, the body of the callback we will configure in this tutorial will have the following structure:

{
"device_id":"{device}"
}

Please, keep in mind that this body can be modified as needed, based on your application's requirements.  

At this point, the body above is going to be received in the UbiFunction engine providing the Sigfox Device ID. With this, Ubidots will identify which device in Ubidots the Sigfox Device ID matches and will automatically update the appropriate data. Further, because Ubidots can recognize and match Sigfox Device IDs with Devices in Ubidots, a single Function will be able to update uplink messages plus send downlink messages to/from multiple pieces of hardware.

To enable the downlink capability, you will need to follow the progession logic below to code the function in the UbiFunctions engine:

  1. Obtain the variable value desired from Ubidots to be sent to the Sigfox device.
  2. Encode the value obtained in the proper data type (HEX).
  3. Return the downlink message expected to the Sigfox backend.

The expected message from the Sigfox backend is:  

{
  '{{deviceId}}': {
'downlinkData':{{data}}
 }
}

As mentioned above, the expected returned data provided from UbiFunction is going to be the Sigfox Device ID (to know to which piece of hardware will receive the message), plus the data desired to be assigned from the downlink message.

Important note: all steps of this tutorial must be followed in order for the Downlink message to be received by the Sigfox backend. 

To clarify the understanding of the Sigfox Downlink messages, please refer to the video below

For a technical explanation of the Sigfox Downlink message, refer to this guide.  

Now, with a basic understanding of how the downlink message need to be created, let's now look at how to configure the UbiFunction to GET a value from Ubidots, encode the expected value in the supported data type, and return the data expected by the Ubidots Backend.

2. UbiFunctions Configuration 

IMPORTANT NOTE: This guide assumes that your Sigfox Device is able to send uplink message to the Sigfox Backend with a flag requesting a downlink message.  

Note:
an UbiFunction is a Node.js cloud function executed when a GET or POST request is made in the Function's URL, as illustrated below. 

1. Create an UbiFunction by going to your Ubidots account –> Device Management –> 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 without any configuration. You will need to configure the function in order to make it work best for your needs. The sample function will not work with Sigfox.

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". Also, it is advisable to relate the name to which kind of message is being triggered; for example, "downlink" can be placed at the end of our function's Name: "Sigfox-Suntech-downlink." 

For this tutorial, the function will be titled "Sigfox-Device-Downlink."  

4. Select POST as HTTP Method and NodeJS 8 as Runtime. With these parameters included, your resulting Function setup will look as follows:

5. Now it 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 the UbiFunction click "Make it live":

Now, the resulting URL endpoint built by the UbidFunctions engine and privately hosted for your Ubidots Application will look a little something like this:

IMPORTANT NOTE: This resulting URL Endpoint is important because it is the endpoint that you will direct your Sigfox callback to send the uplink message that requests the downlink message. If this is confusing, please watch this explainer video.  

As you might have noticed the resulting URL endpoint generated by the UbiFunction is: 

https://parse.ubidots.com/prv/ubidots-tutorials/sigfox-device-downlink

Where, ubidots-tutorial is your Ubidots username and sigfox-device-downlink is the Name assigned to the function within the UbiFuctions engine.

Save the API endpoint URL to be used and assigned later in the Sigfox Callback configuration. 

– Sample Code Breakdown and Explanation

5. Erase the default code located in the UbiFunction editor, then copy and paste the below sample code replacing the default code. After pasting, be sure to assign the following parameters where indicated in the sample code for your function:

var request = require('request-promise');

/* Assign your Ubidots TOKEN */
var TOKEN = "BBFF-Rfcgaxns6HlVb155WA0RhSY85xNDmB";
/* Device Label where the variable desired is located  */
var DEVICE_LABEL = "my-device";
/* Variable Label desired to obtain data (last value) */
var VARIABLE_LABEL = "status";

/**************************************************
 *                MAIN ROUTINE                    *
 **************************************************/
async function main(params) {  
    /* Save device ID of the Sigfox Device */
    var device_id = params.device_id;

    console.log("Retrieving last value");
    /* GET Request to Ubidots - Retrieve last value */
    var var_last_value = await ubidotsGetRequest(DEVICE_LABEL, VARIABLE_LABEL);
    /* Encode the last value received to HEX */
    var hex_value = Buffer.from([var_last_value]).toString('hex');
    /* Complete the 8 bytes downlink data */
    var downlinkData = (Array(16).join('0') + hex_value).slice(-16);

    /* Debuggin messages */
    console.log("Variable last value: " + var_last_value);
    console.log("Last value in HEX: " + hex_value);
    console.log("Donwlink Data to be sent: " + downlinkData);

    console.log("Triggering downlink message");
    /* Return Downlink Data to Sigfox Cloud*/
    return downLink(device_id, downlinkData);
}

/**************************************************
 *                 AUX ROUTINES                   *
 **************************************************/
/*
    Build the Downlink Message to be sent to Sigfox Cloud
    - device_id: Sigfox Device ID
    - downlinkDaTa: Value desired to be sent as Downlink Message
*/
async function downLink(device_id, downLinkData) {
    // Return data to SIGFOX - hardcoding the return data for debugging
    var data = {};
    data[device_id] = { "downlinkData": downLinkData };
    return data;
}

/*
    Build & Handle a GET HTTP request to Ubidots
    - deviceLabel: Device Label where the variable desired is located
    - variable Label: Variable Label desired to obtain data (last value)
*/
async function ubidotsGetRequest(deviceLabel, variableLabel) {
    var options = {
        url: 'https://industrial.api.ubidots.com/api/v1.6/devices/' + deviceLabel + '/' + variableLabel + '/lv',
        headers: {
            "x-auth-token": TOKEN
        },
        json: true
    };
    return await request.get(options);
}

1. The main routine is in charge of receiving the initial uplink data from the Sigfox Backend. As you might have already seen, below the argument of the main routine is the params. This argument will contain the body of the callback configured in the Sigfox Backend.

async function main(params) {
    // Receive and Parse data to be Posted at Ubidots
}

REMINDER: The sample body of the callback is going to be as follows: 

{
  "device_id": "{device}"
}

Please, keep in mind that this body can be modified to fit the requirements of your application.  

Now, inside the main routine of the sample code provided we need to manage the data that will be returned to the Sigfox hardware as a downlink message from Ubidots.

2. The below portion of the sample code, takes the device_id parameter received from the Sigfox Callback and assigns them as temporary shell variables in the UbiFunctions engine. These shell variables are used only to execute the function.

    /* Save device ID of the Sigfox Device */
    var device_id = params.device_id;

Here we can see that the key device_id received in the params object is being assigned to a variable called device_id

The variable device_id is an unique identifier (Sigfox Device ID) per device, assigned by the Sigfox backend, and is based on the underlying hardware handling the message. In this case, the device id is going relate directly to the hardware that is intended to handle the downlink data.

3.  The idea of the downlink message is report a value provided by a variable in Ubidots. For example, the last status of an machine can be sent back as a downlink to the Sigfox hardware. Based on this, the following portion of code is in charge of building and sending an HTTP GET request to Ubidots in order to obtain the last value of the variable that will be sent back to the hardware as a downlink:

    console.log("Retrieving last value");
    /* GET Request to Ubidots - Retrieve last value */
    var var_last_value = await ubidotsGetRequest(DEVICE_LABEL, VARIABLE_LABEL);

You can simply find the ubidotsGetRequest() method after the main function:

/*
    Build & Handle a GET HTTP request to Ubidots
    - deviceLabel: Device Label where the variable desired is located
    - variable Label: Variable Label desired to obtain data (last value)
*/
async function ubidotsGetRequest(deviceLabel, variableLabel) {
    var options = {
        url: 'https://industrial.api.ubidots.com/api/v1.6/devices/' + deviceLabel + '/' + variableLabel + '/lv',
        headers: {
            "x-auth-token": TOKEN
        },
        json: true
    };
    return await request.get(options);
}

3.1.  The last value obtained needs to be encoded into an allowed data type for Ubidots to understand, which is HEX. The following line of code will take the last value of the variable assigned (var_last_value) to encode the decimal result as a HEX

    /* Encode the last value received to HEX */
    var hex_value = Buffer.from([var_last_value]).toString('hex');

3.2. Now, with the last value of the Ubidots variable encoded into HEX, we need assign the value as an 8 byte response. For this, the following portion of code is used: 

    /* Complete the 8 bytes downlink data */
    var downlinkData = (Array(16).join('0') + hex_value).slice(-16);

Here is an example of what a encoded transformation from decimal to HEX looks like: 

  • Before completing the 8 bytes response - hex_value = 01 
  • After completing the 8 bytes response - downlinkData = 0000000000000001 

3.3. [OPTIONAL] If desired, you can uncomment the following portion of code to debug and verify the values which are being encoded and completed:

    /* Debugging messages */

    /*
    console.log("Variable last value: " + var_last_value);
    console.log("Last value in HEX: " + hex_value);
    console.log("Donwlink Data to be sent: " + downlinkData);
    */  

4. Now, with the desired data encoded into the proper format and size, the coded will return the expected response back to the Sigfox Backend. To return the expected data, the donwLink() method is used:

    console.log("Triggering downlink message");
    /* Return Downlink Data to Sigfox Cloud*/
    return downLink(device_id, downlinkData);

Where the downLink() method is in charge of building the expected response which is: 

{
  '{{deviceId}}': {
'downlinkData':{{data}}
 }
}

You can simply find the downLink() method after the main routine: 

/*
    Build the Downlink Message to be sent to Sigfox Cloud
    - device_id: Sigfox Device ID
    - downlinkDaTa: Value desired to be sent as Downlink Message
*/
async function downLink(device_id, downLinkData) {
    // Return data to SIGFOX - hardcoding the return data for debugging
    var data = {};
    data[device_id] = { "downlinkData": downLinkData };
    return data;
}

At this point, if your coded is properly configured you will get the expected response by Sigfox Boackend in the UbiFunction's console:

{
  "2BF076": {
    "downlinkData": "0000000000000001"
  }
}

5.  Now that you have a better idea what the code provided is doing. It's time to save the changes made, and deploy it. To do so, just press the "Make it live." 

With the changes already saved, let's setup the Sigfox Callback to start receiving the data from Ubidots Cloud into the Sigfox Device.  

3. Setting up the Sigfox callback to Ubidots

The management of the data between Sigfox and Ubidots requires a "Callback". 

Sigfox Callbacks use HTTP requests to transmit data bi-directionally with ubidots. In this case, we are going to show how to configure the Sigfox Callback to transmit data from Ubidots to Sigfox Devices by using the UbiFunctions engine previously discussed.

1. To begin, 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. Edit the Device Type by pressing the edit tab located in the right-upper corner of the page:

Set callback as a Downlink: 

To save the changes press "Ok".

4. Next, verify your device information and select "CALLBACKS" from the menu on the left-hand side of the page, as shown below:

At this point, a new callback is needed. To create a new callback, select "New

Select "Custom callback":

Then, in the following window complete the information required with the following parameters in order to setup the callback with your UbiFunction previously created.

  • Type: DATA  - BIDIR    
  • 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-downlink
  • Use HTTP method: POST  
  • Header:  Leave it in  blank 
  • Content Type: application/json    
  • Body:
{
  "device_id": "{device}"
}

After configuring the callback, it should look like this:

Once you've verified the callback, press "OK". 

5. By defautl the BIDIR callback will be inactive after creation. Please activate it, by selecting Downlink check box:

When activated: 

Now your callback is ready and enabled to handle data from Ubidots to Sigfox Devices. At this point, the data is going to be requested by the Sigfox Device and UbiFunction engine (previous step) will return the expected response containing the data desired to be use as downlink message.

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 configure, you will be able of trigger downlink messages from Ubidots to your Sigfox Device.

In this case, the device will send a uplink message requesting the downlink message to Ubidots. To verify if the message was properly triggered by the UbiFunction engine, simply press the "envelop" icon located in the control bar of the function you're looking to track. This will display the logs and executions of your function.

At this point, you will be able to see (refer image below): 

  • The last value of the variable
  • The last value of the variable in HEX
  • The downlink data to be returned
  • Successful message of action 

Finally, the results send to the Sigfox backend will be:

{
    "2BF066":{
        "downlinkData":"0000000000000001"
    }
}

To confirm the downlink message was received, select "messages" from the Device ID tab:

In the messages section you will be able to see the uplink message requesting the downlink, plus the downlink message received:

  • Uplink message requesting downlink message: 
  • Donwlink message received: 

At this point, your Sigfox hardware will show the data received in the downlink message. Below you can see the logs provided from the device previously configured: 

Now is your turn to send and receive data using Sigfox's backend. :)

5. Summary  

With this, your Sigfox Callback is ready and the UbiFunction is properly transmmiting data from Ubidots to your Sigfox Devices. Now it is time to develop your application with Ubidots IoT application development and deployment tools.

Ubidots is an Internet of Things (IoT) Application Development Platform that empowers system integrators and innovators to launch control, monitoring, and automation applications that turn sensor data into actionable insights. Hiring an engineering team to merge the physical world with a digital world and create an IoT application that both function and look great is costly in both time and money, so Ubidots did it for you. Ubidots exists as an efficient and economical resource to develop private cloud-based IoT applications and integrate data-driven solutions into enterprises and research to drive-decisions and improve our working economy.

Other users also found useful:

Did this answer your question?