Trigger Reference

The 28 blocks that start a flow when a device reports something, what fires each one, and the three rules that decide how often: transitions fire on the change, thresholds fire on the crossing, and an unknown previous value seeds instead of firing.

A trigger block has a flow OUT pin and no flow IN pin, which is what makes it a start-of-flow block. It is not reached by the flow walk; the device event dispatcher seeds its out pins and starts the flow from there, the same way a schedule block works.

Every trigger on this page fires only for adopted devices. The single exception is device discovered, whose purpose is to notice devices that are not adopted yet.

The Rules That Surprise People

Transition Triggers Fire on the Change, Not on Every Report

A motion sensor does not send one message when somebody walks in. It re-announces occupancy: true every thirty seconds or so while a person is in the room, and a power meter reports every ten seconds whether or not anything changed.

Every binary trigger requires the value to have changed. So presence detected in a hallway with somebody standing in it fires once, on entry. Without that rule a "turn on the lights" flow would re-run continuously and a "send me a notification" flow would be unusable.

The one deliberate exception is button pressed. A button publishes single and stays single until the next press, so a value-equality test would swallow every repeat. A momentary capability has no meaningful "unchanged", so every press fires.

Threshold Triggers Fire on the Crossing, Not on the Level

temperature changed with above = 25 fires once, when the room passes 25 °C. It does not fire again at 25.5, or 26, or every minute for the rest of the afternoon. It fires again only after the reading has gone back below 25 and crossed up again.

This is the single most common way a threshold automation turns into a notification flood, so the rule is in the platform rather than in your flow. The exact test is: the new reading is above the threshold, and the previous one was at or below it.

One deliberate wrinkle. A first-ever reading above the threshold counts as a crossing, because there is no previous value to have crossed from, and staying silent until the second reading would mean a node restart swallows an alarm.

Setting neither above nor below turns the threshold off entirely and the trigger fires on every changed reading, which for a sensor reporting each minute is a busy flow. Setting both fires on either crossing. Note that 0 is a legitimate threshold and is treated as one: leaving a pin empty is what turns it off, not setting it to zero.

An Unknown Previous Value Seeds Instead of Firing

When the node has no previous value for a capability, an incoming reading is recorded without counting as a transition. Nothing fires; the value is simply learned.

That rule exists because of what a restart otherwise does. With an empty registry, every adopted sensor re-announces the state it has been in for hours, and treating each first report as a change turns a routine restart into a burst of "door opened" and "light turned on" for things that did neither. A window open all night would announce itself as just opened at 03:00, run the alarm flow and switch the lights on.

There are exactly three exceptions, where the asymmetry runs the other way: smoke, gas and water_leak. A duplicate "smoke detected" is an annoyance; a missed one is the thing the sensor exists to prevent. So a node that comes back up to an alarm already sounding says so, and accepts the occasional repeat. Occupancy, contact and vibration are deliberately not on that list: they are the high-frequency ones, they are what a restart most often finds mid-state, and nothing catastrophic follows from learning about them one report late.

Momentary capabilities are also unaffected, because they have no persistent state to seed. Every button press is an event by definition.

In practice you will rarely see this, because last-known state is restored from Redis before the adapters connect, so the first report after a restart usually does have something to compare against. The seeding rule is what makes the behaviour correct even when it does not: a fresh install, a flushed Redis, a device heard from for the first time. See What Survives a Restart.

Every Trigger Has the Same Shape

Two in-pins narrow which devices a trigger listens to, and both are optional.

In-pinEffect
deviceOnly this device. Accepts the platform id, the native id or the exact device name. Leave it empty and the trigger fires for every matching device, which is what makes one block able to be the whole-house version.
roomOnly devices in this room, compared case-insensitively. Empty means every room.

Leaving the device pin optional is the design decision that keeps this usable. Requiring it would force one flow per sensor, which is the shape that makes home automation tedious.

Out-pins are identical on all of them, and the two access-entry triggers add three more:

Out-pinTypeCarries
flowflowThe chain to run.
deviceobjectThe whole device: id, name, room, type, capabilities, current state. Branch on model or battery without a second block.
device idvalueThe stable platform id, ready to feed another block's device pin.
namevalueThe friendly name. There because the common case is putting it in a message, and reaching into an object for that is friction.
roomvalueThe device's room, empty if none.
typevaluesensor, light, switch, climate, cover, lock, button, door or camera.
capabilityvalueWhich capability changed. The pin to branch on when using the catch-all trigger.
valuevalueThe new value.
previousvalueThe value before this change. Empty on the first report.
atnumberUnix seconds the device reported.
actorvalueAccess granted and access denied only. Who: the user or credential name, empty when the reader could not identify them.
methodvalueAccess triggers only. How: nfc, pin, wave, mobile, touchpass or manual.
grantedconditionAccess triggers only. True when access was allowed.

Sensors, the General Ones

BlockFires when
sensor activated Any sensor capability transitions false to true: motion detected, a door opened, water found, smoke detected, gas detected, vibration. The extra sensor type pin narrows it to one of occupancy, contact, water_leak, smoke, gas, vibration; empty means any of them.
sensor deactivated The mirror: a sensor capability transitions true to false.

"Sensor" here means the binary capabilities that describe the world. It excludes power, which has its own light and switch triggers, and excludes tamper and battery_low, which are device health. Folding power in would make every whole-house sensor flow fire on its own lighting changes and livelock.

On sensor deactivated, remember whose delay you are seeing. A motion sensor clears after its own configured stillness timeout, often 60 to 120 seconds, so this fires when the sensor says clear, not when the room empties.

sensor activated starts the flow when a sensor turns ON, and the two value blocks are what narrow it: sensor type keeps it to leak detectors, room keeps it to the basement. Both are optional, and leaving them empty makes this one block the whole-house version. It fires on the TRANSITION, so a sensor sitting in a puddle and re-reporting fires the flow once, and the flow shuts the valve with switch off.

Studio canvas example for the sensor activated block: one trigger for every sensor of one kind.

Presence and Access

BlockFires when
presence detected occupancy goes false to true. Equivalent to sensor activated with the sensor type set to occupancy, and it exists as its own block because it is the single most common automation there is.
presence cleared occupancy goes true to false. The delay before this fires is the sensor's, not the platform's.
contact opened contact goes true, which means open. Zigbee and Matter both report contact true for a closed door on the wire; that inversion is corrected at the adapter, so value here is true when the door is open.
contact closed contact goes false, meaning closed.

Alarms

BlockFires when
water leak detected water_leak transitions to true. On the transition, so a sensor sitting in a puddle and re-reporting fires once.
smoke detected smoke transitions to true.

These supplement a certified alarm, they do not replace one. They depend on a mesh, a broker and a node all being up. Gas has no dedicated trigger; use sensor activated with the sensor type set to gas.

Lights and Switches

BlockFires when
light turned on A device classified as a light transitions power false to true.
light turned off The same device type transitions power true to false.
switch turned on A device classified as a switch transitions power false to true.
switch turned off The same, true to false.

These fire for changes RUAL did not make. A physical wall switch, the Hue app, a scene fired by a dimmer: the radio reports the new state and the trigger fires. That is usually the point, and it is occasionally a trap, because a flow that turns a light on in response to a light turning on is a loop.

The light/switch split follows the derived device type, not the vendor's opinion. A device with on/off but no brightness or colour is a switch, so metering plugs land here rather than under lights, even when the vendor announces them as lights.

Buttons and Scene Controllers

BlockFires when
button pressed Any momentary control emits an action: Aqara buttons, Hue dimmers, scene switches. Fires on every press, including a repeat of the same press type.

Branch on the value pin to tell single from double from hold. The exact strings are the device's own. Common ones are single, double, hold and release, but a four-button remote sends things like 1_single and a Hue dimmer sends initial_press and long_release. Press the button once with the Zigbee2MQTT frontend open, or read the device state through get device, and use what it actually sends rather than what it ought to.

Environment Readings

BlockExtra pinsFires when
temperature changed above, below, in °C The temperature capability changes. With a threshold set, only on the crossing.
humidity changed above, below, in % The humidity capability changes. Same crossing semantics.

Other numeric capabilities have no dedicated trigger. For illuminance, CO₂, power draw or a blind's position, use device state changed and branch on the capability pin, or read the value with get device state inside a flow another trigger started. The threshold-crossing behaviour is specific to these two blocks.

Device Health and the Fleet

BlockFires when
battery low The battery percentage crosses below the below % pin, default 20, or the device raises its own battery_low flag. Both dialects are handled because devices implement one or the other and rarely both.
device unavailable A device transitions to unreachable: a flat battery, out of range, a bulb switched off at the wall. It does not repeat while the device stays away. There is no matching "device came back" trigger; use get status or a periodic get all devices sweep if you need one.
device discovered A new device appears on the radio, before it is adopted. Fires once per device, the first time it is ever seen. The one trigger that fires for unadopted devices.
device adopted A device is taken into service, whether by the API, the studio or a flow calling device adopt. Use it to set a room, apply defaults or announce the new device.

The Catch-All

BlockFires when
device state changed Any capability of any adopted device changes.

High volume by design. A house with a dozen sensors produces hundreds of these an hour. Use it for logging, and for capabilities that have no dedicated trigger, then branch on the capability pin. Where a specific trigger exists, use the specific trigger: it is cheaper and it says what it means on the canvas.

Doors, Access Control and Cameras

These eight arrive with the UniFi Access and Protect adapter, and they are the automations people actually want from a door: when someone rings, when a card is swiped, when the gate opens, when an unknown card is refused at three in the morning.

They ship with rual-core PR 312, which is open at the time of writing, so unlike the blocks above they do not have block pages here yet. Those appear on their own once the block catalog syncs.

BlockExtra pinsFires when
doorbell rang Somebody rings a doorbell or door station, from a UniFi door station or a Protect doorbell camera. Momentary: there is no "still ringing" state.
door or gate opened door_position transitions to true, meaning open. This is the physical position, not the lock: a door can be unlocked and shut.
door or gate closed door_position transitions to false. Pair it with a delay for "the gate has been open too long".
access granted method Somebody is let in: a valid card, PIN, wave or mobile credential. The method pin narrows it to one of nfc, pin, wave, mobile, touchpass. Does not fire on a refusal.
access denied Somebody is refused: an unknown card, a wrong PIN, a credential outside its schedule.
NFC card swiped card A card or fob is presented, regardless of the decision that follows. The card pin narrows it to one token or actor.
camera motion detected A UniFi Protect camera detects motion. One event per detection, not a sustained state.
security alarm activated The controller's own alarm transitions to active. Distinct from the smoke, gas and leak triggers, which are individual detectors.

The two entry triggers carry three extra out-pins, because "someone came in" is only useful with who and how: actor (the user or credential name, empty when the reader could not identify them), method, and granted. They sit beside the standard pins rather than buried in the device object.

Swiped and granted are different questions. NFC card swiped fires when the card is presented, before and regardless of the decision, which is what you want for "when my gym fob is tapped, turn on the porch light". access granted fires only when the door actually opened to somebody. A refused card fires the first and not the second.

One caveat on repeats. Doorbell and camera motion events carry the moment they happened, so consecutive events differ and each one fires; two in the same second collapse into one. NFC carries the card token, so the same card presented twice in a row with nothing in between does not fire the second time. If you need every tap counted, read the access event instead, which carries the full payload.

How Dispatch Actually Works

Two properties are worth knowing because they explain both the speed and the limits.

Dispatch is in process, not queued. Every other trigger in RUAL goes through the queue, which buys durability at the cost of a write and a poll interval. That trade is wrong here: the entire value of "when motion is detected, turn on the light" is that it happens before you have finished walking through the door, and a queue round trip is hundreds of milliseconds on a good day. The cost is that a node restart drops in-flight triggers, which is the correct behaviour anyway. Replaying a motion event from before a restart would turn a light on for somebody who left ten minutes ago.

The trigger index is cached, not searched per event. A single occupancy sensor produces tens of events a minute, and searching your blueprints on each one would make a busy house the node's dominant read load. The index is built at startup, before the adapters connect, so the first motion event after a restart is not dropped into an empty index. It is rebuilt when you save a blueprint, over the same channel that invalidates the blueprint cache, so a studio edit takes effect without a restart.

Concurrent runs are capped at 16. Beyond that, events are dropped with a warning in the log rather than queued: a backlog of stale "turn the light on" commands is worse than none. Sixteen is sized for a house, and hitting it usually means a flow is slow rather than that the house is busy. Only active trigger blocks in saved blueprints are indexed.

Next Steps

Action Reference The 20 blocks that command devices and query the registry. Example Flows These triggers wired into complete automations. Troubleshooting When a trigger does not fire, start here.

Frequently asked

Does a RUAL motion trigger fire every time the sensor reports?

No, it fires on the change. A motion sensor re-announces occupancy every thirty seconds or so while somebody is in the room, and the trigger requires the value to have changed, so the flow runs once, on entry. Button presses are the deliberate exception, because a momentary pulse has no meaningful unchanged state.

How does a temperature threshold trigger work in RUAL?

It fires on the crossing, not the level. A trigger set to above 25 fires once when the room passes 25 degrees, not once per reading for the rest of the afternoon, and it fires again only after the reading has dropped back below 25 and crossed up again. A first-ever reading above the threshold counts as a crossing.

How do I write one RUAL automation for every sensor in a room?

Leave the trigger's device pin empty and set its room pin. The device pin is optional precisely so that one block can be the whole-room or whole-house version; requiring it would force one flow per sensor.