Skip to content

Instantly share code, notes, and snippets.

@vanceb
Last active September 13, 2023 08:48
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save vanceb/b7402b9d1f66a6a2fb5c8e6de2a39b26 to your computer and use it in GitHub Desktop.
Save vanceb/b7402b9d1f66a6a2fb5c8e6de2a39b26 to your computer and use it in GitHub Desktop.
Home Assistant Blueprints - Automated PIR light with manual override
blueprint:
name: PIR-activated Light
description: Turn on a light when motion is detected on PIR, but only after sunset.
domain: automation
source_url: https://gist.github.com/vanceb/b7402b9d1f66a6a2fb5c8e6de2a39b26
input:
motion_entity:
name: Motion Sensor
selector:
entity:
domain: binary_sensor
device_class: motion
light_target:
name: Light
selector:
target:
entity:
domain: light
no_motion_wait:
name: Wait time
description: Time to leave the light on after last motion is detected.
default: 120
selector:
number:
min: 0
max: 3600
unit_of_measurement: seconds
# If motion is detected within the delay,
# we restart the script.
mode: restart
max_exceeded: silent
trigger:
platform: state
entity_id: !input motion_entity
from: "off"
to: "on"
condition:
condition: template
value_template: "{{ state_attr('sun.sun', 'elevation') < 0 }}"
action:
- service: light.turn_on
target: !input light_target
- wait_for_trigger:
platform: state
entity_id: !input motion_entity
from: "on"
to: "off"
- delay: !input no_motion_wait
- service: light.turn_off
target: !input light_target
blueprint:
name: Override PIR-activated Light
description: Override PIR automated switching of light when light is manually turned on
domain: automation
source_url: https://gist.github.com/vanceb/b7402b9d1f66a6a2fb5c8e6de2a39b26
input:
light_target:
name: Light
selector:
entity:
domain: light
auto_script:
name: Light PIR Script
selector:
entity:
domain: automation
reenable_after:
name: Re-enable Automation After
description: How long after manual turn on to turn off light and re-enable automated behaviour.
default: 3
selector:
number:
min: 0
max: 12
unit_of_measurement: hours
# we restart the script, so we can tuen the light off and re-enable automated PIR action
mode: restart
max_exceeded: silent
variables:
light_target: !input 'light_target'
auto_script: !input 'auto_script'
reenable_after: !input 'reenable_after'
trigger:
# Any change to the state of the light (on or off)
# Made more specific to stop trigger by attribute changes
- platform: state
entity_id: !input light_target
from: "on"
to: "off"
- platform: state
entity_id: !input light_target
from: "off"
to: "on"
action:
- delay: 1 # Avoid race condition
- choose:
# Light turned on manually
- conditions: >
{{ trigger.to_state.state == "on" and
is_state_attr(auto_script, "current", 0) }}
sequence:
- service: automation.turn_off
entity_id: !input 'auto_script'
- delay: "{{ (reenable_after | int) * 3600 }}"
- service: automation.turn_on
entity_id: !input 'auto_script'
# Light turned off after being turned on manually
# PIR script not enabled, so re-enable
- conditions: >
{{ trigger.to_state.state == "off" and
is_state(auto_script, "off") }}
sequence:
- service: automation.turn_on
entity_id: !input 'auto_script'
# Light turned off while PIR script is still running
# Maybe turned off automatically by PIR script or manually
# No way of telling (Race condition), so need to reset script
- conditions: >
{{ trigger.to_state.state == "off" and
is_state_attr(auto_script, "current", 1) }}
sequence:
- service: automation.turn_off
entity_id: !input 'auto_script'
- service: automation.turn_on
entity_id: !input 'auto_script'
# All other trigger states need no action
@vanceb
Copy link
Author

vanceb commented Feb 19, 2021

These pair of Home Assistant Blueprints solve the problem of having a light activated by a motion sensor whilst still being able to manually turn the light on without the PIR script continually turning it off. Many Home Assistant Forum posts ask how to do this and the usual answer is to create an "InputBoolean" to keep track of whether the light was tuned on by the motion sensor or manually then take appropriate action. I didn't like this approach as you have to edit the configuration.yaml file to add the InputBoolean, which is not beginner friendly.

These blueprints use the state of the PIR Light automation to decide whether the light was turned on manually or not, which although it does get away from using the InputBoolean, does require a pair of automations created from both blueprints. In my opinion this is more friendly than the other approach.

You can use just the PIR Light blueprint if you are not worried about being able to manually control the light. If you do want to later you can always add a second automation using the Override PIR Light blueprint.

To use:

  1. Save the blueprints into your /config/blueprints/automation/<my automation> folder (You can call the last folder anything you like).
  2. Reload Automations, or restart Home Assistant
  3. Go to Configuration -> Blueprints and create an automation using the PIR Light blueprint - Choose a name for the automation, your light and motion sensor from the drop downs and set the idle time. Once you have clicked OK you should have an automation visible as a UI Automation with the name you gave it. This should now work, but remember the light will only come on after the sun has set!
  4. If you want to be able to control the light manually, say you want to sit quietly with the light on without waving your arms about all the time, then create a second Automation using the Override PIR Light blueprint. You need to select the same light, the previous automation, and a "Stay on" time before clicking OK. This should now allow you to make the light stay on without motion detection for the time you selected in the blueprint before everything returns back to normal and is controlled by the motion sensor again. If you want the light on, but it is already been turned on by the motion sensor, then just turn it off first then back on. If you turn the light off before the time expires it should revert to being motion activated!

Have Fun!

@healeydave
Copy link

healeydave commented Feb 28, 2021

OMG, I really have high hopes for this automation as I've been battling with this for ages.
All my lights are Shelly with Tasmota thought so are switches not lights so no options appear for me to select :(
I just going to try to change a few things like the domain to switch instead of light and light.turn_on to switch.turn_on etc see if that works.

@healeydave
Copy link

😃👍🍾 YYYEEESSS it works. Wow, I can't believe it, my wife has been waiting for this for a long time, thank you, thank you, your a genius!

@healeydave
Copy link

Hi @vanceb
This script hasn't got broken by updates or anything has it, it doesn't seem to be working for us any more, but I can't say how long ago it stopped because the missus has only just admitted to me that the kitchen light goes off all the time when she's cooking irrespective of the wall switch being used 😩

@vanceb
Copy link
Author

vanceb commented Nov 16, 2021 via email

@healeydave
Copy link

As far as I am aware it is still working. I haven't noticed a problem. Which bit isn't working? I presume the "stay on" part? Check that when you manually turn the light on that the PIR automation gets turned off for that light. If you are having trouble maybe try to delete the existing 2 automations and recreate them from the blueprints.

Hi Vance,
Apologies, false alarm I think, I'm not sure if messing with the automations fixed it or whether it was aways working and the wife just forgot that she needs to operator the switch to off and back on again if the sensor has already turned the light on :)

@healeydave
Copy link

Update:
Actually, its a strange one.
If the kitchen switch is off and I can turn the switch on at the wall without entering the kitchen and invoking the PIR, it will stay on with any PIR activity after the fact.
If I enter the kitchen and the PIR has already activated the switch, then the PIR activity will still turn the lights off even if I turn the switch off at the wall and back on again. Its like if the PIR activity and timer is already running, it will continue to work in PIR mode irrespective of switch activity until the next time you are able to use the wall switch without any PIR control invoked.

@vanceb
Copy link
Author

vanceb commented Nov 19, 2021

Thoughts and troubleshooting:

  1. Your kitchen light switch - Is this a standard wall switch? i.e. it physically turns the power off to the kitchen light, or is it a "Pushbutton", or light in the UI, that controls the kitchen light through Home Assistant? If it is a physical switch then this isn't going to work because as far as home assistant is concerned all that has happened is that the kitchen light was "Unavailable" for a short period, not that it was "Turned off".
  2. For troubleshooting - go through each scenario and see whether the PIR automation gets turned off or not [Configuration -> Automations]. (My guess is that it doesn't. If it were off then it wouldn't turn off the light after the timer finishes).

@healeydave
Copy link

The lights are connected to a Shelly 1PM and the physical wall switch is connected to the SW input of the Shelly.
The PIR is an ex-alarm PIR connected via a Konnected board.
I could have sworn it was working but I'm doubting myself now. I'm going to shorten the timeouts and do some controlled testing now I have the house to myself.

@uSlackr
Copy link

uSlackr commented Jan 3, 2022

This is beautiful work. Thanks. One thing for me is due to the size and layout of the kitchen, I use two motion sensors as potential triggers. Is there a way to do that here?

@vanceb
Copy link
Author

vanceb commented Jan 4, 2022

I don't have a setup or time to modify myself, but I think it should be pretty simple. Have a go yourself!

I think you would only need to modify the "Trigger" elements of the first script, no changes to the second script should be needed:

  1. Duplicate the "motion_entity" part of the "Input" section, but give it a different name
  2. Change the "trigger" section to add the second "motion_entity", but use the new name you have given it - This needs to be done as a "list" in YAML (It needs the dashes before the item) See an example in the second script from lines 36-46

Remember to reload blueprints and re-create the automation from the modified blueprint every time you modify it and before you test.

@uSlackr
Copy link

uSlackr commented Jan 4, 2022 via email

@uSlackr
Copy link

uSlackr commented Feb 11, 2022

Found this on using multiple trigger entities

And here's where I wound up:
(Thanks for the challenge)

blueprint:
  name: PIR-activated Light GM
  description: Turn on a light when motion is detected on PIR, but only after sunset.
  domain: automation
  source_url: https://gist.github.com/vanceb/b7402b9d1f66a6a2fb5c8e6de2a39b26
  input:
    motion_entity_a:
      name: First Motion Sensor
      selector:
        entity:
          domain: binary_sensor
          device_class: motion
    motion_entity_b:
      name: Second Motion Sensor
      selector:
        entity:
          domain: binary_sensor
          device_class: motion
    light_target:
      name: Light
      selector:
        target:
          entity:
            domain: light
    no_motion_wait:
      name: Wait time
      description: Time to leave the light on after last motion is detected.
      default: 120
      selector:
        number:
          min: 0
          max: 3600
          unit_of_measurement: seconds

# If motion is detected within the delay,
# we restart the script.
mode: restart
max_exceeded: silent

trigger:
  - type: motion
    platform: state
    entity_id: 
    - !input motion_entity_a
    - !input motion_entity_b
    from: "off"
    to: "on"
condition: 
  condition: template
  value_template: "{{ state_attr('sun.sun', 'elevation') < 0 }}" 
action:
  - service: light.turn_on
    target: !input light_target
  - wait_for_trigger:
      platform: state
      entity_id: 
      - !input motion_entity_a
      - !input motion_entity_b
      from: "on"
      to: "off"
  - delay: !input no_motion_wait
  - service: light.turn_off
    target: !input light_target

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment