How to use this cookbook

Each recipe is a pattern, not a blind copy/paste. Replace example entity IDs, test in Developer Tools, and inspect the trace after the first real run. The safest automation is explicit about its trigger, confirmation, timeout, and human notification.

1. User-adjustable schedule with an input_datetime

Use this when a household member should change a schedule from the dashboard without editing automation logic.

alias: Lounge comfort at chosen time
mode: single
triggers:
  - trigger: template
    value_template: >-
      {{ states('input_datetime.living_room_ac_scheduled_time') == now().strftime('%H:%M:%S') }}
conditions: []
actions:
  - action: climate.set_temperature
    target: {entity_id: climate.lounge}
    data: {hvac_mode: heat, temperature: 22}

Use: your existing AC schedule follows this model. Put both the helper and automation toggle on the relevant dashboard.

2. State must persist before acting (debounce)

Avoid alerts for a brief network hiccup, door-contact bounce, or sensor flap.

triggers:
  - trigger: state
    entity_id: binary_sensor.8_8_8_8
    to: "off"
    for: "00:01:00"
actions:
  - action: notify.mobile_app_iphone
    data:
      title: "Internet monitor"
      message: "WAN monitor has been unavailable for one minute."

Rule: choose the duration from observed behaviour, not wishful thinking.

3. Command, confirm, timeout, escalate

Use for a coop door, gate, cover, or other physical system where a command is not proof of completion.

actions:
  - action: switch.turn_on
    target: {entity_id: switch.example_command}
  - wait_for_trigger:
      - trigger: state
        entity_id: binary_sensor.example_fully_open
        to: "on"
    timeout: "00:02:00"
    continue_on_timeout: true
  - choose:
      - conditions: "{{ wait.completed }}"
        sequence:
          - action: notify.mobile_app_iphone
            data: {message: "Movement confirmed."}
    default:
      - action: notify.mobile_app_iphone
        data: {title: "Attention needed", message: "No completion sensor within timeout."}

This is more reliable than waiting a guessed delay and assuming the actuator succeeded.

4. Manual override with an expiry

Use a helper to suppress a routine temporarily, then return to normal automatically.

# Helper: input_boolean.lounge_manual_override
# Automation trigger: state of the helper to on
actions:
  - delay: "02:00:00"
  - action: input_boolean.turn_off
    target: {entity_id: input_boolean.lounge_manual_override}

Add a condition to the normal automation requiring the override to be off. This prevents two automations fighting each other.

5. Notification on change, not every evaluation

Trigger on the state change and include current state in the message:

triggers:
  - trigger: numeric_state
    entity_id: sensor.example_battery
    below: 20
actions:
  - action: notify.mobile_app_iphone
    data:
      title: "Battery low"
      message: "{{ state_attr(trigger.entity_id, 'friendly_name') }} is {{ states(trigger.entity_id) }}%."

For recurring reminders, add a helper recording the last alert time; do not spam every minute.

6. Time-windowed presence lighting

triggers:
  - trigger: state
    entity_id: binary_sensor.living_room_occupancy
    to: "on"
conditions:
  - condition: sun
    after: sunset
actions:
  - action: light.turn_on
    target: {entity_id: light.lounge_lamp}
    data: {brightness_pct: 45}
mode: restart

Use restart if the same event should refresh an off-delay. Use single when overlap could create a hazard.

7. Retry only when retry is safe

A retry is appropriate when a device occasionally misses a command; it is dangerous when it could repeatedly energise equipment or move something unexpectedly.

repeat:
  sequence:
    - action: switch.turn_on
      target: {entity_id: switch.example}
    - delay: "00:00:10"
  until:
    - condition: state
      entity_id: binary_sensor.example_confirmed
      state: "on"

Always add a maximum retry count and failure notification for physical systems.

8. Track events with helpers

actions:
  - action: input_number.increment
    target: {entity_id: input_number.internet_watchdog_wan_drop_count}
  - action: input_datetime.set_datetime
    target: {entity_id: input_datetime.internet_watchdog_last_wan_drop}
    data:
      datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"

This turns an alert into useful history. Your WAN watchdog uses this approach while deliberately avoiding automatic gateway reboots.

9. Choose branches explicitly

actions:
  - choose:
      - conditions:
          - condition: state
            entity_id: binary_sensor.example
            state: "on"
        sequence:
          - action: notify.mobile_app_iphone
            data: {message: "Restored"}
    default:
      - action: notify.mobile_app_iphone
        data: {message: "Unavailable"}

Use choose instead of deeply nested if blocks when there are several meaningful outcomes.

10. Trace-led debugging checklist

[ ] Did the trigger fire?
[ ] Did a condition block execution?
[ ] What is the last trace step?
[ ] Did the target entity acknowledge the action?
[ ] Was an unavailable/unknown state handled?
[ ] Is a duplicate automation also acting?
[ ] Does mode match the desired repeated-trigger behaviour?

Safety rules

  • Never automate an irreversible action without a clear confirmation/abort path.
  • Prefer notifications and manual review over blind recovery reboots.
  • Explicitly handle unavailable and unknown for critical sensors.
  • Keep entity names meaningful and use helpers for household-adjustable values.
  • Test at a safe time and inspect the trace after every material change.