Skip to content

Instantly share code, notes, and snippets.

@jazzyisj
Last active December 1, 2024 15:33
Show Gist options
  • Save jazzyisj/c53c92779785bb5d9952adf3a3a28107 to your computer and use it in GitHub Desktop.
Save jazzyisj/c53c92779785bb5d9952adf3a3a28107 to your computer and use it in GitHub Desktop.
Music Assistant Play Media Package
##################################################################################################################
# MASS Play Media Package
# Launch Music Assistant Library Media from HASS dashboard & automations
#
# Download this package file to your packages folder (https://www.home-assistant.io/docs/configuration/packages/)
# or copy and paste in appropriate the areas in your configuration.yaml file.
#
# #TODO: List all your MASS media players
##################################################################################################################
input_boolean:
mass_shuffle:
name: "Shuffle"
icon: mdi:shuffle
mass_repeat:
name: "Repeat"
icon: mdi:repeat
mass_radio:
name: "Radio Mode"
icon: mdi:radio
input_select:
mass_enqueue_mode:
name: "Enqueue Mode"
options:
- play
- replace
- next
- replace_next
- add
mass_media_type:
name: "Media Type"
options:
- Artist
- Album
- Track
- Playlist
- Radio
mass_repeat_mode:
name: &repeat_name "Repeat Mode"
icon: &repeat_icon mdi:repeat
options:
- "Off"
- All
- One
input_text:
mass_media_player:
mass_artist:
mass_album:
mass_track:
mass_playlist:
mass_radio:
mass_artist_filter:
mass_album_filter:
input_number:
mass_volume:
name: "Volume"
icon: mdi:volume-high
unit_of_measurement: "%"
mode: slider
min: 0
max: 100
step: 5
template:
###############################################################################
## Update Media Button - used to force update of media select templates
###############################################################################
- button:
- name: "MASS Update Media"
unique_id: mass_udpate_media
icon: mdi:multimedia
press: []
###############################################################################
## Play Media Button - used to start media play with selected options
###############################################################################
- button:
- name: "MASS Play Media"
unique_id: mass_play_media
icon: mdi:play-box
press:
# get the entity id for the selected media player
- variables:
media_player: >
{{ expand('group.mass_players')
| selectattr('name', 'eq', states('select.mass_media_player'))
| map(attribute='entity_id') | join }}
# shuffle / repeat / enqueue not available in radio mode so don't set them
- if: "{{ is_state('input_boolean.mass_radio','off') }}"
then:
# set shuffle parameter using boolean value
- action: media_player.shuffle_set
target:
entity_id: "{{ media_player }}"
data:
shuffle: "{{ is_state('input_boolean.mass_shuffle', 'on') }}"
continue_on_error: true
# set repeat parameter using boolean value
- action: media_player.repeat_set
target:
entity_id: "{{ media_player }}"
data:
repeat: "{{ states('input_select.mass_repeat_mode') | lower }}"
continue_on_error: true
# set media player volume to zero to try and avoid google power on bloop
# you can delete this service call if you are not using Google Cast media players
- action: media_player.volume_set
target:
entity_id: "{{ media_player }}"
data:
volume_level: 0
continue_on_error: true
# play selected media type and set enqueue mode
- action: mass.play_media
target:
entity_id: "{{ media_player }}"
data:
media_id: "{{ states('select.mass_' ~ states('input_select.mass_media_type') | lower) }}"
media_type: "{{ states('input_select.mass_media_type') | lower }}"
artist: "{{ states('select.mass_artist_filter') }}"
album: "{{ states('select.mass_album_filter') }}"
enqueue: "{{ states('input_select.mass_enqueue_mode') | lower }}"
radio_mode: "{{ is_state('input_boolean.mass_radio', 'on') }}"
continue_on_error: true
# wait for media player to start playing
- wait_template: "{{ is_state(media_player, 'playing') }}"
timeout: 60
# set media player to selected volume, done after mass.play_media
# to avoid google bloops when media players turn on
- action: media_player.volume_set
target:
entity_id: "{{ media_player }}"
data:
volume_level: "{{ states('input_number.mass_volume') | float(-1) / 100 }}"
continue_on_error: true
###############################################################################
## Player
###############################################################################
- trigger:
- trigger: homeassistant
event: start
- trigger: event
event_type: event_template_reloaded
- trigger: state
entity_id: group.mass_players
attribute: entity_id
to:
- trigger: state
entity_id: input_text.mass_media_player
to:
select:
- name: "MASS Media Player"
unique_id: mass_media_player
state: "{{ states('input_text.mass_media_player') }}"
select_option:
- condition: template
value_template: "{{ option not in ['', none] }}"
- action: input_text.set_value
target:
entity_id: input_text.mass_media_player
data:
value: "{{ option }}"
options: >
{{ expand('group.mass_players')
| map(attribute='name') | list | sort }}
###############################################################################
## Artist
###############################################################################
- trigger:
- trigger: homeassistant
event: start
- trigger: event
event_type: event_template_reloaded
- trigger: state
entity_id:
- input_text.mass_artist
- button.mass_update_media
to:
- trigger: time_pattern
minutes: 30 # sync with library every hour at 30 min after
action:
- action: mass.get_library
data:
limit: 500
album_artists_only: true
media_type: artist
order_by: sort_name
response_variable: mass_artists
- variables:
artists: >
{% set artist_list = namespace(names=[]) %}
{% for artist in mass_artists['artists'] %}
{% set artist_list.names = artist_list.names + [artist.name] %}
{% endfor %}
{{ artist_list.names | unique | list }}
select:
- name: "MASS Artist"
unique_id: mass_artist
state: "{{ states('input_text.mass_artist') }}"
select_option:
- condition: template
value_template: "{{ option not in ['', none] }}"
- action: input_text.set_value
target:
entity_id: input_text.mass_artist
data:
value: "{{ option }}"
options: "{{ artists }}"
###############################################################################
## Album
###############################################################################
- trigger:
- trigger: homeassistant
event: start
- trigger: event
event_type: event_template_reloaded
- trigger: state
entity_id:
- input_text.mass_album
- button.mass_update_media
to:
- trigger: time_pattern
minutes: 30 # sync with library every hour at 30 min after
action:
- action: mass.get_library
data:
limit: 500
media_type: album
order_by: sort_name
album_type:
- album
- single
- compilation
- ep
- unknown
response_variable: mass_albums
- variables:
albums: >
{% set album_list = namespace(names=[]) %}
{% for album in mass_albums['albums'] %}
{% set album_list.names = album_list.names + [album.name] %}
{% endfor %}
{{ album_list.names | unique | list }}
select:
- name: "MASS Album"
unique_id: mass_album
state: "{{ states('input_text.mass_album') }}"
select_option:
- condition: template
value_template: "{{ option not in ['', none] }}"
- action: input_text.set_value
target:
entity_id: input_text.mass_album
data:
value: "{{ option }}"
options: "{{ albums }}"
###############################################################################
## Track
###############################################################################
- trigger:
- trigger: homeassistant
event: start
- trigger: event
event_type: event_template_reloaded
- trigger: state
entity_id:
- input_text.mass_track
- button.mass_update_media
to:
- trigger: time_pattern
minutes: 30 # sync with library every hour at 30 min after
action:
- action: mass.get_library
data:
limit: 500
media_type: track
order_by: sort_name
response_variable: mass_tracks
- variables:
tracks: >
{% set track_list = namespace(names=[]) %}
{% for track in mass_tracks['tracks'] %}
{% set track_list.names = track_list.names + [track.name] %}
{% endfor %}
{{ track_list.names | unique | list }}
select:
- name: "MASS Track"
unique_id: mass_track
state: "{{ states('input_text.mass_track') }}"
select_option:
- condition: template
value_template: "{{ option not in ['', none] }}"
- action: input_text.set_value
target:
entity_id: input_text.mass_track
data:
value: "{{ option }}"
options: "{{ tracks }}"
###############################################################################
## Playlist
###############################################################################
- trigger:
- trigger: homeassistant
event: start
- trigger: event
event_type: event_template_reloaded
- trigger: state
entity_id:
- input_text.mass_playlist
- button.mass_update_media
to:
- trigger: time_pattern
minutes: 30 # sync with library every hour at 30 min after
action:
- action: mass.get_library
data:
limit: 500
media_type: playlist
order_by: sort_name
response_variable: mass_playlists
- variables:
playlists: >
{% set playlist_list = namespace(names=[]) %}
{% for playlist in mass_playlists['playlists'] %}
{% set playlist_list.names = playlist_list.names + [playlist.name] %}
{% endfor %}
{{ playlist_list.names | unique | list }}
select:
- name: "MASS Playlist"
unique_id: mass_playlist
state: "{{ states('input_text.mass_playlist') }}"
select_option:
- condition: template
value_template: "{{ option not in ['', none] }}"
- action: input_text.set_value
target:
entity_id: input_text.mass_playlist
data:
value: "{{ option }}"
options: "{{ playlists }}"
###############################################################################
## Radio Station
###############################################################################
- trigger:
- trigger: homeassistant
event: start
- trigger: event
event_type: event_template_reloaded
- trigger: state
entity_id:
- input_text.mass_radio
- button.mass_update_media
to:
- trigger: time_pattern
minutes: 30 # sync with library every hour at 30 min after
action:
- action: mass.get_library
data:
limit: 500
media_type: radio
order_by: sort_name
response_variable: mass_radios
- variables:
radios: >
{% set radio_list = namespace(names=[]) %}
{% for radio in mass_radios['radios'] %}
{% set radio_list.names = radio_list.names + [radio.name] %}
{% endfor %}
{{ radio_list.names | unique | list }}
select:
- name: "MASS Radio"
unique_id: mass_radio
state: "{{ states('input_text.mass_radio') }}"
select_option:
- condition: template
value_template: "{{ option not in ['', none] }}"
- action: input_text.set_value
target:
entity_id: input_text.mass_radio
data:
value: "{{ option }}"
options: "{{ radios }}"
###############################################################################
## Artist Filter
###############################################################################
- trigger:
- trigger: homeassistant
event: start
- trigger: event
event_type: event_template_reloaded
- trigger: state
entity_id:
- input_select.mass_media_type
- input_text.mass_artist_filter
- select.mass_track
- select.mass_album
- select.mass_album_filter
- button.mass_update_media
to:
not_from:
- unknown
- unavailable
action:
- action: mass.get_library
data:
media_type: track
response_variable: mass_tracks
- action: mass.get_library
data:
media_type: album
response_variable: mass_albums
- variables:
artists: >
{% set artist_list = namespace(names=['']) %}
{% if states('input_select.mass_media_type') == 'Track' %}
{% for track in mass_tracks['tracks'] %}
{% if track.name == states('select.mass_track')
and states('select.mass_album_filter')
in ['', 'unknown', track.album.name] %}
{% set artist_list.names = artist_list.names + [track.artists[0].name] %}
{% endif %}
{% endfor %}
{% elif states('input_select.mass_media_type') == 'Album' %}
{% for album in mass_albums['albums'] %}
{% if album.name == states('select.mass_album') %}
{% set artist_list.names = artist_list.names + [album.artists[0].name] %}
{% endif %}
{% endfor %}
{% endif %}
{{ artist_list.names | unique | list }}
select:
- name: "MASS Artist Filter"
unique_id: mass_artist_filter
state: "{{ states('input_text.mass_artist_filter') }}"
select_option:
- condition: template
value_template: "{{ option not in ['', none] }}"
- action: input_text.set_value
target:
entity_id: input_text.mass_artist_filter
data:
value: "{{ option }}"
options: "{{ artists }}"
###############################################################################
## Album Filter
###############################################################################
- trigger:
- trigger: homeassistant
event: start
- trigger: event
event_type: event_template_reloaded
- trigger: state
entity_id:
- input_select.mass_media_type
- input_text.mass_album_filter
- select.mass_track
- select.mass_artist_filter
- button.mass_update_media
to:
not_from:
- unknown
- unavailable
action:
- action: mass.get_library
data:
media_type: track
response_variable: mass_tracks
- variables:
albums: >
{% set album_list = namespace(names=['']) %}
{% if states('input_select.mass_media_type') == 'Track' %}
{% for track in mass_tracks['tracks'] %}
{% if track.name == states('select.mass_track')
and states('select.mass_artist_filter')
in ['', 'unknown', track.artists[0].name] %}
{% set album_list.names = album_list.names + [track.album.name] %}
{% endif %}
{% endfor %}
{% endif %}
{{ album_list.names | unique | list }}
select:
- name: "MASS Album Filter"
unique_id: mass_album_filter
state: "{{ states('input_text.mass_album_filter') }}"
select_option:
- condition: template
value_template: "{{ option not in ['', none] }}"
- action: input_text.set_value
target:
entity_id: input_text.mass_album_filter
data:
value: "{{ option }}"
options: "{{ albums }}"
automation:
###############################################################################
## Update Mass Media Player Group
##
## This automation automatically creates a group of all the Music Assistant
## media players available in Home Assistant.
##
## Listed media players are removed from the group if they become unavailable
## and are automatically readded to the group when them become available again.
###############################################################################
- id: mass_update_media_players
alias: "Update Mass Media Players"
description: "Update mass media player group."
mode: single
max_exceeded: silent
triggers:
- trigger: homeassistant
event: start
- trigger: event
event_type: call_service
event_data:
domain: group
service: reload
#TODO list all of your Music Assistant media player entities here
- trigger: state
entity_id: &media_players
- media_player.living_room_speaker_2
- media_player.dining_room_hub_2
- media_player.bedroom_hub_2
- media_player.bathroom_speaker_2
- media_player.laundry_room_speaker_2
- media_player.office_hub_2
to:
- unknown
- unavailable
- trigger: state
entity_id: *media_players
from:
- unknown
- unavailable
actions:
# wait for music assistant to load
- wait_template: >
{{ states.media_player
| selectattr('attributes.mass_player_type', 'defined')
| map(attribute='entity_id') | list
| select('has_value') | list | count > 0 }}
timeout: 300
continue_on_timeout: false
- action: group.set
data:
object_id: mass_players
entities: >
{{ states.media_player
| selectattr('attributes.mass_player_type', 'defined')
| map(attribute='entity_id') | list
| select('has_value') | sort }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment