There are similar reports on GitHub, and the reason is “Voice is not currently supported in the core integration”. However, the good news is that it seems some developers are willing to write a blueprint for this.
I guess my biggest beef is that the Music Assistant page specifically states it works and gives instructions that take you no where apparently.
But that’s Open Source for ya! lol It’ll get worked out soon I’m sure. Soon is relative of course and depends on if anybody working on Music Assistant actually uses voice to control it.
As can be read above, it does work if you add the required snippets for the intent and the intent script on your own. Reading the bug report on github it probably is already sufficient to add the intent script only, but one would have to check that.
That said, I too would prefer a implementation by MA or HA, though.
What currently does not work, or let’s say I have not found out how to do it, is to use GPT for using more relaxed commands.
Just adding my two cents to this. I spent awhile trying @morkator’s approach of defining a `MassPlayMediaAssist script in an intent_script block, but couldn’t get it to work right. I have multiple media players in Mass, so I needed the Intent to pass in the player name, and that just wasn’t working reliably (as an aside, it seems the {name} placeholder in an Intent is “special”, so I’ve got some learning to do there). I finally decided to remove the Mass Integration and install the HACS Mass integration, and that resolved everything. The “play” commands now all work as expected. I didn’t notice until afterwards that the Voice Commands documentation in the Mass docs specifically says it’ll only work with HACS
One caveat with the HACS integration is that all of the players got different entity IDs, so if you swap back and forth, you’ll have to redo your automations and such
I decided to dig into the HACS Mass integration source code to see why it works, and I can see that the HACS integration registers an Intent handler for both the MassPlayMediaAssist and the MassPlayMediaOnMediaPlayer events. The latter one is the one used with OpenAI integration to get more natural requests to work. The handler even handles the call to OpenAI itself - you just configure your OpenAI details directly in the HACS integration config.
I’ll be sticking with the HACS integration until the core integration can handle the voice intents. Implementing it with intent_scripts doesn’t seem to offer the same funtionality.
I was going to temporarily switch back to the HACS integration but it no longer seems to appear in the HACS list and the GitHub repo has been archived.
You’re right - looks like it was archived just a few hours ago. That sucks. I checked the HASS core code and the changes weren’t integrated into HASS (yet, anyway). Perhaps it would work to add the HACS Mass integration as a Custom Repository in HACS? The URL is GitHub - music-assistant/hass-music-assistant: (deprecated) custom integration for Music Assistant. I haven’t tried - I’m not going to touch my config now that they’ve removed the integration!
Already tried that and no joy. It looks like there is a reasonable amount of activity in the core repositories however so hopefully there’s an imminent update coming.
For reference, here’s my current intent_script
with player support. Note that I’ve added my Voice PE as a default, so if I just want to output on the PE, I don’t need to state on which entity to play - you might want to update that or remove it, but then you always have to state an entity to play on when asking it to play something.
intent_script:
MassPlayMediaAssist:
action:
- choose:
# Case 1: Only track
- conditions:
- condition: template
value_template: >
{{ track is defined and track != '' and
(artist is not defined or artist == '') }}
sequence:
- service: music_assistant.play_media
target:
entity_id: "{{ entity | default('media_player.home_assistant_voice_091d31_media_player_2') }}"
data:
enqueue: replace
media_id: "{{ track }}"
media_type: track
radio_mode: false # "{{ radio_mode | default(false) }}"
# Case 2: Only artist
- conditions:
- condition: template
value_template: >
{{ artist is defined and artist != '' and
(track is not defined or track == '') }}
sequence:
- service: music_assistant.play_media
target:
entity_id: "{{ entity | default('media_player.home_assistant_voice_091d31_media_player_2') }}"
data:
enqueue: replace
media_id: "{{ artist }}"
media_type: artist
radio_mode: false # "{{ radio_mode | default(false) }}"
# Case 3: Track and artist
- conditions:
- condition: template
value_template: >
{{ track is defined and track != '' and
artist is defined and artist != '' }}
sequence:
- service: music_assistant.play_media
target:
entity_id: "{{ entity | default('media_player.home_assistant_voice_091d31_media_player_2') }}"
data:
enqueue: replace
media_id: "{{ track }} - {{ artist }}"
media_type: track
radio_mode: false # "{{ radio_mode | default(false) }}"
# Case 4: Radio
- conditions:
- condition: template
value_template: >
{{ radio is defined and radio != '' }}
sequence:
- service: music_assistant.play_media
target:
entity_id: "{{ entity | default('media_player.home_assistant_voice_091d31_media_player_2') }}"
data:
enqueue: replace
media_id: "{{ radio }}"
media_type: radio
radio_mode: false # "{{ radio_mode | default(false) }}"
Did you have to alter the MassPlayMediaAssist
block in the intent
file to get entity
? The intent file uses name
, but if you use name
in the intent_script, you get the unresolved name - i.e if an alias was used in the voice command, you don’t get the resolved entity_id back. I tried using a list
in/out
block to convert the player name to an entity ID, but that didn’t seem to work for name
- I guess name
is “special”? When I renamed it to player
, that worked in the debugger, but then the intent stopped matching altogether. It was at that point that I gave up and installed the HACS integration.
Ah yes, sorry. I’ve used what @rolo did write above and added aliases to the intent
file:
language: "de"
intents:
MassPlayMediaAssist:
data:
# CONTEXT AWARNESS
- sentences:
- "<play> <radio_station> {radio} [<on> (dem|den|der) {entity}] [(im) {radio_mode}]"
- "<play> <track> {track} [ von {artist}] [<on> (dem|den|der) {entity}] [(im) {radio_mode}]"
- "<play> <artist> {artist} [<on> (dem|den|der) {entity}] [(im) {radio_mode}]"
expansion_rules:
play: "(spiel|spiele)"
artist: "[etwas ][(von|vom) ][(der|dem)] [(artist|künstler|band|gruppe)]"
track: "[(das|den) ](track|song|lied|titel)"
album: "[(der|die|das) ](album|ep|platte|sammlung|single)"
playlist: "[der ]playlist"
radio_station: "[((den)|(das)|(die)) ]((radio sender)|(radio)|(sender))"
radio_mode: "(radiomodus|radio modus)"
"on": "(auf|mit)"
# requires_context:
# area:
# slot: true
lists:
artist:
wildcard: true
album:
wildcard: true
track:
wildcard: true
playlist:
wildcard: true
radio:
wildcard: true
query:
wildcard: true
radio_mode:
values:
- "Radiomodus"
- "Radio modus"
entity:
values:
- in: "voice"
out: "media_player.home_assistant_voice_091d31_media_player_2"
- in: "voice assistant"
out: "media_player.home_assistant_voice_091d31_media_player_2"
- in: "boxen"
out: "media_player.s10_2"
- in: "stereoanlage"
out: "media_player.s10_2"
- in: "surroundsystem"
out: "media_player.s10_2"
skip_words:
- "bitte"
- "kannst du"
So I can say something like Play radio XY on surroundsystem
, which will stream to my S10.
Edit: Also, feel free to post what you have and I can have a look what might be wrong.
Another edit:
Since MA didn’t have an intent_script to the intent file (probably because it’s not needed in the HACS implementation), I don’t know what magic it does to resolve the {{name}}
to an actual entity
.
In rolo’s and my intent
, we do a match in lists
to match a “human readable name” like “Speakers” to an actual entity, which is then passed to the intent_script
instead.
In this case the placeholder in the sentences in the intent file was changed to {{entity}}
, but if you want to keep {{name}}
, you can just edit the lists:
and change entity:
to name:
. Note that if you do that, you also need to change that in the intent_script.
If “name” somehow is special, I can’t tell. But there are some specials for sure, like I noticed if you don’t escape "on"
in the expansion_rules, it won’t work. *shrugs*
I think {name}
must be special, because I couldn’t get it to translate using the lists
method.
Here’s how I think it works: The intent engine always tries to resolve a target from the request. The target can be an entity, or an area, in which case all entities in the area are the target. If a target is identified, then the result of the intent are sent to the entity to be processed, assuming the entity has registered an intent handler. Because the entity is getting the event, it doesn’t need to know what entity was picked - it’s obviously itself. I am deducing this from the fact that when I played with Developer->Assist, it was able to resolve a target entity ID as long as I used {name} in the intent, but when I changed the variable to {player}, target
was then empty and matched==false
The HACS Mass integration registers an intent handler, so as long as {name} resolves to a HACS entity, the request is handled.
When I changed {name} to {player} and put a translation in my lists
block as you did, the Developer->Assist then returned the correct value in the player
variable, but matched==false, so the intent_script never even got called.
I definitely have a lot to learn here - I want to get volume and source selection working too, and those currently aren’t for me, but the Play stuff is working using HACS, so I’m going to leave that alone until the developers get that support baked into the core code.
Hi @rolo , @morkator ,
would you be so kind to post your complete sentences and intent script?
Cheers, mel
@mel you can find mine in the posts above.
Intent
Intent Script
Response
End of this Post
Here you can also see the paths / files where I’ve put the snippets into
Cheers
@morkator what version of Home Assistant are you running? I’ve been trying to follow your instructions and I’m stuck at testing the music_asssistant_PlayMediaOnMediaPlay.yaml file in the Sentences Parser. When I type in a prompt and hit “Parse Sentences” nothing happens.
I’m running
HassOS 14.1
Core version 2025.1.0
Supervisor 2024.12.3
I’m using the same versions on a default installation on my Raspi4 and the HA MusicAssistant Integration.
What do you mean by “nothing happens”? Isn’t the (correct) intent being picked up or does nothing happen at all - which would be strange.
Which sentence are you testing and which sentence pattern from the intent is it supposed to match? Maybe there’s something wrong with the sentence pattern, just a guess without knowing any details yet.
Ok, got that part figured out. I realized that it was the whole voice pipeline that went down after I tried to put in the the custom sentence file. Everything, including the parse sentence page started working as soon as I removed it. I must have the configuration wrong. I was just trying the simplest intent that you had showed first just to get it working. Can you help to see what I did wrong?
language: "en"
intents:
MassPlayMediaAssist:
data:
- sentences:
- "<play> <track> {track}"
expansion_rules:
play: "((play)|(listen to))"
track: "[the ](track|song)"
lists:
track:
wildcard: true
The file was placed in ./custom_sentences/en/music_assistant_PlayMediaOnMediaPlayer.yaml
So it turns out trying to keep things simple apparently made things more complicated. I found the MA intent repository on gitbub and tried their code with a few adjustments and with @rolo 's intent script and I got it working!
Has anything changed with this in 2025.1.0?
@taylorb831 glad you have solved it. sorry for not replying, I have to figure out how to get mail notifications, I don’t watch the subscribed threads all day, so I missed your question.
As for the very simple script, I’ve used that to have a working base to build upon.
@HarvsG No, nothing has changed as far as I know.
Music Assistant core integration was updated and music_assistant.play_media now works with voice intents.
Still having the same problems with complex sentences like “Play cold cold ground by Tom Waits”. Getting voice to recognize the end of the track name and the beginning of the artist name is a problem.