Fix false manual override detection and brightness threshold guard in Motion Light
- Add configurable grace period (default 10s) to prevent false manual override detection from delayed device state reports (e.g., Zigbee) - Fix any_device_on guard to respect brightness_threshold so lights below the threshold don't block the automation from triggering Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -17,7 +17,7 @@ This blueprint creates a smart motion-activated light control system. It handles
|
||||
- Day/Night mode (different light settings based on time)
|
||||
- Scene support (activate scenes instead of light parameters)
|
||||
- Dim before off (visual warning before turning off)
|
||||
- Manual override detection (stops automation if user changes light)
|
||||
- Manual override detection (stops automation if user changes light) with configurable grace period
|
||||
- Brightness threshold (only trigger if light is dim)
|
||||
- Custom light parameters (brightness, color, etc.)
|
||||
- Callback actions for enable/disable/manual events
|
||||
@@ -37,7 +37,8 @@ The automation tracks these states via persistent storage:
|
||||
## Behavior Notes
|
||||
|
||||
- Will NOT turn on light if it's already ON (prevents hijacking user control)
|
||||
- If user changes light while automation is active, enters MANUAL mode
|
||||
- If user changes light while automation is active, enters MANUAL mode (after grace period)
|
||||
- Grace period prevents false manual overrides from delayed device state reports (e.g., Zigbee)
|
||||
- MANUAL mode exits when light is turned OFF (by any means)
|
||||
- Timeout delay only applies when turning OFF (motion cleared)
|
||||
- Time conditions support overnight windows (e.g., 22:00 to 06:00)
|
||||
|
||||
@@ -37,6 +37,7 @@ blueprint:
|
||||
- switch
|
||||
- group
|
||||
- light
|
||||
- input_boolean
|
||||
multiple: true
|
||||
|
||||
condition_switches:
|
||||
@@ -384,6 +385,22 @@ blueprint:
|
||||
step: 1
|
||||
unit_of_measurement: "seconds"
|
||||
|
||||
manual_override_grace_period:
|
||||
name: Manual Override Grace Period (seconds)
|
||||
description: >
|
||||
After the automation turns on a light, ignore state changes for
|
||||
this many seconds to avoid false manual override detection.
|
||||
Some devices (especially Zigbee) report delayed state updates
|
||||
that can be mistaken for manual control. Increase this value
|
||||
if you see false manual overrides in the debug log.
|
||||
default: 10
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 30
|
||||
step: 1
|
||||
unit_of_measurement: "seconds"
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Debug
|
||||
# -------------------------------------------------------------------------
|
||||
@@ -546,6 +563,7 @@ variables:
|
||||
min_on_duration: !input min_on_duration
|
||||
brightness_threshold: !input brightness_threshold
|
||||
transition_duration: !input transition_duration
|
||||
manual_override_grace_period: !input manual_override_grace_period
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Target Device Resolution
|
||||
@@ -591,11 +609,22 @@ variables:
|
||||
# Reference light for state checks (first available)
|
||||
reference_light: "{{ resolved_all_lights[0] if resolved_all_lights | length > 0 else none }}"
|
||||
|
||||
# Check if any device is on
|
||||
# Check if any device is on (respects brightness_threshold)
|
||||
any_device_on: >
|
||||
{% set lights_on = resolved_all_lights | select('is_state', 'on') | list | length > 0 %}
|
||||
{% set ns = namespace(lights_on=false) %}
|
||||
{% for light in resolved_all_lights %}
|
||||
{% if is_state(light, 'on') %}
|
||||
{% if brightness_threshold | int(0) > 0 %}
|
||||
{% if state_attr(light, 'brightness') | int(0) >= brightness_threshold | int(0) %}
|
||||
{% set ns.lights_on = true %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% set ns.lights_on = true %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% set switches_on = resolved_all_switches | select('is_state', 'on') | list | length > 0 %}
|
||||
{{ lights_on or switches_on }}
|
||||
{{ ns.lights_on or switches_on }}
|
||||
|
||||
all_devices_off: "{{ not any_device_on }}"
|
||||
|
||||
@@ -884,9 +913,20 @@ action:
|
||||
|
||||
# ----- Sub-case: User manually changed the light -----
|
||||
# Transition from ENABLED to MANUAL (user took control)
|
||||
# Grace period: ignore state changes shortly after the automation
|
||||
# turns on the light to avoid false manual override detection.
|
||||
# Some devices (especially Zigbee) report delayed state updates.
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ state_is_enabled }}"
|
||||
value_template: >
|
||||
{% set last_ts = automation_state.get(state_motion_light_last_action_timestamp, none) %}
|
||||
{% set grace = (transition_duration | float(0)) + (manual_override_grace_period | float(10)) %}
|
||||
{% if state_is_enabled and last_ts is not none %}
|
||||
{% set parsed = last_ts | as_datetime %}
|
||||
{{ parsed is none or (now() - parsed).total_seconds() > grace }}
|
||||
{% else %}
|
||||
{{ state_is_enabled }}
|
||||
{% endif %}
|
||||
sequence:
|
||||
# BUG FIX: Fixed YAML structure - was 'data: >' instead of 'data:' with 'value: >'
|
||||
- service: input_text.set_value
|
||||
|
||||
Reference in New Issue
Block a user