Custom Sentences not loaded or missing

I’m trying to make HA load my YAML file with the following custom sentences:

language: "en"
intents:
  PlayRadio:
    data:
      - sentences:
          - "Play {radio_station} on {media_player}"
          - "Start {radio_station} on {media_player}"
          - "Turn on {radio_station} on {media_player}"
        slots:
          radio_station:
            type: list
            values:
              NRK P1: "7b1266f2-da4f-47a9-9f50-d689a8d64d3f"
              NRK P2: "e17c1cd7-12a1-40b1-a12a-6d8bcf7dc6d8"
              NRK P3: "f3aefc9d-35e1-41aa-bf3f-88d55ff1b21a"
          media_player:
            type: list
            values:
              Ema speaker: "media_player.ema_speaker"
              Nabu speaker: "media_player.home_assistant_voice_094fea_media_player"
              Solarium speaker: "media_player.solarium_speaker"

The file path is /homeassistant/custom_sentences/en/radio_sentences.yaml
But all my attempts to make this work always result in the following error in the log:

hassil.errors.MissingListError: Missing slot list

I haven’t found any clear documentation on the correct syntax for such custom sentence YAML files, so there could be as simple as incorrect syntax or indents, but I’ve tried everything possible that I could think of. I’ve also tried asking AI, but they just hallucinate wildly.
Please help.

Oh, one last question; Is it really necessary to restart Home Assistant every time I make a change to the custom sentence YAML file? Or is it sufficient to reload all yaml configuration ?

Yes, I believe you are structuring your slots wrong, based on the documentation.

I don’t fully understand the documentation, but it appears that slots are defined separately from their lists, and should use an “in/out” syntax to convert something like “NRK P1” into the value you want.

This section in particular has an example you might find instructive.

Excellent! Thank you so much :+1:
I rewrote the YAML file to this:

language: "en"

intents:
  PlayRadio:
    data:
      - sentences:
          - "Play {radio_station} on {media_player}"
          - "Start {radio_station} on {media_player}"
          - "Turn on {radio_station} on {media_player}"

lists:
  radio_station:
    values:
      - in: "Metro"
        out: "7b1266f2-da4f-47a9-9f50-d689a8d64d3f"
      - in: "NRK P2"
        out: "e17c1cd7-12a1-40b1-a12a-6d8bcf7dc6d8"
      - in: "NRK P3"
        out: "f3aefc9d-35e1-41aa-bf3f-88d55ff1b21a"

  media_player:
    values:
      - in: "Ema speaker"
        out: "media_player.ema_speaker"
      - in: "Nabu speaker"
        out: "media_player.home_assistant_voice_094fea_media_player"
      - in: "Solarium speaker"
        out: "media_player.solarium_speaker"

And now it works :blush:
The only part remaining now is Assist is giving the following reply when parsing the sentence Play Metro on Ema speaker

Playing 7b1266f2-da4f-47a9-9f50-d689a8d64d3f on media_player.ema_speaker

as a result of this YAML in the file /homeassistant/intent_script.yaml

speech:
    text: "Playing {{ radio_station }} on {{ media_player }}"

How can I instead make it say:

Playing Metro on Ema speaker

I use a response for that, then you can use the slots variable
https://github.com/TheFes/HA-configuration/blob/46295b71e0a982edc94dcc30388f2aa0c895a8dc/custom_sentences/nl/PlayMusic.yaml

Thanks, but I’m not sure I understand.
As it is now, it carries out the command and plays the music, but the action:

Speech:
   "Playing {{ slots.radio_station }} on {{ slots.media_player }}"

just results in the response “An unexpected error occurred”

I don’t have the speech output in the intent_script, but in the custom_sentences folder as a response.

This is my intent_script, as you can see there is no speech output there. The output is defined in the file I linked in my previous post.

Wow! That’s an overwhelming intent_script :no_mouth:
Here’s mine:

PlayRadio:
  action:
    - action: media_player.play_media
      target:
        entity_id: "{{ media_player }}"
      data:
        media_content_id: "media-source://radio_browser/{{ radio_station }}"
        media_content_type: "audio/mpeg"

  speech:
    text: "Playing {{ slots.radio_station }} on {{ slots.media_player }}"

If I replace the last line with something like

text: "Nice to see you again"

Then that’s exactly the response I get. But when using the text string shown in the file, I get the error message: An unexpected error occurred.

If I instead put:

  speech:
    text: "Playing {{ radio_station }} on {{ media_player }}"

Then the response is:

Playing  7b1266f2-da4f-47a9-9f50-d689a8d64d3f on media_player.ema_speaker

So obviously, my problem is that I need to figure out how to retrieve the spoken word. Now it uses the “out:” value and it seems to have completely forgotten the “in:” value.

The out value is the only thing the intent_script receives. Also the slot variable is not sent to the intent_script.
That’s why I use the response and not the speech option in the intent_script

I see. That makes sense.
But what would the correct syntax be in my case then?

change your custom_sentence file:

language: "en"
intents:
  PlayRadio:
    data:
      - sentences:
          - "Play {radio_station} on {media_player}"
          - "Start {radio_station} on {media_player}"
          - "Turn on {radio_station} on {media_player}"
        slots:
          radio_station:
            type: list
            values:
              NRK P1: "7b1266f2-da4f-47a9-9f50-d689a8d64d3f"
              NRK P2: "e17c1cd7-12a1-40b1-a12a-6d8bcf7dc6d8"
              NRK P3: "f3aefc9d-35e1-41aa-bf3f-88d55ff1b21a"
          media_player:
            type: list
            values:
              Ema speaker: "media_player.ema_speaker"
              Nabu speaker: "media_player.home_assistant_voice_094fea_media_player"
              Solarium speaker: "media_player.solarium_speaker"

# HERE THE RESPONSE IS ADDED
responses:
  intents:
    PlayRadio:
      default: "Playing {{ slots.radio_station }} on {{ slots.media_player }}"

Remove the speech part from the intent script.

If I use this custom sentence file, the response becomes correct:

language: "en"

intents:
  PlayRadio:
    data:
      - sentences:
          - "Play {radio_station} on {media_player}"
          - "Start {radio_station} on {media_player}"
          - "Turn on {radio_station} on {media_player}"

lists:
  radio_station:
    values:
      - in: "Metro"
        out: "7b1266f2-da4f-47a9-9f50-d689a8d64d3f"
      - in: "NRK P2"
        out: "e17c1cd7-12a1-40b1-a12a-6d8bcf7dc6d8"
      - in: "NRK P3"
        out: "f3aefc9d-35e1-41aa-bf3f-88d55ff1b21a"

  media_player:
    values:
      - in: "Ema speaker"
        out: "media_player.ema_speaker"
      - in: "Nabu speaker"
        out: "media_player.home_assistant_voice_094fea_media_player"
      - in: "Solarium speaker"
        out: "media_player.solarium_speaker"
        
responses:
  intents:
    PlayRadio:
      default: "Playing {{ slots.radio_station }} on {{ slots.media_player }}"

But only if I write the command sentence to Assist using my keyboard.
If I try to speak the command, the intent script seems to be completely missed or ignored.

Check in the voice debug what the Speech To Text thought you were saying, probably it isn’t converting you spoken command to the expected text.

Solved it by rewriting the intent script to:

PlayRadio:
  action:
    - action: media_player.play_media
      data:
        entity_id: "{{ media_player }}"
        media_content_id: "media-source://radio_browser/{{ radio_station }}"
        media_content_type: "audio/mpeg"

Still, I wouldn’t have made it without your help. Thank you so very much for everything :blush::+1:

@TheFes
I’ve made it much furter, and so far everything work perfectly in both English and Norwegian (my language) :+1:

But now I wanted to make the intent_script fall back to a default media_player if none is specified in the parsed sentence.
That seems much more difficult than i had anticipated.

My very simple but working intent_script is this:

PlayRadio:
  action:
    - action: media_player.play_media
      data:
        entity_id: "{{ media_player }}"
        media_content_id: "media-source://radio_browser/{{ radio_station }}"
        media_content_type: "audio/mpeg"

If I modify the entity_id like this:

entity_id: {% if media_player is defined and media_player %}
             {{ media_player }}
           {% else %}
              media_player.ema_speaker
           {% endif %}

Then the script throws the following error:

Unexpected error during intent recognition

I have spent hours trying to figure out the correct syntax, but to no avail.
Do you have any ideas to keep me going?

You didn’t wrap the template in quotes, although I would advice to use the multi line character

entity_id: >
  {% if media_player is defined and media_player %}
    {{ media_player }}
  {% else %}
     media_player.ema_speaker
  {% endif %}

Note that you also need to change your custom sentence, as it currently only allows your pre-defined players

Wrap in quotes (?) - do you mean like this:

entity_id: >
  {% if media_player is defined and media_player %}
    "{{ media_player }}"
  {% else %}
     "media_player.ema_speaker"
  {% endif %}

No, what I provided was already correct

You need to wrap it in quotes if you use the single line notation

# single line notation, quotes required 
value_template: "{{ some template }}"

# mult line notation (using >), no quotes required
value_template: >
  {{ some template }}

This is because you can also use JSON in YAML, and the { is used in JSON to start a mapping/dictionary.
So without the quotes it will error because it thinks it’s a malformed mapping/dictionary

Ok, I’ll try - but what do I changed the custom sentence to?
I tried adding

- in: ""
  out: "media_player.ema_speaker"

and I tried:

- in: 
  out: "media_player.ema_speaker"

But the error remains the same: Unexpected error during intent recognition

You need to make the media player part optional.

language: "en"

intents:
  PlayRadio:
    data:
      - sentences:
          - "Play {radio_station}[ on {media_player}]"
          - "Start {radio_station}[ on {media_player}]"
          - "Turn on {radio_station}[ on {media_player}]"

lists:
  radio_station:
    values:
      - in: "Metro"
        out: "7b1266f2-da4f-47a9-9f50-d689a8d64d3f"
      - in: "NRK P2"
        out: "e17c1cd7-12a1-40b1-a12a-6d8bcf7dc6d8"
      - in: "NRK P3"
        out: "f3aefc9d-35e1-41aa-bf3f-88d55ff1b21a"

  media_player:
    values:
      - in: "Ema speaker"
        out: "media_player.ema_speaker"
      - in: "Nabu speaker"
        out: "media_player.home_assistant_voice_094fea_media_player"
      - in: "Solarium speaker"
        out: "media_player.solarium_speaker"
        
responses:
  intents:
    PlayRadio:
      default: "Playing {{ slots.radio_station }} {{ on ~ slots.media_player if slots.media_player is defined }}"

I made the media player part optional by adding [ and ] and check on it in the response.

In the intent script you can use

entity_id: "{{ media_player | default('media_player.ema_speaker') }}"

Yes sir! That worked together with this intent_script:


PlayRadio:
  action:
    - action: media_player.play_media
      data:
        entity_id: "{{ media_player if media_player is defined else 'media_player.ema_speaker' }}"
        media_content_id: "media-source://radio_browser/{{ radio_station }}"
        media_content_type: "audio/mpeg"