This article offers an introduction to UbiFunctions, covering its key features, user interface, and basic usage to help you get started with enhancing your Ubidots experience.
Requirements
An Ubidots account with Industrial plan (or higher).
An Enterprise plan is required to use Global Properties in UbiFunctions.
1. What is an UbiFunction?
An UbiFunction is a user-defined set of functions bundled together that executes specific logic on demand. It can be triggered in two main ways:
HTTP Request: By making an HTTP GET or POST request to the UbiFunction's URL.
Scheduled Execution: Based on a predefined repeat interval.
An UbiFunction is structured as follows:
Modules: These are the building blocks that your function uses. They contain reusable code and functionality.
Entrypoint: This is the main function that serves as the starting point for executing your business logic. In the context of UbiFunctions, this entrypoint is called
main
.
2. When to use UbiFunctions?
You can use UbiFunctions to extend Ubidots’ capabilities with your custom logic. Most use-cases fall into the following three categories:
Extracting data from 3rd party APIs
Customizing your own HTTP API gateway
Transforming and analyzing sensor data
2.1. Extracting data from 3rd party APIs
Most web applications have an API and in most cases, you’ll be able to access your data programmatically without much difficulty.
You can use UbiFunctions to turn on or off a Bitcoin cluster based on the Bitcoin/energy price relationship or analyze the relationship between commodity prices and weather conditions.
Weather data extraction example:
AmbientWeather devices → AmbientWeather Cloud → Ubidots (see example)
2.2. Customizing your own HTTP API gateway
In cases where HTTP communication with Ubidots is problematic or changing HTTP methods, payloads, or URLs is difficult, UbiFunctions allows you to create custom HTTP APIs to ingest and transform data to fit Ubidots’ expected formats.
LoRaWAN Devices --> Comcast machineQ Platform --> Ubidots (show me how)
LoRaWAN Devices --> The Things Network --> Ubidots (show me how)
Sigfox Devices -->Sigfox Cloud --> Ubidots (show me how)
2.3. Transforming and analyzing sensor data
With UbiFunctions, you have access to many Python and Node.js libraries for data transformation and analysis.
Here some possible use-cases for data transformation and analysis:
Assign a GPS location to your devices, based in the neighboring Wi-Fi routers or cell tower IDs. See an example.
Assess the probability of an accident in the shop floor, based on a worker's properties (i.e., city, production process, shift) and a machine's variables (i.e., speed, temperature, pressure, vibration).
3. Understanding the function’s module
3.1. UbiFunctions table
Access the UbiFunctions module from "devices" → "functions":
Once the page loads, you'll see a table with all your previously created functions (in case you have created some, that is) and the button to create a new one:
The functions’ table has the following characteristics:
A search bar to find specific functions based on their name.
The name of your functions.
The date in which the functions were created.
The functions’ URL.
A button (represented with three dots) next to each function with the following options:
Logs: Detailed information about your function’s executions. Logs are explained below in this guide.
Edit: Functions can be modified using this option.
Disable: Used in case you need to temporarily turn off your function, but wish to keep it for later use.
Delete: Used to permanently delete your function.
By clicking on the “+” or the edit buttons, you’ll access the function and its configuration. Every function is divided into three major tabs which are explained below.
3.2. UbiFunction's main view
Functions have 3 tabs or sections:
Code editor
Function's settings
Function's logs
3.2.1. Code editor
The code editor has the following features:
HTTP method drop-down menu: Use it to make either GET or POST requests. This option is also located in the function’s settings.
Function’s URL: Always available to be easily copied.
Save & Run Test button: Test your function with a dummy JSON.
Save & Deploy button: Once your function is ready, save your latest changes and deploy it.
Dark mode button: Change the background color of the code editor between light and dark mode.
Files visibility button: Expand or collapse the files pane.
Runtime: Choose from the available options of Python or Node runtimes. This option is also located in the function’s settings.
Code editor area: This is where you write code.
Files Pane: If enabled, the UbiFunction's files and folders will be shown here. By clicking the "+" icon, you'll be able to create a new file or a folder. Additionally, using the 3 dots button, you can rename and delete files or add files or folders (within a folder).
3.2.2 Function's settings
The following are the available settings to define how a function works:
Name: Your function’s identifier. Keep in mind this name will later become part of the function's URL. The URL can’t be changed later, even if the function’s name is modified.
Runtime: The version of Python or Node that you choose to run your function with will define, to a large extent, what your function will be able to do. Check the available runtimes and the libraries that are supported for each one of them in this guide.
HTTP method: Either GET or POST can be chosen as the method. A GET method is used to request data from a specified resource, while POST is used to send data to a server to create/update a resource.
HTTPS endpoint URL: Here goes the URL of the 3rd party platform to which you'll make the requests.
MQTT host: Send data to this function using MQTT
MQTT username: Achieve MQTT authentication using the username displayed in this field and one of your tokens as the password.
MQTT topic: Payloads received in this topic will be forwarded to this function
Token: You can use the drop-down menu to select the token that will authenticate your requests. You can call in your function’s code using the token key; this spares you from having to copy-paste API tokens in the code directly.
Environment variables: Select any number of environment variables you have previously created through the Global Properties module. With these properties, you can easily store global variables to speed development and keep resources organized. Follow the Global Properties guide to learn how to use them.
Max execution time: If a function isn't executed within this time, it's terminated and a 502 response is generated. By default, this time is 10 seconds and can be increased depending on your plan, as follows:
Entrepreneur: Up to 30 seconds.
Professional: Up to 30 seconds.
Industrial: Up to 60 seconds.
All Enterprise tiers: Up to 60 seconds.
Time-based trigger: If you need your function to run at periodic time intervals, define a time-based trigger, expressed in minutes. The minimum value is 1 and the maximum is 60.
Crontab expression: Specify, based on the date/time, the frequency at which the functions will be executed.
Raw function: Use raw functions to achieve an advanced level of customization. Raw functions allow you to:
Use a custom endpoint path.
Receive and respond custom headers.
Set custom response codes.
Receive and respond custom content-type headers for the request body and response.
Receive any type of data structure (object, string, array, images, etc.). Keep in mind, however, that it will be parsed to a string. Normal functions (those that don’t use raw) can only receive JSON in their bodies.
CORS policy: Used to enable the function being called from web browser's URLs different from parse.ubidots.com.
Notes:
Functions can have "max execution times" above 60 seconds if it's agreed upon between the user and Ubidots. However, if one of this "special" functions takes over 60 seconds to be executed (even with it's higher “max execution time”), it becomes asynchronous. This means that the function will run, but Ubidots won’t wait for its response; the response of an asynchronous function will be available in its logs.
If you require higher execution times, reach out to us at sales@ubidots.com
3.2.3 Function's logs
The logs’ page is divided into two sections, the left pane and the content area. In them, you’ll find the following information.
Logs’ list: Located in the left pane, you’ll find the list of logs of all the executions of your function. Each item of the list contains the date and time of the execution, the execution’s ID, and the function’s execution time. Every item of the list can be clicked to access more information.
Results: Located in the content area, the results of the function’s return statement will be displayed in this field. If your function doesn’t have a return statement, a “null” message will be displayed.
Output: Located below the results field, whatever your function prints will be displayed here. Also, server messages will be displayed here as well when an error occurs on the server side or the function times out.
4. Technical Details
4.1. Runtimes
UbiFunctions support either NodeJS LTS or Python3. This means you can use either JavaScript (Node.js) or Python, but not both simultaneously.
4.2. Function's arguments
The UbiFunction main script receives the arguments as a dictionary labeled "args", which you can then access in your code to execute the desired logic.
4.3. Code modularity
As stated before, UbiFunctions allows you to use multiple files:
Source files: These files contain code that can be executed.
Config files: These are tipically JSON or .conf files whose content is not executable code but data and parameters required by your logic.
Data files: For example a .CSV file.
4.4. UbiFunction's return
An UbiFunction must always return a dictionary, returning a single variable is not allowed:
Function return | Allowed |
| Yes |
| No |
4.5. UbiFunction's entry point
Every UbiFunction must define a script called main (independently of the runtime, albeit conserving the proper extension) that will act as an entry point for the overall logic. This script should make use of all the modules, utils and configuration files defined in the UbiFunction in order to execute the required logic.
4.6. Supported libraries
To know what libraries are currently supports by UbiFunctions, please check this article UbiFunctions & Plugins: Supported libraries.
5. More use cases
5.1. Data Extraction
With UbiFunctions, you can run periodic code executions to query 3rd party APIs for data extraction. Each execution can be programmed to run every "x" amount of minutes, erasing the need to set up and maintain a cron script in a virtual server or Raspberry Pi.
To schedule a data extraction function, simply select the option "Run every" in the left side of the screen
5.2. Data Parsing
Data Parsing refers to the process of breaking a data block into smaller chunks by following a set of rules, so that it can be inserted to Ubidots in its expected JSON packets using HTTP.
With UbiFunctions, you can create your own API endpoint to ingest IoT data from devices or external web services. Here's a list of common scenarios:
Sigfox Devices → Sigfox Cloud → Ubidots
Particle Devices → Particle Cloud → Ubidots
mcThings Devices → mcCloud → Ubidots
LoRaWAN Devices → The Things Network → Ubidots
LoRaWAN Devices → LoRaWAN Network Server → Ubidots
NB-IoT Devices → T-Mobile Cloud → Ubidots
While most of the above platforms are flexible enough to set up HTTPS webhooks or callbacks in the JSON format expected by Ubidots API, there might be instances where additional processing is required, and we designed UbiFunctions just for these instances.
Parsers are most commonly programmed using Node.js. The below diagram shows a common scenario where IoT devices send data to a manufacturer-specific cloud, which is then relayed to a parser using HTTP:
5.3. Data Science
Besides Node.js, UbiFunctions can also be programmed in Python. With Python 3 support, UbiFunctions allow you to run statistics and machine learning methods to analyze your data and insert key output metrics to Ubidots.
Our Python runtime includes the most popular data science libraries:
NumPy
Pandas
SciKit-Learn
These libraries give you the data-types (vectors, matrices and data frames) and tools to organize and understand your data.
6. Billing of UbiFunctions
UbiFunctions are included in Industrial plans and above.
Executions are timed-out after 30 or 60 seconds, based on your plan. If you wish to extend this time, please reach out to our support team.
If any execution surpasses 2 seconds; it is counted as 2 executions (or more, based on time length of the execution)
Executions are billed at increments of $5 per million executions.