"Create automated control loops without coding. Configure sensors, conditions, and actions visually — similar to PLC programming. Your control loops are automatically converted to LUA scripts visible in the Programs tab."

When you create a new control loop (New +), the editor shows two main tables:
The top table lists sensors — devices the loop reads from.
| Column | Meaning |
|---|---|
| Device | The physical device name (e.g. RIO-1, Sonoff-3). |
| Port | Which specific port/channel on the device. |
| Description | A human-readable label (e.g. "Office temperature sensor"). |
| X | The coordinate reference used in formulas — X1 for the first input, X2 for the second, etc. |
| Value | The current value being read from this sensor. |
The bottom table lists actuators — devices the loop controls.
| Column | Meaning |
|---|---|
| Device | The physical device name. |
| Port | Which port/channel. |
| Description | Human-readable label. |
| Y | The coordinate reference — Y1 for the first output, Y2 for the second, etc. |
| Value | This is where you write the formula. The formula references input coordinates (X1, X2...) and produces the output. For example: IF(X1>25, 1, 0) turns the output ON when the temperature (X1) exceeds 25°C. |
Click Add virtual output to add more output rows.


On the right side of the editor, an expandable Table Syntax Guide provides reference for writing formulas. Sections include:
| Button | What It Does |
|---|---|
| Timing | Set how often the loop executes (e.g. every 1 second, every 5 seconds, every minute). |
| Close Guide | Hide/show the Syntax Guide panel. |
| Devices | Add input sensors and output actuators to the tables. |
| Save | Save the control loop. It is automatically converted to a Lua script. |
| Close | Exit the editor. |
The following functions and operators are available in Control Loop formulas (sourced from the official Abilis tutorial):
Standard arithmetic: + (addition), - (subtraction),
* (multiplication), / (division), ( ) (brackets for grouping).
| Function | What It Does |
|---|---|
ABS(value) | Returns the number with a positive sign (absolute value). |
EVEN(value) | Returns 1 if the number is even, 0 if odd. |
ODD(value) | Returns 1 if the number is odd, 0 if even. |
INT(value) | Returns the integer part, removing decimals. |
ROUND(value, decimals) | Rounds the number to the specified decimal places. |
LOG10(value) | Returns the base-10 logarithm. |
MOD(value) | Returns the decimal part, removing the integer. |
RAND() | Returns a random decimal between 0 and 1. |
RANDBETWEEN(from, to) | Returns a random integer between the two values. |
POW(value, exponent) | Raises the number to the exponent. Use decimals for roots (e.g. POW(X1, 0.5) = square root). |
SQRT(value) | Returns the square root. |
| Function | What It Does |
|---|---|
NOT(value) | Returns true if input is false, and vice versa. |
AND(v1, v2 [, v3...]) | Returns true only if all inputs are true. Up to 10 values. |
OR(v1, v2 [, v3...]) | Returns true if any input is true. Up to 10 values. |
XOR(v1, v2) | Returns true if exactly one input is true and the other is false. |
IF(condition, value_if_true, value_if_false)
Example: IF(X1>25, 1, 0) → output 1 when temperature exceeds 25°, otherwise 0.
You can reference a device's previous value by adding a time offset in brackets:
X1(time_to_past). The time unit is determined by the interval set in the
Timing section of the loop. For example, if timing is set to 5 seconds,
X1(3) means "the value of X1 from 15 seconds ago" (3 × 5s).
Functions can be chained by nesting one inside another. For example, to get the average of the square root of two sensor inputs:
AVERAGE(POW(X1, 0.5), POW(X2, 0.5))