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.
| Concept | What it does |
|---|---|
| Rule chain | The visual program: the node graph plus the logic it runs. |
| Graph | The nodes and connections you assemble on the canvas. |
| Trigger | What starts a chain: an entity-change notifier, a cron scheduler, or a manual execution. |
| Input data | The 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.
| Group | Nodes | Role |
|---|---|---|
| Trigger | Input (entity-change, timer, manual) | The single entry point that starts the chain. |
| Data processing | Filter, Transform, Switch | Pass/block, reshape, or route data based on conditions. |
| Control flow | Delay, Time Condition | Pause or gate the flow on timing. |
| Data access | Find Entities, Read Entity, Read History | Query the Store and the Historian. |
| Actions | Write Field, Create Entity, Log, Custom Code | Effect changes, create entities, log, or run arbitrary code. |
| Analytics | PID controller, Kalman filter | Closed-loop control and signal estimation. |
| Composition | Call Rule Chain, Return | Invoke 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.
| Trigger | Input data |
|---|---|
| Entity change | The entity id, the changed value, and the timestamp of the change. |
| Timer | The timestamp the schedule fired (milliseconds since epoch). |
| Manual | The 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 Chainnode passes input to a child chain and receives the value produced by the child chain'sReturnnode, 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(), orsetTimeout(). - 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
0means 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.