7 Commits

View File

@ -4,10 +4,12 @@
### Blueprint definition ### Blueprint definition
######################## ########################
mode: queued
max: 25
blueprint: blueprint:
name: "Mike's Motion Activated Light" name: "Mike's Motion Activated Scenes"
description: "Turn lights on or off based on motion, plus an increasing delay when motion is continuously detected." description: "Activate scenes based on motion with notice and warning phases, plus an increasing delay when motion is continuously detected."
domain: automation domain: automation
input: input:
@ -16,7 +18,7 @@ blueprint:
description: "Entity ID of the motion sensor" description: "Entity ID of the motion sensor"
selector: selector:
entity: entity:
# domain: binary_sensor domain: binary_sensor
# for some reason, using a device_class of motion_sensor ends up hiding the actual motion sensors # for some reason, using a device_class of motion_sensor ends up hiding the actual motion sensors
# device_class: motion_sensor # device_class: motion_sensor
@ -67,7 +69,7 @@ blueprint:
notice_seconds: notice_seconds:
name: "Notice seconds" name: "Notice seconds"
description: "The number of seconds to wait in the Prep1 (Notice) scene." description: "The number of seconds to wait in the Notice scene."
default: 15 default: 15
selector: selector:
number: number:
@ -79,7 +81,7 @@ blueprint:
warning_seconds: warning_seconds:
name: "Warning seconds" name: "Warning seconds"
description: "The number of seconds to wait in the Prep2 (Warning) scene." description: "The number of seconds to wait in the Warning scene."
default: 15 default: 15
selector: selector:
number: number:
@ -97,16 +99,16 @@ blueprint:
domain: scene domain: scene
scene_off_prep_1: scene_notice:
name: "Off Prep Scene 1 (Notice)" name: "Notice Scene"
description: "The first scene to activate when motion is no longer detected (notice phase)." description: "The first scene to activate when motion is no longer detected (notice phase)."
selector: selector:
entity: entity:
domain: scene domain: scene
scene_off_prep_2: scene_warning:
name: "Off Prep Scene 2 (Warning)" name: "Warning Scene"
description: "The second scene to activate when motion is no longer detected (warning phase)." description: "The second scene to activate when motion is no longer detected (warning phase)."
selector: selector:
entity: entity:
@ -139,6 +141,33 @@ blueprint:
mode: box mode: box
enabled_helper:
name: "Enabled helper"
description: >
Helper variable that will control whether motion activation is enabled or disabled.
This will allow this blueprint to correctly select the "On" or "Off" scene, based on whether motion is currently detected when disabled.
An example would be a "Toggle" helper.
default: # Allows no selection
selector:
entity:
domain: input_boolean
disabled_scene:
name: "Disabled scene"
description: >
Choose the scene that will be activated when the "enabled_helper" is set to off.
In the "auto" mode, the "on" or "off" scene will be chosen based on whether motion is currently detected.
selector:
select:
options:
- "auto"
- "on"
- "off"
- "notice"
- "warning"
debug_mode: debug_mode:
name: "Debug mode." name: "Debug mode."
description: "Enable debug mode, which increases logging." description: "Enable debug mode, which increases logging."
@ -154,16 +183,22 @@ blueprint:
variables: variables:
motion_sensor: !input motion_sensor motion_sensor: !input motion_sensor
delay_seconds: !input delay_seconds_helper delay_seconds_helper: !input delay_seconds_helper
delay_seconds_default: !input delay_seconds_default delay_seconds_default: !input delay_seconds_default
delay_seconds_multiplier: !input delay_seconds_multiplier delay_seconds_multiplier: !input delay_seconds_multiplier
delay_seconds_max: !input delay_seconds_max delay_seconds_max: !input delay_seconds_max
notice_seconds: !input notice_seconds notice_seconds: !input notice_seconds
warning_seconds: !input warning_seconds warning_seconds: !input warning_seconds
on_just_before_off_seconds: !input on_just_before_off_seconds on_just_before_off_seconds: !input on_just_before_off_seconds
enabled_helper: !input enabled_helper
disabled_scene: !input disabled_scene
debug_mode: !input debug_mode debug_mode: !input debug_mode
trigger_variables:
enabled_helper: !input enabled_helper
############ ############
### Triggers ### Triggers
############ ############
@ -171,23 +206,74 @@ variables:
trigger: trigger:
- platform: state - platform: state
id: Motion changed
entity_id: entity_id:
- !input motion_sensor - !input motion_sensor
to: to:
- "on" - "on"
- "off" - "off"
- platform: template
id: "Enabled helper is on"
value_template: "{{ (enabled_helper != None) and is_state( enabled_helper, 'on' ) }}"
- platform: template
id: "Enabled helper is off"
value_template: "{{ (enabled_helper != None) and is_state( enabled_helper, 'off' ) }}"
########### ###########
### Actions ### Actions
########### ###########
action: action:
# Action #0
- alias: "Debug log whether the enabled_helper was set"
if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
- if:
- condition: template
value_template: "{{ not enabled_helper == None }}"
then:
- service: logbook.log - service: logbook.log
data: data:
name: "First log" name: "Enabled helper"
message: "Motion automation has started. Delay counter is: {{ states[delay_seconds].state }}" message: "Enabled helper is: {{ enabled_helper }}"
else:
- service: logbook.log
data:
name: "Enabled helper"
message: "Enabled helper is not set."
# Action #1
- alias: "Debug log the enabled_helper name"
if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
- service: logbook.log
data:
name: "Enabled helper"
message: "Enabled helper name is: {{ enabled_helper }}"
# Action #2
- alias: "Debug log the current delay_seconds value"
if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
- service: logbook.log
data:
name: "Delay seconds"
message: "Delay seconds is: {{ states[delay_seconds_helper].state }}"
# Action #3
- alias: "Debug log the on_just_before_off_seconds value" - alias: "Debug log the on_just_before_off_seconds value"
if: if:
- condition: template - condition: template
@ -198,15 +284,140 @@ action:
name: "Debug: On just before off seconds" name: "Debug: On just before off seconds"
message: "On just before off is: {{ on_just_before_off_seconds }} " message: "On just before off is: {{ on_just_before_off_seconds }} "
# Take actions based on whether the "Enabled helper" was just toggled on or off
# Action #4
- if:
- condition: trigger
id:
- Enabled helper is on
- Enabled helper is off
then:
# Debug log
- alias: "Debug log - Enabled Helper On/Off"
if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
- service: logbook.log
data:
name: "Debug: Trigger"
message: "Enabled helper was toggled, and has triggered this automation"
- alias: "Debug log - Disabled scene"
if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
- service: logbook.log
data:
name: "Debug: Disabled scene"
message: "Disabled scene is currently set to: {{ disabled_scene }}"
# In "auto" mode, activate the ON or OFF scene based on whether motion is currently detected
# Also use "auto" mode if motion activation is ENABLED.
- alias: "auto mode: Activate ON scene, if motion is currently detected, otherwise activate the OFF scene"
if:
- condition: template
value_template: "{{ disabled_scene == 'auto' or (enabled_helper != None and is_state( enabled_helper, 'on' )) }}"
then:
- if:
- condition: state
entity_id: !input motion_sensor
state: "on"
then:
- parallel:
- alias: "Activate the ON scene"
service: scene.turn_on
target:
entity_id: !input scene_on
else:
- parallel:
- alias: "Activate the OFF scene"
service: scene.turn_on
target:
entity_id: !input scene_off
- stop: ""
# In ON mode, just activate the ON scene
- alias: "on mode: just activate the ON scene"
if:
- condition: template
value_template: "{{ disabled_scene == 'on' }}"
then:
- parallel:
- service: scene.turn_on
target:
entity_id: !input scene_on
- stop: ""
# In OFF mode, just activate the OF scene
- alias: "off mode: just activate the ON scene"
if:
- condition: template
value_template: "{{ disabled_scene == 'off' }}"
then:
- parallel:
- service: scene.turn_on
target:
entity_id: !input scene_off
- stop: ""
# In notice mode, just activate the NOTICE scene
- alias: "notice mode: just activate the NOTICE scene"
if:
- condition: template
value_template: "{{ disabled_scene == 'notice' }}"
then:
- parallel:
- service: scene.turn_on
target:
entity_id: !input scene_notice
- stop: ""
# In warning mode, just activate the WARNING scene
- alias: "warning mode: just activate the WARNING scene"
if:
- condition: template
value_template: "{{ disabled_scene == 'warning' }}"
then:
- parallel:
- service: scene.turn_on
target:
entity_id: !input scene_warning
- stop: ""
# Don't do anything after processing the enabled_helper triggers
- stop: "Done handling enabled helper"
# Take actions based on whether Motion is detected
- alias: "Refuse to do anything if the enabled-helper says we're OFF."
if:
- condition: template
value_template: "{{ enabled_helper != None }}"
- condition: template
value_template: "{{ not is_state( enabled_helper, 'on' ) }}"
then:
stop: "Refusing to continue because the enabled-helper is OFF."
- if: - if:
- condition: state - condition: state
entity_id: !input motion_sensor entity_id: !input motion_sensor
state: "on" state: "on"
# Take actions based on Motion being detected!
# Motion is detected
then: then:
- alias: "Log that motion was detected." - alias: "Debug Log that motion was detected."
if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
service: logbook.log service: logbook.log
data: data:
name: "Motion On" name: "Motion On"
@ -219,10 +430,14 @@ action:
entity_id: !input scene_on entity_id: !input scene_on
# Take actions based on Motion being undetected # Motion is not detected
else: else:
- alias: "Log that the motion-off sequence will run, due to motion no longer detected." - alias: "Debug Log that the motion-off sequence will run, due to motion no longer detected."
if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
service: logbook.log service: logbook.log
data: data:
name: "Motion Off" name: "Motion Off"
@ -232,7 +447,17 @@ action:
# Initial period where nothing happens # Initial period where nothing happens
- alias: "Delay appropriately before doing anything" - alias: "Delay appropriately before doing anything"
wait_template: "{{ states[motion_sensor].state == 'on' }}" wait_template: "{{ states[motion_sensor].state == 'on' }}"
timeout: "{{ states[delay_seconds].state }}" timeout: "{{ states[delay_seconds_helper].state or (enabled_helper != None and is_state(enabled_helper, 'off') ) }}"
- alias: "Quit now if the enabled-helper went OFF"
if:
- condition: template
value_template: "{{ enabled_helper != None }}"
- condition: template
value_template: "{{ is_state( enabled_helper, 'off' ) }}"
then:
stop: "Quitting early because the enabled-helper went OFF."
- if: - if:
- condition: state - condition: state
entity_id: !input motion_sensor entity_id: !input motion_sensor
@ -240,6 +465,10 @@ action:
then: then:
- stop: "Motion detected again during initial delay." - stop: "Motion detected again during initial delay."
- alias: "Log that the initial delay has finished." - alias: "Log that the initial delay has finished."
if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
service: logbook.log service: logbook.log
data: data:
name: "Motion Off" name: "Motion Off"
@ -249,18 +478,33 @@ action:
# Notice period, where the notice scene is shown # Notice period, where the notice scene is shown
- alias: "Log that the notice period has begun." - alias: "Log that the notice period has begun."
if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
service: logbook.log service: logbook.log
data: data:
name: "Begin notice period" name: "Begin notice period"
message: "Begin notice period; Waiting while motion is still off." message: "Begin notice period; Waiting while motion is still off."
- parallel: - parallel:
- alias: "Activate Scene: Off Prep 1 (Notice)" - alias: "Activate Scene: Notice"
service: scene.turn_on service: scene.turn_on
target: target:
entity_id: !input scene_off_prep_1 entity_id: !input scene_notice
- alias: "Delay during the notice period" - alias: "Delay during the notice period"
wait_template: "{{ states[motion_sensor].state == 'on' }}" wait_template: "{{ states[motion_sensor].state == 'on' or (enabled_helper != None and is_state('enabled_helper', 'off') ) }}"
timeout: "{{ notice_seconds }}" timeout: "{{ notice_seconds }}"
- alias: "Quit now if the enabled-helper went OFF"
if:
- condition: template
value_template: "{{ enabled_helper != None }}"
- condition: template
value_template: "{{ is_state( enabled_helper, 'off' ) }}"
then:
stop: "Quitting early because the enabled-helper went OFF."
- if: - if:
- condition: state - condition: state
entity_id: !input motion_sensor entity_id: !input motion_sensor
@ -275,11 +519,11 @@ action:
service: input_number.set_value service: input_number.set_value
data: data:
entity_id: !input delay_seconds_helper entity_id: !input delay_seconds_helper
value: "{{ states[delay_seconds].state | int * delay_seconds_multiplier }}" value: "{{ states[delay_seconds_helper].state | int * delay_seconds_multiplier }}"
- alias: "Limit delay seconds to its defined maximum" - alias: "Limit delay seconds to its defined maximum"
if: if:
- condition: template - condition: template
value_template: "{{ states[delay_seconds].state | int > delay_seconds_max | int }}" value_template: "{{ states[delay_seconds_helper].state | int > delay_seconds_max | int }}"
then: then:
- service: input_number.set_value - service: input_number.set_value
data: data:
@ -292,7 +536,7 @@ action:
- service: logbook.log - service: logbook.log
data: data:
name: "Limiting delay seconds" name: "Limiting delay seconds"
message: "Delay limited to max: {{ states[delay_seconds].state }}" message: "Delay limited to max: {{ states[delay_seconds_helper].state }}"
- alias: "Log new delay" - alias: "Log new delay"
if: if:
- condition: template - condition: template
@ -301,8 +545,12 @@ action:
- service: logbook.log - service: logbook.log
data: data:
name: "New delay" name: "New delay"
message: "New delay is {{ states[delay_seconds].state }} seconds" message: "New delay is {{ states[delay_seconds_helper].state }} seconds"
- stop: "Motion detected during notice period." - stop: "Motion detected during notice period."
- if:
condition: template
value_template: "{{ debug_mode == true }}"
then:
- service: logbook.log - service: logbook.log
data: data:
name: "Notice period finished." name: "Notice period finished."
@ -311,18 +559,35 @@ action:
# Warning period, just before the light turns off. The warning scene is shown. # Warning period, just before the light turns off. The warning scene is shown.
- alias: "Log that the warning period has begun." - alias: "Log that the warning period has begun."
if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
service: logbook.log service: logbook.log
data: data:
name: "Begin warning period" name: "Begin warning period"
message: "Begin warning period; Waiting while motion is still off." message: "Begin warning period; Waiting while motion is still off."
- parallel: - parallel:
- alias: "Activate Scene: Off Prep 2 (Warning)" - alias: "Activate Scene: Warning"
service: scene.turn_on service: scene.turn_on
target: target:
entity_id: !input scene_off_prep_2 entity_id: !input scene_warning
- alias: "Delay during the warning period" - alias: "Delay during the warning period"
wait_template: "{{ states[motion_sensor].state == 'on' }}" wait_template: "{{ states[motion_sensor].state == 'on' or (enabled_helper != None and is_state('enabled_helper', 'off') ) }}"
timeout: "{{ warning_seconds }}" timeout: "{{ warning_seconds }}"
- alias: "Quit now if the enabled-helper went OFF"
if:
- condition: template
value_template: "{{ enabled_helper != None }}"
- condition: template
value_template: "{{ is_state( enabled_helper, 'off' ) }}"
then:
stop: "Quitting early because the enabled-helper went OFF."
- if: - if:
- condition: state - condition: state
entity_id: !input motion_sensor entity_id: !input motion_sensor
@ -337,11 +602,11 @@ action:
service: input_number.set_value service: input_number.set_value
data: data:
entity_id: !input delay_seconds_helper entity_id: !input delay_seconds_helper
value: "{{ states[delay_seconds].state | int * delay_seconds_multiplier }}" value: "{{ states[delay_seconds_helper].state | int * delay_seconds_multiplier }}"
- alias: "Limit delay seconds to its defined maximum" - alias: "Limit delay seconds to its defined maximum"
if: if:
- condition: template - condition: template
value_template: "{{ states[delay_seconds].state | int > delay_seconds_max | int }}" value_template: "{{ states[delay_seconds_helper].state | int > delay_seconds_max | int }}"
then: then:
- service: input_number.set_value - service: input_number.set_value
data: data:
@ -354,7 +619,7 @@ action:
- service: logbook.log - service: logbook.log
data: data:
name: "Limiting delay seconds" name: "Limiting delay seconds"
message: "Delay limited to max: {{ states[delay_seconds].state }}" message: "Delay limited to max: {{ states[delay_seconds_helper].state }}"
- alias: "Log new delay seconds" - alias: "Log new delay seconds"
if: if:
- condition: template - condition: template
@ -363,8 +628,12 @@ action:
- service: logbook.log - service: logbook.log
data: data:
name: "New delay seconds" name: "New delay seconds"
message: "New delay is {{ states[delay_seconds].state }} seconds." message: "New delay is {{ states[delay_seconds_helper].state }} seconds."
- stop: "Motion detected during the warning period." - stop: "Motion detected during the warning period."
- if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
- service: logbook.log - service: logbook.log
data: data:
name: "Warning period finished." name: "Warning period finished."
@ -415,6 +684,10 @@ action:
entity_id: !input delay_seconds_helper entity_id: !input delay_seconds_helper
value: "{{ delay_seconds_default }}" value: "{{ delay_seconds_default }}"
- if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
- service: logbook.log - service: logbook.log
data: data:
name: "Turning off light, due to motion off." name: "Turning off light, due to motion off."