7 Commits

Author SHA1 Message Date
baa226bcab Uncomment binary sensor domain for the motion sensor 2023-11-15 06:01:26 -08:00
c059a2773f Whoops name 2023-11-15 05:54:36 -08:00
acaf3518c2 Upgrades might be working:
* Specify max delay
* Specify delay multiplier
* Specify off-before-on seconds
* Specify debug mode logging
2023-11-15 05:53:03 -08:00
c289fce42b Work 2023-11-15 05:00:36 -08:00
16db7d752b Upgrade: User can now set the "On" scene to run just before the "Off" scene, if they want
(to mitigate color and other settings not reaching lights that are off, for some reason)
2023-11-10 23:18:32 -08:00
f5b49149e9 Switch senes to parallel to avoid lag, probably 2023-10-20 23:51:25 -07:00
045e87fe73 Turn scene on twice to account for laggy networks
Also quoted some things and improved logging a bit.
2023-10-10 06:46:35 -07:00

View File

@ -1,5 +1,9 @@
########################
### Blueprint definition
########################
blueprint: blueprint:
name: "Mike's Motion Activated Light" name: "Mike's Motion Activated Light"
@ -8,22 +12,26 @@ blueprint:
input: input:
motion_sensor: motion_sensor:
name: Motion Sensor name: "Motion Sensor"
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
# device_class: motion_sensor
delay_seconds_helper: delay_seconds_helper:
name: 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. description: "The delay before the motion-off sequence will be initiated. Must be a helper so it can persist across activations."
selector: selector:
entity: entity:
domain: input_number domain: input_number
delay_seconds_default: delay_seconds_default:
name: Default delay seconds name: "Default delay seconds"
description: The default delay before the motion-off sequence begins. Will be used to reset the running delay. description: "The default delay before the motion-off sequence begins. Will be used to reset the running delay."
default: 30 default: 30
selector: selector:
number: number:
@ -32,8 +40,33 @@ blueprint:
step: 1 step: 1
mode: box mode: box
delay_seconds_multiplier:
name: "Delay seconds multiplier"
description: "When the off sequence gets interrupted by new motion, multiply the delay seconds by this number. A decent value might be 2."
default: 2.0
selector:
number:
min: 1.0
max: 1000.0
step: 0.1
mode: box
delay_seconds_max:
name: "Maximum delay seconds"
description: "The maximum delay during no motion before the motion-off sequence begins."
default: 3600
selector:
number:
min: 5
max: 3000000
step: 1
mode: box
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 Prep1 (Notice) scene."
default: 15 default: 15
selector: selector:
@ -43,8 +76,9 @@ blueprint:
step: 1 step: 1
mode: box mode: box
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 Prep2 (Warning) scene."
default: 15 default: 15
selector: selector:
@ -54,41 +88,85 @@ blueprint:
step: 1 step: 1
mode: box mode: box
scene_on: scene_on:
name: On Scene name: "On Scene"
description: The scene to activate when motion is detected description: "The scene to activate when motion is detected"
selector: selector:
entity: entity:
domain: scene domain: scene
scene_off_prep_1: scene_off_prep_1:
name: Off Prep Scene 1 (Notice) name: "Off Prep Scene 1 (Notice)"
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_off_prep_2:
name: Off Prep Scene 2 (Warning) name: "Off Prep Scene 2 (Warning)"
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:
domain: scene domain: scene
scene_off: scene_off:
name: Off Scene name: "Off Scene"
description: "The scene to activate when the user has failed to produce motion, and the light should be considered \"off\"." description: "The scene to activate when the user has failed to produce motion, and the light should be considered \"off\"."
selector: selector:
entity: entity:
domain: scene domain: scene
on_just_before_off_seconds:
name: "\"On\" just before \"Off\""
description: >
When the "Off" scene is about to be shown, you may wish to quickly show the "On" scene for a number of seconds just before.
This is sometimes helpful to mitigate an issue where the "On" scene doesn't apply all colors and settings correctly from an "Off" state.
Set this to a value greater than 0 to enable.
A value of 0 will disable this feature.
Note that sometimes, a value that is too short (e.g., 1) may also cause issues.
default: 1
selector:
number:
min: 1
max: 86400
step: 1
mode: box
debug_mode:
name: "Debug mode."
description: "Enable debug mode, which increases logging."
default: false
selector:
boolean: {}
#############
### Variables
#############
variables: variables:
motion_sensor: !input motion_sensor motion_sensor: !input motion_sensor
delay_seconds: !input delay_seconds_helper delay_seconds: !input delay_seconds_helper
delay_seconds_default: !input delay_seconds_default delay_seconds_default: !input delay_seconds_default
notice_seconds: !input notice_seconds delay_seconds_multiplier: !input delay_seconds_multiplier
warning_seconds: !input warning_seconds delay_seconds_max: !input delay_seconds_max
notice_seconds: !input notice_seconds
warning_seconds: !input warning_seconds
on_just_before_off_seconds: !input on_just_before_off_seconds
debug_mode: !input debug_mode
############
### Triggers
############
trigger: trigger:
@ -99,12 +177,26 @@ trigger:
- "on" - "on"
- "off" - "off"
###########
### Actions
###########
action: action:
- service: logbook.log - service: logbook.log
data: data:
name: First log name: "First log"
message: "Test Poop Blueprint has started. Motion delay counter is: {{ states[delay_seconds].state }}" message: "Motion automation has started. Delay counter is: {{ states[delay_seconds].state }}"
- alias: "Debug log the on_just_before_off_seconds value"
if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
service: logbook.log
data:
name: "Debug: On just before off seconds"
message: "On just before off is: {{ on_just_before_off_seconds }} "
- if: - if:
- condition: state - condition: state
@ -114,103 +206,210 @@ action:
# Take actions based on Motion being detected! # Take actions based on Motion being detected!
then: then:
- alias: Trying to log the motion state - alias: "Log that motion was detected."
service: logbook.log service: logbook.log
data: data:
name: Motion On name: "Motion On"
message: Motion Detected message: "Motion was detected."
- parallel:
- alias: "Activate the ON scene"
service: scene.turn_on
target:
entity_id: !input scene_on
- alias: "Activate the ON scene"
service: scene.turn_on
target:
entity_id: !input scene_on
# Take actions based on Motion being undetected # Take actions based on Motion being undetected
else: else:
- alias: Announce motion-off sequence - alias: "Log that the motion-off sequence will run, due to motion no longer detected."
service: logbook.log service: logbook.log
data: data:
name: Motion Off name: "Motion Off"
message: Initiating motion-off sequence. message: "Initiating motion-off sequence, because motion no longer detected."
- alias: Delay appropriately before doing anything # Initial period where nothing happens
wait_template: "{{ states[motion_sensor].state == 'on' }}" - alias: "Delay appropriately before doing anything"
wait_template: "{{ states[motion_sensor].state == 'on' }}"
timeout: "{{ states[delay_seconds].state }}" timeout: "{{ states[delay_seconds].state }}"
- if: - if:
- condition: state - condition: state
entity_id: !input motion_sensor entity_id: !input motion_sensor
state: "on" state: "on"
then: then:
- stop: "Motion detected during initial delay." - stop: "Motion detected again during initial delay."
- service: logbook.log - alias: "Log that the initial delay has finished."
service: logbook.log
data: data:
name: Motion Off name: "Motion Off"
message: Finished initial no-motion delay message: "Finished initial no-motion delay"
- alias: "Activate Scene: Off Prep 1 (Notice)" # Notice period, where the notice scene is shown
service: scene.turn_on - alias: "Log that the notice period has begun."
target: service: logbook.log
entity_id: !input scene_off_prep_1 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" - alias: "Delay during the notice period"
wait_template: "{{ states[motion_sensor].state == 'on' }}" wait_template: "{{ states[motion_sensor].state == 'on' }}"
timeout: "{{ notice_seconds }}" timeout: "{{ notice_seconds }}"
- if: - if:
- condition: state - condition: state
entity_id: !input motion_sensor entity_id: !input motion_sensor
state: "on" state: "on"
then: then:
- alias: "Activate Scene: On" - parallel:
service: scene.turn_on - alias: "Activate Scene: On"
target: service: scene.turn_on
entity_id: !input scene_on target:
- alias: "Double countdown timer when user interrupts the notice period." entity_id: !input scene_on
- alias: "Increase countdown timer when user interrupts the notice period."
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 * 2 }}" value: "{{ states[delay_seconds].state | int * delay_seconds_multiplier }}"
- alias: "Limit delay seconds to its defined maximum"
if:
- condition: template
value_template: "{{ states[delay_seconds].state | int > delay_seconds_max | int }}"
then:
- service: input_number.set_value
data:
entity_id: !input delay_seconds_helper
value: "{{ delay_seconds_max | int }}"
- if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
- service: logbook.log
data:
name: "Limiting delay seconds"
message: "Delay limited to max: {{ states[delay_seconds].state }}"
- alias: "Log new delay"
if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
- service: logbook.log
data:
name: "New delay"
message: "New delay is {{ states[delay_seconds].state }} seconds"
- stop: "Motion detected during notice period." - stop: "Motion detected during notice period."
- service: logbook.log - service: logbook.log
data: data:
name: Motion Off name: "Notice period finished."
message: Finished notice delay message: "Notice period has finished (motion is still off)."
- alias: "Activate Scene: Off Prep 2 (Warning)"
service: scene.turn_on # Warning period, just before the light turns off. The warning scene is shown.
target: - alias: "Log that the warning period has begun."
entity_id: !input scene_off_prep_2 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" - alias: "Delay during the warning period"
wait_template: "{{ states[motion_sensor].state == 'on' }}" wait_template: "{{ states[motion_sensor].state == 'on' }}"
timeout: "{{ warning_seconds }}" timeout: "{{ warning_seconds }}"
- if: - if:
- condition: state - condition: state
entity_id: !input motion_sensor entity_id: !input motion_sensor
state: "on" state: "on"
then: then:
- alias: "Activate Scene: On" - parallel:
service: scene.turn_on - alias: "Activate Scene: On"
target: service: scene.turn_on
entity_id: !input scene_on target:
entity_id: !input scene_on
- alias: "Double countdown timer when user interrupts the warning period." - alias: "Double countdown timer when user interrupts the warning period."
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 * 2 }}" value: "{{ states[delay_seconds].state | int * delay_seconds_multiplier }}"
- alias: "Limit delay seconds to its defined maximum"
if:
- condition: template
value_template: "{{ states[delay_seconds].state | int > delay_seconds_max | int }}"
then:
- service: input_number.set_value
data:
entity_id: !input delay_seconds_helper
value: "{{ delay_seconds_max | int }}"
- if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
- service: logbook.log
data:
name: "Limiting delay seconds"
message: "Delay limited to max: {{ states[delay_seconds].state }}"
- alias: "Log new delay seconds"
if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
- service: logbook.log
data:
name: "New delay seconds"
message: "New delay is {{ states[delay_seconds].state }} seconds."
- stop: "Motion detected during the warning period." - stop: "Motion detected during the warning period."
- service: logbook.log - service: logbook.log
data: data:
name: Motion Off name: "Warning period finished."
message: Finished warning delay message: "Warning period has finished and motion is still off."
- alias: "Activate Scene: Off (Done)"
service: scene.turn_on
target:
entity_id: !input scene_off
- alias: "Reset countdown timer after turning on lights." # 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_seconds > 0 }}"
then:
- alias: "Log the number of on-before-off seconds"
if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
service: logbook.log
data:
name: "On-Before-Off seconds"
message: "Will turn on for {{ on_just_before_off_seconds }} seconds before off."
- service: scene.turn_on
target:
entity_id: !input scene_on
- alias: "Wait a second to set the \"On\" scene."
delay:
seconds: "{{ on_just_before_off_seconds }}"
else:
- if:
- condition: template
value_template: "{{ debug_mode == true }}"
then:
- service: logbook.log
data:
name: "Won't run on-before-off"
message: "Won't run on-before-off because seconds was less than 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 service: input_number.set_value
data: data:
entity_id: !input delay_seconds_helper entity_id: !input delay_seconds_helper
@ -218,8 +417,8 @@ action:
- service: logbook.log - service: logbook.log
data: data:
name: Motion Off name: "Turning off light, due to motion off."
message: Activated off-scene and reset delay. message: "Activated off-scene and reset delay."