The **calculate()** function is user-defined script that takes values of arguments configured in the calculated field setup and an additional `ctx` object containing all arguments.
The **calculate()** function is a user-defined script that allows you to perform custom calculations using [TBEL{:target="_blank"}](${siteBaseUrl}/docs${docPlatformPrefix}/user-guide/tbel/) on telemetry and attribute data.
The **calculate()** function is a user-defined script that allows you to perform custom calculations using [TBEL{:target="_blank"}](${siteBaseUrl}/docs${docPlatformPrefix}/user-guide/tbel/) on telemetry and attribute data.
It receives user-configured arguments and an additional `ctx` object, which provides access to all arguments.
It receives arguments configured in the calculated field setup and an additional `ctx` object, which provides access to all arguments.
##### Function signature
##### Function signature
@ -11,48 +9,11 @@ It receives user-configured arguments and an additional `ctx` object, which prov
function calculate(ctx, arg1, arg2, ...): object | object[]
function calculate(ctx, arg1, arg2, ...): object | object[]
```
```
* the function automatically receives a `ctx` object containing all arguments.
##### Argument representation in the script
* user-defined arguments `(arg1, arg2, ...)` are passed based on the calculated field configuration.
* the function must return a JSON object (single result) or an array of objects (multiple telemetry entries).
##### Example: Air Density Calculation
This example demonstrates how to calculate air density using altitude and temperature telemetry data.
```javascript
function calculate(ctx, altitude, temperature) {
var avgTemperature = temperature.mean(); // Get average temperature
var temperatureK = (avgTemperature - 32) * (5 / 9) + 273.15; // Convert Fahrenheit to Kelvin
* `mergeAll(others, settings)` - merges the current rolling argument with multiple rolling arguments by aligning timestamps and combining values.
| `merge(other, settings)` | Merges the current rolling argument with another rolling argument by aligning timestamps and filling missing values with the previous available value. | <ul><li>`other` (another rolling argument)</li><li>`settings` (optional) - configuration object, supports:<ul><br/><li>`ignoreNaN` (boolean, default true) - controls whether NaN values should be ignored.</li><li>`timeWindow` (object, default {}) - defines a custom time window for filtering merged values.</li></ul></li></ul>| Merged object with timeWindow and aligned values. |
Parameters:
| `mergeAll(others, settings)` | Merges the current rolling argument with multiple rolling arguments by aligning timestamps and filling missing values with the previous available value. | <ul><li>`others` (array of rolling arguments)</li><li>`settings` (optional) - configuration object, supports:<ul><br/><li>`ignoreNaN` (boolean, default true) - controls whether NaN values should be ignored.</li><li>`timeWindow` (object, default {}) - defines a custom time window for filtering merged values.</li></ul></li></ul>| Merged object with timeWindow and aligned values.|
* `others` - an array of time series rolling arguments to merge with.
* `settings` (optional) - same as `merge()`.
**Example arguments:**
Returns: an object with timeWindow and aligned values.
```json
```json
{
{
"humidity": {
"humidity": {
"timeWindow": {
"timeWindow": {
"startTs": 1741356332086,
"startTs": 1741356332086,
"endTs": 1741357232086
"endTs": 1741357232086
},
},
"values": [{
"values": [{
"ts": 1741356882759,
"ts": 1741356882759,
"value": 43
"value": 43
}, {
}, {
"ts": 1741356918779,
"ts": 1741356918779,
"value": 46
"value": 46
}]
}]
},
"pressure": {
"timeWindow": {
"startTs": 1741356332086,
"endTs": 1741357232086
},
},
"values": [{
"pressure": {
"ts": 1741357047945,
"timeWindow": {
"value": 1023
"startTs": 1741356332086,
}, {
"endTs": 1741357232086
"ts": 1741357056144,
},
"value": 1026
"values": [{
}, {
"ts": 1741357047945,
"ts": 1741357147391,
"value": 1023
"value": 1025
}, {
}]
"ts": 1741357056144,
},
"value": 1026
"temperature": {
}, {
"timeWindow": {
"ts": 1741357147391,
"startTs": 1741356332086,
"value": 1025
"endTs": 1741357232086
}]
},
},
"values": [{
"temperature": {
"ts": 1741356874943,
"timeWindow": {
"value": 76
"startTs": 1741356332086,
}, {
"endTs": 1741357232086
"ts": 1741357063689,
},
"value": 77
"values": [{
}]
"ts": 1741356874943,
"value": 76
}, {
"ts": 1741357063689,
"value": 77
}]
}
}
}
}
```
```
**Example usage**
**Usage:**
```javascript
var mergedData = temperature.merge(humidity, { ignoreNaN: false });
```
**Output:**
```javascript
```json
var mergedData = temperature.merge(humidity, { ignoreNaN: false });
{
```
"mergedData": {
"timeWindow": {
**Output:**
"startTs": 1741356332086,
"endTs": 1741357232086
```json
},
{
"values": [{
"mergedData": {
"ts": 1741356874943,
"timeWindow": {
"values": [76.0, "NaN"]
"startTs": 1741356332086,
}, {
"endTs": 1741357232086
"ts": 1741356882759,
},
"values": [76.0, 43.0]
"values": [{
}, {
"ts": 1741356874943,
"ts": 1741356918779,
"values": [76.0, "NaN"]
"values": [76.0, 46.0]
}, {
}, {
"ts": 1741356882759,
"ts": 1741357063689,
"values": [76.0, 43.0]
"values": [77.0, 46.0]
}, {
}]
"ts": 1741356918779,
"values": [76.0, 46.0]
}, {
"ts": 1741357063689,
"values": [77.0, 46.0]
}]
}
}
}
}
```
```
**Example usage**
**Usage:**
```javascript
var mergedData = temperature.mergeAll([humidity, pressure], { ignoreNaN: true });
```
**Output:**
```javascript
```json
var mergedData = temperature.mergeAll([humidity, pressure], { ignoreNaN: true });
{
```
"mergedData": {
"timeWindow": {
**Output:**
"startTs": 1741356332086,
"endTs": 1741357232086
```json
},
{
"values": [{
"mergedData": {
"ts": 1741357047945,
"timeWindow": {
"values": [76.0, 46.0, 1023.0]
"startTs": 1741356332086,
}, {
"endTs": 1741357232086
"ts": 1741357056144,
},
"values": [76.0, 46.0, 1026.0]
"values": [{
}, {
"ts": 1741357047945,
"ts": 1741357063689,
"values": [76.0, 46.0, 1023.0]
"values": [77.0, 46.0, 1026.0]
}, {
}, {
"ts": 1741357056144,
"ts": 1741357147391,
"values": [76.0, 46.0, 1026.0]
"values": [77.0, 46.0, 1025.0]
}, {
}]
"ts": 1741357063689,
"values": [77.0, 46.0, 1026.0]
}, {
"ts": 1741357147391,
"values": [77.0, 46.0, 1025.0]
}]
}
}
}
}
```
```
##### Function return format:
##### Function arguments
The script should return a JSON object formatted according to the [ThingsBoard Telemetry Upload API](${siteBaseUrl}/docs${docPlatformPrefix}/user-guide/telemetry/#time-series-data-upload-api/).
* `ctx` - context object that contains all provided arguments, in the representations described above.
The return value must match one of the supported telemetry upload formats.
**Example Formats**:
Single key-value format:
Accessing arguments via `ctx`:
```json
```javascript
{
var altitude = ctx.args.altitude; // single value argument
"airDensity": 1.06
var temperature = ctx.args.temperature; // time series rolling argument
}
```
```
Key-value format with a timestamp:
* `arg1, arg2, ...` - user-defined arguments configured in the calculated field setup.
```json
How they are passed depends on their type:
{
"ts": 1740644636669,
* **single value arguments** are passed as raw values **(e.g., 22.5, "ON")**.
"values": {
* **time series rolling arguments** are passed as objects (containing multiple values).
"airDensity": 1.06
}
##### Example: Air Density Calculation
This function calculates air density using `altitude` (single value argument) and `temperature` (time series rolling argument).
```javascript
function calculate(ctx, altitude, temperature) {
var avgTemperature = temperature.mean(); // Get average temperature
var temperatureK = (avgTemperature - 32) * (5 / 9) + 273.15; // Convert Fahrenheit to Kelvin
var airDensity = pressure / (287.05 * temperatureK);
return {
"airDensity": airDensity
};
}
}
```
```
Array of telemetry entries:
* `altitude` is a single value, passed as number.
* `temperature` is a rolling argument, retaining its full structure.
```json
##### Function return format
[
The script should return a JSON object formatted according to the [ThingsBoard Telemetry Upload API](${siteBaseUrl}/docs${docPlatformPrefix}/user-guide/telemetry/#time-series-data-upload-api/).
The return value must match one of the supported telemetry upload formats.
The script must return data in a format compatible with ThingsBoard’s APIs.
The correct return format depends on the calculated field output configuration:
* if latest telemetry is used for output, the function must return data according to the [Telemetry Upload API](${siteBaseUrl}/docs${docPlatformPrefix}/reference/mqtt-api/#attributes-api/).
* without timestamps
```json
{
"airDensity": 1.06,
"someKey": "value"
}
```
* with a timestamp:
```json
{
{
"ts": 1740644636669,
"ts": 1740644636669,
"values": {
"values": {
"airDensity": 1.06
"airDensity": 1.06,
}
"someKey": "value"
},
}
}
```
* if attributes are used for output, the function must return data according to the [Attributes API](${siteBaseUrl}/docs${docPlatformPrefix}/user-guide/telemetry/#time-series-data-upload-api/).