Arriving Home - Play to Alexa Multi Room Audio Setup
This is building off of this previous project of mine to create a system of automations to automatically play a variety of music of my choosing on my Alexa Multi-Room Music Groups when I get home from work.
* Edited to add blueprints and moved to Blueprints Exchange. *
Alexa Media Player Setup
This project uses the Alexa Media Player custom component to interact with my Alexa Devices. I won’t go into detail on setting this up, because I haven’t deviated any from the standard setup for this custom component.
As I mentioned in the previous project, there is currently a limitation to Alexa Media Player which means you can start and stop music to individual echo devices, but you can’t send music directly to an Alexa Multi-Room Music Group. The workaround that I’ve found to be most consistent - which I use in this project - is sending a custom simulated voice command to Alexa through the component, like “Play Jazz on the Downstairs Music Group.”
Home Assistant Helpers
I used HA’s helpers to set up an input_text entity in the UI by going to Configuration/Helpers and clicking the add button, then “Text.” I then added a name, in my case “Arriving Home Music”. This entity will be used to type text for whatever music or audio I want sent to the Alexa Music Groups. I changed the icon to “mdi:music”
Actionable Notification
I have an iPhone, so this part of the uses actionable notifications for iOS. The process to set this up is well documented here: https://companion.home-assistant.io/docs/notifications/actionable-notifications/
configuration.yaml
I added one section to configuration.yaml for Actionable Notifications for this project:
# configuration.yaml
ios:
push:
categories:
- name: Todays Music
identifier: 'todaysmusic'
actions:
- identifier: 'INPUT_MUSIC'
title: "Type what you'd like to hear"
behavior: 'textInput'
textInputButtonTitle: 'Submit'
textInputPlaceholder: 'music'
- identifier: 'JAZZ_MUSIC'
title: 'Jazz'
- identifier: 'CLASSICAL_MUSIC'
title: 'Classical'
- identifier: 'RANDOM_MUSIC'
title: 'Random'
The “textInput” behavior allows me to respond inside the actionable notification with text that will be sent to Home Assistant:
Automations
I created three automations for this project, and I’ll do my best to explain them and the logic behind them:
What Music Do You Want? Notification
The first few automation sends the actionable notification at prescribed time, about 15 minutes before I leave work each weekday.
Blueprint URL:
blueprint:
name: Alexa Music Group - Send Actionable Notification at Time
description: |
Choose a person to send a notification to at a certain time. Conditioned by zone.
You must set up the Alexa Media Player custom component, a new input_text entity (I used HA helpers), and actionable notifications in your configuration.yaml for this to work.
My configuration.yaml file has an entry that looks something like this (minus the periods)
ios:
..push:
....categories:
......- name: Todays Music
........identifier: 'todaysmusic'
........actions:
..........- identifier: 'INPUT_MUSIC'
............title: "Type what you'd like to hear"
............behavior: 'textInput'
............textInputButtonTitle: 'Submit'
............textInputPlaceholder: 'music'
..........- identifier: 'JAZZ_MUSIC'
............title: 'Jazz Radio'
..........- identifier: 'CLASSICAL_MUSIC'
............title: 'Classical Radio'
..........- identifier: 'RANDOM_MUSIC'
............title: 'Random'
If you want to add a custom choice for yourself (or change one of these choices), just use this same naming convention.
domain: automation
input:
actionable_notification_identifier:
name: Name of Your Actionable Notification Identifier
description: What is the identifier of the actionable notification you created in config.yaml? ex - todaysmusic
selector:
text:
default: todaysmusic
time_on:
name: Time to send notification
description: What time do you want the actionable notification to send?
selector:
time:
default: '16:15:00'
person_entity:
name: Person
description: Who is the notification Zone-conditioned by?
selector:
entity:
domain: person
zone_entity:
name: Zone
description: What zone do you want to use for the condition?
selector:
entity:
domain: zone
notify_device:
name: Device to notify
description: Device needs to run the official Home Assistant app to receive notifications.
selector:
device:
integration: mobile_app
trigger:
platform: time
at: !input time_on
condition:
condition: zone
entity_id: !input person_entity
zone: !input zone_entity
action:
domain: mobile_app
type: notify
device_id: !input notify_device
data:
push:
category: !input actionable_notification_identifier
message: What do you want to hear today?
title: Arriving Home Music
Click to see my automation yaml.
# automations.yaml
- alias: Arriving Home What Music?
description: ''
trigger:
- platform: time
at: '16:15:00'
condition:
- condition: time
weekday:
- mon
- tue
- wed
- thu
- fri
- condition: zone
entity_id: person.me
zone: zone.my_work
action:
- data:
data:
push:
category: todaysmusic
message: What do you want to hear today?
title: Arriving Home Music
service: notify.mobile_app_my_iphone
mode: single
Automation Components
This automation to process the return from the Actionable Notification is where it gets fun. I set the triggers for this one up in the UI to make things easier - there are triggers for each of the actionable notification returns I set up earlier (JAZZ_MUSIC, CLASSICAL_MUSIC, RANDOM_MUSIC, and INPUT_MUSIC). Then I set up the action to fire a service, using as an if statement as the data value (I had to set this up in YAML, because it uses “data_template”). This is using the input_text.set_value service to change the helper I created earlier to whatever my response from the actionable notification was.
Blueprint URL:
blueprint:
name: Alexa Music Group - Process Actionable Notification Return
description: |
You must set up the Alexa Media Player custom component, a new input_text entity (I used HA helpers), and actionable notifications in your configuration.yaml for this to work.
My configuration.yaml file has an entry that looks something like this (minus the periods)
ios:
..push:
....categories:
......- name: Todays Music
........identifier: 'todaysmusic'
........actions:
..........- identifier: 'INPUT_MUSIC'
............title: "Type what you'd like to hear"
............behavior: 'textInput'
............textInputButtonTitle: 'Submit'
............textInputPlaceholder: 'music'
..........- identifier: 'JAZZ_MUSIC'
............title: 'Jazz Radio'
..........- identifier: 'CLASSICAL_MUSIC'
............title: 'Classical Radio'
..........- identifier: 'RANDOM_MUSIC'
............title: 'Random'
If you want to add a custom choice for yourself (or change one of these choices), just use this same naming convention.
domain: automation
input:
text_input_entity:
name: Text Input Helper You Created
description: Use HA Helpers to create a text input entity to use here.
selector:
entity:
domain: input_text
response_action_name_1:
name: Option 1 Action Name
description: What is the identifier of your actionName for your actionable notification in config.yaml? ex - JAZZ_MUSIC
selector:
text:
default: "JAZZ_MUSIC"
response_action_command_1:
name: Option 1 Action Command
description: What do you want to say to Alexa? Text will replace asterisks in the following - "Alexa, play ******* on the (name of music group) group."
selector:
text:
default: "Jazz on Apple Music"
response_action_name_2:
name: Option 2 Action Name
description: What is the identifier of your actionName for your actionable notification in config.yaml? ex - CLASSICAL_MUSIC
selector:
text:
default: "CLASSICAL_MUSIC"
response_action_command_2:
name: Option 2 Action Command
description: What do you want to say to Alexa? Text will replace asterisks in the following - "Alexa, play ******* on the (name of music group) group."
selector:
text:
default: "Classical music on Apple Music"
response_action_name_3:
name: Option 3 Action Name
description: What is the identifier of your actionName for your actionable notification in config.yaml? ex - RANDOM_MUSIC
selector:
text:
default: "RANDOM_MUSIC"
response_action_command_3:
name: Option 3 Action Command
description: What do you want to say to Alexa? Text will replace asterisks in the following - "Alexa, play ******* on the (name of music group) group."
selector:
text:
default: "Music"
response_action_name_4:
name: Option 4 Action Name
description: What is the identifier of your actionName for your actionable notification in config.yaml? ex - RANDOM_MUSIC
selector:
text:
default: "RANDOM_MUSIC"
response_action_command_4:
name: Option 4 Action Command
description: What do you want to say to Alexa? Text will replace asterisks in the following - "Alexa, play ******* on the (name of music group) group."
selector:
text:
default: "Music"
trigger:
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: INPUT_MUSIC
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: !input response_action_name_1
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: !input response_action_name_2
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: !input response_action_name_3
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: !input response_action_name_4
variables:
action_name_1: !input response_action_name_1
action_name_2: !input response_action_name_2
action_name_3: !input response_action_name_3
action_name_4: !input response_action_name_4
action_command_1: !input response_action_command_1
action_command_2: !input response_action_command_2
action_command_3: !input response_action_command_3
action_command_4: !input response_action_command_4
action:
- service: input_text.set_value
data_template:
entity_id: input_text.alex_arriving_home_music
value: >-
{% if trigger.event.data["actionName"] == "INPUT_MUSIC" %}
{{ trigger.event.data["textInput"] }}
{% elif trigger.event.data["actionName"] == action_name_1 %}
{{ action_command_1 }}
{% elif trigger.event.data["actionName"] == action_name_2 %}
{{ action_command_2 }}
{% elif trigger.event.data["actionName"] == action_name_3 %}
{{ action_command_3 }}
{% elif trigger.event.data["actionName"] == action_name_4 %}
{{ action_command_4 }}
{% else %}
Music
{% endif %}
Click to see my automation yaml.
# automations.yaml
- alias: Arriving Home What Music? - Component to Set Text Input
description: ''
trigger:
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: JAZZ_MUSIC
context:
user_id:
- ****************************
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: CLASSICAL_MUSIC
context:
user_id:
- ****************************
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: INPUT_MUSIC
context:
user_id:
- ****************************
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: RANDOM_MUSIC
context:
user_id:
- ****************************
condition: []
action:
- data_template:
entity_id: input_text.arriving_home_music
value: >-
{% if trigger.event.data["actionName"] == "JAZZ_MUSIC" %}
Jazz Radio on Apple Music
{% elif trigger.event.data["actionName"] == "CLASSICAL_MUSIC" %}
Classical Radio on Apple Music
{% elif trigger.event.data["actionName"] == "INPUT_MUSIC" %}
{{ trigger.event.data["textInput"] }}
{% else %}
Music
{% endif %}
service: input_text.set_value
mode: single
Play Music Automation
Finally, this last automation is what sets off the actual music when I get home from work. It’s simply using HA zones and my iOS device to see when I enter the “home” zone. I have it time-conditioned, and conditioned for when my spouse is not already home, because they would probably not appreciate being blasted with my music if they’re home watching TV or just generally minding their own business.
Blueprint URL:
https://github.com/davearneson/blueprints/blob/main/alexa_music_group_play_music_when_arriving.yaml
blueprint:
name: Alexa Music Group - Play Music When Entering Zone
description: |
You must set up the Alexa Media Player custom component, a new input_text entity (I used HA helpers), and actionable notifications in your configuration.yaml for this to work.
Choose from the following options for a person to trigger music playing by entering a zone. Conditioned by time.
domain: automation
input:
which_group:
name: Which Group to Send Music
description: What is the Alexa Multi-Room Group you want to use? ex - everywhere (You must define this group in the Alexa app.)
selector:
text:
default: everywhere
time_start:
name: Start Time for Condition
description: What time do you want the automation window to start?
selector:
time:
default: '12:00:00'
time_stop:
name: Stop Time for Condition
description: What time do you want the automation window to stop?
selector:
time:
default: '21:30:00'
person_entity:
name: Person
description: Who is triggering the music by entering a zone?
selector:
entity:
domain: person
zone_entity:
name: Zone
description: What zone do you want to use?
selector:
entity:
domain: zone
text_input_entity:
name: Text Input Helper You Created
description: The HA Helper text input entity you created for your actionable notification.
selector:
entity:
domain: input_text
which_echo:
name: Amazon Echo Device
description: The device to which you will be sending the simulated voice command.
selector:
entity:
domain: media_player
trigger:
platform: zone
entity_id: !input person_entity
zone: !input zone_entity
event: enter
condition:
condition: time
after: !input time_start
before: !input time_stop
variables:
which_group: !input which_group
text_input_entity: !input text_input_entity
action:
service: media_player.play_media
data_template:
entity_id: !input which_echo
media_content_id: "play {{ states(text_input_entity) }} on the {{ which_group }} group"
media_content_type: custom
Click to see my automation yaml.
# automations.yaml
- alias: Arriving Home Play Music
description: ''
trigger:
- platform: zone
entity_id: person.me
zone: zone.home
event: enter
condition:
- condition: time
after: '12:00:00'
before: '21:30:00'
- condition: not
conditions:
- condition: state
entity_id: person.spouse
state: home
action:
- service: media_player.play_media
data_template:
entity_id: media_player.echo_link
media_content_id: play {{ states('input_text.arriving_home_music') }} on
the downstairs group
media_content_type: custom
Scripts
I also created one script for use in this project. This is an (overkill) fail-safe to make sure all music and audio stops if I want it to stop. I made this as a script so I could control it through automations and manual input buttons in the UI.
##############################################################################
#################Script to stop all audio on all groups#######################
##############################################################################
stop_alexa_music:
alias: Stop Music on Alexa Devices
sequence:
- service: media_player.play_media
data:
entity_id: media_player.echo_link
media_content_id: stop music on everywhere group
media_content_type: custom
- service: media_player.play_media
data:
entity_id: media_player.echo_link
media_content_id: stop music on front of house group
media_content_type: custom
- service: media_player.play_media
data:
entity_id: media_player.echo_link
media_content_id: stop music on downstairs group
media_content_type: custom
- service: media_player.play_media
data:
entity_id: media_player.echo_link
media_content_id: stop music on upstairs group
media_content_type: custom
- service: media_player.play_media
data:
entity_id: media_player.echo_link
media_content_id: stop music on master bedroom group
media_content_type: custom
- service: media_player.play_media
data:
entity_id: media_player.echo_link
media_content_id: stop music
media_content_type: custom
This button is just sending “stop music” commands to all possible groups.
Final Thoughts
I went back and forth on whether I wanted to create another automation to reset the music choice each day, or if I wanted to be able to leave it on a selection for as long as I feel like it. For now, I’m sticking with letting the previous day’s choice hold over until I decide to change it. I’ve had this set up for about a week so far, and overall, I’m really happy with the setup.
**EDIT
The phrases Alexa accepts via text input appear to be a bit of a moving target, at least in my experience. Apple radio is currently not working, but if I play around with the syntax, I’ve been able to get most things working reasonably well. For example, if the phrase, “Play Kate Bush on Apple Music on the Everywhere Group” is sent via this method, in my case, it tries to play an audio book. If I change the syntax to, “Play music by Kate Bush on Apple Music on the Everywhere Group,” it works correctly. However, if I say “Play the Beatles on Apple Music,” it works just fine. You just have to play around with it… Playing a playlist works, but shuffle is extremely unreliable - however shuffle is also unreliable if you request via voice as well.
Frustratingly, these syntax issues seem to be independent of the way actual speech is processed by Alexa. (If I speak the phrase, it works as intended.)