Triggers
Triggers (also called Attribute Triggers) are event-driven automations that execute actions when attribute values change and meet specified conditions. Unlike schedules (time-based) or macros (manually executed), triggers respond immediately to system events.
Each attribute change is filtered through the trigger's condition, active days/hours, and debounce before the macro runs:
Overview
Triggers enable reactive automation:
- Attribute Monitoring: Watch any attribute for changes
- Conditional Execution: Only act when conditions are met
- Immediate Response: Execute within seconds of event
- Scheduled Availability: Limit trigger to specific days/hours
- Debouncing: Prevent rapid repeated executions
Viewing Triggers
The main grid displays all configured triggers with the following columns:
- ID - Unique trigger identifier
- Name - Internal trigger name
- Active Days - Day enable mask (read-only in grid)
- Active Hours - Hour enable mask (read-only in grid)
- Debounce (min) - Minimum minutes between activations
- Actions - Configured actions summary (read-only in grid)
- Last Triggered - Last time trigger executed (read-only in grid)
- Enabled - Whether trigger is active
Grid Actions
- Add - Create a new trigger
- Edit - Modify an existing trigger
- Delete - Remove a trigger
- Reload - Refresh the grid data
The page also accepts an ?edit=<id> deep link that opens a trigger directly — used by the attribute editor's Triggers tab, which lists every trigger reading a given attribute.
Creating a Trigger
To create a new trigger:
- Click Add in the grid toolbar
- The trigger creator opens with these main sections:
- Basic Settings
- Trigger Condition
- Additional Condition (optional gate)
- Action to Execute
- Schedule Configuration
- Configure all sections (see below)
- Click Create Trigger
Trigger Configuration
Basic Settings
Trigger Name
- Internal identifier (lowercase_with_underscores)
- Examples:
motion_lights,door_alert,temp_warning - Auto-formatted on blur
Debounce (minutes)
- Minimum time between trigger activations
- Prevents rapid repeated execution
- Example: Motion sensor triggering every second
- Set debounce: 5 minutes
- Trigger executes max once per 5 minutes
- Default: 0 (no debouncing)
Status
- Toggle to enable/disable trigger
- Disabled triggers:
- Don't monitor attributes
- Don't execute actions
- Configuration preserved
Trigger Condition
Define what attribute change triggers the action:
Condition Builder provides:
Attribute Selection:
- System Target: device, macro, monitor, site, site_space, subsystem, system, variable, zone
- Target Object: Specific entity (shown as
[ID] namefor easy identification). Forvariableandsystemtargets the object is fixed and the row jumps straight to attribute selection. - Attribute Name: Which attribute to monitor
- Use previous value: a checkbox beside the attribute. When ticked, the condition compares against the attribute's value before the change instead of the new value — use it to catch a transition away from a value (e.g.
state/ use previous valueequalsarmedmatches the moment the zone stops being armed).
Comparison — the operator dropdown offers exactly these:
- equals
- does not equal
- greater than
- less than
- contains
- does not contain
- is empty
- is not empty
- matches regex
- does not match regex
There is no "greater than or equal" / "less than or equal" operator in this dropdown. For an inclusive bound, adjust the threshold value (> 74 in place of >= 75) or use an expression comparison value (below).
Value:
- Value to compare against
- Input type adapts to the selected attribute:
- bool attributes show a true/false dropdown
- int attributes show a numeric input (whole numbers)
- float attributes show a numeric input (decimals allowed)
- Attributes with value options show a dropdown of allowed values (with fill-in)
- The
stateattribute (which has no fixed list of values) suggests the state strings currently present elsewhere in the system, scoped to the chosen target type — so a zone condition is offered zone states, a device condition device states. The list is a suggestion only; you can still type any value, and a state no entity currently holds simply won't appear yet. - All other types show a text input
- Can reference dynamic attribute values (e.g.,
[$sunrise],[zone.5.level]+10). See Attributes — Dynamic Attribute Values. - Can be an expression — see below.
Expression comparison value:
Tick expression under the Value field to compute the comparison value with the shared expression engine instead of entering a static value or a single [bracket] reference. The expression is evaluated each time the trigger fires, then compared against the firing attribute's live value using the operator you selected.
This is the same JEXL engine used by the If Expression macro step, so it supports cross-entity references, arithmetic, and transforms that the single-bracket dynamic-value syntax can't express:
Trigger: zone living_room_thermostat . temperature greater than [expression]
Expression: zone(5).setpoint + vr('comfort_offset')
The trigger still fires on the attribute you picked (here, the thermostat's temperature); the expression only computes the threshold. A Test button evaluates the expression against current system state so you can confirm the result before saving. Available references: zone(id), device(id), vr(name), attr(target,id,name), the firing event via ctx.value / ctx.previous_value, and transforms like |round / |default(x). Secure attributes (passwords, API keys) are never exposed to the expression. If an expression errors at fire time, the condition is treated as not-matched (the trigger simply doesn't fire) and the error is logged.
Leaving expression unticked keeps the classic static / [bracket] value, unchanged.
Logic:
- AND: All conditions must be true
- OR: Any condition can be true
Example Conditions:
Motion Detected:
System Target: zone
Target ID: front_porch_motion
Attribute: motion
Comparison: equals
Value: detected
Temperature Too High:
System Target: zone
Target ID: living_room_thermostat
Attribute: temperature
Comparison: greater than
Value: 78
Door Opened:
System Target: zone
Target ID: front_door
Attribute: contact
Comparison: equals
Value: open
Multiple Conditions (AND):
Condition 1: motion = detected
AND
Condition 2: light_level < 30
Multiple Conditions (OR):
Condition 1: front_door = open
OR
Condition 2: back_door = open
Additional Condition (Gate)
An optional secondary check evaluated after the trigger condition matches but before actions run. Use it to gate execution on the live value of any other attribute without complicating the primary trigger condition. It works exactly like a macro schedule's Conditions gate — same condition builder (including the expression comparison value) and the same Run/Skip polarity.
How it differs from a Trigger Condition:
- The trigger condition is what the system watches for change. When that attribute changes and matches, the trigger is "armed".
- The gate condition is read on-demand at fire time against the current value of any attribute (does not need to be the one that changed).
- If the gate blocks the fire, it is logged as
skippedwith reasongate_conditionin Run History and no action runs. The Run History row also shows a condition trace of the evaluated operands (e.g.rainfall 0.13 > 0.125 → not met), so you can see exactly why it was blocked.
Configuration:
A When the condition is met selector sets the polarity:
| Mode | Behavior |
|---|---|
| Run only when met | Actions run only if the condition is true; otherwise the fire is skipped. |
| Skip when met | Actions are skipped when the condition is true; otherwise they run. |
Then build the condition (target → attribute → operator → value, or an expression value). Leave the condition blank for no gate.
Example — only run during night mode:
Trigger Condition: zone.front_porch_motion.motion = detected
When the condition is met: Run only when met
Additional Condition: variable / home_mode = night
Action: command (porch_light on)
Example — suppress alerts while the system is disarmed:
Trigger Condition: zone.back_door.contact = open
When the condition is met: Skip when met
Additional Condition: variable / security_mode = disarmed
Action: webpush_notification
Use a gate condition instead of adding a second trigger condition when the second value rarely changes (e.g. site mode, home/away, schedule flag). Trigger conditions react to changes on every listed attribute — gate conditions are read only when the trigger fires.
Action to Execute
Define what happens when trigger fires:
Action Type Selection:
Command:
- Send command to device or zone
- Configure: Device, Zone, Command, Parameters
- Example: Turn on porch light to 75%
Macro:
- Execute a macro
- Configure: Macro selection, Arguments
- Example: Run "security_alert" macro
Email:
- Send email notification
- Configure: Recipients, Subject, Message
- Example: Email "Front door opened" to homeowner
SMS:
- Send SMS text message
- Configure: Phone number, Message
- Example: Text "Motion detected" to security phone
Web Request:
- Send HTTP request to external service
- Configure: URL, Method, Headers, Body
- Example: POST to webhook API
Set Attribute:
- Modify another attribute value
- Configure: System target, Target ID, Attribute, Value
- Example: Set variable "last_motion" to current timestamp
WebPush Notification:
- Send browser push notification
- Configure: UI, Title, Message, Priority
- Example: Push "Door opened" to mobile app
Call Notification:
- Ring a native full-screen incoming call on mobile app clients
- Configure: Caller Name, Answer URL, Target UIs/Users
- Example: Ring "Front Gate" with an Answer URL to the gates page
If Attribute:
- Conditional branch — evaluate attribute condition(s) and act on the true/false result
- Configure: condition(s), then a when true / when false branch (start a macro, run a command, or set an attribute)
- Example: If
home_modeisaway, start the "arm_security" macro
The action dropdown lists these with underscores removed (e.g. web_request shows as web request). Each is described in full under Action Types below.
Action Context
When a trigger fires, a set of [token] replacements is made available to every action. Use them inside any free-text or argument field — an SMS message, email subject/body, command argument, web request URL/body — and the same keys are exposed as context.* inside a macro action.
Event tokens (always present):
| Token | Resolves to |
|---|---|
[value] | The attribute value that fired the trigger |
[previous_value] | The value immediately before the change |
[raw_value] | The uncast/raw form of the firing value |
[attribute_name] | The name of the attribute that changed |
[value] is sourced from the change event itself, not re-read from the entity — so it is correct even for drivers that write a value and immediately blank it (e.g. a callbox writing a PIN then clearing it).
Entity tokens (zone and device targets only):
When the trigger watches a specific zone or device, that entity's live fields are also available — [name], [id], and every one of its attributes by name (e.g. [temperature], [battery_level]). Entity fields win over event tokens on a name collision, so [name]/[id] always resolve to the entity.
Triggers on any other target type (variable, subsystem, site, system, etc.) run actions with no entity object — only the event tokens above are available. Dynamic-name-pattern and gate-reference targets resolve their entity at fire time, so their entity tokens exist at run time but can't be previewed in the editor.
Action Context Preview
The editor shows an Action Context panel below the action, listing the exact tokens the current target/attribute selection makes available, each with a sample value. Click any token to copy its [token] form to the clipboard, or expand Raw context object to see the full context as JSON. The preview updates as you change the trigger condition's target and attribute.
Schedule Configuration
Limit when trigger can execute:
The Active Days and Active Hours selections are a hard gate, and a brand-new trigger starts with nothing selected. If you leave every day unchecked, or leave the Hour Mask with no hour checked, the trigger's condition can match perfectly and it will still never run — and no fire is recorded, because a schedule block only logs after the condition already matched. Before saving, select the active days and hours (use Select All for an always-on trigger).
Active Days
Select which days trigger is active:
Interface:
- Visual grid of 7 days: SUN, MON, TUE, WED, THU, FRI, SAT
- Click day to toggle
- A single Select All / Clear All button (first click checks all, next click clears all)
Use Cases:
- Weekdays Only: Work-related automation
- Weekends Only: Leisure automation
- All Days: Always-active triggers
Examples:
Motion lights (all days): Sun-Sat all checked
Office hours (weekdays): Mon-Fri checked
Weekend guest access: Sat-Sun checked
Active Hours
Two modes are available for controlling when a trigger is active during the day: Hour Mask and Time Range. Switch between them using the tabs above the hours section.
Hour Mask
Select specific hours the trigger is active:
Interface:
- Visual grid of 24 hours: 12AM, 1AM, 2AM, ... 11PM
- Click hour to toggle
- A single Select All / Clear All button (first click checks all, next click clears all)
Use Cases:
- Night Only: Security alerts, motion lights
- Daytime Only: Occupancy-based climate
- Business Hours: Office automation
- Off Hours: Maintenance windows
Examples:
Night motion lights: 8PM-6AM checked (20-5)
Daytime climate: 6AM-10PM checked (6-21)
Business hours: 8AM-6PM checked (8-17)
Time Range
Define a start and end time for the active window. This is especially useful when active hours should follow dynamic values like sunrise or sunset rather than fixed hourly blocks.
Interface:
- Start Time and End Time fields
- Each can be set to Variable or Static Time mode
Variable Mode:
- Select a date-type variable (e.g.,
sunrise,sunset) from the dropdown - Optionally add an offset in minutes (positive = after, negative = before)
- Example: Variable
sunsetwith offset-30→ active starts 30 minutes before sunset
Static Mode:
- Enter a fixed time (e.g.,
08:00,17:00)
Overnight Ranges: Time ranges that cross midnight are supported. If the start time is later than the end time, the range wraps overnight.
- Example: Start
22:00, End06:00→ active from 10 PM to 6 AM
Examples:
Sunset to sunrise: Start: [$sunset] End: [$sunrise]
Dusk with offset: Start: [$sunset]-30 End: [$sunrise]+30
Fixed range: Start: 08:00 End: 17:00
Time Range mode is ideal for triggers that should follow astronomical events. Use the sunrise and sunset system variables with minute offsets instead of manually adjusting the hour mask seasonally.
Common Trigger Examples
Motion-Activated Lights
Name: porch_motion_lights
Debounce: 5 minutes
Conditions:
zone.front_porch_motion.motion = detected
AND
zone.front_porch_light.power = off
AND
variable.0.light_level < 30
Action: command
Zone: front_porch_light
Command: on
Level: 100%
Days: All days
Hours: Sunset to Sunrise (approximate: 18-6)
Enabled: Yes
Result: When motion detected at night and light is off and it's dark, turn on porch light. Won't re-trigger for 5 minutes.
Door Open Alert
Name: front_door_alert
Debounce: 0 (alert every time)
Conditions:
zone.front_door.contact = open
AND
variable.0.home_mode = away
Action: webpush_notification
Message: "Front door opened while away!"
Priority: critical
Days: All days
Hours: All hours
Enabled: Yes
Result: When away and front door opens, send immediate push notification.
Temperature Control
Name: ac_auto_on
Debounce: 30 minutes
Conditions:
zone.living_room_thermostat.temperature > 76
AND
zone.living_room_thermostat.mode != cool
Action: command
Zone: living_room_thermostat
Command: set_mode
Mode: cool
Setpoint: 72
Days: All days
Hours: 9AM-11PM (9-22, not overnight)
Enabled: Yes
Result: If temperature exceeds 76°F and AC not in cool mode, switch to cooling (max once per 30 min, daytime only).
Low Battery Alert
Name: sensor_low_battery
Debounce: 1440 (once per day)
Conditions:
device.motion_sensor_1.battery_level < 20
Action: email
To: installer@example.com
Subject: "Low Battery Alert"
Body: "Motion sensor battery at {device.battery_level}%"
Days: All days
Hours: 9AM only (single notification time)
Enabled: Yes
Result: Daily email at 9 AM if motion sensor battery below 20%.
Device Offline Notification
Name: thermostat_offline
Debounce: 15 minutes
Conditions:
device.main_thermostat.connection_state = disconnected
Action: sms
Number: +15551234567
Message: "HVAC thermostat offline!"
Days: All days
Hours: All hours
Enabled: Yes
Result: SMS notification if thermostat disconnects (max once per 15 minutes).
Trigger vs. Schedule vs. Macro
When to Use Triggers
Best For:
- Event-driven automation (motion, door, sensor)
- State-based responses (temperature thresholds)
- Alert notifications (errors, status changes)
- Reactive behavior (respond to changes)
Examples:
- Motion detected → Turn on lights
- Door opened → Send alert
- Temperature too high → Activate cooling
When to Use Schedules
Best For:
- Time-based automation (daily routines)
- Predictable recurring events
- Astronomical timing (sunrise/sunset)
Examples:
- 7:00 AM → Good morning macro
- Sunset → Turn on outdoor lights
- 10:30 PM → Goodnight macro
When to Use Macros (Manual)
Best For:
- User-initiated actions
- On-demand sequences
- UI buttons
- Complex multi-step operations
Examples:
- "Movie Time" button → Movie macro
- "All Off" button → All off macro
- Access control → Unlock sequence
Combining All Three
Example: Comprehensive Porch Light Automation
Trigger: Motion detected + dark + nighttime → Turn on light
Schedule: Sunset → Turn on light (base level)
Macro: "Party Mode" → Override automation, force lights on
All three work together for complete automation.
Debouncing
Purpose of Debouncing
Prevents trigger spam from rapidly-changing attributes:
Without Debounce:
Motion sensor triggers every 1 second
↓
Lights commanded on every 1 second
↓
100s of redundant commands per day
With Debounce (5 minutes):
Motion detected at 8:00:00 PM → Lights on
Motion detected at 8:00:15 PM → Ignored (within 5 min)
Motion detected at 8:03:30 PM → Ignored (within 5 min)
Motion detected at 8:05:01 PM → Lights on (>5 min elapsed)
Debounce Guidelines
No Debounce (0 minutes):
- Critical alerts that should always fire
- Infrequent events
- Single-occurrence events
Short Debounce (1-5 minutes):
- Motion sensors
- Door sensors
- Frequent but important events
Medium Debounce (10-30 minutes):
- Temperature thresholds
- Light level changes
- Moderate frequency events
Long Debounce (60-1440 minutes):
- Low battery alerts (daily max)
- Status reports
- Infrequent notifications
Day/Hour Masks
Purpose
Restrict trigger execution to specific times:
Benefits:
- Security lights only at night
- Office automation only during business hours
- Weekend-specific automation
- Seasonal behavior changes
Day Mask
7-bit binary mask: 1111111 (all days enabled)
Format: SMTWTFS (Sun, Mon, Tue, Wed, Thu, Fri, Sat)
Examples:
1111111 → All days
0111110 → Weekdays only (Mon-Fri)
1000001 → Weekends only (Sat-Sun)
0010000 → Wednesdays only
Hour Mask
24-bit binary mask: 111111111111111111111111 (all hours enabled)
Format: Hours 0-23 (midnight to 11 PM)
Examples:
000000111111111111110000 → 6 AM to 9 PM
111111000000000000111111 → Night hours (10 PM to 5 AM)
000000000111111111000000 → Business hours (9 AM to 5 PM)
Time Range (JSON)
When using Time Range mode, the hour mask is stored as a JSON object with start and end fields:
{"start": "[$sunset]-30", "end": "[$sunrise]+30"}
{"start": "08:00", "end": "17:00"}
Values can be:
- Static time:
HH:MMformat (e.g.,08:00) - Variable reference:
[$variable_name]with optional+Nor-Nminute offset
Combined Masks
Example: "Office Hours Only"
Days: Mon-Fri (0111110)
Hours: 8 AM-6 PM
Result: Trigger only active weekdays 8 AM-6 PM.
Action Types
Triggers can execute various action types:
Command Action
Send command to device or zone:
Configuration:
- Device or Zone
- Command name
- Command parameters
- Delay before execution (optional)
Example:
Action: command
Target: Zone - living_room_lights
Command: set_level
Parameters: {level: 75, ramp: 2}
Macro Action
Execute a macro:
Configuration:
- Macro selection
- Macro arguments (optional)
Example:
Action: macro
Macro: security_alert
Arguments: {location: "front_door", type: "open"}
Email Action
Send email notification:
Configuration:
- To: Email addresses (comma-separated)
- CC: CC addresses (optional)
- Subject: Email subject
- Body: Email message (supports variables)
Example:
Action: email
To: homeowner@example.com, security@example.com
Subject: Front Door Alert
Body: Front door opened at {timestamp} by {user}
SMS Action
Send SMS text message:
Configuration:
- Phone number(s) — multiple numbers can be separated by commas or semicolons
- Message text (160 characters max recommended)
Each recipient is checked individually against Notification Profiles. If a recipient is blocked by a profile, the message is skipped for that recipient but still sent to others.
Example:
Action: sms
Number: +15551234567, +15559876543
Message: Motion detected at front door
Web Request Action
Send HTTP request to external service:
Configuration:
- URL: Endpoint URL
- Method: GET, POST, PUT, DELETE
- Headers: HTTP headers (JSON)
- Body: Request body (JSON)
Example:
Action: web_request
URL: https://api.service.com/alert
Method: POST
Headers: {"Content-Type": "application/json", "X-API-Key": "secret"}
Body: {"event": "motion", "location": "front_door", "timestamp": "{timestamp}"}
Set Attribute Action
Modify another attribute:
Configuration:
- System Target: zone, device, variable, etc.
- Target ID: Specific entity
- Attribute Name: Attribute to set
- Value: New value
- Type: Value type (string, int, float, bool)
Example:
Action: set_attribute
System Target: variable
Target ID: 0
Attribute: last_motion_time
Value: {timestamp}
Type: date
WebPush Notification Action
Send browser push notification:
Configuration:
- UI: Which UI to notify (or all)
- Title: Notification title
- Message: Notification body
- Priority: info, warning, error, critical
- Icon: Notification icon (optional)
Example:
Action: webpush_notification
UI: all
Title: Security Alert
Message: Motion detected at front door
Priority: warning
Icon: security
Call Notification Action
Send a native incoming call notification to mobile devices. Triggers the full-screen incoming call UI (CallKit on iOS, full-screen notification on Android). Only delivered to native mobile app clients — web browsers are skipped.
Configuration:
- Caller Name: Name displayed on the incoming call screen
- Answer URL: Page to navigate to when the user answers (e.g.,
/controls/gates) - Target UIs: Which UIs to notify
- Target Users: Which users to notify
- Override Notification Profile: Send regardless of user notification preferences
Example:
Action: call_notification
Caller Name: Front Gate
Answer URL: /controls/gates
UI: all
Override Profile: Yes
Call notifications require the GEM mobile app. Configure push notification tokens via the Mobile App admin page.
If Attribute Action
Evaluate one or more attribute conditions and branch on the result — a compact "if this, then that" without building a full macro:
Configuration:
- Condition(s): one or more
target → attribute → operator → valuechecks, combined with AND or OR - When true: start a macro, run a command, or set an attribute
- When false: start a (different) macro, run a command, or set an attribute
Conditions read the target attribute's current stored value; tick use previous value on a condition to compare against the value before the last change (transition detection). The stop-the-macro / skip-next-step options this action offers have no effect when it runs from a trigger — a trigger fires a single action with no following steps, so use the start a macro / run a command / set an attribute branches instead.
Example:
Action: if_attribute
Condition: variable.0.home_mode equals away
When true: start macro "arm_security"
When false: run command (entry_light on)
Condition Builder
The condition builder creates complex attribute queries:
Simple Condition
Single Attribute Check:
zone.front_door.contact = open
Configuration:
- System Target: zone
- Target ID: front_door (select from dropdown)
- Attribute: contact
- Operator: equals
- Value: open
Dynamic Name Matching
Instead of selecting a specific target, you can match targets by name pattern using wildcards. This is useful when you want a single trigger condition to apply to any entity whose name matches a pattern.
- Select a System Target (zone, device, macro, monitor, or site_space)
- Check the dynamic name checkbox below the Target dropdown
- Enter a name pattern using
*as a wildcard
Pattern examples:
*_climate— matches any target ending in_climateliving_*— matches any target starting withliving_*_motion_*— matches any target containing_motion_
The Target dropdown still selects a specific entity to load its available attributes for configuration, but at runtime the condition evaluates against all entities matching the name pattern.
Dynamic name matching is ideal for conditions that should apply broadly — for example, triggering on any zone whose name ends with _climate rather than creating separate conditions for each climate zone.
Driver Matching
For zone and device targets, the by driver checkbox scopes the condition to every entity whose device runs a given driver — "any lock from the Seam integration", regardless of naming. Pick a driver from the in-use list (or type a * wildcard pattern such as lutron_*). Zones resolve through their bound device; device targets match their own driver. Stored as a [driver:seam_api] target sentinel.
Limiting to One Device
When a zone-target condition uses dynamic name or driver matching, an optional only zones of this device picker narrows the match to a single device's zones — e.g. *_lock battery conditions, but only for the locks behind one hub. In driver mode the picker lists only devices running the selected driver (pattern-aware), and a device that no longer matches after a driver change is cleared automatically. Leave it on Any device for site-wide scope. (Subsystem-target conditions have their own equivalent device filter.)
Compound Conditions
AND Logic (all must be true):
zone.motion_sensor.motion = detected
AND
variable.0.home_mode = away
AND
zone.front_door.contact = closed
OR Logic (any can be true):
zone.smoke_detector_1.alarm = triggered
OR
zone.smoke_detector_2.alarm = triggered
OR
zone.smoke_detector_3.alarm = triggered
Nested Conditions
Complex Logic:
(zone.motion = detected AND zone.light = off)
OR
(zone.door = open AND time > sunset)
Current Limitation: Basic AND/OR supported. Complex nesting may require multiple triggers or macro logic.
Comparison Operators
Equals (=):
- Exact match
- Case-sensitive for strings
- Example:
power = on
Not Equals (!=):
- Does not match
- Example:
mode != vacation
Greater Than (>):
- Numeric comparison
- Example:
temperature > 75
Less Than (<):
- Numeric comparison
- Example:
battery_level < 20
The dropdown has no greater than or equal / less than or equal operator. For an inclusive bound, adjust the threshold (
> 74in place of>= 75) or use an expression comparison value.
Contains / Does Not Contain:
- Substring match, or its inverse
- Example:
error_message contains "timeout"
Is Empty / Is Not Empty:
- True when the value is blank / non-blank — no value field required
Matches (regex):
- JavaScript regular expression match against the source value as a string
- Example:
device_name matches "sensor_.*" - The value is the raw pattern, no
/delimiters (e.g.^\d+$for "is a number") - A preset dropdown beside the value field offers common patterns (valid number, non-blank, valid email, valid IPv4, etc.)
Does Not Match (regex):
- Inverse of Matches — true when the pattern does not match
- Example: gate on
device_name does_not_match "^test_"to skip test devices
Common Trigger Patterns
Security Triggers
Intrusion Alert:
Conditions: zone.motion.motion = detected AND variable.home_mode = away
Action: webpush_notification + email + macro (alarm)
Days: All days
Hours: All hours
Debounce: 1 minute
Door Left Open:
Conditions: zone.front_door.contact = open
Action: webpush_notification "Door left open!"
Days: All days
Hours: All hours
Debounce: 5 minutes
A trigger evaluates the instantaneous attribute change — there is no built-in "for N minutes" / "sustained" condition. To require a state to persist before acting (a real "door left open for 5 minutes"), run a macro as the action and have it wait and re-check the attribute (a Wait / Wait-for-Attribute step), or set a variable and act on it from a follow-up trigger. The Debounce field only limits how often a trigger re-fires; it does not require the state to hold.
Comfort Triggers
Auto Climate:
Conditions: zone.thermostat.temperature > 78
Action: command (set_mode: cool, setpoint: 74)
Days: All days
Hours: 8AM-10PM
Debounce: 30 minutes
Morning Light:
Conditions: zone.bedroom_motion.motion = detected
Action: command (bedroom_lights, set_level, 30%)
Days: All days
Hours: 5AM-8AM only
Debounce: 60 minutes (once per morning)
Energy Triggers
Peak Demand Reduction:
Conditions: variable.energy_price > 0.30
Action: macro (reduce_non_essential_loads)
Days: Weekdays
Hours: 2PM-7PM (peak hours)
Debounce: 60 minutes
Solar Optimization:
Conditions: variable.solar_production > 5000 AND variable.battery_charge < 80
Action: macro (charge_batteries)
Days: All days
Hours: 10AM-4PM (peak solar)
Debounce: 30 minutes
Notification Triggers
Device Offline:
Conditions: device.critical_device.connection_state = disconnected
Action: email + sms (device offline alert)
Days: All days
Hours: All hours
Debounce: 15 minutes
Low Supply Alert:
Conditions: variable.water_level < 20
Action: email (low water alert)
Days: All days
Hours: 9AM-5PM (business hours for service call)
Debounce: 1440 minutes (daily)
Advanced Topics
Trigger Chaining
Triggers can trigger other triggers:
Example:
Trigger 1: Motion detected → Set variable "occupancy" = yes
Trigger 2: Variable "occupancy" = yes → Turn on welcome lights
Trigger 3: Variable "occupancy" = no for 30 minutes → Turn off lights
State Machines
Implement complex state management:
States: home, away, vacation, sleep, party
Triggers:
Trigger 1: All users leave → Set mode = away
Trigger 2: Mode changes to away → Execute "leaving home" macro
Trigger 3: User arrives → Set mode = home
Trigger 4: Mode changes to home → Execute "arriving home" macro
Computed Attributes
Use triggers to calculate derived values:
Example:
Trigger: Any zone's power changes
Action: Set attribute "total_lights_on" = count of zones with power=on
Cascading Actions
One trigger's action creates conditions for another:
Example: Escalating Alerts
Trigger 1: Temperature > 100 → Set variable "overheat_warning" = yes
Trigger 2: Variable "overheat_warning" = yes for 5 min → Send email
Trigger 3: Variable "overheat_warning" = yes for 10 min → Send SMS + shut down
Best Practices
-
Specific Conditions: Make conditions as specific as possible to avoid false triggers
-
Appropriate Debounce: Set debounce to prevent spam while remaining responsive
-
Schedule Limits: Use day/hour masks to prevent unwanted execution
-
Testing: Test triggers thoroughly, especially complex conditions
-
Logging: Monitor trigger execution in logs
-
Naming: Use descriptive names indicating what triggers and what happens
-
Error Handling: Consider what happens if action fails
-
Avoid Loops: Don't create trigger loops (A triggers B triggers A...)
-
Documentation: Document complex trigger logic in description/comments
-
Review Regularly: Audit triggers quarterly to remove unused ones
Troubleshooting
Trigger Not Firing
Check:
- Enabled: Trigger is enabled
- Conditions: Conditions are actually being met
- Day/Hour: Current day and hour are enabled
- Debounce: Not within debounce period
- Attribute Changes: Attribute is actually changing
- Logs: Review trigger logs for evaluation results
Trigger Firing Too Often
Solutions:
- Increase Debounce: Lengthen minimum time between activations
- Narrow Conditions: Make conditions more specific
- Limit Hours: Restrict to fewer hours per day
- Add Conditions: Add additional conditions to filter
Trigger Firing at Wrong Times
Check:
- Day Mask: Verify correct days are checked
- Hour Mask: Verify correct hours are checked
- Time Zone: System time zone matches location
- Conditions: Conditions include time-based checks if needed
Action Not Executing
Check:
- Action Config: Action properly configured
- Device Online: Target devices are online
- Permissions: System has permission to execute action
- Syntax: Email/SMS/Web request syntax is valid
- Logs: Check for action execution errors
Too Many Notifications
Solutions:
- Increase Debounce: Reduce notification frequency
- Limit Hours: Only notify during waking hours
- Increase Threshold: Adjust condition to be less sensitive
- Batch Notifications: Use digest mode if available
Metadata and Monitoring
Last Triggered
Grid shows last trigger time:
- Timestamp of most recent execution
- Helps verify trigger is working
- Useful for debugging
Trigger Logs
View detailed trigger activity:
- Navigate to Insights > Logging or Insights > Activity
- Filter by trigger name
- Review:
- When trigger evaluated
- Whether conditions met
- Whether action executed
- Any errors
Run History (in-editor)
The trigger editor has a Run History panel that lists every recorded fire of the open trigger. Rows include started-at, status (success / failed / skipped), duration, reason, and the attribute change that satisfied the condition (context.system_target.target_id.attribute_name = value). A skipped row carries one of two reasons: schedule — the condition matched but the day/hour mask or the debounce window blocked it (both share this one reason) — or gate condition — the Additional Condition blocked it. A change that simply didn't match the trigger condition is not recorded, so the panel stays readable instead of logging every attribute change in the system.
Clicking a row opens the Cause Chain modal which shows the downstream macros, schedules, or follow-on triggers the fire kicked off. Useful when a single attribute change cascades into several actions and you need to see which trigger fired first.
Trigger fires also render as vertical markers on Attribute History when the corresponding attribute is charted (green = success, red = failed, grey-dashed = skipped). Retention is governed by the Automation History settings under Data Retention.
Command Macros Tab
The Command Macros tab binds a macro to a device command: whenever the command executes — from a UI button, a schedule, another macro, or voice — the macro runs afterward. Each binding has:
- Device and Command — the command name comes from the device's command set; free-typed names also match driver-native commands.
- Macro — runs after the command executes.
- Debounce (ms) — rapid repeats of the command within this window collapse into a single macro run (useful for volume ramps or repeated keypad presses).
- Enabled — disabled bindings stay configured but don't fire.
Saving refreshes the device's in-memory bindings immediately without reconnecting the device.
Related Documentation
- Macros - Macro actions in triggers
- Schedules - Time-based automation
- Attributes - Understanding attribute system
- Zones - Zone state monitoring