Condition
Connect some inputs and some outputs to this node, then write rules in the schema box that describe what to watch for and what to send when a rule is met.
Every time a new value arrives on any input, the node checks all the rules. If a rule’s conditions are all satisfied, it immediately sends the values specified to the chosen outputs — then resets, ready to fire again the next time.
Note: It only fires once per “completion” — after firing, it forgets what it saw and waits for fresh values to arrive again before it can fire a second time.
Writing rules (the schema)
The schema is a JSON array — a list of rules, each with a condition and a list of actions to take when that condition is true.
// A list of rules. You can have as many as you like.
[
{
"condition": { },
"actions": [ ]
}
]Three ways to write a condition
| Type | What it means |
|---|---|
and | All of the sub-conditions must be true at the same time |
or | At least one sub-condition needs to be true |
eval | Check one input value against a number, word, or byte sequence you specify |
Setting up a check (eval)
| Setting | What to put here |
|---|---|
receiver | The name of the input to read. If the input carries a map, use a dot to reach inside it: sensor.temperature |
operator | How to compare: == != < <= > >= |
datatype | What kind of value you’re comparing against: BOOL, INT, FLOAT, STRING, BYTES |
value | The value to compare against. For BYTES, write space-separated hex digits: "00 04 FF" |
Two ways to send output (actions)
Send a fixed value — always sends the same thing, no matter what came in:
"payload": {
"type": "static",
"datatype": "STRING",
"value": "Alert!"
}Forward a value from an input — passes along whatever arrived on a given input. Use a dot to reach into a map:
"payload": {
"type": "dynamic",
"receiver": "sensor.temp"
}Example 1 — temperature alert
Fire when a sensor reads 100 or above AND the system status says "ACTIVE". Send a warning message to one output and the raw temperature number to another.
Inputs: sensor (a map containing temperature), status (a string)
Outputs: alert_channel, metrics_channel
[
{
"condition": {
"type": "and",
"operands": [
{
"type": "eval",
"receiver": "sensor.temperature",
"operator": ">=",
"datatype": "INT",
"value": 100
},
{
"type": "eval",
"receiver": "status",
"operator": "==",
"datatype": "STRING",
"value": "ACTIVE"
}
]
},
"actions": [
{
"sender": "alert_channel",
"payload": { "type": "static", "datatype": "STRING", "value": "Overheating!" }
},
{
"sender": "metrics_channel",
"payload": { "type": "dynamic", "receiver": "sensor.temperature" }
}
]
}
]Example 2 — matching byte sequences
Route two different incoming messages to different places based on a byte ID. Both rules watch the same input; whichever ID matches fires its action.
Inputs: data (a map containing frame_id as bytes)
Outputs: alert_channel
[
{
"condition": {
"type": "eval",
"receiver": "data.frame_id",
"operator": "==",
"datatype": "BYTES",
"value": "00 04 04 10"
},
"actions": [{ "sender": "alert_channel", "payload": { "type": "static", "datatype": "STRING", "value": "Hello" } }]
},
{
"condition": {
"type": "eval",
"receiver": "data.frame_id",
"operator": "==",
"datatype": "BYTES",
"value": "00 04 04 08"
},
"actions": [{ "sender": "alert_channel", "payload": { "type": "static", "datatype": "STRING", "value": "World" } }]
}
]Example 3 — two independent rules sharing inputs
Rule 1 needs sensor1 and sensor2 to both say "HIGH". Rule 2 needs sensor1 and sensor3. Each rule keeps its own memory — when Rule 1 fires and resets, Rule 2 still remembers the value it already received from sensor1.
Inputs: sensor1, sensor2, sensor3
Outputs: alert1, alert2
[
{
"condition": {
"type": "and",
"operands": [
{ "type": "eval", "receiver": "sensor1", "operator": "==", "datatype": "STRING", "value": "HIGH" },
{ "type": "eval", "receiver": "sensor2", "operator": "==", "datatype": "STRING", "value": "HIGH" }
]
},
"actions": [{ "sender": "alert1", "payload": { "type": "static", "datatype": "STRING", "value": "SCHEMA_1_FIRED" } }]
},
{
"condition": {
"type": "and",
"operands": [
{ "type": "eval", "receiver": "sensor1", "operator": "==", "datatype": "STRING", "value": "HIGH" },
{ "type": "eval", "receiver": "sensor3", "operator": "==", "datatype": "STRING", "value": "HIGH" }
]
},
"actions": [{ "sender": "alert2", "payload": { "type": "static", "datatype": "STRING", "value": "SCHEMA_2_FIRED" } }]
}
]Things to keep in mind
| Reaching inside a map | Use a dot to access a field inside a map value — e.g. sensor.temperature. Multiple levels can be chained: data.packet.id |
| Output names must match | The sender name in each action must exactly match an output added to the node |
| Input names must match | The receiver name in each condition must exactly match an input added to the node |
| Waiting for data | If a required input hasn’t arrived yet, the rule simply waits — nothing breaks |
| Multiple actions | All actions in a rule fire together the moment its condition is met |
| Sharing inputs across rules | Multiple rules can watch the same input. Each rule remembers values independently, so one firing doesn’t affect the others |