- spec: name: execute_services description: Use this function to execute service of devices in Home Assistant. parameters: type: object properties: list: type: array items: type: object properties: domain: type: string description: The domain of the service service: type: string description: The service to be called service_data: type: object description: The service data object to indicate what to control. properties: entity_id: type: string description: The entity_id retrieved from available devices. It must start with domain, followed by dot character. required: - entity_id required: - domain - service - service_data function: type: native name: execute_service # Spotify Music Control Functions - spec: name: search_spotify description: >- Search Spotify for an artist, album, track, or playlist and return the Spotify URI. Use this before playing music to get the URI. Use this whenever the user asks to play or queue a specific song, artist, album, or playlist — even if the name contains a number (e.g. "Back on 74", "1979", "Blink 182"). A number that is part of a song/artist/album name is NOT a volume level; only use control_playback's volume_set if the user explicitly says "volume" or "percent". parameters: type: object properties: query: type: string description: Artist, album, track, or playlist name to search for (e.g., "Coldplay", "Parachutes", "Yellow", "Today's Top Hits") type: type: string enum: [artist, album, track, playlist] description: Type of content to search for. Playlist searches check your personal playlists first, then fall back to public Spotify playlists. required: - query - type function: type: script sequence: - service: spotify_voice_assistant.search response_variable: _function_result data: query: "{{ query }}" type: "{{ type }}" - spec: name: play_music description: Play music immediately on a Spotify Connect device using a Spotify URI, replacing current playback. You must first call search_spotify to get the URI. Use this when user says "play". parameters: type: object properties: spotify_uri: type: string description: Spotify URI from search_spotify (e.g., "spotify:artist:4gzpq5DPGxSnKTe4SA8HAU") type: type: string enum: [artist, album, track, playlist] description: The exact "type" value returned by search_spotify for this URI. Required — passing the wrong value causes playback to silently fail. room: type: string description: Spotify Connect source/device name to play on, matching an entry in media_player.spotify_bhetherman's source_list exactly (e.g., "Living Room") required: - spotify_uri - type - room function: type: script sequence: - service: media_player.select_source target: entity_id: media_player.spotify_bhetherman data: source: "{{ room | replace('Living Room', 'd0166d6f83796b0f9059b0adf0f6cb0d81fa6376') | replace('Bedroom', 'a334c8ba989367b52303eaa9dbc424cdd83012b5') }}" - repeat: while: - condition: template value_template: >- {{ repeat.index <= 8 and ( state_attr('media_player.spotify_bhetherman', 'source') != (room | replace('Living Room', 'd0166d6f83796b0f9059b0adf0f6cb0d81fa6376') | replace('Bedroom', 'a334c8ba989367b52303eaa9dbc424cdd83012b5')) or (state_attr('media_player.spotify_bhetherman', 'supported_features') | int(0) | bitwise_and(512)) != 512 ) }} sequence: - delay: "00:00:01" - service: media_player.play_media target: entity_id: media_player.spotify_bhetherman data: media_content_id: "{{ spotify_uri }}" media_content_type: "{{ type }}" enqueue: replace - spec: name: queue_music description: >- Queue or play music using a Spotify URI from search_spotify. Use this whenever the user says "queue" or "add to queue" — always use this function for queue requests, regardless of whether the content is a track, album, artist, or playlist; the correct behavior for each type is handled automatically. (Individual tracks are added to the queue without interrupting playback; since Spotify cannot queue a whole album/artist/playlist, those start playing immediately instead.) parameters: type: object properties: spotify_uri: type: string description: Spotify URI from search_spotify (e.g., "spotify:track:4gzpq5DPGxSnKTe4SA8HAU") type: type: string enum: [artist, album, track, playlist] description: The exact "type" value returned by search_spotify for this URI. room: type: string description: Spotify Connect source/device name to queue on, matching an entry in media_player.spotify_bhetherman's source_list exactly (e.g., "Living Room") required: - spotify_uri - type - room function: type: script sequence: - service: media_player.select_source target: entity_id: media_player.spotify_bhetherman data: source: "{{ room | replace('Living Room', 'd0166d6f83796b0f9059b0adf0f6cb0d81fa6376') | replace('Bedroom', 'a334c8ba989367b52303eaa9dbc424cdd83012b5') }}" - repeat: while: - condition: template value_template: >- {{ repeat.index <= 8 and ( state_attr('media_player.spotify_bhetherman', 'source') != (room | replace('Living Room', 'd0166d6f83796b0f9059b0adf0f6cb0d81fa6376') | replace('Bedroom', 'a334c8ba989367b52303eaa9dbc424cdd83012b5')) or (state_attr('media_player.spotify_bhetherman', 'supported_features') | int(0) | bitwise_and(512)) != 512 ) }} sequence: - delay: "00:00:01" - service: media_player.play_media target: entity_id: media_player.spotify_bhetherman data: media_content_id: "{{ spotify_uri }}" media_content_type: "{{ type }}" enqueue: "{{ 'add' if type == 'track' else 'replace' }}" - spec: name: control_playback description: >- Control playback of music that is ALREADY PLAYING (pause, resume, stop, next track, previous track, set volume, shuffle) on the currently active Spotify Connect session. Only use volume_set when the user explicitly says the word "volume" or "percent" (e.g. "turn the volume up", "set volume to 50", "50 percent volume"). Do NOT use this function to play a requested song, artist, or album — a number in a song/artist/album name (e.g. "Back on 74", "Blink 182", "Sunset 2005") is part of the title, never a volume level. Use search_spotify + play_music for any request to play or start specific music, even if it contains a number. parameters: type: object properties: action: type: string enum: [pause, play, stop, next_track, previous_track, volume_set, shuffle_on, shuffle_off] description: Playback control action volume_level: type: number description: Volume level (0-100) for volume_set action only. Only set this when the user said the word "volume" or "percent". required: - action function: type: script sequence: - choose: - conditions: "{{ action == 'pause' }}" sequence: - service: media_player.media_pause target: entity_id: media_player.spotify_bhetherman - conditions: "{{ action == 'play' }}" sequence: - service: media_player.media_play target: entity_id: media_player.spotify_bhetherman - conditions: "{{ action == 'stop' }}" sequence: # media_player.spotify_bhetherman does not support the media_stop # service (STOP is not in its supported_features); Spotify Connect has # no separate stop concept, so route "stop" through pause instead. - service: media_player.media_pause target: entity_id: media_player.spotify_bhetherman - conditions: "{{ action == 'next_track' }}" sequence: - service: media_player.media_next_track target: entity_id: media_player.spotify_bhetherman - conditions: "{{ action == 'previous_track' }}" sequence: - service: media_player.media_previous_track target: entity_id: media_player.spotify_bhetherman - conditions: "{{ action == 'volume_set' }}" sequence: - service: media_player.volume_set target: entity_id: media_player.spotify_bhetherman data: volume_level: "{{ volume_level / 100 }}" - conditions: "{{ action == 'shuffle_on' }}" sequence: - service: media_player.shuffle_set target: entity_id: media_player.spotify_bhetherman data: shuffle: true - conditions: "{{ action == 'shuffle_off' }}" sequence: - service: media_player.shuffle_set target: entity_id: media_player.spotify_bhetherman data: shuffle: false