Ai-OPs
ai-ops.com
Docs
/
Tags
/

Expression Tags

Expression Tags

Expression tags compute their value from a formula evaluated by the Expression Evaluator service. Expressions can reference tags, devices, AI models, and model bindings, use arithmetic and logical operators, and call built-in math and statistical functions.

Expressions are evaluated in one of two ways:

  • Reactive: when a referenced tag updates, the expression re-evaluates immediately (within milliseconds). This is the default whenever the expression references at least one tag — through its value, status, or error code.
  • Timer-based: if the expression references no tags at all (for example it only references device, model, or binding fields), it evaluates once per second.

Common use cases include:

  • Unit conversions (e.g. Celsius to Fahrenheit)
  • Scaling raw signals (e.g. 4–20 mA to 0–100%)
  • Averaging multiple sensors
  • Smoothing noisy readings with time-aware filters
  • Computing rate of change for trend detection
  • Alarm thresholds with deadband filtering
  • Health monitoring (react to device or model failures)

References

Type @ in the expression editor to search and insert a reference. The autocomplete menu shows tags, devices, AI models, and model bindings, each with the fields you can reference.

Every reference has three segments — @[Type:Name:field]:

SegmentMeaning
TypeTag, Device, Model, or Binding
NameThe entity name as it appears in the platform. Bindings use their numeric ID
fieldvalue, status, or error_code

Status Values

status is a numeric state, not a true/false flag:

ValueState
0Stopped
1Running
2Failed

Test for the state you actually mean — == 1 for running, == 2 for failed, != 1 for "not running". An expression written as status == 0 to detect a failure never fires, because a failed entity reports 2.

Tag References

Reference a tag's live value, status, or error code:

@[Tag:Temperature Sensor:value]       → current numeric value
@[Tag:Temperature Sensor:status]      → 0 stopped, 1 running, 2 failed
@[Tag:Temperature Sensor:error_code]  → numeric error code (0 = no error)

Referencing a tag through any of these fields makes the expression reactive — it re-evaluates as soon as that tag updates.

Device References

Reference a device's connection status or error code:

@[Device:OPC-UA Server 1:status]      → 0 stopped, 1 running, 2 failed
@[Device:OPC-UA Server 1:error_code]  → numeric error code (0 = no error)

A device has no value of its own — status and error code are the only fields it exposes. Use them to publish a health flag for the connection.

Model References

Reference an AI model's status or error code:

@[Model:Chiller Model:status]      → 0 stopped, 1 running, 2 failed
@[Model:Chiller Model:error_code]  → numeric error code (0 = no error)

Binding References

Reference the raw prediction value from a model output binding. Bindings are identified by their numeric ID, not by a model/output name path:

@[Binding:42:value]       → the binding's output value
@[Binding:42:status]      → 0 stopped, 1 running, 2 failed
@[Binding:42:error_code]  → numeric error code (0 = no error)

Binding value references give you access to a model's prediction output without needing an in-memory tag to historize it first.

Arithmetic Operations

Standard math operators are supported:

OperationSymbolExampleResult
Addition+5 + 38
Subtraction-10 - 46
Multiplication*6 * 742
Division/20 / 45.0
Power**2 ** 38
Modulo%10 % 31

Comparison Operations

Comparisons return True or False and are commonly used inside conditional expressions:

OperationSymbolExampleResult
Equal==5 == 5True
Not Equal!=5 != 3True
Greater Than>10 > 5True
Less Than<3 < 7True
Greater or Equal>=5 >= 5True
Less or Equal<=3 <= 5True

Logical Operations

Combine conditions with and, or, and not:

True and True    → True
True or False    → True
not True         → False

Math Functions

Built-in math functions for common calculations:

FunctionDescriptionExampleResult
sin(x)Sine (radians)sin(1.5708)1.0
cos(x)Cosine (radians)cos(3.14159)-1.0
tan(x)Tangent (radians)tan(0.7854)1.0
sqrt(x)Square rootsqrt(16)4.0
exp(x)e raised to power xexp(1)2.718
log(x)Natural logarithmlog(2.71828)1.0
log10(x)Base-10 logarithmlog10(100)2.0
fabs(x)Absolute valuefabs(-5.5)5.5
ceil(x)Round up to integerceil(4.3)5
floor(x)Round down to integerfloor(4.7)4
trunc(x)Truncate to integertrunc(4.7)4
pow(x, y)x raised to power ypow(2, 3)8
degrees(x)Radians to degreesdegrees(3.14159)180.0
radians(x)Degrees to radiansradians(180)3.14159

Statistical Functions

Functions that operate on lists of values:

FunctionDescriptionExampleResult
mean(list)Average of valuesmean([1, 2, 3, 4, 5])3.0
median(list)Middle valuemedian([1, 3, 5, 7, 9])5
std(list)Population standard deviationstd([2, 4, 4, 4, 5, 5, 7, 9])2.0
var(list)Population variancevar([2, 4, 4, 4, 5, 5, 7, 9])4.0
min(list)Minimum valuemin([5, 2, 8, 1, 9])1
max(list)Maximum valuemax([5, 2, 8, 1, 9])9
sum(list)Sum of all valuessum([1, 2, 3, 4, 5])15

Random helpers are also available for testing and simulation: random() (float in 0–1), randint(a, b), uniform(a, b), and choice(list).

Filter Functions

Filter functions smooth, transform, or gate input signals. They maintain internal state across evaluations, so each call remembers its previous output.

filter: Exponential Moving Average

filter(value, tau) applies an exponential moving average. The tau parameter is the time constant in seconds. It controls how quickly the output tracks the input, regardless of how often the expression evaluates.

ParameterDescription
valueThe current input value
tauTime constant in seconds. Larger values = more smoothing

At each evaluation the filter computes: alpha = 1 - e^(-dt / tau), then output = alpha x input + (1 - alpha) x previous. On the first evaluation the output equals the input.

ExpressionDescriptionUse Case
filter(@[Tag:Temperature:value], 5)5-second time constantFast-changing signals, light smoothing
filter(@[Tag:Pressure:value], 30)30-second time constantModerate noise reduction
filter(@[Tag:Level:value], 120)2-minute time constantVery noisy sensors, stable reading needed

moving_avg: Moving Average

moving_avg(value, window) computes the average of all samples received within the last window seconds.

ParameterDescription
valueThe current input value
windowWindow size in seconds
ExpressionDescription
moving_avg(@[Tag:Flow:value], 60)Average flow over the last 60 seconds
moving_avg(@[Tag:Power:value], 300)5-minute rolling average of power consumption

rate: Rate of Change

rate(value) returns the rate of change of the input in units per second. It only updates when the input actually changes, so repeated evaluations with a stale value don't distort the result.

ParameterDescription
valueThe current input value
ExpressionDescription
rate(@[Tag:Temperature:value])Degrees per second of temperature change
rate(@[Tag:Level:value]) * 60Level change per minute

deadband: Deadband Filter

deadband(value, threshold) only passes through changes larger than threshold. The output holds its last accepted value until the input moves far enough away.

ParameterDescription
valueThe current input value
thresholdMinimum change to pass through (must be > 0)
ExpressionDescription
deadband(@[Tag:Setpoint:value], 0.5)Ignore changes smaller than 0.5
deadband(filter(@[Tag:Noisy:value], 10), 1.0)Smooth first, then deadband

Conditional Expressions

Use Python's ternary syntax for if-else logic:

value_if_true if condition else value_if_false
ExpressionDescription
1 if @[Tag:Switch:value] == 1 else 0Binary output based on switch state
@[Tag:Temp:value] * 1.8 + 32 if @[Tag:Units:value] == 1 else @[Tag:Temp:value]Convert to Fahrenheit if units flag is set
100 if @[Tag:Valve:value] == 1 else 50 if @[Tag:Valve:value] == 0.5 else 0Multiple conditions (nested)

Practical Examples

Temperature Conversion

Celsius to Fahrenheit:

@[Tag:Temperature C:value] * 1.8 + 32

Scaling and Offset

Convert a 4–20 mA signal to 0–100%:

(@[Tag:Current:value] - 4) * 100 / 16

Average of Multiple Sensors

(@[Tag:Sensor1:value] + @[Tag:Sensor2:value] + @[Tag:Sensor3:value]) / 3

Device Health Flag

Output 1 while the device connection is up, 0 when it is stopped or failed:

1 if @[Device:Primary OPC-UA:status] == 1 else 0

Device Failure Alarm

Raise an alarm only on a genuine failure, so a device you deliberately disabled does not trigger it:

1 if @[Device:Primary OPC-UA:status] == 2 else 0

Model Health Check

Output 1 when the AI model is running, 0 when it's stopped or failed:

1 if @[Model:Chiller Model:status] == 1 else 0

Alarm with Deadband

High alarm above 95 that ignores input movements smaller than 5 units, so a value hovering around the threshold does not chatter the alarm on and off:

1 if deadband(@[Tag:Process:value], 5) > 95 else 0

Smoothed Differential

Smoothed pressure differential with a 30-second time constant:

filter(@[Tag:Pressure In:value] - @[Tag:Pressure Out:value], 30)

Rate of Temperature Change

Degrees per minute:

rate(@[Tag:Supply Temp:value]) * 60

Smoothed Deadband

Reduce noise first, then gate small changes:

deadband(filter(@[Tag:Vibration:value], 10), 0.5)