Initial commit with existing blueprints
This commit is contained in:
220
Common/Alarm Notification.yaml
Normal file
220
Common/Alarm Notification.yaml
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "Custom: Multi-Sensor Alarm & Notification"
|
||||||
|
description: >
|
||||||
|
Triggers notifications and alarm actions when any of the configured binary sensors
|
||||||
|
change to "on". Supports per-sensor notification texts, optional alarm switch,
|
||||||
|
melody and volume selectors.
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
devices:
|
||||||
|
name: "Devices"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
binary_sensors:
|
||||||
|
name: Binary Sensors
|
||||||
|
description: List of sensors to monitor
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- binary_sensor
|
||||||
|
- input_boolean
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
binary_sensors_decay_duration:
|
||||||
|
name: Binary Sensors Decay Duration (seconds)
|
||||||
|
description: Minimum time a sensor must stay ON before considered active
|
||||||
|
default: 5
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 30
|
||||||
|
unit_of_measurement: "s"
|
||||||
|
|
||||||
|
notification:
|
||||||
|
name: "Notification"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
notify_target:
|
||||||
|
name: Notification Target (optional)
|
||||||
|
description: Device or service to send notifications
|
||||||
|
default: null
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: notify
|
||||||
|
|
||||||
|
notify_texts:
|
||||||
|
name: Notification Texts
|
||||||
|
description: One line per binary sensor, aligned with sensor list
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
alarm_group:
|
||||||
|
name: "Alarm"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
alarm_switch:
|
||||||
|
name: Alarm Switch (optional)
|
||||||
|
description: Switch entity to toggle alarm device
|
||||||
|
default: null
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: switch
|
||||||
|
|
||||||
|
melody_id:
|
||||||
|
name: Melody Identifier
|
||||||
|
description: Static melody identifier string
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
melody_select:
|
||||||
|
name: Melody Selector (optional)
|
||||||
|
description: Input select entity pointing to melody list
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- input_select
|
||||||
|
- select
|
||||||
|
|
||||||
|
|
||||||
|
volume_id:
|
||||||
|
name: Volume Identifier
|
||||||
|
description: Static volume identifier string
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
volume_select:
|
||||||
|
name: Volume Selector (optional)
|
||||||
|
description: Input select entity pointing to volume list
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- input_select
|
||||||
|
- select
|
||||||
|
|
||||||
|
mode: restart
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input binary_sensors
|
||||||
|
to: "on"
|
||||||
|
for:
|
||||||
|
seconds: !input binary_sensors_decay_duration
|
||||||
|
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input binary_sensors
|
||||||
|
to: "off"
|
||||||
|
|
||||||
|
action:
|
||||||
|
- variables:
|
||||||
|
binary_sensors: !input binary_sensors
|
||||||
|
notify_target: !input notify_target
|
||||||
|
melody_select: !input melody_select
|
||||||
|
volume_select: !input volume_select
|
||||||
|
alarm_switch: !input alarm_switch
|
||||||
|
|
||||||
|
enabled_sensors: "{{ binary_sensors | list | select('is_state','on') | list }}"
|
||||||
|
is_any_sensor_on: "{{ enabled_sensors | length != 0 }}"
|
||||||
|
are_all_sensors_off: "{{ enabled_sensors | length == 0 }}"
|
||||||
|
|
||||||
|
delay_between_setters_in_ms: 100
|
||||||
|
|
||||||
|
is_debug: false
|
||||||
|
|
||||||
|
# Debug info (log if required)
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_debug }}"
|
||||||
|
sequence:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Debug Info"
|
||||||
|
message: >
|
||||||
|
binary_sensors = {{ binary_sensors }},
|
||||||
|
enabled_sensors = {{ enabled_sensors }}
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_any_sensor_on and notify_target is not none }}"
|
||||||
|
sequence:
|
||||||
|
- variables:
|
||||||
|
notify_texts: !input notify_texts
|
||||||
|
messages: "{{ notify_texts | list }}"
|
||||||
|
sensor: "{{ trigger.entity_id }}"
|
||||||
|
idx: "{{ (binary_sensors | list).index(sensor) }}"
|
||||||
|
message: >
|
||||||
|
{% if messages | length > idx %}
|
||||||
|
{{ messages[idx] }}
|
||||||
|
{% else %}
|
||||||
|
Sensor {{ sensor }} triggered
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
- service: notify.send_message
|
||||||
|
target:
|
||||||
|
entity_id: !input notify_target
|
||||||
|
data:
|
||||||
|
message: "{{ message }}"
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ alarm_switch is not none }}"
|
||||||
|
sequence:
|
||||||
|
- variables:
|
||||||
|
melody_select: !input melody_select
|
||||||
|
melody_id: !input melody_id
|
||||||
|
|
||||||
|
volume_select: !input volume_select
|
||||||
|
volume_id: !input volume_id
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ melody_select is not none }}"
|
||||||
|
sequence:
|
||||||
|
- service: select.select_option
|
||||||
|
target:
|
||||||
|
entity_id: !input melody_select
|
||||||
|
data:
|
||||||
|
option: !input melody_id
|
||||||
|
- delay:
|
||||||
|
milliseconds: "{{ delay_between_setters_in_ms }}"
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ volume_select is not none }}"
|
||||||
|
sequence:
|
||||||
|
- service: select.select_option
|
||||||
|
target:
|
||||||
|
entity_id: !input volume_select
|
||||||
|
data:
|
||||||
|
option: !input volume_id
|
||||||
|
- delay:
|
||||||
|
milliseconds: "{{ delay_between_setters_in_ms }}"
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_any_sensor_on }}"
|
||||||
|
sequence:
|
||||||
|
- service: switch.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: !input alarm_switch
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ are_all_sensors_off }}"
|
||||||
|
sequence:
|
||||||
|
- service: switch.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: !input alarm_switch
|
||||||
|
|
||||||
|
|
||||||
371
Common/Climate Device Controller.yaml
Normal file
371
Common/Climate Device Controller.yaml
Normal file
@@ -0,0 +1,371 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "Custom: Climate Device Control"
|
||||||
|
description: >
|
||||||
|
Controls device based on window/door sensors with decay duration
|
||||||
|
and current_valueerature threshold.
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
primary_group:
|
||||||
|
name: "General"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
device_switch:
|
||||||
|
name: Device Switch
|
||||||
|
description: Switch associated with device
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: switch
|
||||||
|
|
||||||
|
control_switch:
|
||||||
|
name: Control Switch
|
||||||
|
description: Controls if the device can work or not
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- binary_sensor
|
||||||
|
- input_boolean
|
||||||
|
|
||||||
|
doors_group:
|
||||||
|
name: "Doors & Windows"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
house_windows:
|
||||||
|
name: House Window Sensors
|
||||||
|
description: Sensors of whole house
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: binary_sensor
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
room_windows:
|
||||||
|
name: Room Window Sensors
|
||||||
|
description: Window sensors of the device room
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: binary_sensor
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
room_doors:
|
||||||
|
name: Room Door Sensors
|
||||||
|
description: Door sensors of the device room
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: binary_sensor
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
decay_duration:
|
||||||
|
name: Decay Duration (seconds)
|
||||||
|
default: 3
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 600
|
||||||
|
unit_of_measurement: seconds
|
||||||
|
mode: slider
|
||||||
|
|
||||||
|
env_group:
|
||||||
|
name: "Environment"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
env_sensors:
|
||||||
|
name: Room Value Sensors
|
||||||
|
description: Sensors that controls room value
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: sensor
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
target_value_entity:
|
||||||
|
name: Target Value Entity
|
||||||
|
description: Entity (e.g. input_number) that defines target value dynamically.
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: input_number
|
||||||
|
|
||||||
|
value_threshold:
|
||||||
|
name: Value Threshold
|
||||||
|
description: If value falls below the threshold then device will be turned on (not taking into account other conditions)
|
||||||
|
default: 0
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 100
|
||||||
|
mode: slider
|
||||||
|
|
||||||
|
value_is_low_entity:
|
||||||
|
name: "Low Value Entity (optional)"
|
||||||
|
description: The entity will contain state of low value
|
||||||
|
default: null
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- input_boolean
|
||||||
|
|
||||||
|
schedule_group:
|
||||||
|
name: "Schedules"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
schedule_entities:
|
||||||
|
name: Schedules (optional)
|
||||||
|
description: One or more schedule entities that define when device may run. Leave empty for always.
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: schedule
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
power_group:
|
||||||
|
name: "Power"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
power_sensor:
|
||||||
|
name: Power Sensor
|
||||||
|
description: Sensor reporting device power usage (W)
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: sensor
|
||||||
|
|
||||||
|
power_threshold:
|
||||||
|
name: Power Threshold (W)
|
||||||
|
description: Below this value, device is considered as problematic
|
||||||
|
default: 10
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 50
|
||||||
|
unit_of_measurement: "W"
|
||||||
|
|
||||||
|
power_decay_duration:
|
||||||
|
name: Power Decay Duration (s)
|
||||||
|
description: Time to wait after power is changed before entering problematic power mode.
|
||||||
|
default: 10
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 50
|
||||||
|
unit_of_measurement: "s"
|
||||||
|
|
||||||
|
power_problematic_indicator_entity:
|
||||||
|
name: Indicator Entity (optional)
|
||||||
|
description: "If step then the automation with toggle the entity whenever the device enters power problematic state"
|
||||||
|
default: null
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: input_boolean
|
||||||
|
|
||||||
|
mode: single
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
# Control switch
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input control_switch
|
||||||
|
|
||||||
|
# House window
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input house_windows
|
||||||
|
for:
|
||||||
|
seconds: !input decay_duration
|
||||||
|
|
||||||
|
# Room window
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input room_windows
|
||||||
|
for:
|
||||||
|
seconds: !input decay_duration
|
||||||
|
|
||||||
|
# Room door
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input room_doors
|
||||||
|
for:
|
||||||
|
seconds: !input decay_duration
|
||||||
|
|
||||||
|
# Target value entity
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input target_value_entity
|
||||||
|
|
||||||
|
# Room env sensor
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input env_sensors
|
||||||
|
|
||||||
|
# Power sensor
|
||||||
|
- platform: numeric_state
|
||||||
|
entity_id: !input power_sensor
|
||||||
|
below: !input power_threshold
|
||||||
|
for:
|
||||||
|
seconds: !input power_decay_duration
|
||||||
|
|
||||||
|
condition: []
|
||||||
|
|
||||||
|
action:
|
||||||
|
- variables:
|
||||||
|
env_sensors: !input env_sensors
|
||||||
|
control_switch: !input control_switch
|
||||||
|
device_switch: !input device_switch
|
||||||
|
threshold: !input value_threshold
|
||||||
|
value_is_low_entity: !input value_is_low_entity
|
||||||
|
|
||||||
|
# Target value.
|
||||||
|
target_value_entity: !input target_value_entity
|
||||||
|
target_value: "{{ states(target_value_entity) | int }}"
|
||||||
|
|
||||||
|
# Values/threshold
|
||||||
|
value_stats: >
|
||||||
|
{% set result = [] %}
|
||||||
|
{% if env_sensors | length > 0 %}
|
||||||
|
{% set values = expand(env_sensors) | map(attribute='state') | map('float') | list %}
|
||||||
|
{% if threshold != 0 %}
|
||||||
|
{% set result = result + [values | select('lt', threshold) | list | count] %}
|
||||||
|
{% else %}
|
||||||
|
{% set result = result + [0] %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if target_value != 0 %}
|
||||||
|
{% set result = result + [values | select('lt', target_value) | list | count] %}
|
||||||
|
{% else %}
|
||||||
|
{% set result = result + [0] %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
{% set result = [0, 0] %}
|
||||||
|
{% endif %}
|
||||||
|
{{ result }}
|
||||||
|
is_value_below_threshold: "{{ (value_stats[0] | int) > 0 }}"
|
||||||
|
is_value_below_target_value: "{{ (value_stats[1] | int) > 0 }}"
|
||||||
|
|
||||||
|
# Power
|
||||||
|
power_threshold: !input power_threshold
|
||||||
|
power_sensor: !input power_sensor
|
||||||
|
power_problematic_indicator_entity: !input power_problematic_indicator_entity
|
||||||
|
power_decay_duration: !input power_decay_duration
|
||||||
|
power: "{{ states(power_sensor) | float(0) }}"
|
||||||
|
is_power_not_ok: "{{ (power > 0 and power < power_threshold) if power_threshold != 0 else false }}"
|
||||||
|
|
||||||
|
# doors/windows
|
||||||
|
house_windows: !input house_windows
|
||||||
|
room_windows: !input room_windows
|
||||||
|
room_doors: !input room_doors
|
||||||
|
decay: !input decay_duration
|
||||||
|
house_closed: >
|
||||||
|
{% set ns = namespace(res = true) %}
|
||||||
|
{% for i in range(house_windows | count) %}
|
||||||
|
{% set it = house_windows[i] %}
|
||||||
|
{% set ns.res = ns.res and (is_state(it, 'off') and (now() - states[it].last_changed).total_seconds() > decay) %}
|
||||||
|
{% endfor %}
|
||||||
|
{{ ns.res }}
|
||||||
|
room_closed: >
|
||||||
|
{% if (room_windows | count) or (room_doors | count) == 0 %}
|
||||||
|
{{ false }}
|
||||||
|
{% else %}
|
||||||
|
{% set ns = namespace(res = true) %}
|
||||||
|
{% for i in range(room_windows | count) %}
|
||||||
|
{% set it = room_windows[i] %}
|
||||||
|
{% set ns.res = ns.res and (is_state(it, 'off') and (now() - states[it].last_changed).total_seconds() > decay) %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for i in range(room_doors | count) %}
|
||||||
|
{% set it = room_doors[i] %}
|
||||||
|
{% set ns.res = ns.res and (is_state(it, 'off') and (now() - states[it].last_changed).total_seconds() > decay) %}
|
||||||
|
{% endfor %}
|
||||||
|
{{ ns.res }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Schedules
|
||||||
|
schedule_entities: !input schedule_entities
|
||||||
|
schedule_active: >
|
||||||
|
{% if schedule_entities | length > 0 %}
|
||||||
|
{{ schedule_entities | select('is_state','on') | list | length > 0 }}
|
||||||
|
{% else %}
|
||||||
|
true
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
is_debug: false
|
||||||
|
|
||||||
|
# Debug message
|
||||||
|
- choose:
|
||||||
|
- conditions: "{{ is_debug }}"
|
||||||
|
sequence:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Climate (debug)"
|
||||||
|
message: >
|
||||||
|
room_closed = {{ room_closed }},
|
||||||
|
house_closed = {{ house_closed }}
|
||||||
|
|
||||||
|
# Power problematic.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_state(device_switch, 'on') and power_problematic_indicator_entity is not none }}"
|
||||||
|
sequence:
|
||||||
|
- variables:
|
||||||
|
timeout_elapsed: >
|
||||||
|
{% set last = as_timestamp(states[power_sensor].last_changed) %}
|
||||||
|
{{ (as_timestamp(now()) - last) > power_decay_duration }}
|
||||||
|
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ timeout_elapsed }}"
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions: "{{ is_power_not_ok }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_boolean.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ power_problematic_indicator_entity }}"
|
||||||
|
default:
|
||||||
|
- service: input_boolean.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: "{{ power_problematic_indicator_entity }}"
|
||||||
|
|
||||||
|
# `value_is_low_entity` entity control
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ value_is_low_entity is not none }}"
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_value_below_threshold }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_boolean.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: !input value_is_low_entity
|
||||||
|
default:
|
||||||
|
- service: input_boolean.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: !input value_is_low_entity
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
# Value is not ok override
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_value_below_threshold }}"
|
||||||
|
sequence:
|
||||||
|
- service: switch.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: !input device_switch
|
||||||
|
|
||||||
|
# Control is not enabled
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_state(control_switch, 'off') }}"
|
||||||
|
sequence:
|
||||||
|
- service: switch.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: !input device_switch
|
||||||
|
|
||||||
|
# Windows/doors closed with decay
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ (house_closed or room_closed) and schedule_active and is_value_below_target_value }}"
|
||||||
|
sequence:
|
||||||
|
- service: switch.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: !input device_switch
|
||||||
|
|
||||||
|
default:
|
||||||
|
- service: switch.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: !input device_switch
|
||||||
142
Common/Day Scene Controller.yaml
Normal file
142
Common/Day Scene Controller.yaml
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "Custom: Day Scene Controller"
|
||||||
|
description: "Allows to control time of day scenes"
|
||||||
|
domain: automation
|
||||||
|
|
||||||
|
input:
|
||||||
|
states_group:
|
||||||
|
name: States
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
time_of_day_state:
|
||||||
|
name: Time of Day state selector
|
||||||
|
description: The input_select entity that holds the current time-of-day state
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: input_select
|
||||||
|
|
||||||
|
control_switch:
|
||||||
|
name: Control Switch
|
||||||
|
description: Controls if scenes switch must work or default scene should be applied
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- binary_sensor
|
||||||
|
- input_boolean
|
||||||
|
|
||||||
|
scenes_group:
|
||||||
|
name: Scenes
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
scenes:
|
||||||
|
name: Scenes
|
||||||
|
description: Ordered list of scenes (each scene per time of day state list)
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- scene
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
default_scene:
|
||||||
|
name: Default Scene
|
||||||
|
description: Scene enabled when enable switch is off
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- scene
|
||||||
|
|
||||||
|
enable_default_scene_on_transition:
|
||||||
|
name: Enable Default Scene On Transition
|
||||||
|
description: Controls if default scene should be enabled on scene transition (i.e. before moving to other scene use default scene)
|
||||||
|
default: true
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
|
||||||
|
actions_group:
|
||||||
|
name: Actions
|
||||||
|
collapsed: true
|
||||||
|
input:
|
||||||
|
scene_applied_callback:
|
||||||
|
name: Scene Applied Callback
|
||||||
|
description: Set of action invoked whenever active scene is applied
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
default_scene_applied_callback:
|
||||||
|
name: Default Scene Applied Callback
|
||||||
|
description: Set of action invoked whenever default scene is applied
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
mode: restart
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input time_of_day_state
|
||||||
|
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input control_switch
|
||||||
|
|
||||||
|
variables:
|
||||||
|
# Constants
|
||||||
|
is_debug: false
|
||||||
|
|
||||||
|
# Declarations
|
||||||
|
control_switch: !input control_switch
|
||||||
|
time_of_day_state: !input time_of_day_state
|
||||||
|
enable_default_scene_on_transition: !input enable_default_scene_on_transition
|
||||||
|
|
||||||
|
# Values
|
||||||
|
tod_state: "{{ states(time_of_day_state) }}"
|
||||||
|
tod_options: "{{ state_attr(time_of_day_state, 'options') or [] }}"
|
||||||
|
tod_index: "{{ tod_options.index(tod_state) if tod_state in tod_options else -1 }}"
|
||||||
|
control_on: "{{ states(control_switch) in ['on','true','1'] }}"
|
||||||
|
scenes_list: !input scenes
|
||||||
|
default_scene: !input default_scene
|
||||||
|
|
||||||
|
action:
|
||||||
|
# Debug info (log if required)
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_debug }}"
|
||||||
|
sequence:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Debug Info"
|
||||||
|
message: >
|
||||||
|
tod_index = {{ tod_index }},
|
||||||
|
control_ok = {{ control_ok }}
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ tod_index == -1 }}"
|
||||||
|
sequence:
|
||||||
|
stop: "Scene index is invalid. Check your state-to-scene mapping"
|
||||||
|
default:
|
||||||
|
sequence:
|
||||||
|
- variables:
|
||||||
|
result_scene: >
|
||||||
|
{% if control_on %}
|
||||||
|
{{ scenes_list[tod_index] }}
|
||||||
|
{% else %}
|
||||||
|
{{ default_scene }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ enable_default_scene_on_transition and result_scene != default_scene }}"
|
||||||
|
sequence:
|
||||||
|
- service: scene.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ default_scene }}"
|
||||||
|
|
||||||
|
- service: scene.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ result_scene }}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
198
Common/Home Presense.yaml
Normal file
198
Common/Home Presense.yaml
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "Custom: Home Presence Controller"
|
||||||
|
description: "Allows to control time of day scenes"
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
result_group:
|
||||||
|
name: Output
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
result_value_entity:
|
||||||
|
name: Result Value
|
||||||
|
description: Helper object that will contain result
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: input_boolean
|
||||||
|
|
||||||
|
control_switch:
|
||||||
|
name: Control Switch
|
||||||
|
description: Gatekeeper switch
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- input_boolean
|
||||||
|
- binary_sensor
|
||||||
|
|
||||||
|
door_group:
|
||||||
|
name: Door
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
door_sensors:
|
||||||
|
name: Door Sensor(s)
|
||||||
|
description: Select the door sensor(s) to monitor
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
multiple: true
|
||||||
|
domain:
|
||||||
|
- binary_sensor
|
||||||
|
device_class: door
|
||||||
|
|
||||||
|
door_sensor_threshold:
|
||||||
|
name: Door Sensor Duration Threshold
|
||||||
|
description: Select the door sensor threshold
|
||||||
|
default: 60
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 600
|
||||||
|
unit_of_measurement: seconds
|
||||||
|
mode: slider
|
||||||
|
|
||||||
|
presense_group:
|
||||||
|
name: Presense
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
presence_sensors:
|
||||||
|
name: Presense Sensors
|
||||||
|
description: Select the presense sensors to monitor
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: person
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
motion_sensors:
|
||||||
|
name: Motion Sensors
|
||||||
|
description: Select the motion sensors to monitor
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: binary_sensor
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
wifi_group:
|
||||||
|
name: Wi-Fi
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
wifi_id_sensors:
|
||||||
|
name: Wi-Fi ID Sensors
|
||||||
|
description: Select the sensors that reports Wi-Fi ID(s)
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: sensor
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
home_wifi_ids:
|
||||||
|
name: Home Wi-Fi ID(s)
|
||||||
|
description: Select the home Wi-Fi ID(s)
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
mode: restart
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
# Door
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input door_sensors
|
||||||
|
id: 'door_trigger'
|
||||||
|
|
||||||
|
# Presense
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input presence_sensors
|
||||||
|
|
||||||
|
# Motion
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input motion_sensors
|
||||||
|
|
||||||
|
# Control switch
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input control_switch
|
||||||
|
|
||||||
|
# Wi-Fi sensors
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input wifi_id_sensors
|
||||||
|
|
||||||
|
variables:
|
||||||
|
is_debug: false
|
||||||
|
|
||||||
|
wifi_id_sensors: !input wifi_id_sensors
|
||||||
|
home_wifi_ids: !input home_wifi_ids
|
||||||
|
control_switch: !input control_switch
|
||||||
|
result_value_entity: !input result_value_entity
|
||||||
|
motion_sensors: !input motion_sensors
|
||||||
|
presence_sensors: !input presence_sensors
|
||||||
|
door_sensors: !input door_sensors
|
||||||
|
door_sensor_threshold: !input door_sensor_threshold
|
||||||
|
|
||||||
|
door_on: >
|
||||||
|
{% set ns = namespace(items=[]) %}
|
||||||
|
{% for s in door_sensors %}
|
||||||
|
{% if states(s) not in ['unknown','unavailable'] and (now() - states[s].last_changed).total_seconds() < door_sensor_threshold %}
|
||||||
|
{% set ns.items = ns.items + [s] %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{{ ns.items | count > 0 }}
|
||||||
|
|
||||||
|
presence_on: >
|
||||||
|
{{ (presence_sensors | select('is_state', 'home') | list | length > 0) | bool
|
||||||
|
if presence_sensors | length > 0 else false }}
|
||||||
|
|
||||||
|
motion_on: >
|
||||||
|
{{ (motion_sensors | select('is_state', 'on') | list | length > 0) | bool
|
||||||
|
if motion_sensors | length > 0 else false }}
|
||||||
|
|
||||||
|
wifi_on: >
|
||||||
|
{{ expand(wifi_id_sensors)
|
||||||
|
| map(attribute='state')
|
||||||
|
| select('in', home_wifi_ids)
|
||||||
|
| list
|
||||||
|
| length > 0 }}
|
||||||
|
|
||||||
|
in_on_except_door: "{{ (motion_on or presence_on or wifi_on) and is_state(control_switch, 'on') }}"
|
||||||
|
is_on: "{{ in_on_except_door or door_on }}"
|
||||||
|
|
||||||
|
action:
|
||||||
|
# Debug info (log if required)
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_debug }}"
|
||||||
|
sequence:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Debug Info"
|
||||||
|
message: >
|
||||||
|
motion_on = {{ motion_on }},
|
||||||
|
door_on = {{ door_on }},
|
||||||
|
presence_on = {{ presence_on }},
|
||||||
|
wifi_on = {{ wifi_on }}
|
||||||
|
|
||||||
|
# Setup result value.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_on }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_boolean.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ result_value_entity }}"
|
||||||
|
default:
|
||||||
|
- service: input_boolean.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: "{{ result_value_entity }}"
|
||||||
|
|
||||||
|
|
||||||
|
# If it was door sensor then wait and turn on default scene after delay. On restart it will be retriggered.
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ (not in_on_except_door) and trigger.id == 'door_trigger' }}"
|
||||||
|
|
||||||
|
- delay:
|
||||||
|
seconds: "{{ door_sensor_threshold }}"
|
||||||
|
|
||||||
|
- service: input_boolean.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: "{{ result_value_entity }}"
|
||||||
594
Common/Motion Light.yaml
Normal file
594
Common/Motion Light.yaml
Normal file
@@ -0,0 +1,594 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "Custom: Motion Light"
|
||||||
|
description: >
|
||||||
|
Smart motion sensor automation blueprint.
|
||||||
|
Note: by default will not run if light was already ON. If light was turned ON during automation running the automation will enter manual state and will not triiger untill the light will be turned off.
|
||||||
|
Note:
|
||||||
|
- Not tested when motion sensors and state sensors are used at the same time.
|
||||||
|
domain: automation
|
||||||
|
|
||||||
|
input:
|
||||||
|
controls:
|
||||||
|
name: "Controls"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
motion_sensors:
|
||||||
|
name: Motion sensors
|
||||||
|
description: Select one or more motion sensors. Light is ON if any of the objects is ON.
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- binary_sensor
|
||||||
|
- switch
|
||||||
|
- group
|
||||||
|
- light
|
||||||
|
- binary_sensor
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
condition_switches:
|
||||||
|
name: Condition switches
|
||||||
|
description: >
|
||||||
|
Automation will not trigger if any of switches is off
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- input_boolean
|
||||||
|
- switch
|
||||||
|
- group
|
||||||
|
- light
|
||||||
|
- binary_sensor
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
devices_group:
|
||||||
|
name: "Devices"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
target_light:
|
||||||
|
name: Target Light (optional)
|
||||||
|
description: "Light to control. Setup no light or single light."
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: light
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
target_light_data:
|
||||||
|
name: Light Data Dictionary (optional)
|
||||||
|
default: ""
|
||||||
|
description: >
|
||||||
|
Provide a YAML dictionary of light.turn_on parameters. If parameter not specified then last set if taken.
|
||||||
|
Example:
|
||||||
|
brightness: 200
|
||||||
|
color_temp: 350
|
||||||
|
rgb_color: [255, 0, 0]
|
||||||
|
effect: rainbow
|
||||||
|
selector:
|
||||||
|
object: {}
|
||||||
|
|
||||||
|
brightness_threshold:
|
||||||
|
name: Brightness Threshold
|
||||||
|
description: 'Will trigger automation only if brightness of enabled light is lower then the threshold value'
|
||||||
|
default: 0
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 255
|
||||||
|
step: 1
|
||||||
|
|
||||||
|
target_switch:
|
||||||
|
name: Target Switch (optional)
|
||||||
|
description: "Switch to control. Setup no switch or single switch."
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: switch
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
timeout_delay:
|
||||||
|
name: Timeout delay (seconds)
|
||||||
|
description: Optional delay for motion sensors before turning off the light after all motion sensors are OFF
|
||||||
|
default: 0
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 3600
|
||||||
|
step: 1
|
||||||
|
unit_of_measurement: seconds
|
||||||
|
|
||||||
|
persistent_state:
|
||||||
|
name: "Persistent State"
|
||||||
|
collapsed: true
|
||||||
|
input:
|
||||||
|
automation_state_entity:
|
||||||
|
name: Automation state entity
|
||||||
|
description: "`input_text` that stores the light automation state in JSON format. `Doesn't require specific initial state, values of the entity can be empty. For now each automation must have it's personal entity.`"
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: input_text
|
||||||
|
|
||||||
|
automation_state_placeholder_key:
|
||||||
|
name: Automation state placeholder key
|
||||||
|
description: Overrides key for persistent storage if not empty. By default uses identifier of target light, otherwise uses constant. `Don't override it if you don't understand the meaning`
|
||||||
|
default: ''
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
luminance:
|
||||||
|
name: "Luminance"
|
||||||
|
collapsed: true
|
||||||
|
input:
|
||||||
|
luminance_sensor:
|
||||||
|
name: Luminance sensor (optional)
|
||||||
|
description: Sensor reporting ambient light level (lux)
|
||||||
|
default: null
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: sensor
|
||||||
|
|
||||||
|
luminance_threshold:
|
||||||
|
name: Luminance threshold (optional)
|
||||||
|
description: Light will only turn on if sensor value is below this threshold
|
||||||
|
default: 100
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 10000
|
||||||
|
step: 1
|
||||||
|
unit_of_measurement: "lux"
|
||||||
|
|
||||||
|
luminance_enable_switch:
|
||||||
|
name: Luminance control enable switch (optional)
|
||||||
|
description: Switch or input_boolean to enable/disable luminance control
|
||||||
|
default: null
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- switch
|
||||||
|
- input_boolean
|
||||||
|
|
||||||
|
actions:
|
||||||
|
name: "Actions"
|
||||||
|
collapsed: true
|
||||||
|
input:
|
||||||
|
user_condition:
|
||||||
|
name: Condition block
|
||||||
|
description: Optional condition(s) that must pass for actions to run
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
condition: {}
|
||||||
|
|
||||||
|
enable_action:
|
||||||
|
name: Enable callback action (optional)
|
||||||
|
description: Runs when light is turned on
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
disable_action:
|
||||||
|
name: Disable callback action (optional)
|
||||||
|
description: Runs when light is turned off
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
manual_action_runs_disable_action:
|
||||||
|
name: Manual also runs disable action
|
||||||
|
description: >
|
||||||
|
If checked, executing `Manual Action` will combine it with `Disable Action`.
|
||||||
|
default: false
|
||||||
|
selector:
|
||||||
|
boolean: {}
|
||||||
|
|
||||||
|
manual_action:
|
||||||
|
name: Manual callback action (optional)
|
||||||
|
description: >
|
||||||
|
Runs when light state is changed during automation running.
|
||||||
|
Works only in case if `Automation state entity` is set.
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
mode: restart
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
# Motion sensors ON/OFF
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input motion_sensors
|
||||||
|
id: "motion_sensor"
|
||||||
|
|
||||||
|
# Condition switches ON/OFF
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input condition_switches
|
||||||
|
|
||||||
|
# Light ON/OFF
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input target_light
|
||||||
|
id: "light_state_changed"
|
||||||
|
|
||||||
|
# Switches ON/OFF
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input target_switch
|
||||||
|
id: "switch_state_changed"
|
||||||
|
|
||||||
|
# Luminance sensor ON/OFF
|
||||||
|
- platform: template
|
||||||
|
value_template: >
|
||||||
|
{% if luminance_sensor %}
|
||||||
|
{{ states(luminance_sensor) not in ['unknown','unavailable'] }}
|
||||||
|
{% else %}
|
||||||
|
false
|
||||||
|
{% endif %}
|
||||||
|
- platform: template
|
||||||
|
value_template: >
|
||||||
|
{% if luminance_enable_switch %}
|
||||||
|
{{ states(luminance_enable_switch) not in ['unknown','unavailable'] }}
|
||||||
|
{% else %}
|
||||||
|
false
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
condition: !input user_condition
|
||||||
|
|
||||||
|
# TOFIX:
|
||||||
|
# - state_sensors
|
||||||
|
# - might be problems with storing persistent state
|
||||||
|
|
||||||
|
variables:
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
is_debug: false
|
||||||
|
is_base_debug: false
|
||||||
|
|
||||||
|
# JSON state constants
|
||||||
|
automation_state_invalid: '-1'
|
||||||
|
automation_state_none: '0'
|
||||||
|
automation_state_enabled: '1'
|
||||||
|
automation_state_enabling: '2'
|
||||||
|
automation_state_manual: '3'
|
||||||
|
state_motion_light_state: 'mls'
|
||||||
|
state_motion_light_last_action_timestamp: 'mllat'
|
||||||
|
state_motion_light_last_brightness: 'mllb'
|
||||||
|
date_time_now: "{{ now() }}"
|
||||||
|
trigger_id: "{{ trigger.id }}"
|
||||||
|
|
||||||
|
# Defines
|
||||||
|
sensors: !input motion_sensors
|
||||||
|
condition_switches: !input condition_switches
|
||||||
|
timeout: !input timeout_delay
|
||||||
|
brightness_threshold: !input brightness_threshold
|
||||||
|
|
||||||
|
# Light
|
||||||
|
light_entities: !input target_light
|
||||||
|
light_entity: "{{ light_entities[0] if light_entities | length != 0 else none }}"
|
||||||
|
|
||||||
|
# Switch
|
||||||
|
switch_entities: !input target_switch
|
||||||
|
switch_entity: "{{ switch_entities[0] if switch_entities | length != 0 else none }}"
|
||||||
|
|
||||||
|
# JSON global state.
|
||||||
|
automation_state_entity: !input automation_state_entity
|
||||||
|
automation_state_global: >
|
||||||
|
{% set text = states(automation_state_entity) | string %}
|
||||||
|
{% if text in ['unknown','unavailable','none',''] %}
|
||||||
|
{{ dict() }}
|
||||||
|
{% else %}
|
||||||
|
{{ text | from_json }}
|
||||||
|
{% endif %}
|
||||||
|
automation_state_placeholder_key: !input automation_state_placeholder_key
|
||||||
|
automation_state_key: >
|
||||||
|
{% if automation_state_placeholder_key != '' %}
|
||||||
|
{{ automation_state_placeholder_key }}
|
||||||
|
{% elif switch_entity is not none %}
|
||||||
|
{{ switch_entity }}
|
||||||
|
{% elif light_entity is not none %}
|
||||||
|
{{ light_entity }}
|
||||||
|
{% else %}
|
||||||
|
'default_motion_light_placeholder'
|
||||||
|
{% endif %}
|
||||||
|
automation_state: "{{ automation_state_global.get(automation_state_key, dict()) if light_entity != '' else dict() }}"
|
||||||
|
motion_light_state: "{{ automation_state.get(state_motion_light_state, automation_state_none) }}"
|
||||||
|
motion_light_last_action_timestamp: >
|
||||||
|
{% if trigger_id == 'state_motion' %}
|
||||||
|
{{ date_time_now }}
|
||||||
|
{% else %}
|
||||||
|
{{ (automation_state.get(state_motion_light_last_action_timestamp, none)) }}
|
||||||
|
{% endif %}
|
||||||
|
state_is_none: "{{ ((motion_light_state | string) == automation_state_none) }}"
|
||||||
|
state_is_enabled: "{{ (motion_light_state | string) == automation_state_enabled }}"
|
||||||
|
state_is_enabling: "{{ (motion_light_state | string) == automation_state_enabling }}"
|
||||||
|
state_is_manual: "{{ (motion_light_state | string) == automation_state_manual }}"
|
||||||
|
|
||||||
|
# Actions
|
||||||
|
manual_action: !input manual_action
|
||||||
|
disable_action: !input disable_action
|
||||||
|
enable_action: !input enable_action
|
||||||
|
manual_action_runs_disable_action: !input manual_action_runs_disable_action
|
||||||
|
light_data: !input target_light_data
|
||||||
|
|
||||||
|
# Luminance
|
||||||
|
luminance_sensor: !input luminance_sensor
|
||||||
|
luminance_threshold: !input luminance_threshold
|
||||||
|
luminance_enable_switch: !input luminance_enable_switch
|
||||||
|
luminance_ok: >
|
||||||
|
{% if luminance_sensor is not none and luminance_threshold is not none %}
|
||||||
|
{% set val = states(luminance_sensor) | float(0) %}
|
||||||
|
{% set enabled = true %}
|
||||||
|
{% if luminance_enable_switch %}
|
||||||
|
{% set enabled = is_state(luminance_enable_switch, 'on') %}
|
||||||
|
{% endif %}
|
||||||
|
{{ enabled and val < luminance_threshold }}
|
||||||
|
{% else %}
|
||||||
|
true
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Trigger details
|
||||||
|
all_of_condition_switches_on: >
|
||||||
|
{% set e = condition_switches if condition_switches is iterable else [condition_switches] %}
|
||||||
|
{{ (e | select('is_state', 'on') | list | length) == condition_switches | length }}
|
||||||
|
count_of_enabled_sensor: >
|
||||||
|
{% set e = sensors if sensors is iterable else [sensors] %}
|
||||||
|
{{ e | select('is_state', 'on') | list | length }}
|
||||||
|
motion_on: "{{ count_of_enabled_sensor > 0 }}"
|
||||||
|
motion_all_off: "{{ count_of_enabled_sensor == 0 }}"
|
||||||
|
must_be_enabled_preview: >
|
||||||
|
{{ (all_of_condition_switches_on and luminance_ok and motion_on) | bool }}
|
||||||
|
must_be_enabled_guard: "{{ state_is_none }}"
|
||||||
|
must_be_enabled: >
|
||||||
|
{{ must_be_enabled_preview and must_be_enabled_guard }}
|
||||||
|
|
||||||
|
must_be_disabled_preview: >
|
||||||
|
{{ ((not all_of_condition_switches_on) or motion_all_off) | bool }}
|
||||||
|
must_be_disabled_guard: "{{ state_is_enabled }}"
|
||||||
|
must_be_disabled: >
|
||||||
|
{{ must_be_disabled_preview and must_be_disabled_guard }}
|
||||||
|
|
||||||
|
action:
|
||||||
|
# Debug info.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_base_debug }}"
|
||||||
|
sequence:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Debug Info"
|
||||||
|
message: >
|
||||||
|
must_be_enabled_preview: {{ must_be_enabled_preview }},
|
||||||
|
must_be_disabled_preview: {{ must_be_disabled_preview }},
|
||||||
|
must_be_disabled: {{ must_be_disabled }},
|
||||||
|
must_be_disabled_guard: {{ must_be_disabled_guard }},
|
||||||
|
id: {{ trigger.id }}
|
||||||
|
|
||||||
|
# Guard for 1 light.
|
||||||
|
- choose:
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ light_entities | length > 1}}"
|
||||||
|
sequence:
|
||||||
|
stop: "Only one light is supported currently"
|
||||||
|
|
||||||
|
# Guard for 1 switch.
|
||||||
|
- choose:
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ switch_entities | length > 1}}"
|
||||||
|
sequence:
|
||||||
|
stop: "Only one switch is supported currently"
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
# Disable automation flag if light was changed during automation
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger_id == 'light_state_changed' or trigger_id == 'switch_state_changed' }}"
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
# Disable state if light was turned OFF (no matter how)
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{% set res = false %}
|
||||||
|
{% if light_entity is not none %}
|
||||||
|
{% set brightness = state_attr(light_entity, 'brightness') %}
|
||||||
|
{% set res = res and (is_state(light_entity, 'off') or brightness | int < brightness_threshold) %}
|
||||||
|
{% endif %}
|
||||||
|
{% if switch_entity is not none %}
|
||||||
|
{% set res = res and is_state(switch_entity, 'off') %}
|
||||||
|
{% endif %}
|
||||||
|
{{ res }}
|
||||||
|
|
||||||
|
sequence:
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ automation_state_entity }}"
|
||||||
|
data:
|
||||||
|
value: >
|
||||||
|
{% set new_automation_state = (automation_state | combine({ state_motion_light_state: automation_state_none })) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
||||||
|
|
||||||
|
# This call goes DIRECTLY from the automation
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ state_is_enabling }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ automation_state_entity }}"
|
||||||
|
data:
|
||||||
|
value: >
|
||||||
|
{% set new_automation_state = (automation_state | combine({ state_motion_light_state: automation_state_enabled })) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
||||||
|
|
||||||
|
# If the control was taken by the user
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ state_is_enabled }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ automation_state_entity }}"
|
||||||
|
data: >
|
||||||
|
{% set new_automation_state = (automation_state | combine({ state_motion_light_state: automation_state_manual })) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
||||||
|
|
||||||
|
# Call disable action if required
|
||||||
|
- choose:
|
||||||
|
- conditions: "{{ manual_action_runs_disable_action and disable_action != [] }}"
|
||||||
|
sequence: !input disable_action
|
||||||
|
|
||||||
|
# Call manual action
|
||||||
|
- choose:
|
||||||
|
- conditions: "{{ manual_action != [] }}"
|
||||||
|
sequence: !input manual_action
|
||||||
|
|
||||||
|
# Enable path
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ must_be_enabled }}"
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
# Guard: stop if light already ON and automation_flag exists
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{% set res = false %}
|
||||||
|
{% if light_entity is not none %}
|
||||||
|
{% set res = res or ((is_state(light_entity, 'on') or state_attr(light_entity, 'brightness') | int > brightness_threshold)) %}
|
||||||
|
{% endif %}
|
||||||
|
{% if switch_entity is not none %}
|
||||||
|
{% set res = res or is_state(switch_entity, 'on') %}
|
||||||
|
{% endif %}
|
||||||
|
{{ res }}
|
||||||
|
sequence:
|
||||||
|
- stop: "Light is already ON when sensors were triggered"
|
||||||
|
|
||||||
|
# Enable the light
|
||||||
|
default:
|
||||||
|
|
||||||
|
# Debug info.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_debug }}"
|
||||||
|
sequence:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Debug Info (Must Be Enabled)"
|
||||||
|
message: >
|
||||||
|
Enabled. light_entity: {{ light_entity }}
|
||||||
|
|
||||||
|
- variables:
|
||||||
|
last_brightness: >
|
||||||
|
{% if (light_entity is none) or is_state(light_entity, 'off') %}
|
||||||
|
0
|
||||||
|
{% else %}
|
||||||
|
{{ state_attr(light_entity, 'brightness') }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Turn ON the light
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ light_entity is not none }}"
|
||||||
|
sequence:
|
||||||
|
- service: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ light_entity }}"
|
||||||
|
data: "{{ light_data }}"
|
||||||
|
|
||||||
|
# Enable the switch.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ switch_entity is not none }}"
|
||||||
|
sequence:
|
||||||
|
- service: switch.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ switch_entity }}"
|
||||||
|
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ automation_state_entity }}"
|
||||||
|
data:
|
||||||
|
value: >
|
||||||
|
{% set new_automation_state = (automation_state | combine({ state_motion_light_state: automation_state_enabling, state_motion_light_last_action_timestamp: date_time_now, state_motion_light_last_brightness: last_brightness })) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
||||||
|
|
||||||
|
# Enable action
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ enable_action != [] }}"
|
||||||
|
sequence: !input enable_action
|
||||||
|
|
||||||
|
# Disable path
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ must_be_disabled }}"
|
||||||
|
sequence:
|
||||||
|
|
||||||
|
# Debug info.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_debug }}"
|
||||||
|
sequence:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Debug Info (Must Be Disabled)"
|
||||||
|
message: >
|
||||||
|
Disabled. light_entity: {{ light_entity }}
|
||||||
|
|
||||||
|
- delay:
|
||||||
|
seconds: "{{ timeout }}"
|
||||||
|
|
||||||
|
# Disable the light.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ light_entity is not none }}"
|
||||||
|
sequence:
|
||||||
|
|
||||||
|
- variables:
|
||||||
|
last_brightness: "{{ automation_state.get(state_motion_light_last_brightness, 0) }}"
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ last_brightness > 0 }}"
|
||||||
|
sequence:
|
||||||
|
- service: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ light_entity }}"
|
||||||
|
data:
|
||||||
|
brightness: "{{ last_brightness }}"
|
||||||
|
|
||||||
|
default:
|
||||||
|
- service: light.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: "{{ light_entity }}"
|
||||||
|
|
||||||
|
# Disable the switch.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ switch_entity is not none }}"
|
||||||
|
sequence:
|
||||||
|
- service: switch.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: "{{ switch_entity }}"
|
||||||
|
|
||||||
|
# Modify automation entity.
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ automation_state_entity }}"
|
||||||
|
data:
|
||||||
|
value: >
|
||||||
|
{% set new_automation_state = (automation_state | combine({ state_motion_light_state: automation_state_none })) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ disable_action != [] }}"
|
||||||
|
sequence: !input disable_action
|
||||||
116
Common/Refrigerator.yaml
Normal file
116
Common/Refrigerator.yaml
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "Custom: Refrigerator Express Mode Control"
|
||||||
|
description: >
|
||||||
|
Turns on express mode if the refrigerator temperature is too far from target.
|
||||||
|
Sends a notification when the difference exceeds the allowed threshold.
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
door_sensor:
|
||||||
|
name: Door Sensor
|
||||||
|
description: Binary sensor for refrigerator door
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: binary_sensor
|
||||||
|
|
||||||
|
temp_sensor:
|
||||||
|
name: Temperature Sensor
|
||||||
|
description: Sensor reporting current refrigerator temperature
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: sensor
|
||||||
|
|
||||||
|
climate_entity:
|
||||||
|
name: Refrigerator Climate Entity
|
||||||
|
description: Climate entity that provides target temperature
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: climate
|
||||||
|
|
||||||
|
device_name:
|
||||||
|
name: Device Name
|
||||||
|
description: Name of the device
|
||||||
|
default: 'Refrigerator'
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
express_switch:
|
||||||
|
name: Express Mode Switch
|
||||||
|
description: Switch entity to enable express mode
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: switch
|
||||||
|
|
||||||
|
max_diff:
|
||||||
|
name: Max Allowed Temperature Difference
|
||||||
|
description: Maximum difference between target and actual temperature before express mode is enabled
|
||||||
|
default: 3
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 10
|
||||||
|
step: 0.5
|
||||||
|
unit_of_measurement: "°C"
|
||||||
|
|
||||||
|
notify_target:
|
||||||
|
name: Notification Target
|
||||||
|
description: Device or service to send notifications
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: notify
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
mode: restart
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input temp_sensor
|
||||||
|
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input door_sensor
|
||||||
|
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input climate_entity
|
||||||
|
attribute: temperature
|
||||||
|
|
||||||
|
variables:
|
||||||
|
temp_sensor: !input temp_sensor
|
||||||
|
climate_entity: !input climate_entity
|
||||||
|
door_sensor: !input door_sensor
|
||||||
|
notify_target: !input notify_target
|
||||||
|
device_name: !input device_name
|
||||||
|
max_diff: !input max_diff
|
||||||
|
express_switch: !input express_switch
|
||||||
|
|
||||||
|
curr_temp: "{{ states(temp_sensor) | float(0) }}"
|
||||||
|
target_temp: "{{ state_attr(climate_entity, 'temperature') | float(0) }}"
|
||||||
|
diff: "{{ (curr_temp - target_temp) | abs }}"
|
||||||
|
temp_is_not_ok: "{{ diff > max_diff and is_state(door_sensor, 'off') }}"
|
||||||
|
|
||||||
|
action:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ temp_is_not_ok and is_state(express_switch, 'off') }}"
|
||||||
|
sequence:
|
||||||
|
- service: switch.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: !input express_switch
|
||||||
|
|
||||||
|
- service: notify.send_message
|
||||||
|
target:
|
||||||
|
entity_id: !input notify_target
|
||||||
|
data:
|
||||||
|
message: >
|
||||||
|
{{ device_name }}: обнаружена проблема температурного режима.
|
||||||
|
Текущая {{ curr_temp }}°C, Целевая {{ target_temp }}°C,
|
||||||
|
Разница {{ diff }}°C. Включение экпресс режима.
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ not temp_is_not_ok }}"
|
||||||
|
sequence:
|
||||||
|
- service: switch.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: !input express_switch
|
||||||
|
|
||||||
164
Common/Telegram Commands.yaml
Normal file
164
Common/Telegram Commands.yaml
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "Custom: Telegram Commands"
|
||||||
|
description: >
|
||||||
|
Sends a Telegram message with inline keyboard buttons to multiple chat IDs
|
||||||
|
when executed manually, and reacts to button presses by performing
|
||||||
|
the corresponding action (one per button).
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
commands_group:
|
||||||
|
name: "Commands"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
commands:
|
||||||
|
name: Commands
|
||||||
|
description: List of commands
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
answers:
|
||||||
|
name: Answers
|
||||||
|
description: List of answers (optional)
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
callbacks_group:
|
||||||
|
name: "Callbacks"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
button_1_callback:
|
||||||
|
name: Button 1 Callback
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
button_2_callback:
|
||||||
|
name: Button 2 Callback
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
button_3_callback:
|
||||||
|
name: Button 3 Callback
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
button_4_callback:
|
||||||
|
name: Button 4 Callback
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
button_5_callback:
|
||||||
|
name: Button 5 Callback
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
button_6_callback:
|
||||||
|
name: Button 6 Callback
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
button_7_callback:
|
||||||
|
name: Button 7 Callback
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
button_8_callback:
|
||||||
|
name: Button 8 Callback
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
mode: parallel
|
||||||
|
|
||||||
|
variables:
|
||||||
|
commands: !input commands
|
||||||
|
answers: !input answers
|
||||||
|
|
||||||
|
is_debug: false
|
||||||
|
command: "{{ trigger.event.data.command }}"
|
||||||
|
chat_id: "{{ trigger.event.data.chat_id }}"
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- platform: event
|
||||||
|
event_type: telegram_command
|
||||||
|
|
||||||
|
action:
|
||||||
|
- variables:
|
||||||
|
command_index: >
|
||||||
|
{% set res = -1 %}
|
||||||
|
{% if (commands | length >= 1 and command == commands[0] and button_1_callback != []) %}
|
||||||
|
{% set res = 0 %}
|
||||||
|
{% elif (commands | length >= 2 and command == commands[1] and button_2_callback != []) %}
|
||||||
|
{% set res = 1 %}
|
||||||
|
{% elif (commands | length >= 3 and command == commands[2] and button_3_callback != []) %}
|
||||||
|
{% set res = 2 %}
|
||||||
|
{% elif (commands | length >= 4 and command == commands[3] and button_4_callback != []) %}
|
||||||
|
{% set res = 3 %}
|
||||||
|
{% elif (commands | length >= 5 and command == commands[4] and button_5_callback != []) %}
|
||||||
|
{% set res = 4 %}
|
||||||
|
{% elif (commands | length >= 6 and command == commands[5] and button_6_callback != []) %}
|
||||||
|
{% set res = 5 %}
|
||||||
|
{% elif (commands | length >= 7 and command == commands[6] and button_7_callback != []) %}
|
||||||
|
{% set res = 6 %}
|
||||||
|
{% elif (commands | length >= 8 and command == commands[7] and button_8_callback != []) %}
|
||||||
|
{% set res = 7 %}
|
||||||
|
{% endif %}
|
||||||
|
{{ res }}
|
||||||
|
- choose:
|
||||||
|
- conditions: "{{ command_index == 0 }}"
|
||||||
|
sequence: !input button_1_callback
|
||||||
|
- conditions: "{{ command_index == 1 }}"
|
||||||
|
sequence: !input button_2_callback
|
||||||
|
- conditions: "{{ command_index == 2 }}"
|
||||||
|
sequence: !input button_3_callback
|
||||||
|
- conditions: "{{ command_index == 3 }}"
|
||||||
|
sequence: !input button_4_callback
|
||||||
|
- conditions: "{{ command_index == 4 }}"
|
||||||
|
sequence: !input button_5_callback
|
||||||
|
- conditions: "{{ command_index == 5 }}"
|
||||||
|
sequence: !input button_6_callback
|
||||||
|
- conditions: "{{ command_index == 6 }}"
|
||||||
|
sequence: !input button_7_callback
|
||||||
|
- conditions: "{{ command_index == 7 }}"
|
||||||
|
sequence: !input button_8_callback
|
||||||
|
|
||||||
|
- variables:
|
||||||
|
message: >
|
||||||
|
{% if command_index == -1 or answers | length <= command_index %}
|
||||||
|
{% else %}
|
||||||
|
{{ answers[command_index] }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Debug info (log if required)
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_debug }}"
|
||||||
|
sequence:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Debug Info (Telegram Commands)"
|
||||||
|
message: >
|
||||||
|
command_index = {{ command_index }},
|
||||||
|
commands = {{ commands }},
|
||||||
|
answers = {{ answers }},
|
||||||
|
message = {{ message }}
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions: "{{ message != '' }}"
|
||||||
|
sequence:
|
||||||
|
- service: telegram_bot.send_message
|
||||||
|
data:
|
||||||
|
target: "{{ chat_id }}"
|
||||||
|
message: "{{ message }}"
|
||||||
|
|
||||||
244
Common/Telegram Question.yaml
Normal file
244
Common/Telegram Question.yaml
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "Custom: Telegram Keyboard Action"
|
||||||
|
description: >
|
||||||
|
Sends a Telegram message with inline keyboard buttons to multiple chat IDs
|
||||||
|
when executed manually, and reacts to button presses by performing
|
||||||
|
the corresponding action (one per button).
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
chat_group:
|
||||||
|
name: "Chats"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
chat_ids:
|
||||||
|
name: Telegram Chat IDs
|
||||||
|
description: List of chat IDs
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
chat_entities:
|
||||||
|
name: Telegram Notification Targets
|
||||||
|
description: "List of notification entities (entity friendly names must be in format `<Name> (<ChatID>)`, for example `Alex (2132562465)` )"
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: notify
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
message_group:
|
||||||
|
name: "Message"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
keyboard_id:
|
||||||
|
name: Keyboard ID
|
||||||
|
description: Identifier of the keyboard. This identifier should be unique to distinguish keyboards.
|
||||||
|
default: 'keyboard'
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
message_text:
|
||||||
|
name: Message Text
|
||||||
|
description: Text of the message
|
||||||
|
default: '✉︎ Hey, that a new message'
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
buttons:
|
||||||
|
name: Buttons
|
||||||
|
description: List of buttons texts
|
||||||
|
default:
|
||||||
|
- "✔"
|
||||||
|
- "✖"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
answers:
|
||||||
|
name: Answers
|
||||||
|
description: List of answers (optional)
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
hide_keyboard_on_press:
|
||||||
|
name: Hide Keyboard On Any Button Press
|
||||||
|
description: Controls if keyboard must be hidden after any button press
|
||||||
|
default: true
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
|
||||||
|
hide_message_on_press:
|
||||||
|
name: Hide Message On Any Button Press
|
||||||
|
description: Control if the message must be hidden after any button press
|
||||||
|
default: false
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
|
||||||
|
callbacks_group:
|
||||||
|
name: "Callbacks"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
button_1_callback:
|
||||||
|
name: Button 1 Callback
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
button_2_callback:
|
||||||
|
name: Button 2 Callback
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
button_3_callback:
|
||||||
|
name: Button 3 Callback
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
button_4_callback:
|
||||||
|
name: Button 4 Callback
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
mode: parallel
|
||||||
|
|
||||||
|
variables:
|
||||||
|
buttons: !input buttons
|
||||||
|
keyboard_id: !input keyboard_id
|
||||||
|
hide_keyboard_on_press: !input hide_keyboard_on_press
|
||||||
|
hide_message_on_press: !input hide_message_on_press
|
||||||
|
answers: !input answers
|
||||||
|
|
||||||
|
is_action: "{{ trigger.platform is none }}"
|
||||||
|
should_call_keyboard_callback: >
|
||||||
|
{% if trigger.platform is none%}
|
||||||
|
false
|
||||||
|
{% else %}
|
||||||
|
{% set button_id = trigger.event.data.data %}
|
||||||
|
{{ button_id.startswith('/' ~ keyboard_id) }}
|
||||||
|
{% endif %}
|
||||||
|
is_debug: false
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- platform: event
|
||||||
|
event_type: telegram_callback
|
||||||
|
|
||||||
|
action:
|
||||||
|
|
||||||
|
# Debug info (log if required)
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_debug }}"
|
||||||
|
sequence:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Debug Info"
|
||||||
|
message: >
|
||||||
|
should_call_keyboard_callback = {{ should_call_keyboard_callback}}
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
condition: template
|
||||||
|
value_template: "{{ should_call_keyboard_callback | bool }}"
|
||||||
|
sequence:
|
||||||
|
- variables:
|
||||||
|
callback_data: "{{ trigger.event.data.data }}"
|
||||||
|
chat_id: "{{ trigger.event.data.chat_id }}"
|
||||||
|
idx: "{{ callback_data[callback_data | length - 1] | int }}"
|
||||||
|
- choose:
|
||||||
|
- conditions: "{{ idx == 0 and button_1_callback != [] }}"
|
||||||
|
sequence: !input button_1_callback
|
||||||
|
- conditions: "{{ idx == 1 and button_2_callback != [] }}"
|
||||||
|
sequence: !input button_2_callback
|
||||||
|
- conditions: "{{ idx == 2 and button_3_callback != [] }}"
|
||||||
|
sequence: !input button_3_callback
|
||||||
|
- conditions: "{{ idx == 3 and button_4_callback != [] }}"
|
||||||
|
sequence: !input button_4_callback
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions: "{{ idx != -1 and answers | length > idx and answers[idx] | length > 0 }}"
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
- conditions: "{{ hide_message_on_press }}"
|
||||||
|
sequence:
|
||||||
|
- service: telegram_bot.send_message
|
||||||
|
data:
|
||||||
|
target: "{{ chat_id }}"
|
||||||
|
message: "{{ answers[idx] }}"
|
||||||
|
|
||||||
|
default:
|
||||||
|
- service: telegram_bot.send_message
|
||||||
|
data:
|
||||||
|
target: "{{ chat_id }}"
|
||||||
|
message: "{{ answers[idx] }}"
|
||||||
|
reply_to_message_id: "{{ trigger.event.data.message.message_id }}"
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
# Remove keyboard.
|
||||||
|
- conditions: "{{ hide_message_on_press }}"
|
||||||
|
sequence:
|
||||||
|
- service: telegram_bot.delete_message
|
||||||
|
data:
|
||||||
|
chat_id: "{{ trigger.event.data.chat_id }}"
|
||||||
|
message_id: "{{ trigger.event.data.message.message_id }}"
|
||||||
|
|
||||||
|
# Remove keyboard.
|
||||||
|
- conditions: "{{ hide_keyboard_on_press }}"
|
||||||
|
sequence:
|
||||||
|
- service: telegram_bot.edit_replymarkup
|
||||||
|
data:
|
||||||
|
chat_id: "{{ trigger.event.data.chat_id }}"
|
||||||
|
message_id: "{{ trigger.event.data.message.message_id }}"
|
||||||
|
inline_keyboard: []
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
condition: template
|
||||||
|
value_template: "{{ is_action }}"
|
||||||
|
sequence:
|
||||||
|
- variables:
|
||||||
|
chat_entities: !input chat_entities
|
||||||
|
chat_ids_from_entities: >
|
||||||
|
{% set ns = namespace(numbers=[]) %}
|
||||||
|
{% for e in chat_entities %}
|
||||||
|
{% set friendly_name = state_attr(e, 'friendly_name') %}
|
||||||
|
{% set ns.numbers = ns.numbers + [ friendly_name | regex_findall_index('\((\d+)\)', 0) ] %}
|
||||||
|
{% endfor %}
|
||||||
|
{{ ns.numbers }}
|
||||||
|
|
||||||
|
chat_ids: !input chat_ids
|
||||||
|
result_chat_ids: "{{ chat_ids + chat_ids_from_entities }}"
|
||||||
|
|
||||||
|
message_text: !input message_text
|
||||||
|
keyboard_text: >
|
||||||
|
{% set ns = namespace(result = []) %}
|
||||||
|
{% for i in range(buttons|length) %}
|
||||||
|
{% set ns.result = ns.result + [(buttons[i] ~ ':/' ~ keyboard_id ~ i)] %}
|
||||||
|
{% endfor %}
|
||||||
|
{{ ns.result }}
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
# Broadcast
|
||||||
|
- conditions:
|
||||||
|
condition: template
|
||||||
|
value_template: "{{ result_chat_ids | length == 0 }}"
|
||||||
|
sequence:
|
||||||
|
- stop: "No chat ID(s) were resolved. No message will be sent."
|
||||||
|
|
||||||
|
# Target
|
||||||
|
- conditions:
|
||||||
|
condition: template
|
||||||
|
value_template: "{{ result_chat_ids | length != 0 }}"
|
||||||
|
sequence:
|
||||||
|
- service: telegram_bot.send_message
|
||||||
|
data:
|
||||||
|
target: "{{ result_chat_ids }}"
|
||||||
|
message: "{{ message_text }}"
|
||||||
|
inline_keyboard: "{{ keyboard_text }}"
|
||||||
|
|
||||||
|
|
||||||
80
Common/Time Of Day Controller.yaml
Normal file
80
Common/Time Of Day Controller.yaml
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
blueprint:
|
||||||
|
name: Time of Day State Machine (with Sensors)
|
||||||
|
description: >
|
||||||
|
Map a list of time-of-day states (input_select options) to a list of time entities or sensors.
|
||||||
|
At each threshold, set the input_select to the corresponding state.
|
||||||
|
Index-to-index mapping is guaranteed (state[0] ↔ time[0], state[1] ↔ time[1], etc).
|
||||||
|
Times can be input_datetime or sensors reporting HH:MM[:SS] values (e.g. sunset).
|
||||||
|
domain: automation
|
||||||
|
|
||||||
|
input:
|
||||||
|
tod_select:
|
||||||
|
name: Time of Day selector
|
||||||
|
description: The input_select entity that holds the current time-of-day state
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: input_select
|
||||||
|
|
||||||
|
tod_states:
|
||||||
|
name: Time of Day states
|
||||||
|
description: Ordered list of state names (must match input_select options)
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
tod_times:
|
||||||
|
name: Time of Day times/sensors
|
||||||
|
description: Ordered list of input_datetime or sensor entities (same length as states)
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
mode: restart
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
# Trigger whenever any time-of-day entity changes
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input tod_times
|
||||||
|
# Also trigger every minute to re-evaluate
|
||||||
|
- platform: time_pattern
|
||||||
|
minutes: "/1"
|
||||||
|
|
||||||
|
variables:
|
||||||
|
states: !input tod_states
|
||||||
|
times: !input tod_times
|
||||||
|
tod_select: !input tod_select
|
||||||
|
|
||||||
|
# Convert each entity state into seconds since midnight
|
||||||
|
thresholds: >
|
||||||
|
{% set out = [] %}
|
||||||
|
{% for t in times %}
|
||||||
|
{% set val = states(t) | as_datetime %}
|
||||||
|
{% if val is not none %}
|
||||||
|
{% set sec = dt.hour * 3600 + dt.minute * 60 + dt.second %}
|
||||||
|
{% set out = out + [sec] %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{{ out }}
|
||||||
|
|
||||||
|
now_sec: >
|
||||||
|
{% set n = now() %}
|
||||||
|
{{ n.hour * 3600 + n.minute * 60 + n.second }}
|
||||||
|
|
||||||
|
# Find the correct index based on current time
|
||||||
|
current_index: >
|
||||||
|
{% set idx = 0 %}
|
||||||
|
{% for i in range(thresholds|length) %}
|
||||||
|
{% if now_sec >= thresholds[i] %}
|
||||||
|
{% set idx = i %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{{ idx }}
|
||||||
|
|
||||||
|
current_state: "{{ states[current_index] }}"
|
||||||
|
|
||||||
|
action:
|
||||||
|
- service: input_select.select_option
|
||||||
|
target:
|
||||||
|
entity_id: "{{ tod_select }}"
|
||||||
|
data:
|
||||||
|
option: "{{ current_state }}"
|
||||||
79
Common/Track Abnormal Plug Activity.yaml
Normal file
79
Common/Track Abnormal Plug Activity.yaml
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "Custom: Power Spike Tracker"
|
||||||
|
description: >
|
||||||
|
Monitors a list of power sensors and triggers when consumption spikes
|
||||||
|
beyond a defined ratio compared to the previous reading. Optionally
|
||||||
|
turns off the associated switch.
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
power_sensors:
|
||||||
|
name: Power Sensors
|
||||||
|
description: 'List of power sensors to monitor. Switch entity ids will be calculated by replacing `sensor.` and `_power` substrings. I.e. for `sensor.my_switch_power` switch entity must be `switch.my_switch`.'
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: sensor
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
spike_ratio:
|
||||||
|
name: Power Spike Ratio
|
||||||
|
description: Ratio threshold (e.g. 2.0 means power doubled)
|
||||||
|
default: 2.0
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1.0
|
||||||
|
max: 10.0
|
||||||
|
step: 0.1
|
||||||
|
|
||||||
|
threshold_value:
|
||||||
|
name: Minimum Power Threshold
|
||||||
|
description: Ignore spikes if current power is below this value
|
||||||
|
default: 5
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 5000
|
||||||
|
step: 1
|
||||||
|
unit_of_measurement: "W"
|
||||||
|
|
||||||
|
auto_turn_off:
|
||||||
|
name: Auto Turn Off Switch
|
||||||
|
description: 'If true, turn off the switch linked to the sensor that spiked'
|
||||||
|
default: false
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
|
||||||
|
mode: restart
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input power_sensors
|
||||||
|
|
||||||
|
variables:
|
||||||
|
spike_ratio: !input spike_ratio
|
||||||
|
auto_turn_off: !input auto_turn_off
|
||||||
|
threshold_value: !input threshold_value
|
||||||
|
entity: "{{ trigger.entity_id }}"
|
||||||
|
prev: "{{ trigger.from_state.state | float(0) }}"
|
||||||
|
curr: "{{ trigger.to_state.state | float(0) }}"
|
||||||
|
# Derive switch name if convention is consistent (sensor.<name>_power → switch.<name>)
|
||||||
|
switch_entity: >
|
||||||
|
{{ entity | regex_replace('^sensor\\.', 'switch.') | regex_replace('_power$', '') }}
|
||||||
|
|
||||||
|
condition:
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{{ curr > threshold_value and prev > 0 and (curr / prev) >= spike_ratio }}
|
||||||
|
|
||||||
|
action:
|
||||||
|
- service: notify.notify
|
||||||
|
data:
|
||||||
|
message: >
|
||||||
|
Power spike detected on {{ entity }}:
|
||||||
|
{{ prev }}W → {{ curr }}W (ratio {{ (curr/prev) | round(2) }})
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions: "{{ auto_turn_off }}"
|
||||||
|
sequence:
|
||||||
|
- service: switch.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: "{{ switch_entity }}"
|
||||||
374
Common/Washing Machine.yaml
Normal file
374
Common/Washing Machine.yaml
Normal file
@@ -0,0 +1,374 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "Custom: Washing Machine Notifications"
|
||||||
|
description: >
|
||||||
|
Sends notifications when washing starts (with mode details),
|
||||||
|
when errors occur, and when run completes.
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
time_group:
|
||||||
|
name: "Time"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
remaining_time_sensor:
|
||||||
|
name: Remaining Time Sensor
|
||||||
|
description: "Sensor that contains remaining time in format `hh:mm::ss`. Note: `-`, 'unknown' values means remaining time is not available."
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: sensor
|
||||||
|
|
||||||
|
run_state_sensor:
|
||||||
|
name: Run State Sensor
|
||||||
|
description: "Sensor that run state of the device"
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: sensor
|
||||||
|
|
||||||
|
run_state_completion_id:
|
||||||
|
name: Run State Completion Id
|
||||||
|
description: "Identifier of run state that indicates that run is completed"
|
||||||
|
default: 'Цикл завершен.'
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
notify_time_to_end:
|
||||||
|
name: Notify Time-to-End (minutes)
|
||||||
|
description: "Send notification if run is about to be finished"
|
||||||
|
default: 10
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 60
|
||||||
|
unit_of_measurement: minutes
|
||||||
|
mode: slider
|
||||||
|
|
||||||
|
persistent_state:
|
||||||
|
name: "Persistent State"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
automation_state_entity:
|
||||||
|
name: Automation state entity
|
||||||
|
description: "`input_text` that stores the automation state in JSON format. Required for all features proper functioning. `Doesn't require specific initial state, values of the entity can be empty`"
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: input_text
|
||||||
|
|
||||||
|
automation_state_placeholder_key:
|
||||||
|
name: Automation state placeholder key
|
||||||
|
description: Overrides key for persistent storage if not empty. By default uses identifier of target light, otherwise uses constant. `Don't override it if you don't understand the meaning`
|
||||||
|
default: ''
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
notification_group:
|
||||||
|
name: "Notification"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
input_device_name:
|
||||||
|
name: "Device Name"
|
||||||
|
description: Device name (used for notifications)
|
||||||
|
default: "Стиральная машина"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
notify_target:
|
||||||
|
name: Notification Target
|
||||||
|
description: Device or service to send notifications
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: notify
|
||||||
|
|
||||||
|
info_group:
|
||||||
|
name: "Info"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
non_running_state_ids:
|
||||||
|
name: Non Running State ID(s)
|
||||||
|
description: "List of run state ID(s) that indicates that device is not actually doing its direct job"
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
preparation_state_id:
|
||||||
|
name: Preparation Mode State ID (optional)
|
||||||
|
description: "Optional run state ID that indicates that device is preparing to run"
|
||||||
|
default: 'Подготовка к сушке'
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
error_message_sensor:
|
||||||
|
name: Error Message Sensor
|
||||||
|
description: "Sensor that reports possible error message"
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: sensor
|
||||||
|
|
||||||
|
tub_clean_counter_sensor:
|
||||||
|
name: Tub Clean Counter Sensor (Optional)
|
||||||
|
description: "Sensor that reports tub clean counter value"
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- sensor
|
||||||
|
- input_number
|
||||||
|
|
||||||
|
tub_clean_counter_threshold:
|
||||||
|
name: Tub Clean Counter Threshold
|
||||||
|
description: "Threshold for tub clean counter value when notification should be sent. Zero means no reports."
|
||||||
|
default: 30
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 100
|
||||||
|
mode: slider
|
||||||
|
|
||||||
|
details_group:
|
||||||
|
name: "Details"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
startup_info_sensors:
|
||||||
|
name: Startup Info Sensors (Optional)
|
||||||
|
description: "A list of sensor with some details that will be reported on machine startup notification"
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- sensor
|
||||||
|
- binary_sensor
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
startup_info_texts:
|
||||||
|
name: Startup Info Texts
|
||||||
|
description: "List of texts associated with `Startup Info Sensors` (one per sensor)"
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
mode: restart
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
# Remaining time changes
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input remaining_time_sensor
|
||||||
|
# Error message appears
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input error_message_sensor
|
||||||
|
# Run state
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input run_state_sensor
|
||||||
|
# Tub clean sensor changed
|
||||||
|
- platform: state
|
||||||
|
entity_id: !input tub_clean_counter_sensor
|
||||||
|
|
||||||
|
condition: []
|
||||||
|
|
||||||
|
|
||||||
|
variables:
|
||||||
|
# JSON state constants
|
||||||
|
state_notification_about_renaming_time_sent: 'nart'
|
||||||
|
state_notification_about_start_sent: 'nass'
|
||||||
|
state_notification_about_preparation_sent: 'naps'
|
||||||
|
|
||||||
|
# Inputs
|
||||||
|
run_state_sensor: !input run_state_sensor
|
||||||
|
non_running_state_ids: !input non_running_state_ids
|
||||||
|
preparation_state_id: !input preparation_state_id
|
||||||
|
error_message_sensor: !input error_message_sensor
|
||||||
|
remaining_time_sensor: !input remaining_time_sensor
|
||||||
|
notify_target: !input notify_target
|
||||||
|
notify_time_to_end: !input notify_time_to_end
|
||||||
|
input_device_name: !input input_device_name
|
||||||
|
tub_clean_counter_sensor: !input tub_clean_counter_sensor
|
||||||
|
tub_clean_counter_threshold: !input tub_clean_counter_threshold
|
||||||
|
run_state_completion_id: !input run_state_completion_id
|
||||||
|
|
||||||
|
# States
|
||||||
|
remaining: "{{ states(remaining_time_sensor) }}"
|
||||||
|
device_name: "{{ input_device_name }}"
|
||||||
|
run_state: "{{ states(run_state_sensor) }}"
|
||||||
|
is_running: >
|
||||||
|
{{ run_state not in ['unknown', 'unavailable', 'waiting', '-']
|
||||||
|
and run_state not in non_running_state_ids
|
||||||
|
and run_state != preparation_state_id
|
||||||
|
and run_state != run_state_completion_id
|
||||||
|
and remaining not in ['unknown', 'unavailable'] }}
|
||||||
|
remaining_time_in_minutes: >
|
||||||
|
{% if remaining not in ['unknown', 'unavailable'] %}
|
||||||
|
{% set parts = remaining.split(':') %}
|
||||||
|
{% set total = parts[0]|int * 60 + parts[1]|int %}
|
||||||
|
{{ total }}
|
||||||
|
{% else %}
|
||||||
|
0
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# JSON global state.
|
||||||
|
automation_state_entity: !input automation_state_entity
|
||||||
|
automation_state_global: >
|
||||||
|
{% set text = states(automation_state_entity) | string %}
|
||||||
|
{% if text in ['unknown','unavailable','none',''] %}
|
||||||
|
{{ dict() }}
|
||||||
|
{% else %}
|
||||||
|
{{ text | from_json }}
|
||||||
|
{% endif %}
|
||||||
|
automation_state_placeholder_key: !input automation_state_placeholder_key
|
||||||
|
automation_state_key: >
|
||||||
|
{% if automation_state_placeholder_key != '' %}
|
||||||
|
{{ automation_state_placeholder_key }}
|
||||||
|
{% else %}
|
||||||
|
{{ remaining_time_sensor }}
|
||||||
|
{% endif %}
|
||||||
|
automation_state: "{{ automation_state_global.get(automation_state_key, dict()) }}"
|
||||||
|
|
||||||
|
is_debug: false
|
||||||
|
|
||||||
|
action:
|
||||||
|
|
||||||
|
# Debug info (log if required)
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_debug }}"
|
||||||
|
sequence:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Debug Info"
|
||||||
|
message: >
|
||||||
|
run_state = {{ run_state }},
|
||||||
|
non_running_state_ids = {{ non_running_state_ids }},
|
||||||
|
remaining_time = {{ states(remaining_time_sensor) }},
|
||||||
|
is_running = {{ is_running }},
|
||||||
|
t = {{ automation_state.get(state_notification_about_start_sent, false) }}
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
# 🟢 Case 1: Washing started
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ not automation_state.get(state_notification_about_start_sent, false) and is_running }}"
|
||||||
|
sequence:
|
||||||
|
- variables:
|
||||||
|
startup_info_sensors: !input startup_info_sensors
|
||||||
|
startup_info_texts: !input startup_info_texts
|
||||||
|
message: >
|
||||||
|
{% set ns = namespace(text = '🧺 ' ~ device_name ~ ': старт. Длительность: `' ~ remaining ~ '`.') %}
|
||||||
|
{% for i in range(startup_info_sensors | count) %}
|
||||||
|
{% set ns.text = ns.text ~ ' ' ~ startup_info_texts[i] ~ ': [' ~ states(startup_info_sensors[i]) ~ '].' %}
|
||||||
|
{% endfor %}
|
||||||
|
{{ ns.text }}
|
||||||
|
|
||||||
|
- service: notify.send_message
|
||||||
|
target:
|
||||||
|
entity_id: !input notify_target
|
||||||
|
data:
|
||||||
|
message: "{{ message }}"
|
||||||
|
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ automation_state_entity }}"
|
||||||
|
data:
|
||||||
|
value: >
|
||||||
|
{% set new_automation_state = (automation_state | combine({ state_notification_about_start_sent: true })) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
||||||
|
|
||||||
|
# ✅ Case 2: Run completed
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{{ not is_running
|
||||||
|
and automation_state.get(state_notification_about_start_sent, false)
|
||||||
|
and (states(run_state_sensor) in [run_state_completion_id, 'unknown', '-'] or states(remaining_time_sensor) in ['unknown', '-']) }}
|
||||||
|
sequence:
|
||||||
|
|
||||||
|
- service: notify.send_message
|
||||||
|
target:
|
||||||
|
entity_id: !input notify_target
|
||||||
|
data:
|
||||||
|
message: >
|
||||||
|
🟢 {{ device_name }}: завершено. Не забудьте достать вещи!
|
||||||
|
|
||||||
|
# Reset the state.
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ automation_state_entity }}"
|
||||||
|
data:
|
||||||
|
value: >
|
||||||
|
{% set new_automation_state = (automation_state | combine({ state_notification_about_renaming_time_sent: false, state_notification_about_start_sent: false, state_notification_about_preparation_sent: false })) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
||||||
|
|
||||||
|
# ✅ Case 3: Preparation
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{{ preparation_state_id != ''
|
||||||
|
and states(run_state_sensor) == preparation_state_id
|
||||||
|
and not automation_state.get(state_notification_about_preparation_sent, false) }}
|
||||||
|
sequence:
|
||||||
|
|
||||||
|
# Reset the state.
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ automation_state_entity }}"
|
||||||
|
data:
|
||||||
|
value: >
|
||||||
|
{% set new_automation_state = (automation_state | combine({ state_notification_about_preparation_sent: true })) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
||||||
|
|
||||||
|
- service: notify.send_message
|
||||||
|
target:
|
||||||
|
entity_id: !input notify_target
|
||||||
|
data:
|
||||||
|
message: >
|
||||||
|
⚙️ {{ device_name }}: подготовка активирована!
|
||||||
|
|
||||||
|
# 🔴 Case 4: Error message
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.entity_id == error_message_sensor and error|length > 0 }}"
|
||||||
|
sequence:
|
||||||
|
- variables:
|
||||||
|
error: "{{ states(error_message_sensor) }}"
|
||||||
|
- service: notify.send_message
|
||||||
|
target:
|
||||||
|
entity_id: !input notify_target
|
||||||
|
data:
|
||||||
|
message: >
|
||||||
|
⚠️ {{ device_name }}: ошибка. Детали: {{ error }}. Для более подробной информации обратитесь к приложению LG ThinQ.
|
||||||
|
|
||||||
|
# ⏰ Case 5: Notify before end
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{% if not automation_state.get(state_notification_about_renaming_time_sent, false) and is_running %}
|
||||||
|
{{ remaining_time_in_minutes <= notify_time_to_end }}
|
||||||
|
{% else %}
|
||||||
|
{{ false }}
|
||||||
|
{% endif %}
|
||||||
|
sequence:
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ automation_state_entity }}"
|
||||||
|
data:
|
||||||
|
value: >
|
||||||
|
{% set new_automation_state = (automation_state | combine({ state_notification_about_renaming_time_sent: true })) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
||||||
|
|
||||||
|
- service: notify.send_message
|
||||||
|
target:
|
||||||
|
entity_id: !input notify_target
|
||||||
|
data:
|
||||||
|
message: >
|
||||||
|
🟢 {{ device_name }}: завершение через {{ remaining.split(':')[1] }} минут.
|
||||||
|
|
||||||
|
# 🔴 Case 6: Tub clean notification
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.entity_id == tub_clean_counter_sensor and tub_clean_counter_threshold != 0 and (states(tub_clean_counter_sensor) | int) > tub_clean_counter_threshold }}"
|
||||||
|
sequence:
|
||||||
|
- service: notify.send_message
|
||||||
|
target:
|
||||||
|
entity_id: !input notify_target
|
||||||
|
data:
|
||||||
|
message: >
|
||||||
|
⚠️ {{ device_name }}: внимание. Необходима чистка барабана.
|
||||||
|
Число стирок: {{ states(tub_clean_counter_sensor) | int }}.
|
||||||
|
Допустимый предел: {{ tub_clean_counter_threshold }}.
|
||||||
32
Test/TestBp.yaml
Normal file
32
Test/TestBp.yaml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
blueprint:
|
||||||
|
name: MQTT Multi-Topic Listener
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
mqtt_topics:
|
||||||
|
name: MQTT Topics
|
||||||
|
description: List of topics to react to
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
multiple: true
|
||||||
|
default: []
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- platform: mqtt
|
||||||
|
topic: "#"
|
||||||
|
|
||||||
|
action:
|
||||||
|
- variables:
|
||||||
|
mqtt_topics: !input mqtt_topics
|
||||||
|
received_topic: "{{ trigger.topic }}"
|
||||||
|
received_payload: "{{ trigger.payload }}"
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{{ received_topic in mqtt_topics }}
|
||||||
|
sequence:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Debug Info"
|
||||||
|
message: >
|
||||||
|
{{ trigger.topic }}
|
||||||
216
Zigbee/MQTT Button Control.yaml
Normal file
216
Zigbee/MQTT Button Control.yaml
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
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 interructed switch/light.
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
|
||||||
|
mqtt_group:
|
||||||
|
name: "MQTT"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
mqtt_topic:
|
||||||
|
name: MQTT Topic
|
||||||
|
description: The MQTT topic for your Zigbee button (e.g., zigbee2mqtt/my_button1).
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
mqtt_topic2:
|
||||||
|
name: MQTT Topic 2
|
||||||
|
description: The MQTT topic for your Zigbee button (e.g., zigbee2mqtt/my_button2).
|
||||||
|
default: fake
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
devices:
|
||||||
|
name: "Primary"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
action_ids:
|
||||||
|
name: Action IDs
|
||||||
|
description: The action IDs that must map to lights (action → light)
|
||||||
|
default: []
|
||||||
|
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:
|
||||||
|
- light
|
||||||
|
- switch
|
||||||
|
- input_boolean
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
name: "Outputs"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
last_interacted_text:
|
||||||
|
name: Last Interacted Entity Text Helper (optional)
|
||||||
|
description: "`input_text` entity that will store last enabled entity"
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: input_text
|
||||||
|
|
||||||
|
common:
|
||||||
|
name: "Common"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
timeout_for_indication_blink:
|
||||||
|
name: "Timeout for indicator blink"
|
||||||
|
description: If not zero does blink when button with already enabled light is pressed to indicate that the light is active now if elapsed time from last action is greater then the specified value
|
||||||
|
default: 10
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 100
|
||||||
|
step: 1
|
||||||
|
unit_of_measurement: "s"
|
||||||
|
|
||||||
|
blink_count:
|
||||||
|
name: Count of blinks
|
||||||
|
description: "Count of blinks to indicate active light"
|
||||||
|
default: 3
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 5
|
||||||
|
step: 1
|
||||||
|
|
||||||
|
blink_interval:
|
||||||
|
name: Interval between blinks
|
||||||
|
description: "Interval between indicator blinks (in ms)"
|
||||||
|
default: 250
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 1000
|
||||||
|
step: 50
|
||||||
|
unit_of_measurement: "ms"
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- platform: mqtt
|
||||||
|
topic: !input mqtt_topic
|
||||||
|
- platform: mqtt
|
||||||
|
topic: !input mqtt_topic2
|
||||||
|
enabled: "{{ mqtt_topic2 != '' }}"
|
||||||
|
|
||||||
|
mode: restart
|
||||||
|
|
||||||
|
condition:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ 'action' in trigger.payload_json }}"
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ target_entity is not none }}"
|
||||||
|
sequence:
|
||||||
|
- variables:
|
||||||
|
entity_type: "{{ target_entity.split('.')[0] }}"
|
||||||
|
|
||||||
|
- service: input_text.set_value
|
||||||
|
data:
|
||||||
|
entity_id: "{{ last_interacted_text }}"
|
||||||
|
value: "{{ target_entity }}"
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
# Light
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ entity_type == 'light' }}"
|
||||||
|
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
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_debug }}"
|
||||||
|
sequence:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Debug Info"
|
||||||
|
message: >
|
||||||
|
seconds_elapsed = {{ seconds_elapsed }},
|
||||||
|
should_blink = {{ should_blink }}
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
# Blink
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ should_blink and is_light_on }}"
|
||||||
|
sequence:
|
||||||
|
- repeat:
|
||||||
|
count: "{{ blink_count }}"
|
||||||
|
sequence:
|
||||||
|
|
||||||
|
- service: light.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: "{{ target_entity }}"
|
||||||
|
data:
|
||||||
|
transition: 0
|
||||||
|
- delay:
|
||||||
|
milliseconds: "{{ blink_timeout }}"
|
||||||
|
|
||||||
|
- service: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ target_entity }}"
|
||||||
|
data:
|
||||||
|
transition: 0
|
||||||
|
- delay:
|
||||||
|
milliseconds: "{{ blink_timeout }}"
|
||||||
|
|
||||||
|
# Actually toggle
|
||||||
|
default:
|
||||||
|
- service: light.toggle
|
||||||
|
target:
|
||||||
|
entity_id: "{{ target_entity }}"
|
||||||
|
|
||||||
|
# Switch
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ entity_type == 'switch' }}"
|
||||||
|
sequence:
|
||||||
|
- service: switch.toggle
|
||||||
|
target:
|
||||||
|
entity_id: "{{ target_entity }}"
|
||||||
|
|
||||||
|
# Input Boolean
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ entity_type == 'input_boolean' }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_boolean.toggle
|
||||||
|
target:
|
||||||
|
entity_id: "{{ target_entity }}"
|
||||||
213
Zigbee/MQTT Generic Control.yaml
Normal file
213
Zigbee/MQTT Generic Control.yaml
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "Custom: MQTT Generic Control"
|
||||||
|
description: >
|
||||||
|
Triggered by MQTT messages. Supports up to 8 custom action IDs with optional callbacks.
|
||||||
|
domain: automation
|
||||||
|
|
||||||
|
input:
|
||||||
|
mqtt_group:
|
||||||
|
name: "MQTT"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
mqtt_topic:
|
||||||
|
name: MQTT Topic 1
|
||||||
|
description: The MQTT topic to listen to
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
|
||||||
|
mqtt_topic2:
|
||||||
|
name: MQTT Topic 2
|
||||||
|
description: The MQTT topic to listen to
|
||||||
|
default: 'fake'
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
|
||||||
|
mqtt_topic3:
|
||||||
|
name: MQTT Topic 3
|
||||||
|
description: The MQTT topic to listen to
|
||||||
|
default: 'fake'
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
|
||||||
|
mqtt_topic4:
|
||||||
|
name: MQTT Topic 4
|
||||||
|
description: The MQTT topic to listen to
|
||||||
|
default: 'fake'
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
|
||||||
|
actions_group:
|
||||||
|
name: "Actions"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
action_id_1:
|
||||||
|
name: Action ID 1
|
||||||
|
description: Value of `payload_json.action` that triggers callback 1
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
action_callback_1:
|
||||||
|
name: Action Callback 1
|
||||||
|
description: Actions to run when Action ID 1 is received
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
action_id_2:
|
||||||
|
name: Action ID 2
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
action_callback_2:
|
||||||
|
name: Action Callback 2
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
action_id_3:
|
||||||
|
name: Action ID 3
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
action_callback_3:
|
||||||
|
name: Action Callback 3
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
action_id_4:
|
||||||
|
name: Action ID 4
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
action_callback_4:
|
||||||
|
name: Action Callback 4
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
action_id_5:
|
||||||
|
name: Action ID 5
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
action_callback_5:
|
||||||
|
name: Action Callback 5
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
action_id_6:
|
||||||
|
name: Action ID 6
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
action_callback_6:
|
||||||
|
name: Action Callback 6
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
action_id_7:
|
||||||
|
name: Action ID 7
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
action_callback_7:
|
||||||
|
name: Action Callback 7
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
action_id_8:
|
||||||
|
name: Action ID 8
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
action_callback_8:
|
||||||
|
name: Action Callback 8
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
mode: restart
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- platform: mqtt
|
||||||
|
topic: !input mqtt_topic
|
||||||
|
- platform: mqtt
|
||||||
|
topic: !input mqtt_topic2
|
||||||
|
enabled: "{{ mqtt_topic2 != '' }}"
|
||||||
|
- platform: mqtt
|
||||||
|
topic: !input mqtt_topic3
|
||||||
|
enabled: "{{ mqtt_topic3 != '' }}"
|
||||||
|
- platform: mqtt
|
||||||
|
topic: !input mqtt_topic4
|
||||||
|
enabled: "{{ mqtt_topic4 != '' }}"
|
||||||
|
|
||||||
|
variables:
|
||||||
|
action_id: "{{ trigger.payload_json.action }}"
|
||||||
|
action_id_1: !input action_id_1
|
||||||
|
action_id_2: !input action_id_2
|
||||||
|
action_id_3: !input action_id_3
|
||||||
|
action_id_4: !input action_id_4
|
||||||
|
action_id_5: !input action_id_5
|
||||||
|
action_id_6: !input action_id_6
|
||||||
|
action_id_7: !input action_id_7
|
||||||
|
action_id_8: !input action_id_8
|
||||||
|
is_debug: false
|
||||||
|
|
||||||
|
action:
|
||||||
|
# Debug info (log if required)
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_debug }}"
|
||||||
|
sequence:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Debug Info"
|
||||||
|
message: >
|
||||||
|
action = {{ action_id }},
|
||||||
|
1 = {{ action_id_1 }}
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_id_1 != '' and action_id == action_id_1 }}"
|
||||||
|
sequence: !input action_callback_1
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_id_2 != '' and action_id == action_id_2 }}"
|
||||||
|
sequence: !input action_callback_2
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_id_3 != '' and action_id == action_id_3 }}"
|
||||||
|
sequence: !input action_callback_3
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_id_4 != '' and action_id == action_id_4 }}"
|
||||||
|
sequence: !input action_callback_4
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_id_5 != '' and action_id == action_id_5 }}"
|
||||||
|
sequence: !input action_callback_5
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_id_6 != '' and action_id == action_id_6 }}"
|
||||||
|
sequence: !input action_callback_6
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_id_7 != '' and action_id == action_id_7 }}"
|
||||||
|
sequence: !input action_callback_7
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_id_8 != '' and action_id == action_id_8 }}"
|
||||||
|
sequence: !input action_callback_8
|
||||||
2276
Zigbee/MQTT Light Control.yaml
Normal file
2276
Zigbee/MQTT Light Control.yaml
Normal file
File diff suppressed because it is too large
Load Diff
372
Zigbee/MQTT Light Selector.yaml
Normal file
372
Zigbee/MQTT Light Selector.yaml
Normal file
@@ -0,0 +1,372 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "Custom: MQTT Light Selector"
|
||||||
|
description: >
|
||||||
|
Cycle through a list of lights using MQTT button events (up/down).
|
||||||
|
Selected light is stored in an input_text helper and flashes N times
|
||||||
|
with Z interval when selected.
|
||||||
|
domain: automation
|
||||||
|
|
||||||
|
input:
|
||||||
|
devices:
|
||||||
|
name: "Devices"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
mqtt_topic:
|
||||||
|
name: MQTT Topic
|
||||||
|
description: Topic where button events are published
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
mqtt_topic2:
|
||||||
|
name: MQTT Topic
|
||||||
|
description: Topic where button events are published
|
||||||
|
default: 'fake'
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
|
||||||
|
lights:
|
||||||
|
name: "Lights"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
lights:
|
||||||
|
name: Lights
|
||||||
|
description: List of lights to cycle through
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: light
|
||||||
|
multiple: true
|
||||||
|
|
||||||
|
persistent_state:
|
||||||
|
name: "Persiatent State"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
selected_light_helper:
|
||||||
|
name: Selected Light Helper
|
||||||
|
description: Input_text entity to store the selected light
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: input_text
|
||||||
|
|
||||||
|
automation_state_entity:
|
||||||
|
name: Automation state entity
|
||||||
|
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.`
|
||||||
|
default: null
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain:
|
||||||
|
- input_text
|
||||||
|
|
||||||
|
action_ids:
|
||||||
|
name: "Action IDs"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
action_up:
|
||||||
|
name: Up Action Identifier
|
||||||
|
description: Payload string for "next light"
|
||||||
|
default: ''
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
|
||||||
|
action_down:
|
||||||
|
name: Down Action Identifier
|
||||||
|
description: Payload string for "previous light"
|
||||||
|
default: ''
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
|
||||||
|
action_remind:
|
||||||
|
name: Remind Action Identifier
|
||||||
|
description: Payload string for "current light"
|
||||||
|
default: ''
|
||||||
|
selector:
|
||||||
|
text: {}
|
||||||
|
|
||||||
|
params:
|
||||||
|
name: "Parameters"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
transition:
|
||||||
|
name: Transition Time (ms)
|
||||||
|
description: Duration of brightness transition
|
||||||
|
default: 0
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 500
|
||||||
|
step: 10
|
||||||
|
unit_of_measurement: ms
|
||||||
|
|
||||||
|
remind_using_up_down_delay:
|
||||||
|
name: Force Remind Using Up/Down Delay
|
||||||
|
description: "If specified then `Up`/`Down` action will work like `Remind` in case if duration from the last action was greater then this value"
|
||||||
|
default: 0
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 100
|
||||||
|
step: 1
|
||||||
|
unit_of_measurement: s
|
||||||
|
|
||||||
|
flash_count:
|
||||||
|
name: Flash Count
|
||||||
|
description: Number of times to flash selected light
|
||||||
|
default: 2
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 10
|
||||||
|
step: 1
|
||||||
|
|
||||||
|
flash_interval_ms:
|
||||||
|
name: Flash Interval (ms)
|
||||||
|
description: Interval between flashes in milliseconds
|
||||||
|
default: 500
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 100
|
||||||
|
max: 2000
|
||||||
|
step: 100
|
||||||
|
unit_of_measurement: ms
|
||||||
|
|
||||||
|
actions_group:
|
||||||
|
name: "Actions"
|
||||||
|
collapsed: false
|
||||||
|
input:
|
||||||
|
condition_action:
|
||||||
|
name: Extra Condition
|
||||||
|
description: Optional condition to check before running actions
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
condition: {}
|
||||||
|
|
||||||
|
callback_action:
|
||||||
|
name: Callback Action
|
||||||
|
description: Optional action to run after main sequence
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- platform: mqtt
|
||||||
|
topic: !input mqtt_topic
|
||||||
|
id: "mqtt"
|
||||||
|
- platform: mqtt
|
||||||
|
topic: !input mqtt_topic2
|
||||||
|
id: "mqtt"
|
||||||
|
|
||||||
|
condition: !input condition_action
|
||||||
|
|
||||||
|
mode: restart
|
||||||
|
|
||||||
|
variables:
|
||||||
|
|
||||||
|
# Constants.
|
||||||
|
is_debug: false
|
||||||
|
|
||||||
|
# Defines.
|
||||||
|
lights: !input lights
|
||||||
|
helper: !input selected_light_helper
|
||||||
|
action_up: !input action_up
|
||||||
|
action_down: !input action_down
|
||||||
|
action_remind: !input action_remind
|
||||||
|
flash_count: !input flash_count
|
||||||
|
flash_interval_ms: !input flash_interval_ms
|
||||||
|
transition: !input transition
|
||||||
|
remind_using_up_down_delay: !input remind_using_up_down_delay
|
||||||
|
mqtt_topic: !input mqtt_topic
|
||||||
|
|
||||||
|
# JSON global state.
|
||||||
|
state_key_last_was_on: 'lwo'
|
||||||
|
state_key_last_light: 'll'
|
||||||
|
state_key_last_select_action_datetime: 'lsadt'
|
||||||
|
automation_state_entity: !input automation_state_entity
|
||||||
|
automation_state_global: >
|
||||||
|
{% if automation_state_entity is not none %}
|
||||||
|
{% set text = states(automation_state_entity) | string %}
|
||||||
|
{% if text in ['unknown','unavailable','none',''] %}
|
||||||
|
{{ dict() }}
|
||||||
|
{% else %}
|
||||||
|
{{ text | from_json }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{{ dict() }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
current_datetime: "{{ now() }}"
|
||||||
|
|
||||||
|
# TODO alexeid: it's better to use mqtt_topic as key, but cyrilic characters require use of tranliteration
|
||||||
|
automation_state_key: "mqtt_light_selector:{{ lights[0] }}"
|
||||||
|
automation_state: "{{ automation_state_global.get(automation_state_key, dict()) if automation_state_key != '' else dict() }}"
|
||||||
|
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_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_light: >
|
||||||
|
{% set entity_id = states(helper) %}
|
||||||
|
{{ 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 }}
|
||||||
|
|
||||||
|
action:
|
||||||
|
# Debug info (log if required)
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_debug }}"
|
||||||
|
sequence:
|
||||||
|
- service: persistent_notification.create
|
||||||
|
data:
|
||||||
|
title: "Debug Info"
|
||||||
|
message: "automation_state_key = {{ automation_state_key }}"
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
# MQTT -> handle the message
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.id == 'mqtt' }}"
|
||||||
|
sequence:
|
||||||
|
- variables:
|
||||||
|
action_id: "{{ trigger.payload_json.action }}"
|
||||||
|
# Don't forget to restore last light state
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ state_last_light != '' }}"
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ state_last_was_on }}"
|
||||||
|
sequence:
|
||||||
|
- service: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ state_last_light }}"
|
||||||
|
data:
|
||||||
|
transition: "{{ transition }}"
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ not state_last_was_on }}"
|
||||||
|
sequence:
|
||||||
|
- service: light.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: "{{ state_last_light }}"
|
||||||
|
data:
|
||||||
|
transition: "{{ transition }}"
|
||||||
|
|
||||||
|
# Save persistent state.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ automation_state_entity is not none }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ automation_state_entity }}"
|
||||||
|
data:
|
||||||
|
value: >
|
||||||
|
{% set new_automation_state = (automation_state | combine({ state_key_last_light: '' })) %}
|
||||||
|
{% set new_automation_state = (new_automation_state | combine({ state_key_last_was_on: new_on })) %}
|
||||||
|
{% set new_automation_state = (new_automation_state | combine({ state_key_last_select_action_datetime: current_datetime })) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
||||||
|
|
||||||
|
|
||||||
|
# Do actual selection
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ (action_id != '') and (action_id == action_up or action_id == action_down or action_id == action_remind) }}"
|
||||||
|
sequence:
|
||||||
|
- variables:
|
||||||
|
datetime_diff_seconds: >
|
||||||
|
{% set diff = current_datetime - state_last_select_action_datetime %}
|
||||||
|
{{ diff.total_seconds() }}
|
||||||
|
step: >
|
||||||
|
{% if remind_using_up_down_delay != 0 and datetime_diff_seconds < remind_using_up_down_delay %}
|
||||||
|
0
|
||||||
|
{% elif action_up != '' and action_id == action_up %}
|
||||||
|
1
|
||||||
|
{% elif action_down != '' and action_id == action_down %}
|
||||||
|
-1
|
||||||
|
{% else %}
|
||||||
|
0
|
||||||
|
{% endif %}
|
||||||
|
new_index: "{{ (current_index + step) % lights|length }}"
|
||||||
|
new_light: "{{ lights[new_index] }}"
|
||||||
|
new_on: "{{ is_state(new_light, 'on') }}"
|
||||||
|
|
||||||
|
# Save persistent state.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ automation_state_entity is not none }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ automation_state_entity }}"
|
||||||
|
data:
|
||||||
|
value: >
|
||||||
|
{% set new_automation_state = (automation_state | combine({ state_key_last_light: new_light })) %}
|
||||||
|
{% set new_automation_state = (new_automation_state | combine({ state_key_last_was_on: new_on })) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
||||||
|
|
||||||
|
# Run callback only if user provided it: think if we need to invoke callback here
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ callback_action is defined and (callback_action|length > 0) }}"
|
||||||
|
sequence: !input callback_action
|
||||||
|
|
||||||
|
# Assign new light entity id to helper value
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ helper }}"
|
||||||
|
data:
|
||||||
|
value: "{{ new_light }}"
|
||||||
|
- repeat:
|
||||||
|
count: "{{ flash_count }}"
|
||||||
|
sequence:
|
||||||
|
- service: light.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: "{{ new_light }}"
|
||||||
|
data:
|
||||||
|
transition: "{{ transition }}"
|
||||||
|
- delay:
|
||||||
|
milliseconds: "{{ flash_interval_ms }}"
|
||||||
|
|
||||||
|
- service: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ new_light }}"
|
||||||
|
data:
|
||||||
|
transition: "{{ transition }}"
|
||||||
|
- delay:
|
||||||
|
milliseconds: "{{ flash_interval_ms }}"
|
||||||
|
|
||||||
|
# Optionally turn off the light.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ not new_on }}"
|
||||||
|
sequence:
|
||||||
|
- service: light.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: "{{ new_light }}"
|
||||||
|
data:
|
||||||
|
transition: "{{ transition }}"
|
||||||
|
|
||||||
|
# Save persistent state.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ automation_state_entity is not none }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ automation_state_entity }}"
|
||||||
|
data:
|
||||||
|
value: >
|
||||||
|
{% set new_automation_state = (automation_state | combine({ state_key_last_light: '' })) %}
|
||||||
|
{% set new_automation_state = (new_automation_state | combine({ state_key_last_was_on: new_on })) %}
|
||||||
|
{{ automation_state_global | combine({ automation_state_key: new_automation_state }) | tojson }}
|
||||||
|
|
||||||
69
Zigbee/Media Knob Control.yaml
Normal file
69
Zigbee/Media Knob Control.yaml
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
blueprint:
|
||||||
|
name: "Custom: MQTT Knob Media Controller (Dynamic Step)"
|
||||||
|
description: >
|
||||||
|
Control a media player using a knob switch via MQTT.
|
||||||
|
- `toggle` pauses/unpauses
|
||||||
|
- `rotate_left` decreases volume
|
||||||
|
- `rotate_right` increases volume
|
||||||
|
- Volume step is taken from `action_step` in the MQTT payload
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
mqtt_topic:
|
||||||
|
name: MQTT Topic
|
||||||
|
description: The topic your knob publishes to (e.g., zigbee2mqtt/knob1/action)
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
media_player:
|
||||||
|
name: Media Player
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: media_player
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- platform: mqtt
|
||||||
|
topic: !input mqtt_topic
|
||||||
|
|
||||||
|
variables:
|
||||||
|
media: !input media_player
|
||||||
|
action: "{{ trigger.payload_json.action }}"
|
||||||
|
step: >-
|
||||||
|
{% set key = 'action_step_size' %}
|
||||||
|
{% if key in trigger.payload_json %}
|
||||||
|
{{ (trigger.payload_json[key] | float(0)) / 500 }}
|
||||||
|
{% else %}
|
||||||
|
0
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
action:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action == 'toggle' }}"
|
||||||
|
sequence:
|
||||||
|
- service: media_player.media_play_pause
|
||||||
|
target:
|
||||||
|
entity_id: "{{ media }}"
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action == 'brightness_step_down' }}"
|
||||||
|
sequence:
|
||||||
|
- variables:
|
||||||
|
current: "{{ state_attr(media, 'volume_level') | float(0) }}"
|
||||||
|
new: "{{ [0, current - step] | max }}"
|
||||||
|
- service: media_player.volume_set
|
||||||
|
target:
|
||||||
|
entity_id: "{{ media }}"
|
||||||
|
data:
|
||||||
|
volume_level: "{{ new }}"
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action == 'brightness_step_up' }}"
|
||||||
|
sequence:
|
||||||
|
- variables:
|
||||||
|
current: "{{ state_attr(media, 'volume_level') | float(0) }}"
|
||||||
|
new: "{{ [current + step, 1] | min }}"
|
||||||
|
- service: media_player.volume_set
|
||||||
|
target:
|
||||||
|
entity_id: "{{ media }}"
|
||||||
|
data:
|
||||||
|
volume_level: "{{ new }}"
|
||||||
Reference in New Issue
Block a user