Skip to content

Instantly share code, notes, and snippets.

@yougotborked
Created September 20, 2025 03:34
Show Gist options
  • Select an option

  • Save yougotborked/3bb2dbc56979e01dae601cec7fcfa136 to your computer and use it in GitHub Desktop.

Select an option

Save yougotborked/3bb2dbc56979e01dae601cec7fcfa136 to your computer and use it in GitHub Desktop.
blueprint:
name: Loop Siren Announcer (alarm-triggered, user-selected TTS)
description: >
When any selected alarm panel is TRIGGERED, set volume, announce a message
using the TTS engine you choose, and every N seconds run a siren-control
script and re-announce until that same panel is DISARMED.
domain: automation
input:
alarm_panels:
name: Alarm panels to monitor
description: One or more alarm_control_panel entities to watch for TRIGGERED.
selector:
entity:
domain: alarm_control_panel
multiple: true
media_players:
name: Media players to announce on
description: Speakers/players that will speak the message.
selector:
entity:
domain: media_player
multiple: true
tts_engine:
name: TTS engine
description: Select your TTS entity (e.g., Piper, Google Cloud TTS, etc.).
selector:
entity:
domain: tts
volume_level:
name: Volume level
description: Set volume before speaking (0.0 - 1.0).
default: 1.0
selector:
number:
min: 0
max: 1
step: 0.05
mode: slider
tts_message:
name: TTS message
description: Phrase to repeat while the alarm remains triggered.
default: The alarm is triggered.
selector:
text: {}
tts_language:
name: (Optional) TTS language code
description: Language code for your TTS engine (e.g., en_US). Leave blank to use engine default.
default: ""
selector:
text: {}
tts_voice:
name: (Optional) TTS voice name
description: Voice name supported by your TTS engine (e.g., en_US-amy-low for Piper). Leave blank to use engine default.
default: ""
selector:
text: {}
repeat_seconds:
name: Repeat every (seconds)
description: How often to re-run the siren script and announcement.
default: 20
selector:
number:
min: 5
max: 300
step: 1
unit_of_measurement: s
mode: slider
siren_script:
name: Siren control script
description: This script will be called every N seconds while triggered.
selector:
entity:
domain: script
multiple: false
mode: restart
max_exceeded: silent
variables:
v_media_players: !input media_players
v_tts_engine: !input tts_engine
v_volume: !input volume_level
v_msg: !input tts_message
v_lang: !input tts_language
v_voice: !input tts_voice
v_repeat: !input repeat_seconds
v_siren_script: !input siren_script
trigger:
- platform: state
entity_id: !input alarm_panels
to: triggered
# Operate on the panel that fired; restart retargets if another panel triggers later.
action:
- variables:
triggered_panel: "{{ trigger.entity_id }}"
# 1) Set volume on all players
- service: media_player.volume_set
target:
entity_id: "{{ v_media_players }}"
data:
volume_level: "{{ v_volume }}"
# 2) Speak immediately once using user-chosen TTS engine.
- choose:
- conditions: "{{ v_lang|length > 0 and v_voice|length > 0 }}"
sequence:
- service: tts.speak
data:
entity_id: "{{ v_tts_engine }}"
media_player_entity_id: "{{ v_media_players }}"
message: "{{ v_msg }}"
language: "{{ v_lang }}"
options:
voice: "{{ v_voice }}"
- conditions: "{{ v_lang|length > 0 and v_voice|length == 0 }}"
sequence:
- service: tts.speak
data:
entity_id: "{{ v_tts_engine }}"
media_player_entity_id: "{{ v_media_players }}"
message: "{{ v_msg }}"
language: "{{ v_lang }}"
- conditions: "{{ v_lang|length == 0 and v_voice|length > 0 }}"
sequence:
- service: tts.speak
data:
entity_id: "{{ v_tts_engine }}"
media_player_entity_id: "{{ v_media_players }}"
message: "{{ v_msg }}"
options:
voice: "{{ v_voice }}"
default:
- service: tts.speak
data:
entity_id: "{{ v_tts_engine }}"
media_player_entity_id: "{{ v_media_players }}"
message: "{{ v_msg }}"
# 3) Loop: wait for disarm OR timeout; if timeout, run siren script + re-announce; stop when disarmed
- repeat:
sequence:
- wait_template: "{{ is_state(triggered_panel, 'disarmed') }}"
timeout:
seconds: "{{ v_repeat | int }}"
continue_on_timeout: true
- choose:
- conditions: "{{ is_state(triggered_panel, 'disarmed') }}"
sequence:
- stop: Alarm Disarmed
default:
- service: script.turn_on
target:
entity_id: "{{ v_siren_script }}"
- choose:
- conditions: "{{ v_lang|length > 0 and v_voice|length > 0 }}"
sequence:
- service: tts.speak
data:
entity_id: "{{ v_tts_engine }}"
media_player_entity_id: "{{ v_media_players }}"
message: "{{ v_msg }}"
language: "{{ v_lang }}"
options:
voice: "{{ v_voice }}"
- conditions: "{{ v_lang|length > 0 and v_voice|length == 0 }}"
sequence:
- service: tts.speak
data:
entity_id: "{{ v_tts_engine }}"
media_player_entity_id: "{{ v_media_players }}"
message: "{{ v_msg }}"
language: "{{ v_lang }}"
- conditions: "{{ v_lang|length == 0 and v_voice|length > 0 }}"
sequence:
- service: tts.speak
data:
entity_id: "{{ v_tts_engine }}"
media_player_entity_id: "{{ v_media_players }}"
message: "{{ v_msg }}"
options:
voice: "{{ v_voice }}"
default:
- service: tts.speak
data:
entity_id: "{{ v_tts_engine }}"
media_player_entity_id: "{{ v_media_players }}"
message: "{{ v_msg }}"
until: []
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment