---
title: "Derived Tags | Examples | N3uron KB V1.22"
slug: "derived-tags-examples"
description: "Derived Tags is a N3uron module designed to implement custom logic, advanced calculations, and data aggregation for operational data analysis at N3uron…"
updated: 2025-09-30T15:55:35Z
published: 2025-12-23T13:14:23Z
---

> ## Documentation Index
> Fetch the complete documentation index at: https://docs.n3uron.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Examples

## Expression Tags:

The following examples show the different expressions that can be used in an **Expression Tag**.

### Sum of Two Tags:

```javascript
//Returns the sum of the value of tags a and b
$.output= $.input.a.value + $.input.b.value;
```

### Set a Value Based on a Condition:

```javascript
 //If the value of a is above the threshold, it will return 1,
//otherwise it will return 0
if ($.input.a.value > threshold) $.output =1;
else $.output = 0;
```

### Diagnosing Unresponsive Devices in Poll/Response Protocols using Tag Timestamps:

To determine whether a device is unresponsive or experiencing problems when communicating on a polling/response protocol like Modbus, you can implement a monitoring strategy using tag timestamps and specific **expression tags** for tracking the device status. It is key to set a **deadband**slightly greater than 0.0u, for instance, **0.001u.** This adjustment ensures that the device tag is only updated when there is a real change in its value, preventing unnecessary timestamp changes with each scan rate.

We will use three tags:

- **Derived tag (DeviceStatusOK)**: This tag monitors whether the value of the device tag remains unchanged for a specified period of time. It is an **Expression tag** with a**periodic trigger** set to **1000ms**. In this example, the input **Aliases** are **Tag** for the tag we read from the device and **Timeout** for the timeout value.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/derivedstatus01(1).png)
- **Device tag (DeviceTag)**: This tag represents the value read from the device and, as explained above, its input alias will be **Tag**for the derived tag.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/derivedstatus02.png)
- **Timeout tag (Timeout):** This **memory tag** sets the duration used to determine if the device has a problem or is frozen. Its input alias for the derived tag will be named **Timeout**. Additionally, we will set the **Persistency mode** of this tag to **Disk**to ensure its value remains persistent even after a node restart.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/derivedstatus03.png)

By configuring these tags and using the expression below, we can effectively monitor the status of the device and identify any issues related to it being frozen or unresponsive.

```javascript
/* 
This script checks if the tag value remains uchanged for the period of time specified by the tag named 'Timeout'. 
If the tag value remains unchanged beyond the timeout, the output will be 0 (indicating a potential issue).
Otherwise, the output will be 1 (indicating normal operation).
*/

if ((Date.now() - $.input.Tag.ts) > $.input.Timeout.value) {
  $.output = 0;
} else {
  $.output = 1;
}
```

### Diagnose Connectivity issues using single or multiple Tag Quality:

In this example, we will use Derived Tags to check the quality values of several tags read from a device to determine if there are connectivity issues. While setting an alarm to monitor the quality of a single tag with a delay for activation is possible, checking multiple tags offers a more reliable method for identifying potential problems. By monitoring several tags simultaneously, we can more confidently identify a connectivity issue if multiple quality values indicate problems.

![usingderivetags1](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/usingderivetags2.png)

- **Step 1:** **Create**a tag named **ConnectStatusOK**of type **Derived Tag**.
- **Step 2:**Assign its **Type** as **Boolean**.
- **Step 3:**Assign the appropriate module type and name.
- **Step 4:** Configure the **Mode**as**Expression Tag.**
- **Step 5:** Set the **Trigger**to **'On Change'** so that the expression executes every time there is an update in the input tags.
- **Step 6:** Select all the tags necessary for quality checking.

Click the editor icon next to the Expression JavaScript to enter the code. The code will be simple: each time the expression is executed, it will check the quality of the tags. It is assumed that if any tag's quality is not equal or greater than 192 (indicating good quality), communication with the device is lost. For further information about quality codes, please refer to, [quality codes](https://docs.n3uron.com/v122/docs/platform-tags-overview#quality-codes).

```javascript
const result = (   
  $.input.DeviceTag01.quality >= 192 &&   
  $.input.DeviceTag02.quality >= 192 &&   
  $.input.DeviceTag03.quality >= 192
);

$.output= {value: result, quality:192};
```

### Create an Alarm With an Active Delay Attribute:

```javascript
//If the Process value is above or below the Setpoint
//for a set period of time, defined by another tag named Delay, it will return 1,
//once the alarm condition is not met it will return 0

if ($.input.Process_Value.value-$.input.Setpoint.value==0)

  $.output=0;
  
else if (($.currentValue.value==0) && (Math.floor((Date.now()-$.currentValue.ts)/1000)<Delay.value))
 
  $.output={value:0, ts:$.currentValue.ts};

else
  
  $.output=1;
```

### Configuring a Dynamic Parameterized Alarm for a Process Value:

This example illustrates how to configure a dynamic, parameterized alarm to monitor a process value (**ProcessValue**) and ensure it remains within a defined range. The range is determined by a setpoint, a tolerance, and configurable activation and clearing delays. The implementation leverages a [**Template**](/v122/docs/platform-templates)for scalability and flexibility, while**memory tags**(without source) and **Read/Write permissions** are used for **SetPoint**(**SetPoint**), **Activation Delay (ActivationDelay)**, and **Clear Delay (ClearDelay)**. These tags allow parameters to be dynamically adjusted and include **disk persistence** to retain their values across system restarts, ensuring reliability and continuity.

The template has the following [**Custom properties**](/v122/docs/platform-templates-custom-properties):

1. **ProcessValuePath**: A tag path representing the monitored process value. Tag picker custom property.
2. **InitSetpoint**: The initial or default value for the setpoint value.
3. **Tolerance**: The acceptable range (±) around the setpoint.
4. **InitActivationDelay**: Time (in milliseconds) that the process value must remain outside the acceptable range before activating the alarm.
5. **InitClearDelay**: Time (in milliseconds) that the process value must return within the acceptable range before clearing the alarm.
6. **Priority**: Specifies the severity of the alarm (e.g., Low, Medium, High, Critical). Dropdown menu custom property.
7. **Engineering_units**: Indicates the unit of the process value (e.g., %, °C, etc.).
8. **Description**: A textual description of the alarm, visible in the alarm controls (e.g. Alarms>Realtime, Alarms>Historical, Web Vision Alarm Table). ![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/AnalogAlarm.png)

Within the template the following tags are declared:

- **ActivationDelay**: It is a **memory tag** with **disk persistence** that retains its value across system restarts. It has **Read/Write permissions**, allowing dynamic updates, and its initial value is set by the **InitActivationDelay**custom property during configuration. ![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/AnalogAlarm01.png)
- **ClearDelay**: It is a**memory tag** with **disk persistence** that retains its value across system restarts. It has **Read/Write permissions**, allowing dynamic updates, and its initial value is set by the **InitClearDelay**custom property during configuration. ![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/AnalogAlarm02.png)
- **SetPoint**: It is a **memory tag** with **disk persistence** that retains its value across system restarts. It has **Read/Write permissions**, allowing dynamic updates, and its initial value is set by the **InitSetpoint**custom property during configuration. ![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/AnalogAlarm03(1).png)
- **CheckProcessValue**: It is a **Derived Tag** that evaluates whether the **ProcessValue**is within the range of **SetPoint ± Tolerance**. It returns true if within range or false otherwise, functions as a dynamic driver for alarm activation and clearing. It is **read-only** and calculated at a time interval based on input tags. Its alias input paths are configured using [**relative paths**](https://docs.n3uron.com/v122/docs/derived-tags-tag-configuration#using-relative-and-absolute-tag-paths), ensuring flexibility and adaptability within the tag model hierarchy. ![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/AnalogAlarm04.png)

**JavaScript code:**

```javascript
// Get the current timestamp in milliseconds for delay calculations
const now = Date.now();
//=======================================================
// Safely extract input values or assign default values
const processValue =
  $.input.ProcessValue && $.input.ProcessValue.value !== undefined
    ? $.input.ProcessValue.value
    : undefined;

const setPoint =
  $.input.SetPoint && $.input.SetPoint.value !== undefined
    ? $.input.SetPoint.value
    : undefined;

const activationDelay =
  $.input.ActivationDelay && $.input.ActivationDelay.value !== undefined
    ? $.input.ActivationDelay.value
    : 0; // Default delay to 0 if undefined

const clearDelay =
  $.input.ClearDelay && $.input.ClearDelay.value !== undefined
    ? $.input.ClearDelay.value
    : 0; // Default delay to 0 if undefined
//=======================================================
// Initialize default output values
let ouputValue = $.currentValue.value; // Default to inactive state
let outputQuality = $.currentValue.quality; // Default to bad quality
//=======================================================
// Validate critical inputs (processValue and setPoint)
if (processValue === undefined || setPoint === undefined) {
  // Log an error and keep default output if inputs are missing or undefined
  $.logger.error(
    "Invalid inputs: 'ProcessValue' or 'SetPoint' is missing/undefined."
  );
  ouputValue = null; // Set to null
  outputQuality = 4; // Bad [Configuration Error]
} else {
  // Check if processValue is outside the tolerance range of the setPoint
  if (
    processValue > setPoint + {Tolerance} ||
    processValue < setPoint - {Tolerance}
  ) {
    // Activate if not active and activation delay has elapsed
    if (!$.currentValue.value && now - $.currentValue.ts >= activationDelay) {
      ouputValue = true; // Set to active state
      outputQuality = 192; // Good quality output
    }
  } else {
    // Deactivate if active and clear delay has elapsed
    if ($.currentValue.value && now - $.currentValue.ts >= clearDelay) {
      ouputValue = false; // Set to inactive state
      outputQuality = 192; // Good quality output
    }
  }
}
//=======================================================
// Set final output with state and quality
$.output = {
  value: ouputValue, // Active/inactive state
  quality: outputQuality, // Output quality
};
```

This code implements the logic that **monitors**a **ProcessValue**against a **SetPoint with a specified Tolerance**, incorporating **activation**and **clear delays**. Here's a breakdown of the main points:

First, the **current timestamp** is obtained using**Date.now()**to handle delay calculations. The script then safely extracts the necessary inputs: ProcessValue, SetPoint, ActivationDelay, and ClearDelay. If these **inputs**are **missing**, **default values** are **assigned**(**undefined**for **ProcessValue**and **SetPoint**, and **0** for the **delays**).

The Derived Tag **initializes**its **output state**and **quality**using **$.currentValue.value** and **$.currentValue.quality**.

Next, the code **validates**the **critical inputs** by checking if **ProcessValue**or **SetPoint**is **undefined**. If either is **missing**, an error is logged using **$.logger.error**, and the output remains in its .

If the inputs are valid, the script evaluates whether the ProcessValue is outside the acceptable range defined by SetPoint ± {Tolerance}. The {Tolerance} is accessed as a custom property using curly braces, allowing dynamic configuration. If the ProcessValue exceeds this range and the ActivationDelay has elapsed since the last state change (now - $.currentValue.ts >= activationDelay), the output state is set to active (true) with good quality (192). Conversely, if the ProcessValue returns within the acceptable range and the ClearDelay has passed, the output state is set to inactive (false) with good quality.

Finally, the script sets the final output object with the determined value and quality, ensuring that the alarm state is accurately reflected based on the real-time process conditions.

Access Notes:

Current Value and Timestamp: Use $.currentValue.value to access the current state (active/inactive) and $.currentValue.ts to get the timestamp of the last update.

Custom Properties: Reference custom properties like Tolerance using curly braces {Tolerance} to dynamically incorporate their values into expressions.

This setup ensures that the alarm responds appropriately to changes in the process value, activating and clearing based on configured tolerances and delays while handling input validation effectively.

### Increment a Global Counter Based on a Condition:

```javascript
//First, the global variable counter needs to exist. The counter //then needs to be incremented when the condition is set to true //(a.value must be even)
if ($.input.a.value % 2 === 0) counter++; 
//Return counter so that it is saved to the tag;
$.output=counter;
```

### Capture a Tag Value at Midnight in a Given Time Zone:

```javascript
const currentDay = moment.tz($.currentValue.ts, "Europe/Madrid").get("day");
const newDay = moment.tz($.input.Captured_tag.ts, "Europe/Madrid").get("day");

if(currentDay !== newDay){
    $.output = $.input.Captured_tag.value;
} else {
    $.output = $.currentValue;
}
```

### Bit Extraction From a 16-bit-integer Value:

```javascript
$.output = ($.input.source.value & 0xF000) >> 12; 
// bits 15 to 12 from unit16

$.output = ($.input.source.value & 0xE0) >> 5; 
// bits 7 to 5 from unit16

$.output = ($.input.source.value & 0xF00) >> 8; 
// bits 11 to 8 from unit16

$.output = ($.input.source.value & 0xE000) >> 13;
// bits 15 to 13 from unit16

$.output = ($.input.source.value & 0x1C) >> 2; 
// bits 4 to 2 from unit16
```

### Get the Total RAM for This Machine:

> [!WARNING]
> Note:
> 
> From **N3uron**version **1.21.4** onwards, it is possible to retrieve this information through a **Node Tag.**

```javascript
//os.totalmem() returns the total memory of the machine in
//bytes, divided twice by 1024 to obtain MB.
$.output = os.totalmem()/1024/1024;
```

### Get Free RAM for This Machine:

> [!WARNING]
> Note:
> 
> From **N3uron**version **1.21.4** onwards, it is possible to retrieve this information through a **Node Tag.**

```javascript
//os.freemem() returns the free memory of the machine in
//bytes, divided twice by 1024 to obtain MB.
$.output = os.freemem()/1024/1024;
```

### Get Hostname:

> [!WARNING]
> Note:
> 
> From **N3uron**version **1.21.4** onwards, it is possible to retrieve this information through a **Node Tag.**

```javascript
//os.hostname() returns the hostname as a string
$.output = os.hostname();
```

### Get Uptime:

> [!WARNING]
> Note:
> 
> From **N3uron**version **1.21.4** onwards, it is possible to retrieve this information through a **Node Tag.**

```javascript
//os.uptime() returns the host machine in seconds as a number
$.output =  os.uptime();
```

### Get Derived Tags Memory Usage:

> [!WARNING]
> Note:
> 
> From **N3uron**version **1.21.4** onwards, it is possible to retrieve this information through a **Node Tag.**

```javascript
//process.memoryUsage() returns an object with memory 
//information. The rss property holds the total memory usage
//of the process (in this case DerivedTags), in bytes
$.output =  process.memoryUsage().rss/1024/1024;
```

### Assigning a Quality Based on a Condition:

```javascript
//If the value of the tag is above 100, we set the quality
//to 16 (BAD_SENSOR_FAILURE)
if ($.input.a.value > 100) $.output = {value: -1, quality:16}
else $.output = {value: a.value, quality:192};
```

### Redundant Tags:

In this example, the **Derived Tags**module is used to provide an output tag after evaluating the quality of two redundant tags coming from two redundant nodes linked to a central node.

> [!WARNING]
> Note:
> 
> From **N3uron**version **1.21.4** onwards, it is possible to create a **Redundant Tag** without requiring an Expression Tag by selecting the**Redundant Tag mode**.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/Redundanttgas01.png)

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/Redundanttgas02.png)

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/Redundanttgas03.png)

- **Step 1:** Add a new module in the “Modules” section, give it a name, and select “DerivedTags” in the “Module type” field.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/Redundanttgas04.png)
- **Step 2:** Configure the **Logger**and **API**for the **Derived Tags**module. In this example, the default configuration settings have been left unedited, since (in most cases) this is a valid configuration option.
- **Step 3:** Configure the module. In this example, the default configuration settings have been left unedited.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/Redundanttgas05.png)
- **Step 4:** Configure the tag Source section. In this example, **Mode**is set to Expression tag and **Trigger**is set to Periodic. The **Aliases**created are “Amplitude”, which has the **Input tag** /SITE01/LINE01/MACHINE01/AMPLITUDE of the main node, and “AmplitudeBis”, which has the **Input tag** /SITE01Bis/LINE01/MACHINE01/AMPLITUDE of the redundant node.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/Redundanttgas06.png)

```javascript
if($.input.Amplitude.quality >= $.input.AmplitudeBis.quality)
{
    $.output = {value:$input.Amplitude.value, quality:$input.Amplitude.quality, ts:$input.Amplitude.ts};
}else{
    $.output = {value:$input.AmplitudeBis.value, quality:$input.AmplitudeBis.quality, ts:$input.AmplitudeBis.ts};
}
```

**Result:**

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/Redundanttgas07.png)

## Aggregated Tag

In this example, the **Derived Tags**module will be used to output the result of an aggregation of a source tag in a tag value over a period of time.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/derivedaggregation01.png)

- **Step 1:**Add a new module in the “Modules” section, give it a name, and select “DerivedTags” in the “Module type” field.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/derivedaggregation02.png)
- **Step 2:** Configure the Logger and **API**for the **Derived Tags**module. In this example, the default configuration settings have been left unedited, since (in most cases) this is a valid configuration option.
- **Step 3**: Configure the module. In this example, the default configuration settings have been left unedited.

![Figure 1 - Derived Tags configuration options](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/Figure%201%20-%20Derived%20Tags%20configuration%20options.png)

- **Step 4:** Configure the tag Source section. In this example, **Mode** is set to Aggregated tag, **Aggregation method**is set to Average, and the **Source Tag** is /000_PLANT/010_ZONE/010_MTR/AP.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/derivedaggregation03.png)

**Result:**

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/derivedaggregation04.png)

### Custom Aggregation:

In this example, we will use the **Derived Tags** module to **sum**all values from a**source tag**over a**specified aggregation period,**using the **Custom Aggregation.**

Follow these steps to achieve this:

- **Step 1:**Create a new tag.
- **Step 2:** Once the tag is created, **enable**its **source**.
- **Step 3:**Choose the appropriate **module type** and specify the **module name** for the Derived Tags module.
- **Step 4:**Set the tag's **mode**to **Aggregation Tag**.
- **Step 5:**Select **Custom** as the **aggregation method**.
- **Step 6:**Choose the**Period type.**This can be a **Cron expression** or **Periodic**interval.
- **Step 7:**Specify the **Aggregation period / Cron expression**.
- **Step 8:** From the data model, select the **Source Tag**.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/customexample(1).png)

After configuring the source, you need to write the custom JavaScript code to sum all the values from the source tag. Here is an example:

```javascript
/****************************************************************************************************************
 * This code is just an example on how to use execute a custom calculation given a buffer of tag events. 
 * In this case, the calculation is a sum of all the events that occured in the tag interval, skipping the 
 * first and last events if they are virtual (meaning they did not occur in this interval, they were pulled 
 * from the last interval and from the last sample in this interval respectively). 
 * Feel free to modify it or replace it completely to adapt it to your specific needs. 
 * The ultimate goal is to return a value that is the result of the custom calculation.
*****************************************************************************************************************/

let sum = 0;
let goodCount=0;
for (const tagEvent of buffer){
  if (tagEvent.virtual){
    $.logger.trace("Ignoring virtual tag event: %j", tagEvent)
    continue;
  } else if (tagEvent.quality >= 192){
    sum += tagEvent.value;
    goodCount += 1;
  }
}
$.logger.debug("Added %d good events", goodCount);
if (goodCount === 0){
  throw new Error("Unable to calculate sum, only bad events available");
} else {
  return sum;
}
```

## Node tag

In this example, the **Derived Tags**module will be used to get information about the disk and the RAM usage in our node.

- **Step 1:**Add a new module in the “Modules” section, give it a name, and select “DerivedTags” in the “Module type” field.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/nodetag01.png)
- **Step 2:**Configure the Logger and **API**for the **Derived Tags**module. In this example, the default configuration settings have been left unedited, since (in most cases) this is a valid configuration option.
- **Step 3:** Configure the module. In this example, the default configuration settings have been left unedited.

![Figure 1 - Derived Tags configuration options](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/Figure%201%20-%20Derived%20Tags%20configuration%20options.png)

- **Step 4:** Configure the tag Source section. In this example, **Mode** is set to Node tag, **Type**is set to Node information, and the **Variable**is set to Disk usage and RAM usage respectively in both tags.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/nodetag02.png)

**Result:**

![Figure - Node Real Time](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/Figure%20-%20Node%20Real%20Time.png)

## **Alias Tag**

In this example, the **Derived Tags**module will be used to make a copy of the value of an input tag.

- **Step 1:**Add a new module in the Modules section, give it a name, and select DerivedTags in the Module type field.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/aliasTag01.png)
- **Step 2:**Configure the Logger and **API**for the **Derived Tags**module. In this example, the default configuration settings have been left unedited, since (in most cases) this is a valid configuration option.
- **Step 3:** Configure the module. In this example, the default configuration settings have been left unedited.

![Figure 1 - Derived Tags configuration options](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/Figure%201%20-%20Derived%20Tags%20configuration%20options.png)

- **Step 4:** Configure the tag Source section. In this example, **Mode** is set to Alias tag, and the**Input tag**is /OPCUA/Kep_Group1_Sine01.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/aliasTag02.png)

**Result:**

![Figure - Alias Real time 2](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/Figure%20-%20Alias%20Real%20time%202.png)

![Figure - Alias Real time](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/Figure%20-%20Alias%20Real%20time.png)

## **Redundant Tag**

In this example, we will use the **Derived Tags** module to create a **Redundant Tag**. The **output**value, quality, and timestamp of the **Redundant Tag** will reflect those of the**highest quality input tag**. If two or more tags have the same quality, the system will select the first tag listed among the **Sources** for the output.

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/redundanttag01(1).webp)

**Result:**

![](https://cdn.document360.io/54093ab5-6b22-4542-a265-04377931f11a/Images/Documentation/redundanttag02.webp)

[Derived Tags Full Product Details](https://n3uron.com/iiot-platform-modules/derived-tags/)
