Skip to main content

Rule Examples

Worked end-to-end examples covering the most common automation patterns.

1. Door alert during specific hours​

Notify when the front door opens between 8 AM and 10 PM.

id       = ""
name = "Front door — daytime alert"
enabled = true
priority = 10
tags = ["door-alerts", "security"]

[trigger]
type = "device_state_changed"
device_id = "yolink_front_door"
attribute = "open"
to = true

[[conditions]]
type = "time_window"
start = "08:00"
end = "22:00"

[[actions]]
type = "notify"
channel = "telegram"
message = "Front door opened at {{time}}"

2. Garage door — alert if left open 10 minutes​

Check every minute; alert if the garage has been open for 10+ continuous minutes.

id       = ""
name = "Garage — left open alert"
enabled = true
priority = 10
tags = ["garage", "door-alerts"]
cooldown_secs = 600 # don't spam — alert at most every 10 minutes

[trigger]
type = "cron"
expression = "0 * * * * *" # every minute

[[conditions]]
type = "device_state"
device_id = "yolink_garage_door"
attribute = "open"
op = "Eq"
value = true

[[conditions]]
type = "time_elapsed"
device_id = "yolink_garage_door"
attribute = "open"
duration_secs = 600

[[actions]]
type = "notify"
channel = "telegram"
message = "Garage door has been open for 10+ minutes!"

3. Sunset — outdoor lights on​

Turn on porch and deck lights 15 minutes before sunset.

id       = ""
name = "Outdoor lights — on at sunset"
enabled = true
priority = 10
tags = ["outdoor", "lighting", "solar"]

[trigger]
type = "sun_event"
event = "sunset"
offset_minutes = -15

[[actions]]
type = "parallel"

[[actions.actions]]
type = "set_device_state"
device_id = "light_porch"
state = { on = true, brightness_pct = 80 }

[[actions.actions]]
type = "set_device_state"
device_id = "light_deck"
state = { on = true, brightness_pct = 60 }

4. Motion-triggered light with auto-off​

Turn on a hallway light when motion is detected, turn it off 5 minutes after no motion. Cancel the off timer if motion is detected again.

Rule A — turn on and schedule off:

id       = ""
name = "Hallway — motion on"
enabled = true
priority = 10

[trigger]
type = "device_state_changed"
device_id = "motion_hallway"
attribute = "motion"
to = true

[[actions]]
type = "set_device_state"
device_id = "light_hallway"
state = { on = true }

[[actions]]
type = "comment"
text = "Wait 5 minutes then turn off"

[[actions]]
type = "delay"
duration_secs = 300
cancelable = true
cancel_key = "hallway_off_delay"

[[actions]]
type = "set_device_state"
device_id = "light_hallway"
state = { on = false }

Rule B — cancel the off timer on new motion:

id       = ""
name = "Hallway — motion cancel off"
enabled = true
priority = 20 # higher priority — fires before rule A

[trigger]
type = "device_state_changed"
device_id = "motion_hallway"
attribute = "motion"
to = true

[[actions]]
type = "cancel_delays"
cancel_key = "hallway_off_delay"

5. Morning routine — fan-out with CustomEvent​

A single motion trigger starts a chain of parallel actions via CustomEvent.

Rule 1 — motion → fire event:

id       = ""
name = "Morning — motion detected"
enabled = true
priority = 10

[trigger]
type = "device_state_changed"
device_id = "motion_bedroom"
attribute = "motion"
to = true

[[conditions]]
type = "time_window"
start = "06:00"
end = "09:00"

[[actions]]
type = "fire_event"
event_type = "morning_routine_started"
payload = {}

Rule 2 — coffee on:

id = ""
name = "Morning — start coffee"
enabled = true
priority = 10

[trigger]
type = "custom_event"
event_type = "morning_routine_started"

[[actions]]
type = "set_device_state"
device_id = "smart_plug_coffee"
state = { on = true }

Rule 3 — thermostat:

id = ""
name = "Morning — thermostat"
enabled = true
priority = 10

[trigger]
type = "custom_event"
event_type = "morning_routine_started"

[[actions]]
type = "set_device_state"
device_id = "thermostat_main"
state = { setpoint = 21 } # °C

Rule 4 — raise blinds:

id = ""
name = "Morning — open blinds"
enabled = true
priority = 10

[trigger]
type = "custom_event"
event_type = "morning_routine_started"

[[actions]]
type = "set_device_state"
device_id = "zwave_blinds_bedroom"
state = { position = 100 }

6. Arrival home — context-aware welcome​

When front door opens and away mode is active: turn on lights, turn off away mode, welcome announcement.

id       = ""
name = "Arrival home"
enabled = true
priority = 10
tags = ["presence", "arrival"]

[trigger]
type = "device_state_changed"
device_id = "yolink_front_door"
attribute = "open"
to = true

[[conditions]]
type = "mode_is"
mode = "mode_away"
value = true

[[actions]]
type = "parallel"

[[actions.actions]]
type = "set_device_state"
device_id = "light_entryway"
state = { on = true, brightness_pct = 80 }

[[actions.actions]]
type = "set_device_state"
device_id = "thermostat_main"
state = { hvac_mode = "heat", setpoint = 21 } # °C

[[actions]]
type = "set_mode"
name = "mode_away"
value = false

[[actions]]
type = "call_service"
url = "http://sonos.local:5005/Entryway/say/Welcome+home"
method = "GET"

7. Play a Sonos favorite by name​

Start a named Sonos favorite when a virtual switch turns on.

This example demonstrates the preferred pattern for media playback in HomeCore:

  • target the HomeCore canonical device name
  • send a structured command payload
  • let the plugin resolve the favorite internally

You do not need to hardcode a Sonos player IP, plugin-local HTTP endpoint, or a raw transport URI.

id       = ""
name = "Kitchen music — play favorite"
enabled = true
priority = 10
tags = ["music", "sonos", "kitchen"]

[trigger]
type = "device_state_changed"
device = "kitchen.music_switch"
attribute = "on"
to = true

[[actions]]
type = "set_device_state"
device = "kitchen.sonos"
state = { action = "play_favorite", favorite = "Morning Jazz" }

What the rule does​

  1. A virtual switch named switch_kitchen_music turns on
  2. HomeCore resolves kitchen.sonos to the real device ID and publishes a command to homecore/devices/{device_id}/cmd
  3. hc-sonos receives that command
  4. The plugin looks up the Sonos favorite named Morning Jazz
  5. The plugin starts playback on the kitchen speaker

When to use this pattern​

Use this form when:

  • the target is a HomeCore media player device such as sonos_kitchen
  • the target is a HomeCore media player device such as kitchen.sonos
  • the content is a named Sonos favorite or playlist
  • you want the rule to stay stable even if the speaker IP or Sonos URI changes
# Play a playlist by name
[[actions]]
type = "set_device_state"
device = "kitchen.sonos"
state = { action = "play_playlist", playlist = "Dinner" }

# Use the generic media command shape
[[actions]]
type = "set_device_state"
device_id = "sonos_kitchen"
state = { action = "play_media", media_type = "favorite", name = "Morning Jazz" }

8. Hysteresis control — humidifier​

Turn a humidifier on when humidity drops below 35%, off when it rises above 50%.

# Turn ON
id = ""
name = "Humidifier — on"
enabled = true
priority = 10

[trigger]
type = "device_state_changed"
device_id = "yolink_humidity_sensor"
attribute = "humidity"

[[conditions]]
type = "device_state"
device_id = "yolink_humidity_sensor"
attribute = "humidity"
op = "Lt"
value = 35

[[conditions]]
type = "device_state"
device_id = "smart_plug_humidifier"
attribute = "on"
op = "Eq"
value = false

[[actions]]
type = "set_device_state"
device_id = "smart_plug_humidifier"
state = { on = true }
# Turn OFF
id = ""
name = "Humidifier — off"
enabled = true
priority = 10

[trigger]
type = "device_state_changed"
device_id = "yolink_humidity_sensor"
attribute = "humidity"

[[conditions]]
type = "device_state"
device_id = "yolink_humidity_sensor"
attribute = "humidity"
op = "Gt"
value = 50

[[conditions]]
type = "device_state"
device_id = "smart_plug_humidifier"
attribute = "on"
op = "Eq"
value = true

[[actions]]
type = "set_device_state"
device_id = "smart_plug_humidifier"
state = { on = false }

9. Webhook — doorbell integration​

Flash a light when a smart doorbell POSTS to a webhook.

id       = ""
name = "Doorbell — flash light"
enabled = true
priority = 10
tags = ["security", "doorbell"]

[trigger]
type = "webhook_received"
path = "doorbell-secret-path-a3f9c2"

[[actions]]
type = "repeat_count"
count = 3
delay_ms = 500

[[actions.actions]]
type = "set_device_state"
device_id = "light_living_room"
state = { on = true, color = "yellow" }

[[actions]]
type = "set_device_state"
device_id = "light_living_room"
state = { on = false }

[[actions]]
type = "notify"
channel = "telegram"
message = "Doorbell rang"

Fire it:

curl -X POST http://homecore.local/api/v1/webhooks/doorbell-secret-path-a3f9c2

10. Security alert — multi-condition with script logic​

Alert when motion is detected at night AND the house is not in "expected motion" mode.

id       = ""
name = "Security — nighttime motion alert"
enabled = true
priority = 50
tags = ["security"]
cooldown_secs = 120

[trigger]
type = "device_state_changed"
device_id = "motion_exterior"
attribute = "motion"
to = true

[[conditions]]
type = "mode_is"
mode = "mode_night"
value = true

[[conditions]]
type = "script_expression"
script = '''
!device_state("virtual_switch_expected_motion")["on"]
&& !device_state("mode_away")["on"]
'''

[[actions]]
type = "parallel"

[[actions.actions]]
type = "notify"
channel = "telegram"
message = "Motion detected outside at night!"
title = "Security Alert"

[[actions.actions]]
type = "notify"
channel = "pushover"
message = "Exterior motion detected"

[[actions.actions]]
type = "set_device_state"
device_id = "light_exterior"
state = { on = true, brightness_pct = 100 }

11. Startup state check​

Check critical devices when HomeCore starts, alert if anything is in a wrong state.

id       = ""
name = "Startup — check critical devices"
enabled = true
priority = 10

[trigger]
type = "system_started"

[[actions]]
type = "conditional"
condition = 'device_state("yolink_garage_door")["open"] == true'

[[actions.then_actions]]
type = "notify"
channel = "telegram"
message = "Garage door is OPEN (detected at startup)"

[[actions]]
type = "conditional"
condition = 'device_state("yolink_water_sensor")["wet"] == true'

[[actions.then_actions]]
type = "notify"
channel = "telegram"
message = "Water sensor is WET (detected at startup)"
title = "WATER ALERT"

Debugging rules​

# Dry-run a rule (no execution)
curl -s -X POST http://localhost:8080/api/v1/automations/RULE_ID/test \
-H "Authorization: Bearer $TOKEN" | jq

# View last 20 evaluation attempts
curl -s http://localhost:8080/api/v1/automations/RULE_ID/history \
-H "Authorization: Bearer $TOKEN" | jq

# Find rules that never fired
curl -s http://localhost:8080/api/v1/automations \
-H "Authorization: Bearer $TOKEN" \
| jq '[.[] | select(.enabled == true) | {name, trigger: .trigger.type}]'

# Find broken rules
curl -s "http://localhost:8080/api/v1/automations?stale=true" \
-H "Authorization: Bearer $TOKEN" \
| jq '.[] | {name, error}'