--- title: "Derived Metrics" slug: "derived-metrics" updated: 2026-06-16T08:19:20Z published: 2026-06-16T08:19:20Z canonical: "learn.servitly.com/derived-metrics" --- > ## Documentation Index > Fetch the complete documentation index at: https://learn.servitly.com/llms.txt > Use this file to discover all available pages before exploring further. # Derived Metrics Derived metrics can be used to compute new values by using an expression based on the value of other metrics. The expression result could be a number, a boolean or a string value. # Creating a Derived metric To add a new *Derived* metric to a *Thing Definition*, you should: 1. Enter the *Computed Data* page. 2. Select the *Thing Definitions* tab. 3. Select the *Thing Definition* to edit. 4. Press the *Add Metric* button. 5. Select the *Derived* type and provide the required information. 6. Press the Save button and edit the additional information, if needed. ![](https://cdn.document360.io/6759e9c9-3ce3-49df-965a-7231d2d9a10a/Images/Documentation/image(91).png) # Editing a Derived metric The configuration of a *Derived* metric is subdivided into several sections: ## General - **Label**: the metric label shown within the widget. - **Name**: the name of the metric, also used to reference it within the dashboard's templates. - **Description**: the text describing the metric. The description is displayed as a tooltip within the dashboard widgets. - **Unit**: the unit of measurement (e.g., Kg, °C, pieces, liters, etc.) - **Group**: the group the metric belongs to (e.g., Temperatures, System). - **Metric Sets**: The list of [Metric Sets](/v1/docs/metric-sets) in which this metric is included. - **Privatizable by customer**: allow the customer to define whether the metric is private or not. For more details, refer to this [Privatizable date](/docs/privatizable-data) article. ## Computation You can configure whether the computation is to be `SAMPLED` or `CONTINUOUS`*.* The `CONTINUOUS` computation takes into account all input values and can generate the same number of output values. While the `SAMPLED` computation is just based on the last available value and generates only one output value per sampling period (e.g., 1h, 1d). ![](https://cdn.document360.io/6759e9c9-3ce3-49df-965a-7231d2d9a10a/Images/Documentation/image(92).png) Both `SAMPLED` and `CONTINUOUS` computations are [periodically evaluated](/v1/docs/environment-advanced-settings#periodic-computations) at a fixed time interval. By using the *Sample* computation, you can reduce the number of consumed DPH, and, in addition, you can reference more input variables than `CONTINUOUS`. For old metrics with a sampling period defined, a warning informs you to choose to clear the sampling period or change the computation to `SAMPLED`. Suppose you have a derived metric that sums two other metrics. Here, we resume the different behaviors in the case of `CONTINUOUS` and `SAMPLED `(1 hour) computation. ```plaintext Output = Metric1 + Metric2 ``` The Timestamp column represents the time when the value becomes available. | | | OUTPUT | | --- | --- | --- | | Timestamp | Metric1 | Metric2 | Continuous | Sampled (1h) | | 10:00 | 10 | 20 | 30 | 30 | | 10:10 | 20 | 20 | 40 | - | | 10:20 | 20 | 10 | 30 | - | | 10:40 | 20 | 30 | 50 | - | | 11:00 | - | - | 50 (10:40) | 50 (11:00) | | 11:10 | 15 | 20 | 35 | - | The `SAMPLED` computation is performed every sampling period with a few-second delay; using the last received values, the new value is computed and stored using the last received timestamp. So, for example, at 11:00, the computation is performed, but the resulting value "50" is stored using the 10:40 timestamp corresponding to the last value of Metric2. In either case, the computed values might become available with a delay of a few seconds from the input values. This delay could depend on the complexity of the derivation to be processed for each thing: - Number of computed metrics. - Number of DPH input to each computed metric (in case of Continuous evaluation). - Computed metrics are used as input into other computed metrics, and so on. > [!WARNING] > Computation on input updated > > Computed metrics are only calculated if at least one of the input metrics has newer data than the last computation. ## Derivation In the derivation panel, you can select one or more metrics or properties to use in the expression. In addition, you can refer to the previous value calculated for the metric. Note that the number of selectable metrics depends on the computation policy. For *Continuous* computation, you can select up to 3 metrics. Once the metrics/properties have been selected, it is possible to configure the derivation expression. Here are some examples: ```plaintext // total weight in kg (unitWeight * quantity)/1000 // milliseconds to hour #floor(time / 3600000) // substring alertCode.#substring(3,6) // energy increment in kWh (energy / 1000) - previousValue ``` Values encoding into expressions: | Type | Sample Encoding | | --- | --- | | STRING | `'foobar'` | | BOOLEAN | `true` or `false` | | INTEGER | `123` | | FLOAT | `123.456` | By pressing the *Add Condition* button, it is possible to add multiple result conditions to implement the IF, ELSE, OTHERWISE pattern. ## Previous Input Metric Value When referring to a metric, you can access not only its current value but also its previous value. In this way, you can use the difference of consecutive values in your derivation logic. ```plaintext outputPieces - outputPieces.PREVIOUS ``` > [!WARNING] > Note that the previous value can be used only with *Continuous* computation. ### Null Result In case the result expression of the activated case (including the default one) is empty, no new data is stored in the database. For instance: - *IF metric1 > 100* → left the result empty to do nothing - *ELSE RETURN (metric1 + metric2)* → save new value ### Functions The expression language used to define Derived Metric expressions is based on the following operators. | **OPERATOR** | **NOTATION** | **SAMPLE** | | --- | --- | --- | | Mathematical | + - * / % ^ | (x + y^2)/4 | | Logical | or and true/false | x==y && (b==true \|\| b==c) | | Relational | ==, !=, <, <=, >=, > | a != b | | Elvis | Ternary operator | condition ? foo : bar | It is possible to use this predefined set of functions. | MATH | DESCRIPTION | SAMPLE | | --- | --- | --- | | cos | Returns the trigonometric cosine of an angle, in radians. | #cos(x) | | sen | Returns the trigonometric sine of an angle, in radians. | #sen(x) | | abs | Returns the absolute value of a numeric value. | #abs(x) | | sqrt | Returns the rounded positive square root of a numeric value. | #sqrt(x) | | pi | The PI value (3.14159…​). | #pi | | ceil | Returns the smallest integer value greater than or equal to the float argument. | #ceil(x) | | floor | Returns the largest integer value that is less than or equal to the float argument. | #floor(x) | | log | Returns the natural logarithm (base e) of the argument. | #log(x) | | log10 | Returns the base 10 logarithm of the argument. | #log(x) | | max | Returns the greater of two values. | #max(x, y) | | min | Returns the smallest of two values. | #min(x, y) | | pow | Returns the value of the first argument raised to the power of the second argument. | #pow(x, exp) | | **CONVERSION** | **DESCRIPTION** | **SAMPLE** | | parseInt | Converts the string argument to integer using the given radix (optional). | #parseInt('12') #parseInt('BF123', 16) | | intToString | Converts an integer to string using a radix. | #intToString(123456, 16) | | parseFloat | Converts the string argument to float using the given radix (optional). | #parseFloat('12.3') | | floatToString | Converts a float to string using a radix. | #floatToString(12.3) | | toString | Converts the source value to string. | var.#toString() | | STRING | DESCRIPTION | SAMPLE | | substring | Returns a substring considering the start (inclusive) and end (exclusive) zero based indexes. | str.#substring(startIndex) str.#substring(startIndex, endIndex) | | length | Returns the length of the string. | str.#length() | | charAt | Returns the character at the specified index. | str.#charAt(index) | | indexOf | Returns the index (zero-based) of the first occurrence of the argument string. | str.#indexOf('foo') | | lastIndexOf | Returns the index (zero-based) of the last occurrence of the argument string. | str.#lastIndexOf('foo') | | split | Returns the arrays of tokens splitting by the argument string. | str.#split(',') | | toUpperCase | Converts the source string to upper-case. | str.#toUpperCase() | | toLowerCase | Converts the source string to lower case. | str.#toLowerCase() | ## Data In case of numeric metrics, the Data Type allows you to define whether the metric values are *DISCRETE* or *CONTINUOUS*, and then you can also define [Dictionary and Thresholds](/docs/dictionary-and-thresholds-1).