Skip to content

Variables in Workflows

Introduction to Variables

Variables are named containers that store data produced by tasks and can be used by subsequent tasks. They enable data flow and communication between different stages of a workflow.


Built-in Special Variables

Besides variables you declare yourself, AndroMate provides built-in special variables resolved automatically by the runtime — no Start declaration, no task needed to produce them.

Syntax is different from your own variables: special variables use curly braces${NAME} — while your declared variables use a plain $ prefix — $NAME. The resolver ([AndroMateContext.resolveSpecialVariables]) replaces any ${NAME} token it finds in a task parameter with its live value at execution time, the same way it replaces $NAME with a value from the runtime dictionary.

Use a special variable directly inside any parameter that accepts text — no extra task, no Start variable required:

{
  "SetAndromateVariable": [
    {
      "id": "1",
      "variable_input": "$SMS_MESSAGE",
      "variable_value": "Battery Level: $BATTERY_LEVEL%, Timestamp: ${CURRENT_DATE}"
    }
  ]
}

Time

Special variable Resolved value Format
${CURRENT_TIME_STAMP} Current Unix epoch time in milliseconds e.g. "1770963342000"
${CURRENT_DATE} Current date and time on the device "dd/MM/yyyy HH:mm:ss", e.g. "13/08/2026 09:15:42"
${UPTIME_MS} Milliseconds since the device last booted (excludes deep sleep) e.g. "48213045"
${ELAPSED_REALTIME_MS} Milliseconds since boot, including deep sleep e.g. "52007112"

OS

Special variable Resolved value
${CURRENT_SDK} Android SDK level, e.g. "34"
${ANDROID_VERSION} Android release version, e.g. "14"
${ANDROID_CODENAME} Android codename, e.g. "UpsideDownCake"

Device

Special variable Resolved value
${MANUFACTURER} Device manufacturer, e.g. "samsung"
${MODEL} Device model, e.g. "SM-S911B"
${DEVICE} Device codename
${BRAND} Device brand
${PRODUCT} Product name
${BOARD} Board name
${HARDWARE} Hardware name
${HOST} Build host
${ID} Build ID
${TAGS} Build tags
${TYPE} Build type
${USER} Build user

Boolean literals

Special variable Resolved value
${TRUE} "true"
${FALSE} "false"

Enum comparison constants

Used to compare a task's output against a known enum value (e.g. in a CompareStrings task) instead of hardcoding the string:

Special variable Resolved value Produced by
${CHARGING_TYPE_USB} "USB" GetChargingType
${CHARGING_TYPE_AC} "AC" GetChargingType
${CHARGING_TYPE_WIRELESS} "Wireless" GetChargingType
${CHARGING_TYPE_NONE} "None" GetChargingType
${BATTERY_HEALTH_GOOD} "Good" GetBatteryHealth
${BATTERY_HEALTH_OVERHEAT} "Overheat" GetBatteryHealth
${BATTERY_HEALTH_DEAD} "Dead" GetBatteryHealth
${BATTERY_HEALTH_OVER_VOLTAGE} "Over Voltage" GetBatteryHealth
${BATTERY_HEALTH_COLD} "Cold" GetBatteryHealth
${BATTERY_HEALTH_UNKNOWN} "Unknown" GetBatteryHealth
${BATTERY_STATUS_CHARGING} "Charging" GetBatteryStatus
${BATTERY_STATUS_DISCHARGING} "Discharging" GetBatteryStatus
${BATTERY_STATUS_FULL} "Full" GetBatteryStatus
${BATTERY_STATUS_NOT_CHARGING} "Not Charging" GetBatteryStatus
${BATTERY_STATUS_UNKNOWN} "Unknown" GetBatteryStatus

Special variables vs. declared variables

Declared variable ($NAME) Special variable (${NAME})
Declaration Required in Start.variables None — always available
Source of value A task's output Device/system state, resolved live
Fixed list No — you choose the name Yes — fixed set defined by the runtime
Typical use Passing data between tasks Timestamps, device info, enum comparisons

Variable Declaration and Roles

Variables must be declared in the START node with these characteristics:

  • Naming: Must start with $ (mandatory prefix)
  • Scope: Available throughout the entire workflow
  • Types Supported:
  • String - Text values
  • Double - Decimal numbers
  • JSON - Complex structured data

Example: Variable Declaration in START Node

{
  "Start": [
    {
      "id": "0",
      "variables": [
        {
          "variableName": "$PING_ERROR",
          "variableValue": "",
          "is_kpi": false
        },
        {
          "variableName": "$NETWORK_STATUS",
          "variableValue": "unknown",
          "is_kpi": false
        },
        {
          "variableName": "$TEMPERATURE",
          "variableValue": "0.0",
          "is_kpi": true
        }
      ]
    }
  ]
}

Task Output Registration

Task outputs can be registered into variables declared in START for reuse in other tasks:

{
  "CmdStage": [
    {
      "id": "1",
      "cmd_text": "ping -c 1 8.8.8.8",
      "cmd_error_output": "$PING_ERROR"
    }
  ]
}

How it works: 1. Declare variable $PING_ERROR in START node 2. Task CmdStage (id:1) executes ping command 3. Error output is automatically stored in $PING_ERROR 4. Variable becomes available for subsequent tasks


Variable Usage in Other Tasks

Once a variable is populated by a task output, it can be used in subsequent tasks:

{
  "CompareText": [
    {
      "id": "2",
      "text_x": "$PING_ERROR",
      "text_y": "unreachable",
      "compare_type": 2
    }
  ]
}

Variable references: - Use the variable name with $ prefix: $PING_ERROR - Can be used in any parameter that accepts variable values - Variable persists until workflow ends


Variable Types and Examples

Type Example Declaration Task Output Usage
String "$ERROR_MSG" "variableValue": "" cmd_error_output CompareText, TextReport
Double "$TEMPERATURE" "variableValue": "0.0" ntp_offset_output CompareNumber
JSON "$RESPONSE_DATA" "variableValue": "{}" http_response_output Parse, extract

String Variables

Store text data produced by commands or APIs:

"variableName": "$ERROR_MESSAGE",
"variableValue": ""

Usage: Error messages, command outputs, API responses

Double Variables

Store decimal numbers for arithmetic operations and comparisons:

"variableName": "$TEMPERATURE",
"variableValue": "0.0"

Usage: Temperature values, sensor readings, metrics

JSON Variables

Store complex structured data for detailed processing:

"variableName": "$API_RESPONSE",
"variableValue": "{}"

Usage: API responses, data arrays, nested objects


Complete Workflow Example with Variables

{
  "Start": [
    {
      "id": "0",
      "variables": [
        {
          "variableName": "$PING_ERROR",
          "variableValue": "",
          "is_kpi": false
        },
        {
          "variableName": "$NETWORK_STATUS",
          "variableValue": "unknown",
          "is_kpi": false
        },
        {
          "variableName": "$RESPONSE_TIME",
          "variableValue": "0.0",
          "is_kpi": true
        }
      ]
    }
  ],

  "CmdStage": [
    {
      "id": "1",
      "cmd_text": "ping -c 1 8.8.8.8",
      "cmd_error_output": "$PING_ERROR"
    }
  ],

  "CompareText": [
    {
      "id": "2",
      "text_x": "$PING_ERROR",
      "text_y": "unreachable",
      "compare_type": 2
    }
  ],

  "TextReport": [
    {
      "id": "3",
      "texte": "Network unreachable: $PING_ERROR"
    },
    {
      "id": "4",
      "texte": "Network available - Status: $NETWORK_STATUS"
    }
  ],

  "End": [{"id": "100"}],

  "Links": [
    {"from": "0", "to": "1"},
    {"from": "1", "to": "2"},
    {"from": "2", "true": "3", "false": "4"},
    {"from": "3", "to": "100"},
    {"from": "4", "to": "100"}
  ]
}

Variable Data Flow

flowchart LR
    Start["START<br/>Declare Variables<br/>$PING_ERROR<br/>$NETWORK_STATUS<br/>$RESPONSE_TIME"] -->|"Register output"| Task1["CmdStage<br/>ping -c 1 8.8.8.8<br/>→ $PING_ERROR"]
    Task1 -->|"Use variable"| Task2["CompareText<br/>$PING_ERROR contains<br/>unreachable?"]
    Task2 -->|"TRUE: Use variable"| Task3["TextReport<br/>Display $PING_ERROR"]
    Task2 -->|"FALSE: Use variable"| Task4["TextReport<br/>Display $NETWORK_STATUS"]
    Task3 --> End["END"]
    Task4 --> End

    style Start fill:#e3f2fd
    style Task1 fill:#f3e5f5
    style Task2 fill:#fff9c4
    style Task3 fill:#ffe0e0
    style Task4 fill:#e0f0e0
    style End fill:#c8e6c9

Best Practices

1. Declare All Variables in START

Declare variables upfront in the START node:

{
  "Start": [
    {
      "id": "0",
      "variables": [
        {"variableName": "$VAR1", "variableValue": ""},
        {"variableName": "$VAR2", "variableValue": "0.0"}
      ]
    }
  ]
}

2. Use Descriptive Variable Names

"$PING_ERROR"      // Good: Clear purpose
"$NETWORK_STATUS"  // Good: Descriptive

"$x"               // Bad: Not descriptive
"$var1"            // Bad: Generic name

3. Initialize with Appropriate Defaults

"$ERROR_MSG": ""           // String: empty string
"$TEMPERATURE": "0.0"      // Double: zero value
"$RESPONSE": "{}"          // JSON: empty object

4. Use Variables for Data Continuity

Pass data between tasks using variables instead of hardcoding values:

// ✅ Good: Use variable
"text_x": "$PING_ERROR"

// ❌ Bad: Hardcoded value
"text_x": "Network unreachable"

Variable Lifecycle

  1. Declaration - Variable declared in START node
  2. Initialization - Given initial value (usually empty/zero)
  3. Population - Task output registers value in variable
  4. Usage - Subsequent tasks reference the variable
  5. Persistence - Value persists until workflow ends

Common Use Cases

Case 1: Error Handling

{
  "CmdStage": [{"id": "1", "cmd_error_output": "$ERROR"}],
  "CompareText": [
    {"id": "2", "text_x": "$ERROR", "text_y": "failed"}
  ]
}

Case 2: Conditional Branching

{
  "CmdStage": [{"id": "1", "cmd_result_output": "$RESULT"}],
  "CompareNumber": [
    {"id": "2", "num_x": "$RESULT", "num_y": "100"}
  ]
}

Case 3: Data Passing

{
  "HttpRequest": [{"id": "1", "response_output": "$API_DATA"}],
  "TextReport": [
    {"id": "2", "texte": "Response: $API_DATA"}
  ]
}