feat: add debug mode and clarify docs in MQTT Button Control
- Add optional debug notifications for trigger and light-branch decisions - Document index-based action/entity mapping and two-topic support - Add configuration reference table and debug-mode section to README
This commit is contained in:
@@ -6,10 +6,13 @@
|
||||
|
||||
blueprint:
|
||||
name: "Custom: MQTT Button Control"
|
||||
description: Control a Zigbee2MQTT device with multiple actions, that allows to toggle lights and switches and store entity identifier of last interacted switch/light.
|
||||
description: >
|
||||
Control a Zigbee2MQTT device with multiple actions: toggle lights,
|
||||
switches and input_booleans, and optionally remember the entity that
|
||||
was last interacted with in an input_text helper.
|
||||
domain: automation
|
||||
input:
|
||||
|
||||
|
||||
mqtt_group:
|
||||
name: "MQTT"
|
||||
collapsed: false
|
||||
@@ -19,7 +22,7 @@ blueprint:
|
||||
description: The MQTT topic for your Zigbee button (e.g., zigbee2mqtt/my_button1).
|
||||
selector:
|
||||
text:
|
||||
|
||||
|
||||
mqtt_topic2:
|
||||
name: MQTT Topic 2 (Optional)
|
||||
description: >
|
||||
@@ -28,7 +31,7 @@ blueprint:
|
||||
default: "blueprint/disabled/mqtt_button_control"
|
||||
selector:
|
||||
text:
|
||||
|
||||
|
||||
devices:
|
||||
name: "Primary"
|
||||
collapsed: false
|
||||
@@ -40,19 +43,19 @@ blueprint:
|
||||
selector:
|
||||
text:
|
||||
multiple: true
|
||||
|
||||
|
||||
switches:
|
||||
name: Switches
|
||||
description: "The list of switches to control. Next types are supported: `light`, `switch`, `input_boolean`"
|
||||
default: []
|
||||
selector:
|
||||
entity:
|
||||
domain:
|
||||
domain:
|
||||
- light
|
||||
- switch
|
||||
- input_boolean
|
||||
multiple: true
|
||||
|
||||
multiple: true
|
||||
|
||||
outputs:
|
||||
name: "Outputs"
|
||||
collapsed: false
|
||||
@@ -64,7 +67,7 @@ blueprint:
|
||||
selector:
|
||||
entity:
|
||||
domain: input_text
|
||||
|
||||
|
||||
common:
|
||||
name: "Common"
|
||||
collapsed: false
|
||||
@@ -78,8 +81,8 @@ blueprint:
|
||||
min: 0
|
||||
max: 100
|
||||
step: 1
|
||||
unit_of_measurement: "s"
|
||||
|
||||
unit_of_measurement: "s"
|
||||
|
||||
blink_count:
|
||||
name: Count of blinks
|
||||
description: "Count of blinks to indicate active light"
|
||||
@@ -88,8 +91,8 @@ blueprint:
|
||||
number:
|
||||
min: 0
|
||||
max: 5
|
||||
step: 1
|
||||
|
||||
step: 1
|
||||
|
||||
blink_interval:
|
||||
name: Interval between blinks
|
||||
description: "Interval between indicator blinks (in ms)"
|
||||
@@ -98,18 +101,36 @@ blueprint:
|
||||
number:
|
||||
min: 0
|
||||
max: 1000
|
||||
step: 50
|
||||
unit_of_measurement: "ms"
|
||||
step: 50
|
||||
unit_of_measurement: "ms"
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Debug
|
||||
# -------------------------------------------------------------------------
|
||||
debug_group:
|
||||
name: "Debug"
|
||||
collapsed: true
|
||||
input:
|
||||
enable_debug_notifications:
|
||||
name: Enable Debug Notifications
|
||||
description: >
|
||||
Send persistent notifications for debugging automation behavior.
|
||||
Shows received action, resolved target entity and blink decision.
|
||||
default: false
|
||||
selector:
|
||||
boolean:
|
||||
|
||||
trigger:
|
||||
- platform: mqtt
|
||||
topic: !input mqtt_topic
|
||||
id: button_1
|
||||
- platform: mqtt
|
||||
topic: !input mqtt_topic2
|
||||
enabled: "{{ mqtt_topic2 != '' }}"
|
||||
|
||||
id: button_2
|
||||
enabled: "{{ mqtt_topic2 not in ['', 'blueprint/disabled/mqtt_button_control'] }}"
|
||||
|
||||
mode: restart
|
||||
|
||||
|
||||
condition:
|
||||
- condition: template
|
||||
value_template: "{{ 'action' in trigger.payload_json }}"
|
||||
@@ -117,21 +138,59 @@ condition:
|
||||
action:
|
||||
- variables:
|
||||
action_id: "{{ trigger.payload_json.action }}"
|
||||
|
||||
|
||||
switches: !input switches
|
||||
action_ids: !input action_ids
|
||||
|
||||
target_index: >
|
||||
{% if action_id in action_ids %}
|
||||
{{ action_ids.index(action_id) }}
|
||||
{% else %}
|
||||
-1
|
||||
{% endif %}
|
||||
target_entity: "{{ switches[target_index] if target_index != -1 else none }}"
|
||||
last_interacted_text: !input last_interacted_text
|
||||
|
||||
is_debug: false
|
||||
|
||||
is_debug: !input enable_debug_notifications
|
||||
|
||||
# Resolve action_id → switch index. Whitespace-controlled and coerced
|
||||
# to int so subscripting `switches[target_index]` is safe.
|
||||
target_index: >-
|
||||
{%- if action_id in action_ids -%}
|
||||
{{ action_ids.index(action_id) }}
|
||||
{%- else -%}
|
||||
-1
|
||||
{%- endif -%}
|
||||
# Bounds-check the index: action_ids may have more entries than switches.
|
||||
target_entity: >-
|
||||
{%- set idx = target_index | int(-1) -%}
|
||||
{%- if idx >= 0 and idx < (switches | length) -%}
|
||||
{{ switches[idx] }}
|
||||
{%- else -%}
|
||||
{{ none }}
|
||||
{%- endif -%}
|
||||
has_last_interacted_text: "{{ last_interacted_text is string and last_interacted_text | trim != '' }}"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Debug: trigger received
|
||||
# ---------------------------------------------------------------------------
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ is_debug }}"
|
||||
sequence:
|
||||
- service: persistent_notification.create
|
||||
data:
|
||||
notification_id: "mqtt_button_control_debug"
|
||||
title: "MQTT Button Control Debug"
|
||||
message: >
|
||||
Trigger: {{ trigger.id }}
|
||||
|
||||
Topic: {{ trigger.topic }}
|
||||
|
||||
action_id: {{ action_id }}
|
||||
|
||||
action_ids: {{ action_ids }}
|
||||
|
||||
switches: {{ switches }}
|
||||
|
||||
target_index: {{ target_index | int(-1) }}
|
||||
|
||||
target_entity: {{ target_entity if target_entity is not none else 'none' }}
|
||||
|
||||
has_last_interacted_text: {{ has_last_interacted_text }}
|
||||
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
@@ -139,12 +198,18 @@ action:
|
||||
sequence:
|
||||
- variables:
|
||||
entity_type: "{{ target_entity.split('.')[0] }}"
|
||||
|
||||
- service: input_text.set_value
|
||||
data:
|
||||
entity_id: "{{ last_interacted_text }}"
|
||||
value: "{{ target_entity }}"
|
||||
|
||||
|
||||
# Persist last interacted entity only when a helper is configured.
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ has_last_interacted_text }}"
|
||||
sequence:
|
||||
- service: input_text.set_value
|
||||
data:
|
||||
entity_id: "{{ last_interacted_text }}"
|
||||
value: "{{ target_entity }}"
|
||||
|
||||
- choose:
|
||||
# Light
|
||||
- conditions:
|
||||
@@ -153,14 +218,29 @@ action:
|
||||
sequence:
|
||||
- variables:
|
||||
timeout_for_indication_blink: !input timeout_for_indication_blink
|
||||
seconds_elapsed: >
|
||||
{{ (as_timestamp(now()) - as_timestamp(states[target_entity].last_changed)) | int }}
|
||||
should_blink: "{{ timeout_for_indication_blink != 0 and seconds_elapsed > timeout_for_indication_blink }}"
|
||||
blink_count: !input blink_count
|
||||
blink_timeout: !input blink_interval
|
||||
is_light_on: "{{ is_state(target_entity, 'on') }}"
|
||||
|
||||
# Debug
|
||||
# Inline state access — HA stringifies State objects when
|
||||
# stored in `variables:`, so `.last_changed` must be read
|
||||
# within a single template render.
|
||||
seconds_elapsed: >-
|
||||
{%- set s = states[target_entity] -%}
|
||||
{%- if s is not none -%}
|
||||
{{ (as_timestamp(now()) - as_timestamp(s.last_changed)) | int(0) }}
|
||||
{%- else -%}
|
||||
0
|
||||
{%- endif -%}
|
||||
# Blink only when both the idle timeout AND a positive
|
||||
# blink count are configured; otherwise fall through to a
|
||||
# plain toggle (a 0 count would otherwise run an empty
|
||||
# repeat and leave the light untouched).
|
||||
should_blink: >-
|
||||
{{ timeout_for_indication_blink != 0
|
||||
and (blink_count | int(0)) > 0
|
||||
and (seconds_elapsed | int(0)) > timeout_for_indication_blink }}
|
||||
|
||||
# Debug: light branch state
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
@@ -168,13 +248,25 @@ action:
|
||||
sequence:
|
||||
- service: persistent_notification.create
|
||||
data:
|
||||
title: "Debug Info"
|
||||
notification_id: "mqtt_button_control_debug_light"
|
||||
title: "MQTT Button Control Debug (light)"
|
||||
message: >
|
||||
seconds_elapsed = {{ seconds_elapsed }},
|
||||
should_blink = {{ should_blink }}
|
||||
|
||||
target_entity: {{ target_entity }}
|
||||
|
||||
is_light_on: {{ is_light_on }}
|
||||
|
||||
seconds_elapsed: {{ seconds_elapsed }}
|
||||
|
||||
timeout_for_indication_blink: {{ timeout_for_indication_blink }}
|
||||
|
||||
should_blink: {{ should_blink }}
|
||||
|
||||
blink_count: {{ blink_count }}
|
||||
|
||||
blink_timeout (ms): {{ blink_timeout }}
|
||||
|
||||
- choose:
|
||||
# Blink
|
||||
# Blink (indicate light is already on after idle timeout)
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ should_blink and is_light_on }}"
|
||||
@@ -182,7 +274,6 @@ action:
|
||||
- repeat:
|
||||
count: "{{ blink_count }}"
|
||||
sequence:
|
||||
|
||||
- service: light.turn_off
|
||||
target:
|
||||
entity_id: "{{ target_entity }}"
|
||||
@@ -190,7 +281,7 @@ action:
|
||||
transition: 0
|
||||
- delay:
|
||||
milliseconds: "{{ blink_timeout }}"
|
||||
|
||||
|
||||
- service: light.turn_on
|
||||
target:
|
||||
entity_id: "{{ target_entity }}"
|
||||
@@ -198,13 +289,13 @@ action:
|
||||
transition: 0
|
||||
- delay:
|
||||
milliseconds: "{{ blink_timeout }}"
|
||||
|
||||
# Actually toggle
|
||||
|
||||
# Actually toggle
|
||||
default:
|
||||
- service: light.toggle
|
||||
target:
|
||||
entity_id: "{{ target_entity }}"
|
||||
|
||||
|
||||
# Switch
|
||||
- conditions:
|
||||
- condition: template
|
||||
@@ -213,7 +304,7 @@ action:
|
||||
- service: switch.toggle
|
||||
target:
|
||||
entity_id: "{{ target_entity }}"
|
||||
|
||||
|
||||
# Input Boolean
|
||||
- conditions:
|
||||
- condition: template
|
||||
@@ -221,4 +312,4 @@ action:
|
||||
sequence:
|
||||
- service: input_boolean.toggle
|
||||
target:
|
||||
entity_id: "{{ target_entity }}"
|
||||
entity_id: "{{ target_entity }}"
|
||||
|
||||
Reference in New Issue
Block a user