Hi all,
I have been working on a small control panel to easily select the music you would like.
Basically, the interface has two modes:
-
When no music is playing, a block gives the opportunity to select which music app you want to use (in my case, Plex, Web Radio, or Spotify) with for each a list of favorite playlists/Channels and on which room (Chromecast Speaker Groups).
-
When music is playing, a simple view of what’s playing, the opportunity to change sound level, stop or mute.
In this one, I had to “reproduce” a basic media player as custom button because media player cannot be dynamic. As I am neither an artist, nor a CSS pro, that “player” has visual room for improvement.
The challenge (fun) was to simply combine many options in an easy interface.
The add-ons/integration used in this project are:
- Custom button cards in the interface
- Spocast to launch spotify music on sleeping Google Home speakers
- The Plex Integration for local media
- The URL’s of web radio come from this site, but Google can help if you are looking for different ones
The full code has been centralized in one package:
###################################################################################################
# #
# Music Player - Configuration & Selection #
# #
###################################################################################################
###################################################################################################
# Music Player - Audio Selection
###################################################################################################
input_select:
audio_media_player_select:
name: Choix du media audio
options:
- Plex
- Spotify
- Webradio
initial: Plex
icon: mdi:music-box-multiple
audio_media_device_select:
name: Choix des hauts-parleurs
options:
- Cuisine
- Rez-de-chaussée
- Maison entière
initial: Cuisine
icon: mdi:cast-audio
plex_playlist_select:
name: Playlist Plex à jouer
options:
- All Music
- Cinéma & Télévision
- Dinner Classics
- Français
- International
- Madeleine & Lucien
- Musique Classique
- Noël
initial: All Music
icon: mdi:music
spotify_playlist_select:
name: Playlist Spotify à jouer
options:
- Hits Français
- Culture Tubes
- Noël Top 100
- La Vie est Belle
- Life Sucks
- Dinner with Friends
- Soft Pop
- Classical Movie Music
initial: La Vie est Belle
icon: mdi:spotify
webradio_select:
name: Choix Webradio
options:
- Joe FM
- La Première
- Nostalgie 80
- Nostalgie Cinéma
- Q-Music
- Q Foute Radio
- RTL 2
initial: Q-Music
icon: mdi:radio
###################################################################################################
# Music Player - Selected Audio Transformation
###################################################################################################
template:
- sensor:
- unique_id: "selected_plex_playlist_url"
icon: "mdi:music"
state: >-
{% if is_state("input_select.plex_playlist_select", "All Music") %} plex://{ "library_name": "Musique", "playlist_name": "All Music", "shuffle":"1" }
{% elif is_state("input_select.plex_playlist_select", "Cinéma & Télévision") %} plex://{ "library_name": "Musique", "playlist_name": "Cinéma & Télévision", "shuffle":"1" }
{% elif is_state("input_select.plex_playlist_select", "Dinner Classics") %} plex://{ "library_name": "Musique", "playlist_name": "Dinner Classics", "shuffle":"1" }
{% elif is_state("input_select.plex_playlist_select", "Français") %} plex://{ "library_name": "Musique", "playlist_name": "Français", "shuffle":"1" }
{% elif is_state("input_select.plex_playlist_select", "International") %} plex://{ "library_name": "Musique", "playlist_name": "International", "shuffle":"1" }
{% elif is_state("input_select.plex_playlist_select", "Madeleine & Lucien") %} plex://{ "library_name": "Musique", "playlist_name": "Madeleine & Lucien", "shuffle":"1" }
{% elif is_state("input_select.plex_playlist_select", "Musique Classique") %} plex://{ "library_name": "Musique", "playlist_name": "Musique Classique", "shuffle":"1" }
{% elif is_state("input_select.plex_playlist_select", "Noël") %} plex://{ "library_name": "Musique", "playlist_name": "Noël", "shuffle":"1" }
{% endif %}
attributes:
friendly_name: "URL Playlist Plex Choisie"
filter_key: "Music_Player"
- unique_id: "selected_webradio_url"
icon: "mdi:radio"
state: >-
{% if is_state("input_select.webradio_select", "Q-Music") %}
http://icecast-qmusic.cdp.triple-it.nl/Qmusic_be_live_128.mp3
{% elif is_state("input_select.webradio_select", "Joe FM") %}
http://icecast-qmusic.cdp.triple-it.nl/JOEfm_be_live_128.mp3
{% elif is_state("input_select.webradio_select", "Q Foute Radio") %} http://playerservices.streamtheworld.com/api/livestream-redirect/QFOUTERADIO.mp3
{% elif is_state("input_select.webradio_select", "RTL 2") %} http://streaming.radio.rtl2.fr/rtl2-1-44-128?listen=webCwsBCggNCQgLDQUGBAcGBg
{% elif is_state("input_select.webradio_select", "Nostalgie 80") %} http://cdn.nrjaudio.fm/adwz1/fr/30605/mp3_128.mp3?origine=fluxradios
{% elif is_state("input_select.webradio_select", "Nostalgie Cinéma") %}
http://streamingp.shoutcast.com/NostalgieCinema
{% elif is_state("input_select.webradio_select", "La Première") %}
http://radios.rtbf.be/laprem1erebxl-128.mp3
{% endif %}
picture: >-
{% if is_state("input_select.webradio_select", "Q-Music") %}
/local/radio-logo/qmusic.png
{% elif is_state("input_select.webradio_select", "Joe FM") %}
/local/radio-logo/joefm.png
{% elif is_state("input_select.webradio_select", "Q Foute Radio") %}
/local/radio-logo/qfout.png
{% elif is_state("input_select.webradio_select", "RTL 2") %}
/local/radio-logo/rtl2.png
{% elif is_state("input_select.webradio_select", "Nostalgie 80") %}
/local/radio-logo/nostalgie80.png
{% elif is_state("input_select.webradio_select", "Nostalgie Cinéma") %}
/local/radio-logo/nostalgie_cinema.png
{% elif is_state("input_select.webradio_select", "La Première") %}
/local/radio-logo/premiere.png
{% endif %}
attributes:
friendly_name: "URL Webradio Choisie"
filter_key: "Music_Player"
- unique_id: "selected_spotify_playlist_uri"
state: >-
{% if is_state("input_select.spotify_playlist_select", "Hits Français") %}
spotify:playlist:37i9dQZF1DXcSPhLAnCjoM
{% elif is_state("input_select.spotify_playlist_select", "Culture Tubes") %}
spotify:playlist:37i9dQZF1DXd0Y4aXXQXWv
{% elif is_state("input_select.spotify_playlist_select", "Noël Top 100") %}
spotify:playlist:2wlZ9OIdKnLrSLRqIpBPax
{% elif is_state("input_select.spotify_playlist_select", "Soft Pop") %}
spotify:playlist:37i9dQZF1DWTwnEm1IYyoj
{% elif is_state("input_select.spotify_playlist_select", "La Vie est Belle") %}
spotify:playlist:37i9dQZF1DXdrln2UyZD7F
{% elif is_state("input_select.spotify_playlist_select", "Life Sucks") %}
spotify:playlist:37i9dQZF1DX3YSRoSdA634
{% elif is_state("input_select.spotify_playlist_select", "Dinner with Friends") %}
spotify:playlist:37i9dQZF1DX4xuWVBs4FgJ
{% elif is_state("input_select.spotify_playlist_select", "Classical Movie Music") %}
spotify:playlist:1UdKFAMBjM3prK7hieeqjC
{% endif %}
icon: mdi:spotify
attributes:
friendly_name: "URI Playlist Spotify Choisie"
filter_key: "Music_Player"
- unique_id: "selected_audio_media_type"
state: >-
{% if is_state("input_select.audio_media_player_select", "Plex") %} PLAYLIST
{% elif is_state("input_select.audio_media_player_select", "Webradio") %} audio/mp4
{% elif is_state("input_select.audio_media_player_select", "Spotify") %} playlist
{% endif %}
attributes:
friendly_name: "Catégorie Media Choisi"
filter_key: "Music_Player"
- unique_id: "selected_audio_media_device"
icon: "mdi:cast-audio"
state: >-
{% if is_state("input_select.audio_media_device_select", "Cuisine") %} media_player.paire_cuisine
{% elif is_state("input_select.audio_media_device_select", "Rez-de-chaussée") %} media_player.rez_de_chaussee
{% elif is_state("input_select.audio_media_device_select", "Maison entière") %} media_player.maison
{% endif %}
attributes:
friendly_name: "Groupe de Hauts-Parleurs choisi"
filter_key: "Music_Player"
plexid: >-
{% if is_state("input_select.audio_media_device_select", "Cuisine") %} media_player.plex_chromecast_paire_cuisine
{% elif is_state("input_select.audio_media_device_select", "Rez-de-chaussée") %} media_player.plex_chromecast_rez_de_chaussee
{% elif is_state("input_select.audio_media_device_select", "Maison entière") %} media_player.plex_chromecast_maison
{% endif %}
- unique_id: "selected_audio_media_device_state"
icon: "mdi:cast-audio-variant"
state: >-
{{ states(states("sensor.selected_audio_media_device")) }}
attributes:
friendly_name: "Groupe de Hauts-Parleurs choisi - Etat"
filter_key: "Music_Player"
- unique_id: "selected_audio_media_device_muted"
icon: "mdi:volume-mute"
state: >-
{{ (state_attr(states('sensor.selected_audio_media_device'), 'is_volume_muted')) }}
attributes:
friendly_name: "Groupe de Hauts-Parleurs choisi - Mute/Unmute"
filter_key: "Music_Player"
- unique_id: "selected_audio_media_device_picture"
icon: "mdi:panorama-variant"
state: >-
{% if is_state('input_select.audio_media_player_select', 'Plex') %}
{{ (state_attr(state_attr('sensor.selected_audio_media_device', 'plexid'), 'entity_picture')) }}
{% elif is_state('input_select.audio_media_player_select', 'Webradio') %}
{{ (state_attr('sensor.selected_webradio_url', 'entity_picture')) }}
{% elif is_state('input_select.audio_media_player_select', 'Spotify') %}
{{ (state_attr(states('sensor.selected_audio_media_device'), 'entity_picture_local'))}}
{% endif %}
attributes:
friendly_name: "Groupe de Hauts-Parleurs choisi - Image"
filter_key: "Music_Player"
###################################################################################################
# Music Player - Sound Volume Management
###################################################################################################
- unique_id: "sound_volume_selected_audio_device"
state: >-
{% if is_state("input_select.audio_media_device_select", "Cuisine") %}
{{ (state_attr('media_player.paire_cuisine', 'volume_level') | float *100) |int }}
{% elif is_state("input_select.audio_media_device_select", "Rez-de-chaussée") %}
{{ (state_attr('media_player.rez_de_chaussee', 'volume_level') | float *100) |int }}
{% elif is_state("input_select.audio_media_device_select", "Maison entière") %}
{{ (state_attr('media_player.maison', 'volume_level') | float *100) |int }}
{% endif %}
icon: >-
{% if states("sensor.sound_volume_selected_audio_device")|float(0) >37 %} mdi:volume-high
{% elif states("sensor.sound_volume_selected_audio_device")|float(0) >17 %} mdi:volume-medium
{% elif states("sensor.sound_volume_selected_audio_device")|float(0) >0 %} mdi:volume-low
{% else %} mdi:speaker-off
{% endif %}
attributes:
friendly_name: "Groupe de Hauts-Parleurs choisi - Volume"
filter_key: "Music_Player"
###################################################################################################
# Music Player - Artist & Title Information Extract
###################################################################################################
- unique_id: "artist_playing"
state: >-
{% if is_state("input_select.audio_media_player_select", "Webradio") %}
{{ states("input_select.webradio_select") }}
{% else %}
{{ (state_attr(states('sensor.selected_audio_media_device'), 'media_artist')) }}
{% endif %}
icon: mdi:account-music
attributes:
friendly_name: "Interprète de la chanson en cours"
filter_key: "Music_Player"
- unique_id: "title_playing"
state: >-
{% if is_state("input_select.audio_media_player_select", "Webradio") %}
{{ states("input_select.webradio_select") }}
{% else %}
{{ (state_attr(states('sensor.selected_audio_media_device'), 'media_title')) }}
{% endif %}
icon: mdi:file-music
attributes:
friendly_name: "Titre de la chanson en cours"
filter_key: "Music_Player"
###################################################################################################
# Music Player - Scripts
###################################################################################################
script:
# Music Player - Scripts dynamiques
music_control_play_music:
alias: Musique Dynamique - Jouer de la musique
sequence:
- choose:
- conditions:
- condition: state
entity_id: input_select.audio_media_player_select
state: Spotify
sequence:
- service: spotcast.start
data:
random_song: true
shuffle: true
entity_id: >-
{{ states("sensor.selected_audio_media_device")}}
uri: '{{ (states(''sensor.selected_spotify_playlist_uri'')) }}'
account: quizmaster
default:
- service: media_player.play_media
data:
media_content_type: '{{ states("sensor.selected_audio_media_type")}}'
media_content_id: >-
{% if is_state("input_select.audio_media_player_select", "Plex") %}
{{ states("sensor.selected_plex_playlist_url") }}
{% elif is_state("input_select.audio_media_player_select", "Webradio") %}
{{ states("sensor.selected_webradio_url")}}
{% endif %}
target:
entity_id: '{{ states("sensor.selected_audio_media_device")}}'
mode: single
icon: mdi:folder-music-outline
music_control_stop_music:
alias: Musique Dynamique - Arrêter la musique
sequence:
- service: media_player.media_stop
target:
entity_id: '{{ states("sensor.selected_audio_media_device")}}'
mode: single
icon: mdi:volume-off
music_control_decrease_sound_level:
alias: Musique Dynamique - Augmenter le volume
sequence:
- service: media_player.volume_set
target:
entity_id: '{{ states("sensor.selected_audio_media_device") }}'
data:
volume_level: >-
{{ ((((states("sensor.sound_volume_selected_audio_device")|float(0))
/ 500)|round(2) * 5) - 0.05) |round(2) |float(0.05) }}
mode: single
icon: mdi:volume-minus
music_control_increase_sound_level:
alias: Musique Dynamique - Augmenter le volume
sequence:
- service: media_player.volume_set
target:
entity_id: '{{ states("sensor.selected_audio_media_device") }}'
data:
volume_level: >-
{{ ((((states("sensor.sound_volume_selected_audio_device")|float(0))
/ 500)|round(2) * 5) + 0.05) |round(2) |float(0.05) }}
mode: single
icon: mdi:volume-plus
music_control_mute_unmute_music:
alias: Musique Dynamique - Mute/Unmute Speakers
sequence:
- service: media_player.volume_mute
target:
entity_id: '{{ states("sensor.selected_audio_media_device")}}'
data:
is_volume_muted: >-
{% if is_state_attr(states("sensor.selected_audio_media_device"),'is_volume_muted', true) %}
false
{% else %}
true
{% endif %}
mode: single
icon: mdi:volume-off
music_control_next_track:
alias: Musique Dynamique - Morceau suivant si API le permets
sequence:
- service: media_player.media_next_track
target:
entity_id: '{{ states("sensor.selected_audio_media_device")}}'
mode: single
icon: mdi:skip-next
As you can see I have created some simple templates and scripts, to keep the conditional part in the lovelace interface reasonable. (see first reply for lovelace code)
Anyway, it’s there to inspire anyone who would like to make something similar.
Comments, suggestions for improvement, feedback welcome.