---
title: Use the Tengo Script Function
slug: manufacturing-connect-edge/use-the-tengo-script-function
docTags: 
createdAt: 2024-05-24T20:15:21.784Z
---

You can use Tengo Script to manipulate data. The processor uses Tengo scripting rules similar to the Go programming language.

:::hint{type="info"}
**Note:&#x20;**&#x49;f you need further information on Tengo scripting, please refer to the following:

- [Available Standard Library](https://github.com/d5/tengo/blob/master/docs/stdlib.md)
- [Syntax details Github](https://github.com/d5/tengo)
:::

# Understanding the Tengo Script Processor

This function allows adding, removing, or modifying fields from a single input or multiple inputs.

## Single Input&#x20;

Each message from the input is stored in an array called values. It is important to note:

- Using the `for _, message in values{}` statement allows you to access this input and manipulate it.
- The definition in the connection wire is optional for single input but helpful for multi-inputs to differentiate between them.
- The `message` parameter contains the entire input message, and you can manipulate it as needed.&#x20;

:::hint{type="info"}
**Note:** `_` and `message` can be any custom variable name.
:::

## Multiple Inputs

Suppose you have three different inputs attached to this scripting processor, with the connecting wires named A, B, and C:

- `for i, message in values{}` will now have three inputs.
- `i` represents the connection wire from which the input is coming.
- With `if-else` statements, each input can be either individually manipulated or receive a common manipulation.
- You have the option to output the result for one or all inputs.

# User Scenario

Review the following scenario for the Tengo Script processor function. Then, you will simulate PLC data and manipulate outputs using a single input and multiple inputs processor.

## Single Input User Scenario: Environmental Monitoring in a Factory

In a factory setting, many sensors constantly monitor air quality by measuring parameters such as CO2 levels, humidity, and temperature. Using the Tengo Script and inputting a single value, such as a CO2 emission reading, it is possible to manipulate this data stream to create a comprehensive air quality index. This can be achieved by dividing the data reading by the standard average of the factory and then multiplying it by 100.

:::CodeblockTabs
Tengo Script

```go
// Single input example

result := 0

for _, message in values{
  
  // 'value' is the CO2 emission reading.
  // Normalize this reading by dividing by a standard average and multiplying by 100
  standardAverage := 400 // Example value for standard CO2 level in parts per million
  normalizedCO2Index := (float(message["value"]) / standardAverage) * 100
  
  result = {
    "timestamp": message["timestamp"],
    "normalizedCO2": normalizedCO2Index,
    "success": message["success"],
    "actual value": message["value"]
  }
}

```
:::

## Multiple Inputs User Scenario: Manufacturing Plant Management

In a manufacturing plant, three key sensors track the production line's efficiency: one measures the speed of the conveyor belt, another monitors the temperature of machinery, and the third tracks the number of units produced for adjusting the output rate of finished products. Using the Tengo Script with these three inputs, you can optimize production efficiency. It adjusts production speed based on output rate data, converts temperature to a normalized scale for monitoring, and adjusts production rate for the number of units produced.

:::CodeblockTabs
Tengo Script

```go
// Multiple inputs example

result := 0

for i, message in values{
  
  // Adjusting conveyor speed based on output rate
  if i == "A"{
    // 'value' is the conveyor speed, adjust it based on output rate (C)
    speedAdjustmentFactor := 1 + (float(values["C"]["value"]) * 0.01)
    message["adjustedSpeed"] = float(message["value"]) * speedAdjustmentFactor
  }

  // Machinery temperature monitoring
  if i == "B"{
    // Convert temperature to a normalized scale for monitoring
    message["normalizedTemperature"] = float(message["value"]) / 100
  }

  // Monitoring and adjusting production based on output rate
  if i == "C"{
    // Adjusting production rate, 'value' is the number of units produced
    productionAdjustmentFactor := 1 + (float(message["value"]) * 0.005)
    message["adjustedProduction"] = float(message["value"]) * productionAdjustmentFactor
  }
  
  result = {
    "timestamp": values[i]["timestamp"],
    "original_value": values[i]["value"],
    "customized_value": message["adjustedSpeed"] || message["normalizedTemperature"] || message["adjustedProduction"], 
    "input_source": i,
    "success": message["success"]
  }
}

```
:::

# Step 1: Add a Device

Follow the steps to [Connect a Device](docId\:nm1lQfefyA-DSIfFitIty) and configure the following parameters:

- **Device Type**: Simulator
- **Driver Name**: Generator
- **Enable Alias Topics**: Select the checkbox.&#x20;

# Step 2: Add Tags

After connecting the device, add the following tags. See [Add a Tag](docId\:h5heqIcXrCY3NCH9KBg9I) to learn more. Each tag will be used for simulating the different user scenarios mentioned above.

## Tag 1: co2emission

- **Name**: Select **S - Random value generator**
- **Value Type:** Select **int64**
- **Polling Interval**: Enter **5**
- **Tag Name**: Enter **co2emission**
- **Min\_value**: Enter **50**
- **Max\_value**: Enter **800**

## Tag 2: speed

- **Name**: Select **S - Random value generator**
- **Value Type:** Select **float64**
- **Polling Interval**: Enter **5**
- **Tag Name**: Enter **speed**
- **Min\_value**: Enter **0**
- **Max\_value**: Enter **250**

## Tag 3: temperature

- **Name**: Select **S - Random value generator**
- **Value Type:** Select **float64**
- **Polling Interval**: Enter **5**
- **Tag Name**: Enter **temperature**
- **Min\_value**: Enter **10**
- **Max\_value**: Enter **150**

## Tag 4: units

- **Name**: Select **S - Random value generator**
- **Value Type:** Select **int64**
- **Polling Interval**: Enter **5**
- **Tag Name**: Enter **units**
- **Min\_value**: Enter **1**
- **Max\_value**: Enter **1000**

# Step 3: Create Analytics Flows

You can now create the analytics flows using data from the device and tag you previously created. Follow the appropriate step (3a or 3b) based on the two user scenarios for the Tengo Script function you want to use.

## Step 3a: Configure Single Input User Scenario

1. Navigate to **Analytics**.&#x20;
2. On the analytics canvas, click **Add processor**.
   The *Create a processor* dialog box displays.
   ![](https://api.archbee.com/api/optimize/SSUUxKZUk9bFTEPNn_6Zo/rO1yG0_YvIL0OmyZFWHCG_image.png "The Add processor option")
3. Select **DataHub Subscribe**.&#x20;
4. In the *Topic&#x20;*&#x66;ield, click the **Search&#x20;**&#x69;con, select the device you previously created, and then select the alias topic for the **co2emission** tag.
   ::Image[]{src="https://api.archbee.com/api/optimize/SSUUxKZUk9bFTEPNn_6Zo/HCuUAP6kQj3nn_RL8H1rV_image.png" size="80" width="1141" height="571" position="center" caption="Create a Processor dialog box" showCaption="true"}
5. Click **Save**.
6. Click **Add processor** again and select **Tengo script&#x20;**&#x70;rocessor.
   The following information defines this function:
   - **Timeout**: Enter **waiting period** in ms in the system before a specific event occurs.
   - **Code Block**: Copy and paste the Single Input User Scenario **code&#x20;**&#x65;xample.
     `// Single input example`
     `result := 0`
     `for _, message in values{`
     `  `
     `  // 'value' is the CO2 emission reading.`
     `  // Normalize this reading by dividing by a standard average and multiplying by 100`
     `  standardAverage := 400 // Example value for standard CO2 level in parts per million`
     `  normalizedCO2Index := (float(message["value"]) / standardAverage) * 100`
     `  `
     `  result = {`
     `    "timestamp": message["timestamp"],`
     `    "normalizedCO2": normalizedCO2Index,`
     `    "success": message["success"],`
     `    "actual value": message["value"]`
     `  }`
     `}`
7. Click **Save**.
   ::Image[]{src="https://api.archbee.com/api/optimize/SSUUxKZUk9bFTEPNn_6Zo/FhW07oPP4lc4wLvckavlH_image.png" size="80" width="1122" height="742" position="center" caption="Tengo script processor dialog box" showCaption="true"}
8. Connect the DataHub Subscribe processor (tag: *co2emission*) to the Tengo script processor with a wire and enter the definition of **co2emission&#x20;**&#x66;or the **value-type** connection.
9. On the analytics canvas, click **Save**.

The configured analytics flows should look like the following:&#x20;

::Image[]{src="https://api.archbee.com/api/optimize/SSUUxKZUk9bFTEPNn_6Zo/AvXfKMH0ocznf2CyHQB21_image.png" size="80" width="657" height="253" position="center" caption="Completed analytics canvas with one input" showCaption="true"}

## Step 3b: Configure Multiple Inputs User Scenario

1. Navigate to **Analytics**. &#x20;
2. On the analytics canvas, click **Add processor**.
   The *Create a processor* dialog box displays.
   ![](https://api.archbee.com/api/optimize/SSUUxKZUk9bFTEPNn_6Zo/T3ROoi7f2-2OTUSNggQWf_image.png "The Add processor option")
3. Select **DataHub Subscribe**.
4. In the *Topic&#x20;*&#x66;ield, click the **Search&#x20;**&#x69;con, select the device you previously created, and then select the alias topic for the **speed&#x20;**&#x74;ag.
   ::Image[]{src="https://api.archbee.com/api/optimize/SSUUxKZUk9bFTEPNn_6Zo/M1Wk0B0_fda-yJ8JahZS2_image.png" size="80" width="1141" height="571" position="center" caption="Create a Processor dialog box" showCaption="true"}
5. Click **Save**.
6. Repeat steps 2-5 to add another *DataHub Subscribe* node. Select the alias topic for the **temperature&#x20;**&#x61;nd **units&#x20;**&#x72;espectively.&#x20;
7. Click **Add processor** again and select **Tengo script&#x20;**&#x70;rocessor.
   The following information defines this function:
   - **Timeout**: Enter **waiting period** in ms in the system before a specific event occurs.
   - **Code Block**: Copy and paste the Multiple Inputs User Scenario **code&#x20;**&#x65;xample.
     `// Multiple inputs example`
     `result := 0`
     `for i, message in values{`
     `  `
     `  // Adjusting conveyor speed based on output rate`
     `  if i == "A"{`
     `    // 'value' is the conveyor speed, adjust it based on output rate (C)`
     `    speedAdjustmentFactor := 1 + (float(values["C"]["value"]) * 0.01)`
     `    message["adjustedSpeed"] = float(message["value"]) * speedAdjustmentFactor`
     `  }`
     `  // Machinery temperature monitoring`
     `  if i == "B"{`
     `    // Convert temperature to a normalized scale for monitoring`
     `    message["normalizedTemperature"] = float(message["value"]) / 100`
     `  }`
     `  // Monitoring and adjusting production based on output rate`
     `  if i == "C"{`
     `    // Adjusting production rate, 'value' is the number of units produced`
     `    productionAdjustmentFactor := 1 + (float(message["value"]) * 0.005)`
     `    message["adjustedProduction"] = float(message["value"]) * productionAdjustmentFactor`
     `  }`
     `  `
     `  result = {`
     `    "timestamp": values[i]["timestamp"],`
     `    "original_value": values[i]["value"],`
     `     "customized_value": message["adjustedSpeed"] || message["normalizedTemperature"] || message["adjustedProduction"],  `
     `    "input_source": i,`
     `    "success": message["success"]`
     `  }`
     `}`
8. Click **Save**.
   ::Image[]{src="https://api.archbee.com/api/optimize/SSUUxKZUk9bFTEPNn_6Zo/oaZxSvyAt2z4Jj-QsxMew_image.png" size="80" width="1123" height="755" position="center" caption="Tengo script processor dialog box" showCaption="true"}
9. Connect the DataHub Subscribe processor (tag: *speed*) to the Tengo script processor with a wire and enter the definition of **A&#x20;**&#x66;or the **value-type&#x20;**&#x63;onnection.
10. Connect the DataHub Subscribe processor (tag: *temperature*) to the Tengo script processor with a wire and enter the definition of **B** for the **value-type** connection.
11. Connect the DataHub Subscribe processor (tag: *units*) to the Tengo script processor with a wire and enter the definition of **C** for the **value-type** connection.
12. On the analytics canvas, click **Save**.

The configured analytics flows should look like the following:&#x20;

::Image[]{src="https://api.archbee.com/api/optimize/SSUUxKZUk9bFTEPNn_6Zo/6tcLJ0dbKGA1O1WLg1462_image.png" size="80" width="642" height="475" position="center" caption="Completed analytics canvas with multiple inputs" showCaption="true"}

# Step 4: View Output of Processor

Click the **View&#x20;**&#x69;con in the *Tengo Script&#x20;*&#x70;rocessor to view the output values.

## View Output for Single Input User Scenario

The Tengo Script function calculates the air quality index from the defined tag values and gives the output.&#x20;

::Image[]{src="https://api.archbee.com/api/optimize/SSUUxKZUk9bFTEPNn_6Zo/8krn8_AP23G5hBYckxYBg_image.png" size="80" width="922" height="536" position="center" caption="Output for Tengo script function with one input" showCaption="true"}

## View Output for Multiple Inputs User Scenario

The Tengo Script function manipulates the data from the defined tag values and gives the output.&#x20;

::Image[]{src="https://api.archbee.com/api/optimize/SSUUxKZUk9bFTEPNn_6Zo/XhsdK14Icc3FgzDcDwCaH_image.png" size="80" width="1113" height="704" position="center" caption="Output for Tengo script function with multiple inputs" showCaption="true"}

