Automation Rules

React to data changes automatically with visual rule chains.

Overview

Automation Rules in ControlBird are built with the Rule Chain Editor, a node-based visual programming interface for expressing automation logic without hand-writing code. You assemble nodes on a canvas (a trigger Input, data-processing and control-flow nodes, and one or more action outputs) and connect them with wires that describe how data flows from left to right.

Once saved, a chain runs in response to entity field changes, a cron schedule, or a manual invocation. Reach for Automation Rules whenever you need reactive, store-driven logic: threshold alarms, unit conversions, derived values, scheduled health checks, or routing data between entities.

Prefer a guided tutorial?

New to this? Follow the Create Automation walkthrough for a step-by-step tour, then come back here for the full reference.

Key Concepts

A rule chain combines a visual definition, the logic it runs, and a trigger that decides when that logic runs.

ConceptWhat it does
Rule chainThe visual program: the node graph plus the logic it runs.
GraphThe nodes and connections you assemble on the canvas.
TriggerWhat starts a chain: an entity-change notifier, a cron scheduler, or a manual execution.
Input dataThe payload handed to the chain's Input node, shaped by the trigger type (see below).

Node types

The editor offers 18+ node types, grouped by role. Data flows from the single Input node through processing and control-flow nodes to action outputs.

GroupNodesRole
TriggerInput (entity-change, timer, manual)The single entry point that starts the chain.
Data processingFilter, Transform, SwitchPass/block, reshape, or route data based on conditions.
Control flowDelay, Time ConditionPause or gate the flow on timing.
Data accessFind Entities, Read Entity, Read HistoryQuery the Store and the Historian.
ActionsWrite Field, Create Entity, Log, Custom CodeEffect changes, create entities, log, or run arbitrary code.
AnalyticsPID controller, Kalman filterClosed-loop control and signal estimation.
CompositionCall Rule Chain, ReturnInvoke another chain and return a value.

Trigger input shapes

The structure of the data delivered to the Input node depends on how the chain was triggered.

TriggerInput data
Entity changeThe entity id, the changed value, and the timestamp of the change.
TimerThe timestamp the schedule fired (milliseconds since epoch).
ManualThe custom JSON payload configured on the trigger, or an empty object.

Triggers

A rule chain runs in one of three ways. You configure triggers from the entity tree and the rule chain's settings.

On entity change

Run a chain whenever a field changes. You choose which entity type to watch, optionally a specific entity, and the field to monitor. You can also choose whether the chain fires only when the value actually changes or on every write. The changed value, its timestamp, and the entity id are passed to the chain as its input data.

On a schedule

Run a chain on a recurring schedule using a standard 5-field cron expression (minute, hour, day-of-month, month, day-of-week). The timestamp the schedule fired is passed to the chain.

Manually

Run a chain on demand. You can attach a custom JSON payload that is passed to the chain as its input data.

Execution Model

When a chain is triggered, ControlBird runs its logic in a sandboxed JavaScript runtime. Saving graph changes updates what the chain runs automatically. Each chain tracks how many times it has run, how many runs succeeded or failed, when it last ran, the status of the last run, and the message from the most recent error.

One instance runs automation at a time

Scheduled and notified rule chains execute only on the active instance. In a multi-instance deployment, a single instance runs all automation while the others stay on standby, taking over automatically if the active instance becomes unavailable.

Reading and writing data

Custom Code nodes can read and write entity fields, create entities, find entities by type, and query historical data from within the chain. All calls are synchronous.

Configuration Examples

Filter and transform expressions

Filter and Transform nodes use JavaScript expressions over the incoming data object:

// Filter conditions
data.value > 100
data.status === 'active'
data.temperature >= 20 && data.temperature <= 30

// Transform node: add a derived field, pass the rest through
return { ...data, fahrenheit: data.celsius * 9/5 + 32 };

Common Patterns

  • Threshold alarm. Input (entity-change) → Filter (data.value > 100) → Write Field on an alarm entity.
  • Unit conversion. Input → Transform (return { ...data, fahrenheit: data.celsius * 9/5 + 32 };) → Write Field.
  • Scheduled sweep. A scheduled trigger fires a chain that uses Find Entities to read many entities and write a derived summary.
  • Composition. A Call Rule Chain node passes input to a child chain and receives the value produced by the child chain's Return node, letting you build reusable sub-chains.
  • Closed-loop control. Read History feeds a PID controller or Kalman filter node; both require a historian table to be configured.

Node behaviors worth knowing

  • Filter auto-routes errors to its false output.
  • Transform passes the original data through unchanged when its code throws.
  • Write Field requires a target entity, a field, and a value expression.
  • Create Entity takes an entity type, a parent, and a name, and returns the new entity's id.

Validation

The compiler validates a chain before it can run. A chain must satisfy all of the following:

  • Exactly one Input node.
  • Every non-input node has an incoming connection (no disconnected nodes).
  • The graph is acyclic: no cycles are permitted.
  • For manual and timer triggers, action nodes must be entity-bound, and there must be at least one output path from Input to an action node.
  • Read History, PID, and Kalman nodes must have a historian table configured.

Entity binding

Set entity binding by dragging a data point from the entity tree onto the canvas (which also switches the Input node to entity-change), or configure it manually. A “Entity binding required” validation error means you must either drag a data point onto the canvas (for entity-change) or configure at least one entity-bound action (for timer/manual triggers).

Limitations & Troubleshooting

  • Synchronous JavaScript only. The script runtime does not support async/await, Promises, fetch(), or setTimeout().
  • Delay nodes block the chain. The chain pauses for the full delay before continuing, so avoid delays beyond a few hundred milliseconds.
  • Store calls are synchronous and serialized. Reading or writing many entities in a loop is slow and can block execution; concurrent writes from multiple chains run one at a time.
  • Historian table names are exact and case-sensitive. Historian queries will not find a table by an approximate name.
  • Triggering on every write is noisy. When you choose to trigger on every write rather than only on change, the chain fires on every write, including writes that overwrite a value with the same value.
  • Cron uses the 5-field format (minute hour day-of-month month day-of-week). Minute 0 means the top of the hour, not every minute.
  • Saving updates what the chain runs. Saving graph changes regenerates the chain's logic from the current graph, so the saved graph is always the source of truth.
  • The last error reflects only the most recent run: older errors are overwritten. For full execution history, check the program logs in the data/{NODE_ID}/program-logs/ directory, which keeps a rotated log file per rule chain.