637 lines
22 KiB
YAML
637 lines
22 KiB
YAML
################################################################################
|
|
# PACKAGE: View Road Announcement Router
|
|
################################################################################
|
|
#
|
|
# Version: 1.4
|
|
# Date: 2026-06-02
|
|
#
|
|
# Purpose:
|
|
# Central announcement router for general Home Assistant announcements.
|
|
# Other scripts and automations can call script.view_road_announcement and pass
|
|
# values such as channels, title, short_announcement, long_announcement,
|
|
# payload, and indicator.
|
|
#
|
|
# How to call this script:
|
|
#
|
|
# - action: script.view_road_announcement
|
|
# data:
|
|
# channels: "pushover_zorruno, lounge_google_home_voice, led_matrix_1"
|
|
# title: "View Road"
|
|
# short_announcement: "Washing complete"
|
|
# long_announcement: "The washing machine has finished."
|
|
# payload: ""
|
|
# indicator: "dry,1,15,10,2,1"
|
|
#
|
|
# Available channels:
|
|
#
|
|
# pushover_zorruno:
|
|
# Uses:
|
|
# title
|
|
# long_announcement
|
|
#
|
|
# pushover_kim:
|
|
# Uses:
|
|
# title
|
|
# long_announcement
|
|
#
|
|
# sony_tv_lounge:
|
|
# Uses:
|
|
# title
|
|
# short_announcement
|
|
# payload
|
|
# Message format:
|
|
# "<short_announcement> is <payload>"
|
|
#
|
|
# lounge_google_home_voice:
|
|
# Also accepts alias:
|
|
# google_home_voice
|
|
# Uses:
|
|
# long_announcement
|
|
# Fallback:
|
|
# If long_announcement is blank, uses short_announcement and payload.
|
|
# Quiet time:
|
|
# Blocked by default when input_boolean.quiet_time is on.
|
|
#
|
|
# lounge_touchscreen_voice:
|
|
# Placeholder only.
|
|
# Quiet time:
|
|
# Blocked by default when input_boolean.quiet_time is on.
|
|
#
|
|
# mqtt_view_rd_feed:
|
|
# Placeholder only.
|
|
#
|
|
# led_matrix_1:
|
|
# Uses:
|
|
# short_announcement
|
|
# indicator
|
|
# Publishes to MQTT topic:
|
|
# viewroad-commands/ledmatrix1/announce
|
|
# Message format:
|
|
# "<short_announcement> [<indicator>]"
|
|
# Example:
|
|
# "Washing complete [dry,1,15,10,2,1]"
|
|
#
|
|
# led_matrix_2:
|
|
# Future channel.
|
|
# Uses the same format as led_matrix_1.
|
|
# Publishes to MQTT topic:
|
|
# viewroad-commands/ledmatrix2/announce
|
|
#
|
|
# LED matrix announcement format:
|
|
#
|
|
# Message text [identifier,transition_mode,speed,repeat_seconds,repeat_times,sounder_quantity]
|
|
#
|
|
# Example script call:
|
|
#
|
|
# - action: script.view_road_announcement
|
|
# data:
|
|
# channels: "led_matrix_1"
|
|
# short_announcement: "Washing complete"
|
|
# indicator: "dry,1,15,10,2,1"
|
|
#
|
|
# Result sent to MQTT:
|
|
#
|
|
# Washing complete [dry,1,15,10,2,1]
|
|
#
|
|
# Indicator fields:
|
|
#
|
|
# identifier:
|
|
# Announcement identifier used by the LED matrix ESPHome logic.
|
|
# It is cleaned by ESPHome to letters, numbers, underscore, or dash, and
|
|
# is limited to 8 characters.
|
|
#
|
|
# transition_mode:
|
|
# 0 = Slide up
|
|
# 1 = Slide down
|
|
# 2 = Pixel fall
|
|
#
|
|
# speed:
|
|
# Per-message scroll delay in ms.
|
|
# Clamped by ESPHome from 1 to 100.
|
|
#
|
|
# repeat_seconds:
|
|
# Delay between completed scrolls.
|
|
# Clamped by ESPHome from 0 to 99.
|
|
#
|
|
# repeat_times:
|
|
# Total number of scroll displays.
|
|
# Clamped by ESPHome from 0 to 99.
|
|
# 0 is treated as a one-shot announcement.
|
|
#
|
|
# sounder_quantity:
|
|
# Number of announcement displays that should beep first.
|
|
# 0 means no sounder beep.
|
|
#
|
|
# Notes:
|
|
# The announcement router does not parse, clean, or clamp the indicator
|
|
# fields. It passes the indicator through to the LED matrix in square
|
|
# brackets. The LED matrix ESPHome YAML handles validation and behaviour.
|
|
#
|
|
# Changes:
|
|
# 1.4:
|
|
# - Documented LED matrix indicator format.
|
|
# - Clarified that LED matrix indicator validation is handled by ESPHome.
|
|
#
|
|
# 1.3:
|
|
# - Added led_matrix_1 announcement channel.
|
|
# - Added future led_matrix_2 announcement channel.
|
|
# - Added MQTT topic settings for LED matrix announcement channels.
|
|
# - Added channel enable helpers for led_matrix_1 and led_matrix_2.
|
|
# - Added package instructions for calling script.view_road_announcement.
|
|
# - Moved more configurable values into the package settings section.
|
|
# - Added lounge Google Home cast chime suppression setting.
|
|
#
|
|
# 1.2:
|
|
# - Updated Lounge Google Home voice channel to use working Piper TTS setup.
|
|
# - Added Piper voice option en_GB-alba-medium.
|
|
# - Removed separate TTS language option from the voice channel.
|
|
#
|
|
# 1.1:
|
|
# - Removed old YAML Pushover notify service setup.
|
|
# - Uses existing Pushover integration notify entities.
|
|
# - Added quiet time channel blocking.
|
|
# - Added Lounge Google Home voice announcement channel.
|
|
#
|
|
# Notes:
|
|
# - Use input_boolean helpers for channel enable/disable control.
|
|
# - Binary sensors are read-only, so input_boolean is the correct helper type.
|
|
# - Channels with no action block yet intentionally do nothing.
|
|
#
|
|
################################################################################
|
|
|
|
################################################################################
|
|
# CHANNEL ENABLE HELPERS
|
|
################################################################################
|
|
|
|
input_boolean:
|
|
announcement_channel_pushover_zorruno:
|
|
name: Announcement Channel - Pushover Zorruno
|
|
icon: mdi:cellphone-message
|
|
initial: true
|
|
|
|
announcement_channel_pushover_kim:
|
|
name: Announcement Channel - Pushover Kim
|
|
icon: mdi:cellphone-message
|
|
initial: true
|
|
|
|
announcement_channel_sony_tv_lounge:
|
|
name: Announcement Channel - Sony TV Lounge
|
|
icon: mdi:television
|
|
initial: true
|
|
|
|
announcement_channel_lounge_google_home_voice:
|
|
name: Announcement Channel - Lounge Google Home Voice
|
|
icon: mdi:speaker
|
|
initial: true
|
|
|
|
announcement_channel_lounge_touchscreen_voice:
|
|
name: Announcement Channel - Lounge Touchscreen Voice
|
|
icon: mdi:tablet-dashboard
|
|
initial: true
|
|
|
|
announcement_channel_mqtt_view_rd_feed:
|
|
name: Announcement Channel - MQTT View Rd Feed
|
|
icon: mdi:message-processing
|
|
initial: true
|
|
|
|
announcement_channel_led_matrix_1:
|
|
name: Announcement Channel - LED Matrix 1
|
|
icon: mdi:led-strip-variant
|
|
initial: true
|
|
|
|
announcement_channel_led_matrix_2:
|
|
name: Announcement Channel - LED Matrix 2
|
|
icon: mdi:led-strip-variant
|
|
initial: true
|
|
|
|
################################################################################
|
|
# MAIN ANNOUNCEMENT ROUTER SCRIPT
|
|
################################################################################
|
|
|
|
script:
|
|
view_road_announcement:
|
|
alias: View Road Announcement
|
|
icon: mdi:bullhorn
|
|
mode: parallel
|
|
max: 20
|
|
|
|
fields:
|
|
channels:
|
|
name: Channels
|
|
description: Comma separated list of announcement channels to use.
|
|
example: "pushover_zorruno, sony_tv_lounge, led_matrix_1"
|
|
selector:
|
|
text:
|
|
|
|
title:
|
|
name: Title
|
|
description: Announcement title.
|
|
example: "View Road"
|
|
selector:
|
|
text:
|
|
|
|
short_announcement:
|
|
name: Short Announcement
|
|
description: Short announcement text.
|
|
example: "Garage door"
|
|
selector:
|
|
text:
|
|
|
|
long_announcement:
|
|
name: Long Announcement
|
|
description: Longer announcement text.
|
|
example: "The garage door has been opened."
|
|
selector:
|
|
text:
|
|
multiline: true
|
|
|
|
payload:
|
|
name: Payload
|
|
description: Payload value such as On, Off, Open, Closed, etc.
|
|
example: "Open"
|
|
selector:
|
|
text:
|
|
|
|
indicator:
|
|
name: Indicator
|
|
description: LED matrix indicator data in the format identifier,transition_mode,speed,repeat_seconds,repeat_times,sounder_quantity.
|
|
example: "dry,1,15,10,2,1"
|
|
selector:
|
|
text:
|
|
|
|
sequence:
|
|
##########################################################################
|
|
# PACKAGE SETTINGS / SUBSTITUTIONS
|
|
##########################################################################
|
|
#
|
|
# Home Assistant packages do not support ESPHome-style substitutions.
|
|
# These variables act as the package-level settings for this script.
|
|
#
|
|
# If a value is not passed to the script, the default below is used.
|
|
# If a value is passed as "", it clears the default to blank.
|
|
#
|
|
##########################################################################
|
|
|
|
- variables:
|
|
default_channels: "pushover_zorruno, pushover_kim, sony_tv_lounge, lounge_google_home_voice, lounge_touchscreen_voice, mqtt_view_rd_feed, led_matrix_1, led_matrix_2"
|
|
default_title: "View Road"
|
|
default_short_announcement: "Home automation announcement"
|
|
default_long_announcement: "Home automation announcement"
|
|
default_payload: ""
|
|
default_indicator: ""
|
|
|
|
quiet_time_blocked_channels:
|
|
- "google_home_voice"
|
|
- "lounge_google_home_voice"
|
|
- "lounge_touchscreen_voice"
|
|
|
|
lounge_google_home_voice_media_player: "media_player.lounge_google_tichome_speaker"
|
|
lounge_google_home_voice_tts_entity: "tts.piper"
|
|
lounge_google_home_voice_piper_voice: "en_GB-jenny_dioco-medium"
|
|
lounge_google_home_voice_volume_level: 0.80
|
|
lounge_google_home_voice_suppress_cast_chime: false
|
|
|
|
led_matrix_1_mqtt_topic: "viewroad-commands/ledmatrix1/announce"
|
|
led_matrix_2_mqtt_topic: "viewroad-commands/ledmatrix2/announce"
|
|
led_matrix_mqtt_qos: 0
|
|
led_matrix_mqtt_retain: false
|
|
led_matrix_leading_space_guard: ""
|
|
|
|
##########################################################################
|
|
# RESOLVE PASSED VALUES
|
|
##########################################################################
|
|
#
|
|
# Lowercase field names are preferred:
|
|
# channels
|
|
# title
|
|
# short_announcement
|
|
# long_announcement
|
|
# payload
|
|
# indicator
|
|
#
|
|
# Some uppercase variants are also accepted for tolerance.
|
|
#
|
|
##########################################################################
|
|
|
|
- variables:
|
|
ann_channels_raw: >-
|
|
{% if channels is defined %}
|
|
{{ channels }}
|
|
{% elif channel is defined %}
|
|
{{ channel }}
|
|
{% elif Channel is defined %}
|
|
{{ Channel }}
|
|
{% else %}
|
|
{{ default_channels }}
|
|
{% endif %}
|
|
|
|
ann_title: >-
|
|
{% if title is defined %}
|
|
{{ title }}
|
|
{% elif Title is defined %}
|
|
{{ Title }}
|
|
{% else %}
|
|
{{ default_title }}
|
|
{% endif %}
|
|
|
|
ann_short_announcement: >-
|
|
{% if short_announcement is defined %}
|
|
{{ short_announcement }}
|
|
{% elif Short_Announcement is defined %}
|
|
{{ Short_Announcement }}
|
|
{% else %}
|
|
{{ default_short_announcement }}
|
|
{% endif %}
|
|
|
|
ann_long_announcement: >-
|
|
{% if long_announcement is defined %}
|
|
{{ long_announcement }}
|
|
{% elif Long_Announcement is defined %}
|
|
{{ Long_Announcement }}
|
|
{% else %}
|
|
{{ default_long_announcement }}
|
|
{% endif %}
|
|
|
|
ann_payload: >-
|
|
{% if payload is defined %}
|
|
{{ payload }}
|
|
{% elif Payload is defined %}
|
|
{{ Payload }}
|
|
{% else %}
|
|
{{ default_payload }}
|
|
{% endif %}
|
|
|
|
ann_indicator: >-
|
|
{% if indicator is defined %}
|
|
{{ indicator }}
|
|
{% elif Indicator is defined %}
|
|
{{ Indicator }}
|
|
{% else %}
|
|
{{ default_indicator }}
|
|
{% endif %}
|
|
|
|
##########################################################################
|
|
# NORMALISE CHANNEL LISTS AND MESSAGE TEXT
|
|
##########################################################################
|
|
|
|
- variables:
|
|
ann_channels_normalised: >-
|
|
{{ ',' ~ (ann_channels_raw | string | lower | replace(' ', '') | replace('\n', '') | trim(',')) ~ ',' }}
|
|
|
|
ann_quiet_time_blocked_channels_normalised: >-
|
|
{{ ',' ~ (quiet_time_blocked_channels | join(',') | lower | replace(' ', '') | replace('\n', '') | trim(',')) ~ ',' }}
|
|
|
|
ann_sony_tv_message: >-
|
|
{% set short_text = ann_short_announcement | string | trim %}
|
|
{% set payload_text = ann_payload | string | trim %}
|
|
{% if short_text | length > 0 and payload_text | length > 0 %}
|
|
{{ short_text }} is {{ payload_text }}
|
|
{% elif short_text | length > 0 %}
|
|
{{ short_text }}
|
|
{% else %}
|
|
{{ payload_text }}
|
|
{% endif %}
|
|
|
|
ann_voice_message: >-
|
|
{% set long_text = ann_long_announcement | string | trim %}
|
|
{% set short_text = ann_short_announcement | string | trim %}
|
|
{% set payload_text = ann_payload | string | trim %}
|
|
{% if long_text | length > 0 %}
|
|
{{ long_text }}
|
|
{% elif short_text | length > 0 and payload_text | length > 0 %}
|
|
{{ short_text }} is {{ payload_text }}
|
|
{% elif short_text | length > 0 %}
|
|
{{ short_text }}
|
|
{% else %}
|
|
{{ payload_text }}
|
|
{% endif %}
|
|
|
|
ann_led_matrix_message: >-
|
|
{% set short_text = short_announcement if short_announcement is defined
|
|
else Short_Announcement if Short_Announcement is defined
|
|
else default_short_announcement %}
|
|
{% set short_text = short_text | string %}
|
|
{% set indicator_text = ann_indicator | string | trim %}
|
|
{{ (led_matrix_leading_space_guard if short_text[0:1] == ' ' else '') ~ short_text ~
|
|
(' [' ~ indicator_text ~ ']'
|
|
if indicator_text | length > 0
|
|
else '') }}
|
|
|
|
##########################################################################
|
|
# CHANNEL: PUSHOVER ZORRUNO
|
|
##########################################################################
|
|
|
|
- if:
|
|
- condition: template
|
|
value_template: "{{ ',pushover_zorruno,' in ann_channels_normalised }}"
|
|
- condition: state
|
|
entity_id: input_boolean.announcement_channel_pushover_zorruno
|
|
state: "on"
|
|
then:
|
|
- action: notify.pushover_zorruno
|
|
data:
|
|
title: "{{ ann_title }}"
|
|
message: "{{ ann_long_announcement }}"
|
|
|
|
##########################################################################
|
|
# CHANNEL: PUSHOVER KIM
|
|
##########################################################################
|
|
|
|
- if:
|
|
- condition: template
|
|
value_template: "{{ ',pushover_kim,' in ann_channels_normalised }}"
|
|
- condition: state
|
|
entity_id: input_boolean.announcement_channel_pushover_kim
|
|
state: "on"
|
|
then:
|
|
- action: notify.pushover_kim
|
|
data:
|
|
title: "{{ ann_title }}"
|
|
message: "{{ ann_long_announcement }}"
|
|
|
|
##########################################################################
|
|
# CHANNEL: SONY TV LOUNGE
|
|
##########################################################################
|
|
|
|
- if:
|
|
- condition: template
|
|
value_template: "{{ ',sony_tv_lounge,' in ann_channels_normalised }}"
|
|
- condition: state
|
|
entity_id: input_boolean.announcement_channel_sony_tv_lounge
|
|
state: "on"
|
|
then:
|
|
- action: notify.sony_android_tv_lounge
|
|
data:
|
|
title: "{{ ann_title }}"
|
|
message: "{{ ann_sony_tv_message }}"
|
|
|
|
##########################################################################
|
|
# CHANNEL: LOUNGE GOOGLE HOME VOICE
|
|
##########################################################################
|
|
#
|
|
# Also accepts google_home_voice as an alias channel name.
|
|
#
|
|
# This channel is blocked during quiet time by default.
|
|
#
|
|
##########################################################################
|
|
|
|
- if:
|
|
- condition: template
|
|
value_template: >-
|
|
{{
|
|
',lounge_google_home_voice,' in ann_channels_normalised
|
|
or ',google_home_voice,' in ann_channels_normalised
|
|
}}
|
|
- condition: state
|
|
entity_id: input_boolean.announcement_channel_lounge_google_home_voice
|
|
state: "on"
|
|
- condition: template
|
|
value_template: >-
|
|
{{ not (
|
|
is_state('input_boolean.quiet_time', 'on')
|
|
and (
|
|
',lounge_google_home_voice,' in ann_quiet_time_blocked_channels_normalised
|
|
or ',google_home_voice,' in ann_quiet_time_blocked_channels_normalised
|
|
)
|
|
) }}
|
|
- condition: template
|
|
value_template: "{{ ann_voice_message | string | trim | length > 0 }}"
|
|
then:
|
|
- choose:
|
|
- conditions:
|
|
- condition: template
|
|
value_template: "{{ lounge_google_home_voice_suppress_cast_chime | bool(false) }}"
|
|
- condition: template
|
|
value_template: "{{ states(lounge_google_home_voice_media_player) in ['off', 'unavailable', 'unknown'] }}"
|
|
sequence:
|
|
- action: media_player.volume_set
|
|
data:
|
|
entity_id: "{{ lounge_google_home_voice_media_player }}"
|
|
volume_level: 0
|
|
|
|
- action: media_player.turn_on
|
|
target:
|
|
entity_id: "{{ lounge_google_home_voice_media_player }}"
|
|
|
|
- wait_template: >-
|
|
{{ states(lounge_google_home_voice_media_player) in ['idle', 'paused', 'playing', 'on'] }}
|
|
timeout:
|
|
seconds: 5
|
|
continue_on_timeout: true
|
|
|
|
- delay:
|
|
seconds: 1
|
|
|
|
- action: media_player.volume_set
|
|
data:
|
|
entity_id: "{{ lounge_google_home_voice_media_player }}"
|
|
volume_level: "{{ lounge_google_home_voice_volume_level | float(0.8) }}"
|
|
|
|
- delay:
|
|
seconds: 1
|
|
|
|
- action: tts.speak
|
|
target:
|
|
entity_id: "{{ lounge_google_home_voice_tts_entity }}"
|
|
data:
|
|
cache: false
|
|
media_player_entity_id: "{{ lounge_google_home_voice_media_player }}"
|
|
message: "{{ ann_voice_message }}"
|
|
options:
|
|
voice: "{{ lounge_google_home_voice_piper_voice }}"
|
|
preferred_format: mp3
|
|
preferred_sample_rate: 44100
|
|
|
|
##########################################################################
|
|
# CHANNEL: LOUNGE TOUCHSCREEN VOICE
|
|
##########################################################################
|
|
#
|
|
# Placeholder only. No action yet.
|
|
#
|
|
# This channel is listed in quiet_time_blocked_channels for future use.
|
|
#
|
|
##########################################################################
|
|
|
|
##########################################################################
|
|
# CHANNEL: MQTT VIEW RD FEED
|
|
##########################################################################
|
|
#
|
|
# Placeholder only. No action yet.
|
|
#
|
|
##########################################################################
|
|
|
|
##########################################################################
|
|
# CHANNEL: LOUNGE LED MATRIX DISPLAY - MATRIX 1
|
|
##########################################################################
|
|
#
|
|
# Channel name:
|
|
# led_matrix_1
|
|
#
|
|
# Uses:
|
|
# short_announcement
|
|
# indicator
|
|
#
|
|
# Publishes:
|
|
# <short_announcement> [<indicator>]
|
|
#
|
|
# Example payload:
|
|
# Washing complete [dry,1,15,10,2,1]
|
|
#
|
|
# Indicator format:
|
|
# identifier,transition_mode,speed,repeat_seconds,repeat_times,sounder_quantity
|
|
#
|
|
##########################################################################
|
|
|
|
- if:
|
|
- condition: template
|
|
value_template: "{{ ',led_matrix_1,' in ann_channels_normalised }}"
|
|
- condition: state
|
|
entity_id: input_boolean.announcement_channel_led_matrix_1
|
|
state: "on"
|
|
- condition: template
|
|
value_template: "{{ ann_led_matrix_message | string | trim | length > 0 }}"
|
|
then:
|
|
- action: mqtt.publish
|
|
data:
|
|
topic: "{{ led_matrix_1_mqtt_topic }}"
|
|
payload: "{{ ann_led_matrix_message }}"
|
|
qos: "{{ led_matrix_mqtt_qos | int(0) }}"
|
|
retain: "{{ led_matrix_mqtt_retain | bool(false) }}"
|
|
|
|
##########################################################################
|
|
# CHANNEL: LOUNGE LED MATRIX DISPLAY - MATRIX 2
|
|
##########################################################################
|
|
#
|
|
# Future channel.
|
|
#
|
|
# Channel name:
|
|
# led_matrix_2
|
|
#
|
|
# Uses:
|
|
# short_announcement
|
|
# indicator
|
|
#
|
|
# Publishes:
|
|
# <short_announcement> [<indicator>]
|
|
#
|
|
# Indicator format:
|
|
# identifier,transition_mode,speed,repeat_seconds,repeat_times,sounder_quantity
|
|
#
|
|
##########################################################################
|
|
|
|
- if:
|
|
- condition: template
|
|
value_template: "{{ ',led_matrix_2,' in ann_channels_normalised }}"
|
|
- condition: state
|
|
entity_id: input_boolean.announcement_channel_led_matrix_2
|
|
state: "on"
|
|
- condition: template
|
|
value_template: "{{ ann_led_matrix_message | string | trim | length > 0 }}"
|
|
then:
|
|
- action: mqtt.publish
|
|
data:
|
|
topic: "{{ led_matrix_2_mqtt_topic }}"
|
|
payload: "{{ ann_led_matrix_message }}"
|
|
qos: "{{ led_matrix_mqtt_qos | int(0) }}"
|
|
retain: "{{ led_matrix_mqtt_retain | bool(false) }}"
|