diff --git a/Occupancy_Lighting_with_Manual_Override.yaml b/Occupancy_Lighting_with_Manual_Override.yaml index 64743c0..29c3dc3 100644 --- a/Occupancy_Lighting_with_Manual_Override.yaml +++ b/Occupancy_Lighting_with_Manual_Override.yaml @@ -1,15 +1,14 @@ blueprint: name: Occupancy Lighting with Manual Override description: > - Turns lights on when any presence sensor, motion sensor, or door sensor - indicates occupancy. Turns lights off when all sensors are inactive for - the configured delay. + Turns lights on when an occupancy group sensor indicates presence. Turns + lights off when the group becomes inactive for the configured delay. - A physical switch input (e.g. Shelly in detached mode) toggles the light - and suppresses sensor-based automation for a configurable period using a - timer helper. + A physical switch input toggles the light on any flip and suppresses + sensor-based automation for a configurable period using a timer helper. - Create one timer helper per room and pass it to the blueprint. + Create a 'Binary Sensor Group' helper for your room's sensors, and one + timer helper per room. domain: automation input: light_target: @@ -19,29 +18,12 @@ blueprint: entity: domain: light - presence_sensors: - name: Presence sensors - default: [] + occupancy_group: + name: Occupancy Sensor / Group + description: Select a single binary sensor or a Binary Sensor Group helper containing this room's sensors. selector: entity: domain: binary_sensor - multiple: true - - motion_sensors: - name: Motion sensors - default: [] - selector: - entity: - domain: binary_sensor - multiple: true - - door_sensors: - name: Door sensors - default: [] - selector: - entity: - domain: binary_sensor - multiple: true switch_input: name: Physical switch input @@ -56,15 +38,15 @@ blueprint: domain: timer override_duration: - name: Override duration (seconds) - default: 1800 + name: Override duration (minutes) + default: 30 selector: number: - min: 60 - max: 86400 - step: 60 + min: 1 + max: 1440 + step: 1 mode: box - unit_of_measurement: seconds + unit_of_measurement: minutes off_delay: name: Off delay (seconds) @@ -80,29 +62,18 @@ blueprint: mode: restart variables: - presence_entities: !input presence_sensors - motion_entities: !input motion_sensors - door_entities: !input door_sensors + occupancy_entity: !input occupancy_group timer_entity: !input override_timer + duration_minutes: !input override_duration trigger: - id: occupancy_change platform: state - entity_id: !input presence_sensors - - - id: occupancy_change - platform: state - entity_id: !input motion_sensors - - - id: occupancy_change - platform: state - entity_id: !input door_sensors + entity_id: !input occupancy_group - id: manual_switch platform: state entity_id: !input switch_input - from: "off" - to: "on" - id: timer_finished platform: event @@ -113,14 +84,10 @@ trigger: action: - variables: override_active: "{{ is_state(timer_entity, 'active') }}" - occupied: > - {{ - (presence_entities | length > 0 and expand(presence_entities) | selectattr('state', 'eq', 'on') | list | count > 0) or - (motion_entities | length > 0 and expand(motion_entities) | selectattr('state', 'eq', 'on') | list | count > 0) or - (door_entities | length > 0 and expand(door_entities) | selectattr('state', 'eq', 'on') | list | count > 0) - }} + occupied: "{{ is_state(occupancy_entity, 'on') }}" - choose: + # Case 1: Manual physical switch flipped - conditions: - condition: template value_template: "{{ trigger.id == 'manual_switch' }}" @@ -131,13 +98,16 @@ action: target: entity_id: !input override_timer data: - duration: !input override_duration + # We multiply by 60 because timer.start data maps natively to HH:MM:SS or raw seconds + duration: "{{ duration_minutes * 60 }}" + # Case 2: Occupancy changed, but manual override is currently active (Do Nothing) - conditions: - condition: template value_template: "{{ trigger.id == 'occupancy_change' and override_active }}" sequence: [] + # Case 3: Occupancy detected and override is NOT active - conditions: - condition: template value_template: "{{ occupied }}" @@ -145,6 +115,7 @@ action: - action: light.turn_on target: !input light_target + # Default Case: No occupancy detected / timer finished -> sequence handles turning off default: - delay: seconds: !input off_delay @@ -155,3 +126,4 @@ action: }} - action: light.turn_off target: !input light_target +