Add outdoor template
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
blueprint:
|
||||
name: Outdoor Lighting with Manual Override ("Is Dark" mode)
|
||||
description: >
|
||||
Turns lights on when an occupancy group sensor indicates presence AND
|
||||
a UniFi Protect camera reports darkness (its built-in "Is Dark" binary
|
||||
sensor). Turns lights off when the group becomes inactive for the
|
||||
configured delay.
|
||||
|
||||
A physical switch toggle suppresses sensor-based automation for a
|
||||
configurable period using a timer helper. This automation never
|
||||
commands the light directly in response to the switch - it assumes
|
||||
your switch/relay (e.g. a Shelly in edge/detached input mode) already
|
||||
controls the light locally and instantly, independent of Home
|
||||
Assistant. HA only watches for the switch event to start the override
|
||||
window, so it never fights a manual on/off.
|
||||
|
||||
Create a 'Binary Sensor Group' helper for your occupancy sensors
|
||||
(e.g. camera motion or a dedicated PIR), and one timer helper per
|
||||
light/zone. If you have multiple outdoor cameras whose "Is Dark"
|
||||
readings might disagree (e.g. one is aimed near a porch light or a
|
||||
neighbor's floodlight), create a Binary Sensor Group with "all"
|
||||
logic over their isDark sensors instead of pointing at just one
|
||||
camera, so a single glare-affected camera can't force lights on.
|
||||
domain: automation
|
||||
input:
|
||||
light_target:
|
||||
name: Light
|
||||
selector:
|
||||
target:
|
||||
entity:
|
||||
domain: light
|
||||
|
||||
occupancy_group:
|
||||
name: Occupancy Sensor / Group
|
||||
description: Select a single binary sensor or a Binary Sensor Group helper (camera motion, PIR, etc.) covering this zone.
|
||||
selector:
|
||||
entity:
|
||||
domain: binary_sensor
|
||||
|
||||
is_dark_sensor:
|
||||
name: Darkness Sensor / Group
|
||||
description: Select a UniFi Protect camera's "Is Dark" binary sensor, or a Binary Sensor Group helper (all-logic) combining several if their readings might disagree.
|
||||
selector:
|
||||
entity:
|
||||
domain: binary_sensor
|
||||
|
||||
switch_input:
|
||||
name: Physical switch input
|
||||
description: >
|
||||
Select the switch/relay's INPUT entity (e.g. a Shelly's input
|
||||
binary_sensor reporting the physical toggle), NOT the light entity
|
||||
itself and not a mirror of the light's on/off state. If this is
|
||||
wired to something that also changes state whenever this
|
||||
automation calls light.turn_on/off, you'll get a feedback loop
|
||||
where the automation's own actions look like manual switch events.
|
||||
selector:
|
||||
entity:
|
||||
domain: binary_sensor
|
||||
|
||||
override_timer:
|
||||
name: Override timer
|
||||
selector:
|
||||
entity:
|
||||
domain: timer
|
||||
|
||||
override_duration:
|
||||
name: Override duration (minutes)
|
||||
default: 30
|
||||
selector:
|
||||
number:
|
||||
min: 1
|
||||
max: 1440
|
||||
step: 1
|
||||
mode: box
|
||||
unit_of_measurement: minutes
|
||||
|
||||
off_delay:
|
||||
name: Off delay (seconds)
|
||||
default: 5
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 300
|
||||
step: 1
|
||||
mode: box
|
||||
unit_of_measurement: seconds
|
||||
|
||||
mode: restart
|
||||
|
||||
variables:
|
||||
occupancy_entity: !input occupancy_group
|
||||
is_dark_entity: !input is_dark_sensor
|
||||
timer_entity: !input override_timer
|
||||
duration_minutes: !input override_duration
|
||||
|
||||
trigger:
|
||||
- id: occupancy_change
|
||||
platform: state
|
||||
entity_id: !input occupancy_group
|
||||
|
||||
- id: manual_switch
|
||||
platform: state
|
||||
entity_id: !input switch_input
|
||||
|
||||
- id: timer_finished
|
||||
platform: event
|
||||
event_type: timer.finished
|
||||
event_data:
|
||||
entity_id: !input override_timer
|
||||
|
||||
# Re-evaluate if it gets dark while someone/something is already
|
||||
# triggering occupancy (e.g. dusk falls while a car is still parked
|
||||
# in view of a camera-based occupancy sensor).
|
||||
- id: darkness_change
|
||||
platform: state
|
||||
entity_id: !input is_dark_sensor
|
||||
for:
|
||||
seconds: 10
|
||||
|
||||
action:
|
||||
- variables:
|
||||
override_active: "{{ is_state(timer_entity, 'active') }}"
|
||||
occupied: "{{ is_state(occupancy_entity, 'on') }}"
|
||||
is_dark: "{{ is_state(is_dark_entity, 'on') }}"
|
||||
|
||||
- choose:
|
||||
# Case 1: Manual physical switch flipped (either direction).
|
||||
# The Shelly's edge input mode has already flipped the relay locally -
|
||||
# HA must NOT issue a light.turn_on/off here, or it will fight the
|
||||
# person's manual action. We only start the override timer so that
|
||||
# occupancy/darkness logic stays out of the way for the configured window.
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ trigger.id == 'manual_switch' }}"
|
||||
sequence:
|
||||
- action: timer.start
|
||||
target:
|
||||
entity_id: !input override_timer
|
||||
data:
|
||||
# We multiply by 60 because timer.start data maps natively to HH:MM:SS or raw seconds
|
||||
duration: "{{ duration_minutes * 60 }}"
|
||||
|
||||
# Case 2: Occupancy or darkness changed, but manual override is currently active (Do Nothing)
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ (trigger.id in ['occupancy_change', 'darkness_change']) and override_active }}"
|
||||
sequence: []
|
||||
|
||||
# Case 3: Occupancy detected, override NOT active, and it's dark out
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ occupied and is_dark }}"
|
||||
sequence:
|
||||
- action: light.turn_on
|
||||
target: !input light_target
|
||||
|
||||
# Default Case: Not occupied, or occupied-but-daylight, or timer finished -> sequence handles turning off
|
||||
default:
|
||||
- delay:
|
||||
seconds: !input off_delay
|
||||
- condition: template
|
||||
value_template: >
|
||||
{{
|
||||
not is_state(timer_entity, 'active')
|
||||
and (not is_state(occupancy_entity, 'on') or not is_state(is_dark_entity, 'on'))
|
||||
}}
|
||||
- action: light.turn_off
|
||||
target: !input light_target
|
||||
Reference in New Issue
Block a user