diff --git a/ui-ngx/src/assets/help/en_US/calculated-field/expression_fn.md b/ui-ngx/src/assets/help/en_US/calculated-field/expression_fn.md index eb06cda0cb..2e764d7c16 100644 --- a/ui-ngx/src/assets/help/en_US/calculated-field/expression_fn.md +++ b/ui-ngx/src/assets/help/en_US/calculated-field/expression_fn.md @@ -1,25 +1,31 @@ #### Calculated field TBEL script function -The **calculate()** function is user-defined and receives arguments configured by the user to generate new telemetry data. -It allows you to perform custom calculations using [TBEL{:target="_blank"}](${siteBaseUrl}/docs${docPlatformPrefix}/user-guide/tbel/). +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. +It receives user-configured arguments and an additional `ctx` object, which provides access to all arguments. ##### Function signature ```javascript - function calculate(arg1, arg2, ...): object | object[] + function calculate(ctx, arg1, arg2, ...): object | object[] ``` -The function automatically receives user-defined arguments **(arg1, arg2, ...)** and should return a JSON object. +* the function automatically receives a `ctx` object containing all arguments. +* 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(altitude, temperature) { +function calculate(ctx, altitude, temperature) { var avgTemperature = temperature.mean(); // Get average temperature var temperatureK = (avgTemperature - 32) * (5 / 9) + 273.15; // Convert Fahrenheit to Kelvin // Estimate air pressure based on altitude - var pressure = 101325 * Math.pow((1 - 2.25577e-5 * altitude.value), 5.25588); + var pressure = 101325 * Math.pow((1 - 2.25577e-5 * altitude), 5.25588); // Air density formula var airDensity = pressure / (287.05 * temperatureK); @@ -32,7 +38,21 @@ function calculate(altitude, temperature) { ##### Function arguments -The function receives user-configured arguments, which can be of two types: +* `ctx` - context object containing all predefined arguments. + + Use `ctx.args.argName` to access arguments. + + ```javascript + var altitude = ctx.args.altitude.ts; + var temperature = ctx.args.temperature; + ``` + +* `arg1, arg2, ...` - user-defined arguments configured in the calculated field setup. These arguments follow the previously described types: + * if an argument represents the latest telemetry data or attribute, it will be passed as a direct value. + + * if an argument is a time series rolling argument, it will be provided as a time series rolling argument described above. + +The **calculate()** function receives predefined arguments, which fall into two categories: * single value arguments - represent the latest telemetry data or attribute. ```json @@ -44,11 +64,11 @@ The function receives user-configured arguments, which can be of two types: } ``` - Use dot notation (`.`) to access argument properties. +Use dot notation (`.`) to access argument properties. ```javascript - var altitudeTimestamp = altitude.ts; - var altitudeValue = altitude.value; + var altitudeTimestamp = ctx.args.altitude.ts; + var altitudeValue = ctx.args.altitude.value; ``` * time series rolling arguments - contain historical data within a defined time window. @@ -57,8 +77,7 @@ The function receives user-configured arguments, which can be of two types: "temperature": { "timeWindow": { "startTs": 1740643762896, - "endTs": 1740644662896, - "limit": 5000 + "endTs": 1740644662896 }, "values": [ { "ts": 1740644355935, "value": 72.32 }, @@ -69,8 +88,8 @@ The function receives user-configured arguments, which can be of two types: } } ``` - - Use dot notation (`.`) to access argument properties. + + Use dot notation (`.`) to access argument properties. ```javascript var startOfInterval = temperature.timeWindow.startTs; @@ -81,27 +100,27 @@ The function receives user-configured arguments, which can be of two types: **Built-in methods for rolling arguments** Time series rolling arguments provide built-in functions for calculations. -These functions accept an optional 'ignoreNaN' boolean parameter, which controls how NaN values are handled. -Each method has two function signatures: +These functions accept an optional `ignoreNaN` boolean parameter, which controls how NaN values are handled. +Each function has two function signatures: * **Without parameters:** `method()` → called **without parameters** and defaults to `ignoreNaN = true`, meaning NaN values are ignored. * **With an explicit parameter:** `method(boolean ignoreNaN)` → called with a boolean `ignoreNaN` parameter: * `true` → ignores NaN values (default behavior). * `false` → includes NaN values in calculations. -| Method | Default Behavior (`ignoreNaN = true`) | Alternative (`ignoreNaN = false`) | -|-----------|--------------------------------------------------|---------------------------------------------| -| `max()` | Returns the highest value, ignoring NaN values. | Returns NaN if any NaN values exist. | -| `min()` | Returns the lowest value, ignoring NaN values. | Returns NaN if any NaN values exist. | -| `mean()` | Computes the average value, ignoring NaN values. | Returns NaN if any NaN values exist. | -| `std()` | Calculates the standard deviation, ignoring NaN. | Returns NaN if any NaN values exist. | +| Method | Default Behavior (`ignoreNaN = true`) | Alternative (`ignoreNaN = false`) | +|------------|--------------------------------------------------|---------------------------------------------| +| `max()` | Returns the highest value, ignoring NaN values. | Returns NaN if any NaN values exist. | +| `min()` | Returns the lowest value, ignoring NaN values. | Returns NaN if any NaN values exist. | +| `mean()` | Computes the average value, ignoring NaN values. | Returns NaN if any NaN values exist. | +| `std()` | Calculates the standard deviation, ignoring NaN. | Returns NaN if any NaN values exist. | | `median()` | Returns the median value, ignoring NaN values. | Returns NaN if any NaN values exist. | -| `count()` | Counts only valid (non-NaN) values. | Counts all values, including NaN. | -| `last()` | Returns the most recent non-NaN value. | Returns the last value, even if it is NaN. | -| `first()` | Returns the oldest non-NaN value. | Returns the first value, even if it is NaN. | -| `sum()` | Computes the total sum, ignoring NaN values. | Returns NaN if any NaN values exist. | +| `count()` | Counts only valid (non-NaN) values. | Counts all values, including NaN. | +| `last()` | Returns the most recent non-NaN value. | Returns the last value, even if it is NaN. | +| `first()` | Returns the oldest non-NaN value. | Returns the first value, even if it is NaN. | +| `sum()` | Computes the total sum, ignoring NaN values. | Returns NaN if any NaN values exist. | -##### The following calculations are executed over the provided above arguments: +The following calculations are executed over the provided above arguments: **Example usage: default (`ignoreNaN = true`)** @@ -139,6 +158,131 @@ var valueCount = temperature.count(false); // Counts all values, including NaN } ``` +Time series rolling arguments can be merged for multi-sensor analysis. + +Function Signatures: + +* `merge(other, settings)` - merges the current rolling argument with another rolling argument by aligning timestamps and combining values. + Parameters: + * `other` - another time series rolling argument to merge with. + * `settings` (optional) - configuration object, supports: + * `ignoreNaN` (boolean, default true) - controls whether NaN values should be ignored. + * `timeWindow` (object, default {}) - defines a custom time window for filtering merged values. + Returns: an object with time window and values from each provided time series rolling arguments. + + * `mergeAll(others, settings)` - merges the current rolling argument with multiple rolling arguments by aligning timestamps and combining values. + Parameters: + * `others` - an array of time series rolling arguments to merge with. + * `settings` (optional) - same as `merge()`. + Returns: an object with timeWindow and aligned values. + +```json +{ + "humidity": { + "timeWindow": { + "startTs": 1741356332086, + "endTs": 1741357232086 + }, + "values": [{ + "ts": 1741356882759, + "value": 43 + }, { + "ts": 1741356918779, + "value": 46 + }] + }, + "pressure": { + "timeWindow": { + "startTs": 1741356332086, + "endTs": 1741357232086 + }, + "values": [{ + "ts": 1741357047945, + "value": 1023 + }, { + "ts": 1741357056144, + "value": 1026 + }, { + "ts": 1741357147391, + "value": 1025 + }] + }, + "temperature": { + "timeWindow": { + "startTs": 1741356332086, + "endTs": 1741357232086 + }, + "values": [{ + "ts": 1741356874943, + "value": 76 + }, { + "ts": 1741357063689, + "value": 77 + }] + } +} +``` + +**Example usage** +```javascript +var mergedData = temperature.merge(humidity, { ignoreNaN: false }); +``` + +**Output:** +```json +{ + "mergedData": { + "timeWindow": { + "startTs": 1741356332086, + "endTs": 1741357232086 + }, + "values": [{ + "ts": 1741356874943, + "values": [76.0, "NaN"] + }, { + "ts": 1741356882759, + "values": [76.0, 43.0] + }, { + "ts": 1741356918779, + "values": [76.0, 46.0] + }, { + "ts": 1741357063689, + "values": [77.0, 46.0] + }] + } +} +``` + +**Example usage** +```javascript +var mergedData = temperature.mergeAll([humidity, pressure], { ignoreNaN: true }); +``` + +**Output:** +```json +{ + "mergedData": { + "timeWindow": { + "startTs": 1741356332086, + "endTs": 1741357232086 + }, + "values": [{ + "ts": 1741357047945, + "values": [76.0, 46.0, 1023.0] + }, { + "ts": 1741357056144, + "values": [76.0, 46.0, 1026.0] + }, { + "ts": 1741357063689, + "values": [77.0, 46.0, 1026.0] + }, { + "ts": 1741357147391, + "values": [77.0, 46.0, 1025.0] + }] + } +} +``` + ##### 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/).