Last active
August 13, 2025 07:55
-
-
Save cmsj/85eedaf1f1f4d0dc8c3d31fe5ebfa7c1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
alias: Universal TTS Announcement 2 | |
description: Sends a TTS message, routing to Alexa or Cloud TTS based on the target entity. | |
icon: mdi:bullhorn-variant-outline | |
fields: | |
message: | |
name: Message | |
description: The text you want to announce. | |
required: true | |
selector: | |
text: | |
multiline: true | |
target: | |
name: Target | |
description: Select any combination of media player entities, areas, devices, or labels. | |
required: true | |
selector: | |
target: | |
entity: | |
domain: media_player | |
volume: | |
name: (Optional) Announcement Volume | |
description: Set a temporary volume for the announcement (0.0 to 1.0). | |
selector: | |
number: | |
min: 0 | |
max: 1 | |
step: 0.05 | |
mode: slider | |
sequence: | |
- variables: | |
expanded_targets: > | |
{# Create the namespace object we'll use to store all our working data #} | |
{% set data = namespace(expanded_targets=[]) %} | |
{# Declare two helper macros #} | |
{% macro m_listifyIfNot(someValue, returns) %} | |
{% if someValue is list %} | |
{% do returns(someValue) %} | |
{% else %} | |
{% do returns([someValue]) %} | |
{% endif %} | |
{% endmacro %} | |
{% macro m_noop(someValue, returns) %} | |
{% do returns(someValue) %} | |
{% endmacro %} | |
{# Declare our helper macros as functions, so they can return values #} | |
{% set f_listifyIfNot = m_listifyIfNot | as_function %} | |
{% set f_noop = m_noop | as_function %} | |
{# Iterate our input dictionary #} | |
{% for value in target %} | |
{# Store a function pointer we'll use to turn the input value into a list of entities #} | |
{% if value == "device_id" %} | |
{% set f_getEntities = device_entities %} | |
{% elif value == "area_id" %} | |
{% set f_getEntities = area_entities %} | |
{% elif value == "label_id" %} | |
{% set f_getEntities = label_entities %} | |
{% elif value == "entity_id" %} | |
{% set f_getEntities = f_noop %} | |
{% else %} | |
{# This should never be hit #} | |
{% set f_getEntities = none %} | |
{% endif %} | |
{# Ensure the input value is a list. It will be a string if only one value is supplied #} | |
{% set listifiedValues = f_listifyIfNot(target[value]) %} | |
{# Iterate the input list and use our function pointer to expand it to a list of entities, and filter out anything that isn't a media_player #} | |
{% for entry in listifiedValues %} | |
{% set data.expanded_targets = data.expanded_targets + expand(f_getEntities(entry)) | map(attribute="entity_id") | select("match", "media_player") | list %} | |
{% endfor %} | |
{% endfor %} | |
{{ data.expanded_targets | unique | list }} | |
- variables: | |
all_alexa_entities: "{{ integration_entities('alexa_media') }}" | |
alexa_targets: | | |
{{ expanded_targets | select('in', all_alexa_entities) | list }} | |
media_player_targets: | | |
{{ expanded_targets | reject('in', all_alexa_entities) | list }} | |
- if: | |
- condition: template | |
value_template: "{{ volume is defined and volume > 0 }}" | |
then: | |
- target: | |
entity_id: "{{ expanded_targets }}" | |
data: | |
volume_level: "{{ volume }}" | |
action: media_player.volume_set | |
- delay: | |
milliseconds: 250 | |
- if: | |
- condition: template | |
value_template: "{{ alexa_targets | count > 0 }}" | |
then: | |
- target: | |
entity_id: "{{ alexa_targets }}" | |
data: | |
message: "{{ message }}" | |
data: | |
type: tts | |
action: notify.alexa_media | |
- if: | |
- condition: template | |
value_template: "{{ media_player_targets | count > 0 }}" | |
then: | |
- target: | |
entity_id: "{{ media_player_targets }}" | |
data: | |
message: "{{ message }}" | |
action: tts.cloud_say |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment