[Claude] - Analyze MQTT Light Selector.yaml file designed to work as automation blueprint for Home Assistant OS. Refactor it improving overall code quality, fix obvious or critical bugs/mistakes, fix spelling if required and add comments that will make the code more easy to read and understand.
This commit is contained in:
@@ -1,92 +1,137 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# MQTT Light Selector Blueprint
|
||||||
|
# =============================================================================
|
||||||
|
# Cycles through a list of lights using MQTT button events (up/down/remind).
|
||||||
|
# The selected light flashes to provide visual feedback, then returns to its
|
||||||
|
# original state. Selection is persisted in an input_text helper.
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
blueprint:
|
blueprint:
|
||||||
name: "Custom: MQTT Light Selector"
|
name: "MQTT Light Selector"
|
||||||
description: >
|
description: >
|
||||||
Cycle through a list of lights using MQTT button events (up/down).
|
Cycle through a list of lights using MQTT button events.
|
||||||
Selected light is stored in an input_text helper and flashes N times
|
|
||||||
with Z interval when selected.
|
**Features:**
|
||||||
|
- Navigate lights with up/down actions
|
||||||
|
- Remind action flashes the currently selected light
|
||||||
|
- Visual feedback via configurable flash pattern
|
||||||
|
- Persists selection in an input_text helper
|
||||||
|
- Optional state persistence across restarts (JSON storage)
|
||||||
|
- Optional "remind on idle" - up/down acts as remind if idle too long
|
||||||
|
|
||||||
|
**How it works:**
|
||||||
|
1. Press up/down to cycle through the light list
|
||||||
|
2. Selected light flashes N times to confirm selection
|
||||||
|
3. Light returns to its original on/off state after flashing
|
||||||
domain: automation
|
domain: automation
|
||||||
|
|
||||||
input:
|
input:
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# MQTT Device Configuration
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
devices:
|
devices:
|
||||||
name: "Devices"
|
name: "MQTT Devices"
|
||||||
collapsed: false
|
collapsed: false
|
||||||
input:
|
input:
|
||||||
mqtt_topic:
|
mqtt_topic:
|
||||||
name: MQTT Topic
|
name: Primary MQTT Topic
|
||||||
description: Topic where button events are published
|
description: Main topic where button events are published (e.g., `zigbee2mqtt/button/action`)
|
||||||
selector:
|
|
||||||
text: {}
|
|
||||||
mqtt_topic2:
|
|
||||||
name: MQTT Topic
|
|
||||||
description: Topic where button events are published
|
|
||||||
default: 'fake'
|
|
||||||
selector:
|
selector:
|
||||||
text: {}
|
text: {}
|
||||||
|
|
||||||
|
mqtt_topic2:
|
||||||
|
name: Secondary MQTT Topic (Optional)
|
||||||
|
description: >
|
||||||
|
Additional MQTT topic for a second device.
|
||||||
|
Leave as default placeholder if not using a second device.
|
||||||
|
default: "blueprint/disabled/mqtt_light_selector"
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Light Selection
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
lights:
|
lights:
|
||||||
name: "Lights"
|
name: "Lights"
|
||||||
collapsed: false
|
collapsed: false
|
||||||
input:
|
input:
|
||||||
lights:
|
lights:
|
||||||
name: Lights
|
name: Lights to Cycle
|
||||||
description: List of lights to cycle through
|
description: >
|
||||||
|
List of lights to cycle through.
|
||||||
|
Order determines navigation sequence.
|
||||||
selector:
|
selector:
|
||||||
entity:
|
entity:
|
||||||
domain: light
|
domain: light
|
||||||
multiple: true
|
multiple: true
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Persistent State Configuration
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
persistent_state:
|
persistent_state:
|
||||||
name: "Persiatent State"
|
name: "Persistent State"
|
||||||
collapsed: false
|
collapsed: false
|
||||||
input:
|
input:
|
||||||
selected_light_helper:
|
selected_light_helper:
|
||||||
name: Selected Light Helper
|
name: Selected Light Helper
|
||||||
description: Input_text entity to store the selected light
|
description: >
|
||||||
|
Input_text entity to store the currently selected light entity ID.
|
||||||
|
Create one via Settings → Devices & Services → Helpers.
|
||||||
selector:
|
selector:
|
||||||
entity:
|
entity:
|
||||||
domain: input_text
|
domain: input_text
|
||||||
|
|
||||||
automation_state_entity:
|
automation_state_entity:
|
||||||
name: Automation state entity
|
name: Automation State Entity (Optional)
|
||||||
description: The `input_text` entity will store state of the automation in JSON format. `Doesn't require any initial state, can be empty. For now each automation must have it's personal entity.`
|
description: >
|
||||||
|
Input_text entity for storing automation state as JSON.
|
||||||
|
Used to remember light state during flash sequence.
|
||||||
|
Leave empty to disable state persistence.
|
||||||
default: null
|
default: null
|
||||||
selector:
|
selector:
|
||||||
entity:
|
entity:
|
||||||
domain:
|
domain: input_text
|
||||||
- input_text
|
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Action ID Mapping
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
action_ids:
|
action_ids:
|
||||||
name: "Action IDs"
|
name: "Action IDs"
|
||||||
collapsed: false
|
collapsed: false
|
||||||
input:
|
input:
|
||||||
action_up:
|
action_up:
|
||||||
name: Up Action Identifier
|
name: Next Light Action ID
|
||||||
description: Payload string for "next light"
|
description: MQTT payload action value for selecting the next light in the list.
|
||||||
default: ''
|
default: ""
|
||||||
selector:
|
selector:
|
||||||
text: {}
|
text: {}
|
||||||
|
|
||||||
action_down:
|
action_down:
|
||||||
name: Down Action Identifier
|
name: Previous Light Action ID
|
||||||
description: Payload string for "previous light"
|
description: MQTT payload action value for selecting the previous light in the list.
|
||||||
default: ''
|
default: ""
|
||||||
selector:
|
selector:
|
||||||
text: {}
|
text: {}
|
||||||
|
|
||||||
action_remind:
|
action_remind:
|
||||||
name: Remind Action Identifier
|
name: Remind Action ID (Optional)
|
||||||
description: Payload string for "current light"
|
description: >
|
||||||
default: ''
|
MQTT payload action value for flashing the current selection without changing it.
|
||||||
|
Leave empty to disable.
|
||||||
|
default: ""
|
||||||
selector:
|
selector:
|
||||||
text: {}
|
text: {}
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Behavior Parameters
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
params:
|
params:
|
||||||
name: "Parameters"
|
name: "Parameters"
|
||||||
collapsed: false
|
collapsed: false
|
||||||
input:
|
input:
|
||||||
transition:
|
transition:
|
||||||
name: Transition Time (ms)
|
name: Light Transition Time
|
||||||
description: Duration of brightness transition
|
description: Duration of on/off transitions during flash sequence.
|
||||||
default: 0
|
default: 0
|
||||||
selector:
|
selector:
|
||||||
number:
|
number:
|
||||||
@@ -96,8 +141,11 @@ blueprint:
|
|||||||
unit_of_measurement: ms
|
unit_of_measurement: ms
|
||||||
|
|
||||||
remind_using_up_down_delay:
|
remind_using_up_down_delay:
|
||||||
name: Force Remind Using Up/Down Delay
|
name: Idle Remind Threshold
|
||||||
description: "If specified then `Up`/`Down` action will work like `Remind` in case if duration from the last action was greater then this value"
|
description: >
|
||||||
|
If set, up/down actions will act as "remind" (flash current selection)
|
||||||
|
when more than this many seconds have passed since the last selection.
|
||||||
|
Set to 0 to disable this behavior.
|
||||||
default: 0
|
default: 0
|
||||||
selector:
|
selector:
|
||||||
number:
|
number:
|
||||||
@@ -108,7 +156,7 @@ blueprint:
|
|||||||
|
|
||||||
flash_count:
|
flash_count:
|
||||||
name: Flash Count
|
name: Flash Count
|
||||||
description: Number of times to flash selected light
|
description: Number of times to flash the selected light.
|
||||||
default: 2
|
default: 2
|
||||||
selector:
|
selector:
|
||||||
number:
|
number:
|
||||||
@@ -117,8 +165,8 @@ blueprint:
|
|||||||
step: 1
|
step: 1
|
||||||
|
|
||||||
flash_interval_ms:
|
flash_interval_ms:
|
||||||
name: Flash Interval (ms)
|
name: Flash Interval
|
||||||
description: Interval between flashes in milliseconds
|
description: Time between each flash on/off cycle.
|
||||||
default: 500
|
default: 500
|
||||||
selector:
|
selector:
|
||||||
number:
|
number:
|
||||||
@@ -127,42 +175,53 @@ blueprint:
|
|||||||
step: 100
|
step: 100
|
||||||
unit_of_measurement: ms
|
unit_of_measurement: ms
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Advanced: Conditions & Callbacks
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
actions_group:
|
actions_group:
|
||||||
name: "Actions"
|
name: "Actions"
|
||||||
collapsed: false
|
collapsed: false
|
||||||
input:
|
input:
|
||||||
condition_action:
|
condition_action:
|
||||||
name: Extra Condition
|
name: Extra Condition
|
||||||
description: Optional condition to check before running actions
|
description: Optional condition that must be true for the automation to run.
|
||||||
default: []
|
default: []
|
||||||
selector:
|
selector:
|
||||||
condition: {}
|
condition: {}
|
||||||
|
|
||||||
callback_action:
|
callback_action:
|
||||||
name: Callback Action
|
name: Callback Action
|
||||||
description: Optional action to run after main sequence
|
description: Optional action to run after selecting a new light (before flashing).
|
||||||
default: []
|
default: []
|
||||||
selector:
|
selector:
|
||||||
action: {}
|
action: {}
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Triggers: Listen for MQTT messages from configured devices
|
||||||
|
# =============================================================================
|
||||||
trigger:
|
trigger:
|
||||||
- platform: mqtt
|
- platform: mqtt
|
||||||
topic: !input mqtt_topic
|
topic: !input mqtt_topic
|
||||||
id: "mqtt"
|
id: "mqtt_primary"
|
||||||
|
|
||||||
- platform: mqtt
|
- platform: mqtt
|
||||||
topic: !input mqtt_topic2
|
topic: !input mqtt_topic2
|
||||||
id: "mqtt"
|
id: "mqtt_secondary"
|
||||||
|
|
||||||
|
# Apply user-defined condition before processing
|
||||||
condition: !input condition_action
|
condition: !input condition_action
|
||||||
|
|
||||||
|
# Restart mode ensures rapid button presses are handled correctly
|
||||||
mode: restart
|
mode: restart
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Variables: Configuration and state management
|
||||||
|
# =============================================================================
|
||||||
variables:
|
variables:
|
||||||
|
# ----- Debug flag (set to true for troubleshooting) -----
|
||||||
# Constants.
|
|
||||||
is_debug: false
|
is_debug: false
|
||||||
|
|
||||||
# Defines.
|
# ----- Input references -----
|
||||||
lights: !input lights
|
lights: !input lights
|
||||||
helper: !input selected_light_helper
|
helper: !input selected_light_helper
|
||||||
action_up: !input action_up
|
action_up: !input action_up
|
||||||
@@ -172,14 +231,19 @@ variables:
|
|||||||
flash_interval_ms: !input flash_interval_ms
|
flash_interval_ms: !input flash_interval_ms
|
||||||
transition: !input transition
|
transition: !input transition
|
||||||
remind_using_up_down_delay: !input remind_using_up_down_delay
|
remind_using_up_down_delay: !input remind_using_up_down_delay
|
||||||
mqtt_topic: !input mqtt_topic
|
callback_action: !input callback_action
|
||||||
|
|
||||||
# JSON global state.
|
# ----- State persistence keys (short names to save space in JSON) -----
|
||||||
state_key_last_was_on: 'lwo'
|
# lwo = last_was_on, ll = last_light, lsadt = last_select_action_datetime
|
||||||
state_key_last_light: 'll'
|
state_key_last_was_on: "lwo"
|
||||||
state_key_last_select_action_datetime: 'lsadt'
|
state_key_last_light: "ll"
|
||||||
|
state_key_last_select_action_datetime: "lsadt"
|
||||||
|
|
||||||
|
# ----- Automation state entity and global state parsing -----
|
||||||
automation_state_entity: !input automation_state_entity
|
automation_state_entity: !input automation_state_entity
|
||||||
automation_state_global: >
|
|
||||||
|
# Parse the JSON state from the helper entity (or return empty dict)
|
||||||
|
automation_state_global: >-
|
||||||
{% if automation_state_entity is not none %}
|
{% if automation_state_entity is not none %}
|
||||||
{% set text = states(automation_state_entity) | string %}
|
{% set text = states(automation_state_entity) | string %}
|
||||||
{% if text in ['unknown', 'unavailable', 'none', ''] %}
|
{% if text in ['unknown', 'unavailable', 'none', ''] %}
|
||||||
@@ -193,23 +257,35 @@ variables:
|
|||||||
|
|
||||||
current_datetime: "{{ now() }}"
|
current_datetime: "{{ now() }}"
|
||||||
|
|
||||||
# TODO alexeid: it's better to use mqtt_topic as key, but cyrilic characters require use of tranliteration
|
# Unique key for this automation instance (based on first light in list)
|
||||||
|
# Note: Using entity_id avoids issues with special characters in MQTT topics
|
||||||
automation_state_key: "mqtt_light_selector:{{ lights[0] }}"
|
automation_state_key: "mqtt_light_selector:{{ lights[0] }}"
|
||||||
automation_state: "{{ automation_state_global.get(automation_state_key, dict()) if automation_state_key != '' else dict() }}"
|
|
||||||
|
# Extract this automation's state from the global state object
|
||||||
|
automation_state: >-
|
||||||
|
{{ automation_state_global.get(automation_state_key, dict()) if automation_state_key != '' else dict() }}
|
||||||
|
|
||||||
|
# Retrieve persisted values (with defaults)
|
||||||
state_last_was_on: "{{ automation_state.get(state_key_last_was_on, false) | bool }}"
|
state_last_was_on: "{{ automation_state.get(state_key_last_was_on, false) | bool }}"
|
||||||
state_last_light: "{{ automation_state.get(state_key_last_light, '') | string }}"
|
state_last_light: "{{ automation_state.get(state_key_last_light, '') | string }}"
|
||||||
state_last_select_action_datetime: "{{ as_datetime(automation_state.get(state_key_last_select_action_datetime, current_datetime)) }}"
|
state_last_select_action_datetime: >-
|
||||||
|
{{ as_datetime(automation_state.get(state_key_last_select_action_datetime, current_datetime)) }}
|
||||||
|
|
||||||
# Current index from helper (fallback to 0 if empty)
|
# ----- Current selection from helper -----
|
||||||
current_light: >
|
current_light: >-
|
||||||
{% set entity_id = states(helper) %}
|
{% set entity_id = states(helper) %}
|
||||||
{{ entity_id if entity_id in lights else none }}
|
{{ entity_id if entity_id in lights else none }}
|
||||||
current_index: >
|
|
||||||
{% set idx = lights.index(current_light) if current_light in lights else 0 %}
|
|
||||||
{{ idx }}
|
|
||||||
|
|
||||||
|
current_index: >-
|
||||||
|
{{ lights.index(current_light) if current_light in lights else 0 }}
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Actions: Main automation logic
|
||||||
|
# =============================================================================
|
||||||
action:
|
action:
|
||||||
# Debug info (log if required)
|
# ---------------------------------------------------------------------------
|
||||||
|
# Debug: Log state information if debug mode is enabled
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
- choose:
|
- choose:
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
@@ -217,23 +293,38 @@ action:
|
|||||||
sequence:
|
sequence:
|
||||||
- service: persistent_notification.create
|
- service: persistent_notification.create
|
||||||
data:
|
data:
|
||||||
title: "Debug Info"
|
title: "MQTT Light Selector Debug"
|
||||||
message: "automation_state_key = {{ automation_state_key }}"
|
message: >
|
||||||
|
State key: {{ automation_state_key }}
|
||||||
|
Current light: {{ current_light }}
|
||||||
|
Current index: {{ current_index }}
|
||||||
|
Last light: {{ state_last_light }}
|
||||||
|
Last was on: {{ state_last_was_on }}
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# MQTT Message Handler
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
- choose:
|
- choose:
|
||||||
# MQTT -> handle the message
|
|
||||||
- conditions:
|
- conditions:
|
||||||
|
# Handle messages from either MQTT trigger
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ trigger.id == 'mqtt' }}"
|
value_template: "{{ trigger.id in ['mqtt_primary', 'mqtt_secondary'] }}"
|
||||||
sequence:
|
sequence:
|
||||||
|
# Extract action ID from MQTT payload
|
||||||
- variables:
|
- variables:
|
||||||
action_id: "{{ trigger.payload_json.action }}"
|
action_id: "{{ trigger.payload_json.action }}"
|
||||||
# Don't forget to restore last light state
|
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
# Step 1: Restore previous light state if interrupted mid-flash
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
# If automation was restarted during a flash sequence, restore
|
||||||
|
# the light to its original state before proceeding
|
||||||
- choose:
|
- choose:
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ state_last_light != '' }}"
|
value_template: "{{ state_last_light != '' }}"
|
||||||
sequence:
|
sequence:
|
||||||
|
# Restore light to its previous on/off state
|
||||||
- choose:
|
- choose:
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
@@ -244,18 +335,14 @@ action:
|
|||||||
entity_id: "{{ state_last_light }}"
|
entity_id: "{{ state_last_light }}"
|
||||||
data:
|
data:
|
||||||
transition: "{{ transition }}"
|
transition: "{{ transition }}"
|
||||||
|
default:
|
||||||
- conditions:
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ not state_last_was_on }}"
|
|
||||||
sequence:
|
|
||||||
- service: light.turn_off
|
- service: light.turn_off
|
||||||
target:
|
target:
|
||||||
entity_id: "{{ state_last_light }}"
|
entity_id: "{{ state_last_light }}"
|
||||||
data:
|
data:
|
||||||
transition: "{{ transition }}"
|
transition: "{{ transition }}"
|
||||||
|
|
||||||
# Save persistent state.
|
# Clear the "last light" from state since we've restored it
|
||||||
- choose:
|
- choose:
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
@@ -265,25 +352,34 @@ action:
|
|||||||
target:
|
target:
|
||||||
entity_id: "{{ automation_state_entity }}"
|
entity_id: "{{ automation_state_entity }}"
|
||||||
data:
|
data:
|
||||||
value: >
|
value: >-
|
||||||
{% set new_automation_state = (automation_state | combine({ state_key_last_light: '' })) %}
|
{% set new_state = automation_state | combine({
|
||||||
{% set new_automation_state = (new_automation_state | combine({ state_key_last_was_on: new_on })) %}
|
state_key_last_light: '',
|
||||||
{% set new_automation_state = (new_automation_state | combine({ state_key_last_select_action_datetime: current_datetime })) %}
|
state_key_last_was_on: state_last_was_on,
|
||||||
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
state_key_last_select_action_datetime: current_datetime | string
|
||||||
|
}) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_state }) | tojson }}
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------
|
||||||
# Do actual selection
|
# Step 2: Process selection action (up/down/remind)
|
||||||
|
# -----------------------------------------------------------------
|
||||||
- choose:
|
- choose:
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ (action_id != '') and (action_id == action_up or action_id == action_down or action_id == action_remind) }}"
|
value_template: >-
|
||||||
|
{{ action_id != '' and action_id in [action_up, action_down, action_remind] }}
|
||||||
sequence:
|
sequence:
|
||||||
|
# Calculate the new selection
|
||||||
- variables:
|
- variables:
|
||||||
datetime_diff_seconds: >
|
# Time since last selection (for idle remind feature)
|
||||||
{% set diff = current_datetime - state_last_select_action_datetime %}
|
datetime_diff_seconds: >-
|
||||||
{{ diff.total_seconds() }}
|
{{ (current_datetime - state_last_select_action_datetime).total_seconds() }}
|
||||||
step: >
|
|
||||||
{% if remind_using_up_down_delay != 0 and datetime_diff_seconds < remind_using_up_down_delay %}
|
# Determine step direction:
|
||||||
|
# - If idle too long and remind_using_up_down_delay is set, treat as remind (step=0)
|
||||||
|
# - Otherwise: up=+1, down=-1, remind=0
|
||||||
|
step: >-
|
||||||
|
{% if remind_using_up_down_delay > 0 and datetime_diff_seconds > remind_using_up_down_delay %}
|
||||||
0
|
0
|
||||||
{% elif action_up != '' and action_id == action_up %}
|
{% elif action_up != '' and action_id == action_up %}
|
||||||
1
|
1
|
||||||
@@ -292,11 +388,15 @@ action:
|
|||||||
{% else %}
|
{% else %}
|
||||||
0
|
0
|
||||||
{% endif %}
|
{% endif %}
|
||||||
new_index: "{{ (current_index + step) % lights|length }}"
|
|
||||||
|
# Calculate new index with wraparound
|
||||||
|
new_index: "{{ (current_index + step) % (lights | length) }}"
|
||||||
new_light: "{{ lights[new_index] }}"
|
new_light: "{{ lights[new_index] }}"
|
||||||
|
|
||||||
|
# Remember if light was on before we start flashing
|
||||||
new_on: "{{ is_state(new_light, 'on') }}"
|
new_on: "{{ is_state(new_light, 'on') }}"
|
||||||
|
|
||||||
# Save persistent state.
|
# Save state before flashing (to restore if interrupted)
|
||||||
- choose:
|
- choose:
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
@@ -306,24 +406,31 @@ action:
|
|||||||
target:
|
target:
|
||||||
entity_id: "{{ automation_state_entity }}"
|
entity_id: "{{ automation_state_entity }}"
|
||||||
data:
|
data:
|
||||||
value: >
|
value: >-
|
||||||
{% set new_automation_state = (automation_state | combine({ state_key_last_light: new_light })) %}
|
{% set new_state = automation_state | combine({
|
||||||
{% set new_automation_state = (new_automation_state | combine({ state_key_last_was_on: new_on })) %}
|
state_key_last_light: new_light,
|
||||||
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
state_key_last_was_on: new_on,
|
||||||
|
state_key_last_select_action_datetime: current_datetime | string
|
||||||
|
}) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_state }) | tojson }}
|
||||||
|
|
||||||
# Run callback only if user provided it: think if we need to invoke callback here
|
# Run user-defined callback action (if provided)
|
||||||
- choose:
|
- choose:
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ callback_action is defined and (callback_action | length > 0) }}"
|
value_template: "{{ callback_action is defined and (callback_action | length > 0) }}"
|
||||||
sequence: !input callback_action
|
sequence: !input callback_action
|
||||||
|
|
||||||
# Assign new light entity id to helper value
|
# Update the helper with the new selection
|
||||||
- service: input_text.set_value
|
- service: input_text.set_value
|
||||||
target:
|
target:
|
||||||
entity_id: "{{ helper }}"
|
entity_id: "{{ helper }}"
|
||||||
data:
|
data:
|
||||||
value: "{{ new_light }}"
|
value: "{{ new_light }}"
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
# Flash sequence: Visual feedback for selection
|
||||||
|
# -----------------------------------------------------------------
|
||||||
- repeat:
|
- repeat:
|
||||||
count: "{{ flash_count }}"
|
count: "{{ flash_count }}"
|
||||||
sequence:
|
sequence:
|
||||||
@@ -332,6 +439,7 @@ action:
|
|||||||
entity_id: "{{ new_light }}"
|
entity_id: "{{ new_light }}"
|
||||||
data:
|
data:
|
||||||
transition: "{{ transition }}"
|
transition: "{{ transition }}"
|
||||||
|
|
||||||
- delay:
|
- delay:
|
||||||
milliseconds: "{{ flash_interval_ms }}"
|
milliseconds: "{{ flash_interval_ms }}"
|
||||||
|
|
||||||
@@ -340,10 +448,11 @@ action:
|
|||||||
entity_id: "{{ new_light }}"
|
entity_id: "{{ new_light }}"
|
||||||
data:
|
data:
|
||||||
transition: "{{ transition }}"
|
transition: "{{ transition }}"
|
||||||
|
|
||||||
- delay:
|
- delay:
|
||||||
milliseconds: "{{ flash_interval_ms }}"
|
milliseconds: "{{ flash_interval_ms }}"
|
||||||
|
|
||||||
# Optionally turn off the light.
|
# Restore light to original state if it was off
|
||||||
- choose:
|
- choose:
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
@@ -355,7 +464,7 @@ action:
|
|||||||
data:
|
data:
|
||||||
transition: "{{ transition }}"
|
transition: "{{ transition }}"
|
||||||
|
|
||||||
# Save persistent state.
|
# Clear state after successful completion
|
||||||
- choose:
|
- choose:
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
@@ -365,8 +474,10 @@ action:
|
|||||||
target:
|
target:
|
||||||
entity_id: "{{ automation_state_entity }}"
|
entity_id: "{{ automation_state_entity }}"
|
||||||
data:
|
data:
|
||||||
value: >
|
value: >-
|
||||||
{% set new_automation_state = (automation_state | combine({ state_key_last_light: '' })) %}
|
{% set new_state = automation_state | combine({
|
||||||
{% set new_automation_state = (new_automation_state | combine({ state_key_last_was_on: new_on })) %}
|
state_key_last_light: '',
|
||||||
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
state_key_last_was_on: new_on,
|
||||||
|
state_key_last_select_action_datetime: current_datetime | string
|
||||||
|
}) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_state }) | tojson }}
|
||||||
|
|||||||
Reference in New Issue
Block a user