Skip to main content
All CollectionsUser Guides
Analytics: UbiFunctions User Guide
Analytics: UbiFunctions User Guide

Use UbiFunctions' serverless computation environment to extract, transform, schedule, and analyze data.

Sergio M avatar
Written by Sergio M
Updated over 3 months ago

UbiFunctions is a serverless computing environment designed for IoT applications, eliminating the need for additional servers. This guide will walk you through the use of UbiFunctions to enhance your Ubidots experience, whether by extracting data from third-party APIs, customizing HTTP API gateways, or transforming and analyzing sensor data.

Requirements

1. Creating an UbiFunction

Go to Ubidots Devices Functions.

Click the "+" button:

1.1. Default example

By default, every new UbiFunction is populated with a sample code that uses input data (token, device, & temp value) to make a request to Ubidots’ API. This sample code demonstrates a simple HTTP GET endpoint that receives an Ubidots token, a device label, and a temperature value as URL parameters, then uses this data to make an HTTP POST request to Ubidots’ API.

You can actually test the sample function by clicking on the “save & deploy” button, then paste the following URL into your web browser (updating the username and token of your account).

2. Coding the UbiFunction

Suppose that you have a fleet of several different devices on an LNS constantly sending data. On each uplink, you require to decode that data and then forward it to the corresponding device in Ubidots.

For this, you can create an UbiFunction and forward all the LNS data to it by using its URL. Here you'll have separate scripts for each device's type decoder and properly use them from the main function.

For the example, proceed to create:

  • A folder called modules.

    • Within the modules folder, create a Python script called s2100.py. This is the decoder for the s2100 device.

    • Within modules folder, create a Python script called s210x.py. This is the decoder for the s210x device.

    • within modules folder, create a Python script called utils.py. This one will contain all utils scripts.

  • A configuration file containing the configuration for each device type. This one is called device_config.json.

s2100.py

def s2100_decode(data: int) -> dict:
"""Decode data for s2100 device."""
temperature = (data & 0x3) >> 0
humidity = (data & (0x3 << 2)) >> 2
battery = (data & (0x3 << 4)) >> 4

return {
"temperature": temperature,
"humidity": humidity,
"battery": battery
}

s210x.py

def s210x_decode(data: int) -> dict:
"""Decode data for s210x device."""
soil_electrical_conductivity = (data & 0x3) >> 0
battery = (data & (0x3 << 2)) >> 2

return {
"soil_electrical_conductivity": soil_electrical_conductivity,
"battery": battery
}

utils.py

def parse_data(data_str: str) -> int:
"""Convert a binary string to an integer."""
return int(data_str, 2)

device_config.json

{
"s2100" : {"color" : "#fefefe"},
"s210x" : {"color" : "#ffffff"}
}

main.py

import requests
import time
import json
import os
from modules.utils import parse_data
from modules.s2100 import s2100_decode
from modules.s210x import s210x_decode

decoders = {
"s210x" : s2100_decode,
"s2100" : s210x_decode
}

def main(args):

"""Decode payload based on device type."""
device_type = args.get("device")
data_str = args.get("data")

if not device_type or device_type not in decoders:
print(f"Device type: {device_type} not supported...")
return {"status" : "error"}

# Convert binary string to integer
data = parse_data(data_str)
decoded_data = decoders[device_type](data)

# Open and read the JSON file
with open("device_config.json", 'r') as file:
config = json.load(file)

print(config[device_type])
print(decoded_data)
return {"status" : "success" , "data" : decoded_data}


This is how it should look like:​

If you execute this UbiFunction with the following test payload, it should output something like this:

Test payload:

{"device": "s2100", "data": "0b01011010"}

UbiFunction's output:

{'color': '#fefefe'}
{'soil_electrical_conductivity': 2, 'battery': 2}

3. Running the UbiFunction

During the development process, you will want to test your function to see if you are on the right track towards the desired output. To do so, click on the "save & run test” button. This will bring up a modal screen requesting some input data to test it with. Enter a JSON dictionary of sample inputs if required. The console will display the function’s output and logs. You may leave this blank if your function does not require an input.

In the case of Ubidots' default sample function, enter the below JSON payload containing the parameters you look to pass through the HTTP GET request:

{
"token":"your-token",
"Device":"sample-function",
"Temperature":"45"
}

After clicking on the "save" button, a console window will emerge with both the function’s output and the logs of the results:

  • Function’s output: This is what your function returns. It must be in a JSON dictionary format. In your code, make sure to use "return" to quit the function and return the dictionary.

  • Logs: This is used for debugging purposes. Use console.log("hello") to leave trails in this console.

Note: For your function to be fully deployed after clicking on the “save & deploy” button, wait some time (about 10 seconds are usually enough).

Did this answer your question?