######################## ### Blueprint definition ######################## blueprint: name: "Mike's Motion Activated Light" description: "Turn lights on or off based on motion, plus an increasing delay when motion is continuously detected." domain: automation input: motion_sensor: name: "Motion Sensor" description: "Entity ID of the motion sensor" selector: entity: domain: binary_sensor # for some reason, using a device_class of motion_sensor ends up hiding the actual motion sensors # device_class: motion_sensor delay_seconds_helper: name: "Delay seconds (helper)" description: "The delay before the motion-off sequence will be initiated. Must be a helper so it can persist across activations." selector: entity: domain: input_number delay_seconds_default: name: "Default delay seconds" description: "The default delay before the motion-off sequence begins. Will be used to reset the running delay." default: 30 selector: number: min: 1 max: 86400 step: 1 mode: box notice_seconds: name: "Notice seconds" description: "The number of seconds to wait in the Prep1 (Notice) scene." default: 15 selector: number: min: 1 max: 86400 step: 1 mode: box warning_seconds: name: "Warning seconds" description: "The number of seconds to wait in the Prep2 (Warning) scene." default: 15 selector: number: min: 1 max: 86400 step: 1 mode: box scene_on: name: "On Scene" description: "The scene to activate when motion is detected" selector: entity: domain: scene scene_off_prep_1: name: "Off Prep Scene 1 (Notice)" description: "The first scene to activate when motion is no longer detected (notice phase)." selector: entity: domain: scene scene_off_prep_2: name: "Off Prep Scene 2 (Warning)" description: "The second scene to activate when motion is no longer detected (warning phase)." selector: entity: domain: scene scene_off: name: "Off Scene" description: "The scene to activate when the user has failed to produce motion, and the light should be considered \"off\"." selector: entity: domain: scene on_just_before_off: name: "Use On scene just before Off scene." description: "Toggle this to \"on\" if you would like the \"On\" scene to trigger just before the \"Off\" scene. This is sometimes helpful to mitigate an issue where the \"On\" scene doesn't apply all colors and settings correctly from an \"Off\" state." selector: boolean: {} ############# ### Variables ############# variables: motion_sensor: !input motion_sensor delay_seconds: !input delay_seconds_helper delay_seconds_default: !input delay_seconds_default notice_seconds: !input notice_seconds warning_seconds: !input warning_seconds on_just_before_off: !input on_just_before_off ############ ### Triggers ############ trigger: - platform: state entity_id: - !input motion_sensor to: - "on" - "off" ########### ### Actions ########### action: - service: logbook.log data: name: "First log" message: "Motion automation has started. Delay counter is: {{ states[delay_seconds].state }}" - alias: "Debug log the on_just_before_off bool" enabled: false service: logbook.log data: name: "Debug: On just before off?" message: "On just before off is: {{ on_just_before_off }} " - if: - condition: state entity_id: !input motion_sensor state: "on" # Take actions based on Motion being detected! then: - alias: "Log that motion was detected." service: logbook.log data: name: "Motion On" message: "Motion was detected." - parallel: - alias: "Activate the ON scene" service: scene.turn_on target: entity_id: !input scene_on # Take actions based on Motion being undetected else: - alias: "Log that the motion-off sequence will run, due to motion no longer detected." service: logbook.log data: name: "Motion Off" message: "Initiating motion-off sequence, because motion no longer detected." # Initial period where nothing happens - alias: "Delay appropriately before doing anything" wait_template: "{{ states[motion_sensor].state == 'on' }}" timeout: "{{ states[delay_seconds].state }}" - if: - condition: state entity_id: !input motion_sensor state: "on" then: - stop: "Motion detected again during initial delay." - alias: "Log that the initial delay has finished." service: logbook.log data: name: "Motion Off" message: "Finished initial no-motion delay" # Notice period, where the notice scene is shown - alias: "Log that the notice period has begun." service: logbook.log data: name: "Begin notice period" message: "Begin notice period; Waiting while motion is still off." - parallel: - alias: "Activate Scene: Off Prep 1 (Notice)" service: scene.turn_on target: entity_id: !input scene_off_prep_1 - alias: "Delay during the notice period" wait_template: "{{ states[motion_sensor].state == 'on' }}" timeout: "{{ notice_seconds }}" - if: - condition: state entity_id: !input motion_sensor state: "on" then: - parallel: - alias: "Activate Scene: On" service: scene.turn_on target: entity_id: !input scene_on - alias: "Double countdown timer when user interrupts the notice period." service: input_number.set_value data: entity_id: !input delay_seconds_helper value: "{{ states[delay_seconds].state | int * 2 }}" - stop: "Motion detected during notice period." - service: logbook.log data: name: "Notice period finished." message: "Notice period has finished (motion is still off)." # Warning period, just before the light turns off. The warning scene is shown. - alias: "Log that the warning period has begun." service: logbook.log data: name: "Begin warning period" message: "Begin warning period; Waiting while motion is still off." - parallel: - alias: "Activate Scene: Off Prep 2 (Warning)" service: scene.turn_on target: entity_id: !input scene_off_prep_2 - alias: "Delay during the warning period" wait_template: "{{ states[motion_sensor].state == 'on' }}" timeout: "{{ warning_seconds }}" - if: - condition: state entity_id: !input motion_sensor state: "on" then: - parallel: - alias: "Activate Scene: On" service: scene.turn_on target: entity_id: !input scene_on - alias: "Double countdown timer when user interrupts the warning period." service: input_number.set_value data: entity_id: !input delay_seconds_helper value: "{{ states[delay_seconds].state | int * 2 }}" - stop: "Motion detected during the warning period." - service: logbook.log data: name: "Warning period finished." message: "Warning period has finished and motion is still off." # Finally, we decide to actually turn off the lights with the "Off" scene. # Maybe turn on the "On" scene just before the "Off" scene, if the user enabled this option - if: - condition: template value_template: "{{ on_just_before_off == true }}" then: - alias: "Do a debug log" enabled: false service: logbook.log data: name: "DEBUG: Will turn on before off?" message: "Yes, will turn on just before off!" - service: scene.turn_on target: entity_id: !input scene_on - alias: "Wait a second to set the \"On\" scene." delay: seconds: 1 - parallel: - alias: "Activate Scene: Off (Done)" service: scene.turn_on target: entity_id: !input scene_off - alias: "Reset countdown timer after turning off lights." service: input_number.set_value data: entity_id: !input delay_seconds_helper value: "{{ delay_seconds_default }}" - service: logbook.log data: name: "Turning off light, due to motion off." message: "Activated off-scene and reset delay."