Add transition duration, scene activation, JSON presets, and group/area targeting to MQTT Light Control
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
- Add configurable transition duration (0-10s) for smooth light changes - Add scene activation support with 4 configurable scene slots - Change preset format from key:value;key:value to JSON with expanded keys - Add light group entity and area-based targeting options
This commit is contained in:
@@ -10,7 +10,10 @@
|
|||||||
# - Brightness control (increment, hold, list-based, min/max)
|
# - Brightness control (increment, hold, list-based, min/max)
|
||||||
# - Color temperature control (increment, hold, list-based)
|
# - Color temperature control (increment, hold, list-based)
|
||||||
# - RGB/Hue control (increment, hold, list-based)
|
# - RGB/Hue control (increment, hold, list-based)
|
||||||
# - Preset list support for quick scene switching
|
# - Preset list support (JSON format) for quick scene switching
|
||||||
|
# - Scene activation support (up to 4 scenes)
|
||||||
|
# - Light group and area targeting
|
||||||
|
# - Configurable transition duration for smooth changes
|
||||||
# - Alternative light support (control secondary lights when primary are off)
|
# - Alternative light support (control secondary lights when primary are off)
|
||||||
# - Persistent state storage via input_text entity
|
# - Persistent state storage via input_text entity
|
||||||
# - Custom action callbacks for extending functionality
|
# - Custom action callbacks for extending functionality
|
||||||
@@ -133,6 +136,25 @@ blueprint:
|
|||||||
- input_text
|
- input_text
|
||||||
multiple: true
|
multiple: true
|
||||||
|
|
||||||
|
target_light_group:
|
||||||
|
name: Target Light Group (optional)
|
||||||
|
description: >
|
||||||
|
A light group entity to control. The group will be controlled as
|
||||||
|
a single entity. Can be used alongside individual lights.
|
||||||
|
default: null
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: light
|
||||||
|
|
||||||
|
target_area:
|
||||||
|
name: Target Area (optional)
|
||||||
|
description: >
|
||||||
|
An area to control. All lights in the area will be discovered
|
||||||
|
and controlled. Provide the area ID (e.g., "living_room").
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# Alternative Lights Configuration
|
# Alternative Lights Configuration
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
@@ -443,6 +465,20 @@ blueprint:
|
|||||||
selector:
|
selector:
|
||||||
boolean:
|
boolean:
|
||||||
|
|
||||||
|
transition_duration:
|
||||||
|
name: Transition Duration
|
||||||
|
description: >
|
||||||
|
Duration in seconds for light transitions (brightness, color changes).
|
||||||
|
Set to 0 for instant changes. Note: Hold actions ignore this setting
|
||||||
|
for immediate response.
|
||||||
|
default: 0
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 10
|
||||||
|
step: 0.5
|
||||||
|
unit_of_measurement: "s"
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# Brightness Increment Actions
|
# Brightness Increment Actions
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
@@ -904,10 +940,12 @@ blueprint:
|
|||||||
preset_list_entity:
|
preset_list_entity:
|
||||||
name: Preset List Entity
|
name: Preset List Entity
|
||||||
description: >
|
description: >
|
||||||
An input_select entity containing preset values. Each entry must have
|
An input_select entity containing preset values in JSON format.
|
||||||
the following layout: `key:value;key:value`, example
|
Example: `{"color_temp_kelvin": 4000, "brightness": 255}`
|
||||||
`color_temp_kelvin:4000;brightness:255`. Supported keys are:
|
Example with RGB: `{"rgb_color": [255, 0, 0], "brightness": 200}`
|
||||||
`color_temp_kelvin`, `rgb_color`, `brightness`
|
Example with effect: `{"effect": "colorloop", "brightness": 128}`
|
||||||
|
Supported keys: brightness, color_temp_kelvin, rgb_color, hs_color,
|
||||||
|
xy_color, effect, transition
|
||||||
default: null
|
default: null
|
||||||
selector:
|
selector:
|
||||||
entity:
|
entity:
|
||||||
@@ -920,6 +958,102 @@ blueprint:
|
|||||||
selector:
|
selector:
|
||||||
action: {}
|
action: {}
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Scene Activation Actions
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
# Directly activate Home Assistant scenes via MQTT actions
|
||||||
|
Action_Group_Scene:
|
||||||
|
name: "Actions: Scene Activation"
|
||||||
|
collapsed: true
|
||||||
|
input:
|
||||||
|
action_scene_1:
|
||||||
|
name: Scene 1 Action ID
|
||||||
|
description: Action ID to activate Scene 1
|
||||||
|
default: ''
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
scene_entity_1:
|
||||||
|
name: Scene 1 Entity
|
||||||
|
description: The scene entity to activate when Scene 1 Action ID is received
|
||||||
|
default: null
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: scene
|
||||||
|
|
||||||
|
action_scene_1_callback:
|
||||||
|
name: Scene 1 Callback
|
||||||
|
description: Callback action triggered after Scene 1 activation
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
action_scene_2:
|
||||||
|
name: Scene 2 Action ID
|
||||||
|
description: Action ID to activate Scene 2
|
||||||
|
default: ''
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
scene_entity_2:
|
||||||
|
name: Scene 2 Entity
|
||||||
|
description: The scene entity to activate when Scene 2 Action ID is received
|
||||||
|
default: null
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: scene
|
||||||
|
|
||||||
|
action_scene_2_callback:
|
||||||
|
name: Scene 2 Callback
|
||||||
|
description: Callback action triggered after Scene 2 activation
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
action_scene_3:
|
||||||
|
name: Scene 3 Action ID
|
||||||
|
description: Action ID to activate Scene 3
|
||||||
|
default: ''
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
scene_entity_3:
|
||||||
|
name: Scene 3 Entity
|
||||||
|
description: The scene entity to activate when Scene 3 Action ID is received
|
||||||
|
default: null
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: scene
|
||||||
|
|
||||||
|
action_scene_3_callback:
|
||||||
|
name: Scene 3 Callback
|
||||||
|
description: Callback action triggered after Scene 3 activation
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
action_scene_4:
|
||||||
|
name: Scene 4 Action ID
|
||||||
|
description: Action ID to activate Scene 4
|
||||||
|
default: ''
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
scene_entity_4:
|
||||||
|
name: Scene 4 Entity
|
||||||
|
description: The scene entity to activate when Scene 4 Action ID is received
|
||||||
|
default: null
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: scene
|
||||||
|
|
||||||
|
action_scene_4_callback:
|
||||||
|
name: Scene 4 Callback
|
||||||
|
description: Callback action triggered after Scene 4 activation
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
# Common List Parameters
|
# Common List Parameters
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
@@ -1117,17 +1251,38 @@ variables:
|
|||||||
apply_common_options_to_newly_enabled_light: !input apply_common_options_to_newly_enabled_light
|
apply_common_options_to_newly_enabled_light: !input apply_common_options_to_newly_enabled_light
|
||||||
target_lights_helper: !input target_lights_helper
|
target_lights_helper: !input target_lights_helper
|
||||||
target_lights: !input target_lights
|
target_lights: !input target_lights
|
||||||
|
target_light_group: !input target_light_group
|
||||||
|
target_area: !input target_area
|
||||||
best_source_light_for_options: !input best_source_light_for_options
|
best_source_light_for_options: !input best_source_light_for_options
|
||||||
|
|
||||||
# Resolve all lights from either helper entities or direct selection
|
# Resolve all lights from direct selection, helpers, groups, and areas
|
||||||
resolved_all_lights: >-
|
resolved_all_lights: >-
|
||||||
{% set result = [] %}
|
{% set result = [] %}
|
||||||
{% if target_lights_helper != '' %}
|
{# Direct light selection #}
|
||||||
{% set result = target_lights_helper | map('states') | list %}
|
{% if target_lights | length > 0 %}
|
||||||
{% elif target_lights | length > 0 %}
|
|
||||||
{% set result = result + target_lights %}
|
{% set result = result + target_lights %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ result }}
|
{# Helper-based selection #}
|
||||||
|
{% if target_lights_helper != '' %}
|
||||||
|
{% set result = result + (target_lights_helper | map('states') | list) %}
|
||||||
|
{% endif %}
|
||||||
|
{# Light group - add the group entity itself #}
|
||||||
|
{% if target_light_group is not none %}
|
||||||
|
{% set result = result + [target_light_group] %}
|
||||||
|
{% endif %}
|
||||||
|
{# Area-based selection #}
|
||||||
|
{% if target_area != '' %}
|
||||||
|
{% set area_lights = area_entities(target_area) | select('match', '^light\\.') | list %}
|
||||||
|
{% set result = result + area_lights %}
|
||||||
|
{% endif %}
|
||||||
|
{# Remove duplicates while preserving order #}
|
||||||
|
{% set seen = namespace(items=[]) %}
|
||||||
|
{% for item in result %}
|
||||||
|
{% if item not in seen.items %}
|
||||||
|
{% set seen.items = seen.items + [item] %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{{ seen.items }}
|
||||||
|
|
||||||
# Determine which lights are currently enabled (ON state)
|
# Determine which lights are currently enabled (ON state)
|
||||||
enabled_lights_default: "{{ resolved_all_lights | select('is_state','on') | list }}"
|
enabled_lights_default: "{{ resolved_all_lights | select('is_state','on') | list }}"
|
||||||
@@ -1259,6 +1414,7 @@ variables:
|
|||||||
action_brightness_set_min_or_max: !input action_brightness_set_min_or_max
|
action_brightness_set_min_or_max: !input action_brightness_set_min_or_max
|
||||||
result_max_brightness: !input max_brightness
|
result_max_brightness: !input max_brightness
|
||||||
result_min_brightness: !input min_brightness
|
result_min_brightness: !input min_brightness
|
||||||
|
transition_duration: !input transition_duration
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Color Temperature Action IDs and Limits
|
# Color Temperature Action IDs and Limits
|
||||||
@@ -1311,6 +1467,18 @@ variables:
|
|||||||
action_preset_list_up: !input action_preset_list_up
|
action_preset_list_up: !input action_preset_list_up
|
||||||
action_preset_list_down: !input action_preset_list_down
|
action_preset_list_down: !input action_preset_list_down
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Scene Action IDs and Entities
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
action_scene_1: !input action_scene_1
|
||||||
|
action_scene_2: !input action_scene_2
|
||||||
|
action_scene_3: !input action_scene_3
|
||||||
|
action_scene_4: !input action_scene_4
|
||||||
|
scene_entity_1: !input scene_entity_1
|
||||||
|
scene_entity_2: !input scene_entity_2
|
||||||
|
scene_entity_3: !input scene_entity_3
|
||||||
|
scene_entity_4: !input scene_entity_4
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Callbacks
|
# Callbacks
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -1564,9 +1732,12 @@ action:
|
|||||||
result_options_reference_light: "{{ alternative_target if alternative_target is not none else options_reference_light }}"
|
result_options_reference_light: "{{ alternative_target if alternative_target is not none else options_reference_light }}"
|
||||||
color_mode: "{{ state_attr(result_options_reference_light, 'color_mode') if (result_options_reference_light is not none) else none }}"
|
color_mode: "{{ state_attr(result_options_reference_light, 'color_mode') if (result_options_reference_light is not none) else none }}"
|
||||||
|
|
||||||
# Build light data (brightness, color) to apply
|
# Build light data (brightness, color, transition) to apply
|
||||||
light_data: >
|
light_data: >
|
||||||
{% set d = dict() %}
|
{% set d = dict() %}
|
||||||
|
{% if transition_duration > 0 %}
|
||||||
|
{% set d = d | combine({ 'transition': transition_duration }) %}
|
||||||
|
{% endif %}
|
||||||
{% if not color_mode or (result_options_reference_light is none) or (not apply_common_options_to_newly_enabled_light) %}
|
{% if not color_mode or (result_options_reference_light is none) or (not apply_common_options_to_newly_enabled_light) %}
|
||||||
{% if set_max_brightness_on_turn_on %}
|
{% if set_max_brightness_on_turn_on %}
|
||||||
{% set d = d | combine({ 'brightness': result_max_brightness }) %}
|
{% set d = d | combine({ 'brightness': result_max_brightness }) %}
|
||||||
@@ -1746,6 +1917,8 @@ action:
|
|||||||
- service: light.turn_off
|
- service: light.turn_off
|
||||||
target:
|
target:
|
||||||
entity_id: "{{ lights_to_turn_off }}"
|
entity_id: "{{ lights_to_turn_off }}"
|
||||||
|
data:
|
||||||
|
transition: "{{ transition_duration }}"
|
||||||
|
|
||||||
# Turn off the switches
|
# Turn off the switches
|
||||||
- service: switch.turn_off
|
- service: switch.turn_off
|
||||||
@@ -1824,6 +1997,7 @@ action:
|
|||||||
entity_id: "{{ lights_to_control }}"
|
entity_id: "{{ lights_to_control }}"
|
||||||
data:
|
data:
|
||||||
brightness: "{{ result_brightness }}"
|
brightness: "{{ result_brightness }}"
|
||||||
|
transition: "{{ transition_duration }}"
|
||||||
|
|
||||||
- choose:
|
- choose:
|
||||||
- conditions:
|
- conditions:
|
||||||
@@ -1865,6 +2039,7 @@ action:
|
|||||||
entity_id: "{{ lights_to_control }}"
|
entity_id: "{{ lights_to_control }}"
|
||||||
data:
|
data:
|
||||||
brightness: "{{ result_brightness }}"
|
brightness: "{{ result_brightness }}"
|
||||||
|
transition: "{{ transition_duration }}"
|
||||||
|
|
||||||
- choose:
|
- choose:
|
||||||
- conditions:
|
- conditions:
|
||||||
@@ -2220,6 +2395,9 @@ action:
|
|||||||
|
|
||||||
light_data: >
|
light_data: >
|
||||||
{% set d = dict() %}
|
{% set d = dict() %}
|
||||||
|
{% if transition_duration > 0 %}
|
||||||
|
{% set d = d | combine({ 'transition': transition_duration }) %}
|
||||||
|
{% endif %}
|
||||||
{% set d = d | combine({ result_attribute: value_to_set }) %}
|
{% set d = d | combine({ result_attribute: value_to_set }) %}
|
||||||
{% if has_switched_mode and state_key_prefix != '' %}
|
{% if has_switched_mode and state_key_prefix != '' %}
|
||||||
{% set d = d | combine({ 'brightness': brightness_to_set }) %}
|
{% set d = d | combine({ 'brightness': brightness_to_set }) %}
|
||||||
@@ -2363,6 +2541,9 @@ action:
|
|||||||
|
|
||||||
light_data: >
|
light_data: >
|
||||||
{% set d = dict() %}
|
{% set d = dict() %}
|
||||||
|
{% if transition_duration > 0 %}
|
||||||
|
{% set d = d | combine({ 'transition': transition_duration }) %}
|
||||||
|
{% endif %}
|
||||||
{% set d = d | combine({ result_attribute: value_to_set }) %}
|
{% set d = d | combine({ result_attribute: value_to_set }) %}
|
||||||
{{ d }}
|
{{ d }}
|
||||||
|
|
||||||
@@ -2458,30 +2639,30 @@ action:
|
|||||||
{{ [0, [(value_sequence | length - 1), next_index_preview]|min]|max }}
|
{{ [0, [(value_sequence | length - 1), next_index_preview]|min]|max }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
# Parse preset string (format: "key:value;key:value")
|
# Parse preset JSON format
|
||||||
preset: "{{ value_sequence[next_index] | lower }}"
|
preset_str: "{{ value_sequence[next_index] | trim }}"
|
||||||
light_data: >
|
light_data: >
|
||||||
{% set parts = preset.split(";") %}
|
|
||||||
{% set ns = namespace(res=dict(), brightness_found=False) %}
|
{% set ns = namespace(res=dict(), brightness_found=False) %}
|
||||||
{% for i in range(parts|length) %}
|
{% set parsed = preset_str | from_json %}
|
||||||
{% set temp = parts[i].split(':') %}
|
{% for key, value in parsed.items() %}
|
||||||
{% set key = temp[0] | trim %}
|
|
||||||
{% set value = temp[1] | trim %}
|
|
||||||
{% if key == 'brightness' %}
|
{% if key == 'brightness' %}
|
||||||
{% set ns.res = ns.res | combine({ 'brightness': value | int }) %}
|
{% set ns.res = ns.res | combine({ 'brightness': value | int }) %}
|
||||||
{% set ns.brightness_found = True %}
|
{% set ns.brightness_found = True %}
|
||||||
{% elif key == 'color_temp_kelvin' %}
|
{% elif key in ['color_temp_kelvin', 'effect', 'transition'] %}
|
||||||
{% set ns.res = ns.res | combine({ 'color_temp_kelvin': value | int }) %}
|
{% set ns.res = ns.res | combine({ key: value }) %}
|
||||||
{% elif key == 'rgb_color' %}
|
{% elif key in ['rgb_color', 'hs_color', 'xy_color'] %}
|
||||||
{% set ns.res = ns.res | combine({ 'rgb_color': value | from_json }) %}
|
{% set ns.res = ns.res | combine({ key: value }) %}
|
||||||
{% elif key == 'color_mode' %}
|
|
||||||
{% set ns.res = ns.res | combine({ 'color_mode': value }) %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{# Preserve current brightness if not specified in preset #}
|
||||||
{% if not ns.brightness_found %}
|
{% if not ns.brightness_found %}
|
||||||
{% set existing_brightness = state_attr(options_reference_light, 'brightness') | int %}
|
{% set existing_brightness = state_attr(options_reference_light, 'brightness') | int %}
|
||||||
{% set ns.res = ns.res | combine({ 'brightness': existing_brightness }) %}
|
{% set ns.res = ns.res | combine({ 'brightness': existing_brightness }) %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{# Add transition if not specified in preset #}
|
||||||
|
{% if 'transition' not in ns.res and transition_duration > 0 %}
|
||||||
|
{% set ns.res = ns.res | combine({ 'transition': transition_duration }) %}
|
||||||
|
{% endif %}
|
||||||
{{ ns.res }}
|
{{ ns.res }}
|
||||||
|
|
||||||
# Apply preset to lights
|
# Apply preset to lights
|
||||||
@@ -2525,6 +2706,70 @@ action:
|
|||||||
value_template: "{{ any_action_callback != [] }}"
|
value_template: "{{ any_action_callback != [] }}"
|
||||||
sequence: !input any_action_callback
|
sequence: !input any_action_callback
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
# SCENE ACTIVATION ACTIONS
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{{ action_id != '' and action_id in [action_scene_1, action_scene_2, action_scene_3, action_scene_4] }}
|
||||||
|
sequence:
|
||||||
|
- variables:
|
||||||
|
action_scene_1_callback: !input action_scene_1_callback
|
||||||
|
action_scene_2_callback: !input action_scene_2_callback
|
||||||
|
action_scene_3_callback: !input action_scene_3_callback
|
||||||
|
action_scene_4_callback: !input action_scene_4_callback
|
||||||
|
|
||||||
|
scene_to_activate: >
|
||||||
|
{% if action_id == action_scene_1 %}
|
||||||
|
{{ scene_entity_1 }}
|
||||||
|
{% elif action_id == action_scene_2 %}
|
||||||
|
{{ scene_entity_2 }}
|
||||||
|
{% elif action_id == action_scene_3 %}
|
||||||
|
{{ scene_entity_3 }}
|
||||||
|
{% elif action_id == action_scene_4 %}
|
||||||
|
{{ scene_entity_4 }}
|
||||||
|
{% else %}
|
||||||
|
{{ none }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Activate the scene
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ scene_to_activate is not none }}"
|
||||||
|
sequence:
|
||||||
|
- service: scene.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ scene_to_activate }}"
|
||||||
|
data:
|
||||||
|
transition: "{{ transition_duration }}"
|
||||||
|
|
||||||
|
# Execute scene callbacks
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_id == action_scene_1 and action_scene_1_callback != [] }}"
|
||||||
|
sequence: !input action_scene_1_callback
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_id == action_scene_2 and action_scene_2_callback != [] }}"
|
||||||
|
sequence: !input action_scene_2_callback
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_id == action_scene_3 and action_scene_3_callback != [] }}"
|
||||||
|
sequence: !input action_scene_3_callback
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_id == action_scene_4 and action_scene_4_callback != [] }}"
|
||||||
|
sequence: !input action_scene_4_callback
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ any_action_callback != [] }}"
|
||||||
|
sequence: !input any_action_callback
|
||||||
|
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
# CUSTOM ACTIONS HANDLER
|
# CUSTOM ACTIONS HANDLER
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user