iOS Actionable Notification/Automatically Playing Music on Alexa Group When I Get Home

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:

https://github.com/davearneson/blueprints/blob/main/alexa_music_group_send_actionable_notification.yaml

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:

https://github.com/davearneson/blueprints/blob/main/alexa_music_group_process_action_from_notification.yaml

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

Stop Music as a button in Lovelace
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.)

6 Likes

Edited today add some comments about phrase syntax.

Hi Dave,

Can you please give the actionable notification example you use. I’m getting the push notification but no text input and no choices coming up on screen and I’m not seeing a really well described actions notifications documentation for these either, although the actions notifications describe alarm interactions - I’m not finding that super useful.

Thank you,
Daniel

Daniel, I’m sorry I missed this. I have been wrapped up with school work and off of the forum for a few weeks.

Since I originally posted this, the home assistant app fundamentally changed how it handles actionable notifications. I assume you’ve looked at this: Actionable Notifications | Home Assistant Companion Docs

Basically, the actions are not in the configuration file anymore, but are directly in the automation - which is much easier. Here’s what my updated automation looks like:

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.me_work
action:
  - service: notify.mobile_app_my_iphone
    data:
      message: What do you want to hear today?
      title: Arriving Home Music
      data:
        actions:
          - action: INPUT_MUSIC
            title: Type what you'd like to hear
            behavior: textInput
            textInputButtonTitle: Submit
            textInputPlaceholder: Music
          - action: INDIE_MUSIC
            title: Indie Radio
          - action: RUSH_MUSIC
            title: Rush
          - action: KATE_BUSH_MUSIC
            title: Kate Bush
          - action: PAVEMENT_MUSIC
            title: Pavement and Steven Malkmus
          - action: BEATLES_MUSIC
            title: The Beatles
          - action: SOLO_BEATLES_MUSIC
            title: The Beatles Solo Music
          - action: GLASS_MUSIC
            title: Philip Glass
          - action: DEBUSSY_MUSIC
            title: Claude Debussy
          - action: MORE_MUSIC
            title: More Choices
mode: single

Hope that helps.

Hi Dave, I’m trying it now, unfortunately won’t be in the office until Thursday full day - hopefully I’ve got the syntax and structure passing all the new arguments correctly! Really appreciate your response to my questions! Thank you, Daniel

This is fantastic! I am quite new to all of this so this seems like a good little project for myself.