Skip to content

Instantly share code, notes, and snippets.

@thomasmaxson
Last active September 7, 2025 16:48
Show Gist options
  • Select an option

  • Save thomasmaxson/635084f3a7f8e1877542c210b39c6ed5 to your computer and use it in GitHub Desktop.

Select an option

Save thomasmaxson/635084f3a7f8e1877542c210b39c6ed5 to your computer and use it in GitHub Desktop.
Home Assistant Blueprint to manage room occupancy state via door and presence sensors.
blueprint:
name: Manage Area State via Sensors
description: >-
Manage occupancy state via multiple sensors.
- Control what happens when a door opens or occupancy is detected.
- Control what happens when a door closes or occupancy is cleared.
author: Thomas Maxson
source_url: https://gist.github.com/thomasmaxson/635084f3a7f8e1877542c210b39c6ed5
homeassistant:
min_version: 2024.6.0
domain: automation
input:
sensor_door:
name: Door Sensor
selector:
entity:
multiple: false
filter:
domain: binary_sensor
sensor_occupancy:
name: Occupancy Sensor
selector:
entity:
multiple: false
filter:
domain: binary_sensor
group_door_specific_actions:
name: Door Actions
icon: mdi:door
collapsed: true
input:
enable_door_action:
name: Door Opened Action(s)
description: "Action(s) to perform when the door is opened."
default: []
selector:
action:
disable_door_action:
name: Door Closed Action(s)
description: "Action(s) to perform when the door is closed."
default: []
selector:
action:
group_occupancy_specific_actions:
name: Occupancy Actions
icon: mdi:account
collapsed: true
input:
enable_occupancy_action_now:
name: Occupancy Detected Action(s)
description: "Action(s) to perform when occupancy is detected."
default: []
selector:
action:
disable_occupancy_action_now:
name: Occupancy Cleared Action(s)
description: "Action(s) to perform when occupancy is cleared."
default: []
selector:
action:
enable_action_wait_duration:
name: Action Delay Duration
description: "The amount of time to wait until delayed active actions are triggered."
default: 60
selector:
number:
mode: box
unit_of_measurement: seconds
min: 0.0
max: 3600.0
step: 1.0
enable_occupancy_action_wait:
name: Delayed Occupancy Detected Action(s)
description: "Action(s) to perform when activity is detected, after a specified delay."
default: []
selector:
action:
disable_action_wait_duration:
name: Inaction Delay Duration
description: "The amount of time to wait until delayed inactive actions are triggered."
default: 60
selector:
number:
mode: box
unit_of_measurement: seconds
min: 0.0
max: 3600.0
step: 1.0
disable_occupancy_action_wait:
name: Delayed Occupancy Cleared Action(s)
description: "Action(s) to perform when activity is no longer detected, after a specified delay."
default: []
selector:
action:
group_area_config:
name: Helpers
icon: mdi:cog
collapsed: true
input:
idle_timer:
name: Idle Timer
description: "After this timer elapses, devices will automatically revert to their inactive state."
default: "timer.undefined"
selector:
entity:
multiple: false
filter:
domain: timer
# variables:
# sensor_door: !input sensor_door
# sensor_occupancy: !input sensor_occupancy
# enable_door_action: !input enable_door_action
# disable_door_action: !input disable_door_action
# enable_occupancy_action_now: !input enable_occupancy_action_now
# disable_occupancy_action_now: !input disable_occupancy_action_now
# enable_action_wait_duration: !input enable_action_wait_duration
# disable_action_wait_duration: !input disable_action_wait_duration
# enable_occupancy_action_wait: !input enable_occupancy_action_wait
# disable_occupancy_action_wait: !input disable_occupancy_action_wait
# idle_timer: !input idle_timer
triggers:
- alias: "When door is OPENED - IMMEDIATE"
trigger: state
entity_id: !input sensor_door
from: "off"
to: "on"
id: event_now_door_open
- alias: "When door is OPENED - DELAYED"
trigger: state
entity_id: !input sensor_door
from: "off"
to: "on"
for: !input enable_action_wait_duration
id: event_wait_door_open
- alias: "When door is CLOSED - IMMEDIATE"
trigger: state
entity_id: !input sensor_door
from: "on"
to: "off"
id: event_now_door_close
- alias: "When door is CLOSED - DELAYED"
trigger: state
entity_id: !input sensor_door
from: "on"
to: "off"
for: !input disable_action_wait_duration
id: event_wait_door_close
- alias: "When motion is DETECTED - IMMEDIATE"
trigger: state
entity_id: !input sensor_occupancy
from: "off"
to: "on"
id: event_now_motion_detect
- alias: "When motion is DETECTED - DELAYED"
trigger: state
entity_id: !input sensor_occupancy
from: "on"
to: "off"
for: !input enable_action_wait_duration
id: event_wait_motion_detect
- alias: "When motion is CLEARED - IMMEDIATE"
trigger: state
entity_id: !input sensor_occupancy
from: "on"
to: "off"
id: event_now_motion_clear
- alias: "When motion is CLEARED - DELAYED"
trigger: state
entity_id: !input sensor_occupancy
from: "on"
to: "off"
for: !input disable_action_wait_duration
id: event_wait_motion_clear
- alias: "When idle timer ENDS - IMMEDIATE"
trigger: event
event_type: timer.finished
event_data:
entity_id: !input idle_timer
id: event_idle_timer_finished
actions:
- alias: "Choose actions to check and run"
choose:
- alias: "Actions to perform if DOOR OPENED"
conditions:
- alias: "Check if trigged by event"
condition: trigger
id: event_now_door_open
sequence: !input enable_door_action
- alias: "Actions to perform if DOOR CLOSED"
conditions:
- alias: "Check if trigged by event"
condition: trigger
id: event_now_door_close
sequence: !input disable_door_action
- alias: "Actions to perform if DOOR OPENED, and MOTION DETECTED"
conditions:
- alias: "Ensure all events are true"
condition: and
conditions:
- alias: "Check if trigged by event"
condition: trigger
id: event_wait_door_open
- alias: "Check if occupancy is detected"
condition: state
entity_id: !input sensor_occupancy
state: "on"
sequence: !input enable_occupancy_action_wait
- alias: "Actions to perform if DOOR OPENED, and MOTION CLEAR"
conditions:
- alias: "Ensure all events are true"
condition: and
conditions:
- alias: "Check if trigged by event"
condition: trigger
id: event_now_door_open
- alias: "Check if occupancy is not detected"
condition: state
entity_id: !input sensor_occupancy
state: "off"
sequence:
- alias: "If configured, manage idle TIMER"
if:
- alias: "Confirm idle time is set"
condition: template
value_template: "{{ true if idle_timer != 'timer.undefined' }}"
then:
- alias: "Idle Timer, RESET"
action: timer.cancel
target:
entity_id: !input idle_timer
data: {}
- alias: "Idle Timer, START"
action: timer.start
metadata: {}
data: {}
target:
entity_id: !input idle_timer
# Action: IMMEDIATE DISABLE
- alias: "Actions to perform if DOOR CLOSED, and MOTION CLEAR"
conditions:
- alias: "Ensure all events are true"
condition: and
conditions:
- alias: "Check if trigged by event"
condition: trigger
id: event_now_door_close
- alias: "Check if occupancy is not detected"
condition: state
entity_id: !input sensor_occupancy
state: "off"
sequence: !input disable_occupancy_action_now
- alias: "Actions to perform when DOOR CLOSED, and MOTION CLEARED after delay"
conditions:
- alias: "Ensure all events are true"
condition: and
conditions:
- alias: "Check if trigged by event"
condition: trigger
id: event_wait_door_close
- alias: "Check if occupancy is not detected"
condition: state
entity_id: !input sensor_occupancy
state: "off"
sequence:
- alias: "If configured, RUN delayed disable ACTIONS"
if:
- condition: template
value_template: "{{ disable_occupancy_action_wait | length > 0 }}"
then: !input disable_occupancy_action_wait
- alias: "If configured, CANCEL idle TIMER"
if:
- alias: "Ensure all events are true"
condition: and
conditions:
- alias: "Confirm idle time is set"
condition: template
value_template: "{{ true if idle_timer != 'timer.undefined' }}"
- alias: "Check if idle time is running"
condition: state
entity_id: !input idle_timer
state: active
then:
- alias: "Idle Timer, RESET"
action: timer.cancel
data: {}
target:
entity_id: !input idle_timer
- alias: "Actions to perform when DOOR OPEN, and MOTION DETECTED"
conditions:
- alias: "Ensure all events are true"
condition: and
conditions:
- alias: "Check if trigged by event"
condition: trigger
id: event_now_motion_detect
- alias: "Check if door is open"
condition: state
entity_id: !input sensor_door
state: "on"
sequence:
- alias: "If configured, RUN immediate enable ACTIONS"
if:
- condition: template
value_template: "{{ enable_occupancy_action_now | length > 0 }}"
then: !input enable_occupancy_action_now
- alias: ""
if:
- condition: template
value_template: "{{ enable_occupancy_action_wait | length > 0 }}"
then: !input enable_occupancy_action_wait
- alias: "If configured, START idle TIMER"
if:
- alias: "Ensure all events are true"
condition: and
conditions:
- alias: "Confirm idle time is set"
condition: template
value_template: "{{ true if idle_timer != 'timer.undefined' }}"
- alias: "Check if idle timer is active"
condition: state
entity_id: !input idle_timer
state: active
then:
- alias: "Idle Timer, RESET"
action: timer.cancel
data: {}
target:
entity_id: !input idle_timer
- alias: "Actions to perform when MOTION CLEARED"
conditions:
- alias: "Check if trigged by event"
condition: trigger
id: event_wait_motion_clear
sequence:
- alias: "If configured, RUN immediate disable ACTIONS"
if:
- condition: template
value_template: "{{ disable_occupancy_action_now | length > 0 }}"
then: !input disable_occupancy_action_now
# - if:
# - condition: template
# value_template: "{{ disable_occupancy_action_wait | length > 0 }}"
# then: !input disable_occupancy_action_wait
- alias: "If DOOR is OPEN"
if:
- alias: "Ensure all events are true"
condition: and
conditions:
- alias: "Confirm idle time is set"
condition: template
value_template: "{{ true if idle_timer != 'timer.undefined' }}"
- alias: "Check if door is open"
condition: state
entity_id: !input sensor_door
state: "on"
then:
- alias: "Idle Timer, RESET"
action: timer.cancel
target:
entity_id: !input idle_timer
data: {}
- alias: "Idle Timer, START"
action: timer.start
metadata: {}
data: {}
target:
entity_id: !input idle_timer
- alias: "Actions to perform when occupancy TIMER FINISHED"
conditions:
- condition: trigger
id: event_idle_timer_finished
sequence:
- if:
- alias: "Check if occupancy is not detected"
condition: state
entity_id: !input sensor_occupancy
state: "off"
then:
- alias: "Idle Timer, RESET"
action: timer.cancel
data: {}
target:
entity_id: !input idle_timer
- alias: "If configured, RUN immediate disable ACTIONS"
if:
- condition: template
value_template: "{{ disable_occupancy_action_now | length > 0 }}"
then: !input disable_occupancy_action_now
- alias: "If configured, RUN delayed disable ACTIONS"
if:
- condition: template
value_template: "{{ disable_occupancy_action_wait | length > 0 }}"
then: !input disable_occupancy_action_wait
else:
- alias: "Idle Timer, RESET"
action: timer.cancel
data: {}
target:
entity_id: !input idle_timer
- alias: "Idle Timer, START"
action: timer.start
metadata: {}
data: {}
target:
entity_id: !input idle_timer
mode: single
max_exceeded: silent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment