Specifying substitutions on slot lists

Say I have some movies defined in a slot list, like so:

{"movies": ["kill bill 1", "kill bill 2"]}

I’d like the spoken text that’s matched to be different than the value that’s eventually passed along to Kodi via HASS. As an example, I’d like to be able to say the words “kill bill 1” and have that converted to the text “Kill Bill - Vol 1” (or in an extreme case, have my spoken text converted to some integer ID value)

It seems that substitutions can generally accomplish what I’m trying to do, but I can’t figure out a way to use substitutions on an item by item level in a slot list. I’ve tried a bunch of variations that look like the below without any success:

{"movies": ["(kill bill 1):(Kill Bill - Vol 1)", "(kill bill 2):(Kill Bill - Vol 2"]}

Is this possible, or something not currently supported?

I think this is what you are going for in your slots:

(kill bill 1):Kill Bill - Vol 1

The only thing that I am not sure of are the spaces on your final results. I use this approach for lighting:

(upstairs hallway):light.upstairs_hallway

See I have no spaces, so not sure how things will get handled, may need quotes or something. Check out this page for reference:


1 Like

Appears spaces were in fact my issue, thanks!

I’m curious as to what characters are/aren’t allowed in a substitution like that (and if there’s anyway to escape those characters). Interestingly enough, Alien³ with that stylized 3 had no issues.

I wish I had the answer for that, I think you are going to have to try several different things like this:

(kill bill 1):“Kill Bill - Vol 1”
(kill bill 1):‘Kill Bill - Vol 1’
(kill bill 1):Kill\ Bill\ -\ Vol\ 1

Maybe one of those will work, Good Luck.

This works for me:

In sentences.ini

play ($movies){movie}

In slots/movies

(kill bill 1):(Kill Bill - Vol 1)
(kill bill 2):(Kill Bill - Vol 2)

When I say “play kill bill one”, it outputs (abbreviated):

    "intent": {
        "confidence": 1,
        "name": "PlayMovie"
    "raw_text": "play kill bill one",
    "slots": {
        "movie": "Kill Bill - Vol 1"
    "text": "play Kill Bill - Vol 1"

Damn, that is the one syntax that I left off, cause I figured there is no way that one would work : )

1 Like

Hm, this exact syntax was actually the first thing I tried. Was questioning my sanity until trying again just now:

Just updated to 2.4.20 and have the same result. Trying to simplify things to reproduce the error with as few variables in play as possible:

Current sentences:

play ($videos){video_name}

Current slots:

    "videos": [
        "(kill bill one):(Kill Bill - Vol 1)"

Resulting log:

INFO:__main__:Starting training
DEBUG:DialogueManager:asleep -> training_sentences
[2020-07-16 08:39:50,564] GET /api/unknown-words 1.1 200 2 2591
INFO:quart.serving: GET /api/unknown-words 1.1 200 2 2591
DEBUG:train:Parsing ini file(s): ['/profiles/en/sentences.ini']
DEBUG:rhasspynlu.ini_jsgf:Loaded ini file
Traceback (most recent call last):
  File "/usr/share/rhasspy/.venv/lib/python3.7/site-packages/doit/doit_cmd.py", line 177, in run
    return command.parse_execute(args)
  File "/usr/share/rhasspy/.venv/lib/python3.7/site-packages/doit/cmd_base.py", line 127, in parse_execute
    return self.execute(params, args)
  File "/usr/share/rhasspy/.venv/lib/python3.7/site-packages/doit/cmd_base.py", line 389, in execute
    self, params, args)
  File "/usr/share/rhasspy/.venv/lib/python3.7/site-packages/doit/cmd_base.py", line 270, in load_tasks
    return self._load_from(cmd, self.mod_dict, self.cmd_names)
  File "/usr/share/rhasspy/.venv/lib/python3.7/site-packages/doit/cmd_base.py", line 254, in _load_from
    task_list = loader.load_tasks(members, cmd_list, cmd.execute_tasks)
  File "/usr/share/rhasspy/.venv/lib/python3.7/site-packages/doit/loader.py", line 147, in load_tasks
  File "/usr/share/rhasspy/.venv/lib/python3.7/site-packages/doit/loader.py", line 138, in _process_gen
    task_list.extend(generate_tasks(name, ref(), ref.__doc__))
  File "/usr/share/rhasspy/rhasspy/train/__init__.py", line 390, in task_ini_graph
    sentence = jsgf.Sentence.parse(line)
  File "/usr/share/rhasspy/.venv/lib/python3.7/site-packages/rhasspynlu/jsgf.py", line 97, in parse
    parse_expression(s, text)
  File "/usr/share/rhasspy/.venv/lib/python3.7/site-packages/rhasspynlu/jsgf.py", line 279, in parse_expression
    None, text[current_index + 1 :], end=[" "] + end, is_literal=False
  File "/usr/share/rhasspy/.venv/lib/python3.7/site-packages/rhasspynlu/jsgf.py", line 342, in parse_expression
    assert last_group is not None
DEBUG:DialogueManager:training_sentences -> ready
INFO:DialogueManager:Automatically listening for wake word
DEBUG:DialogueManager:ready -> asleep
DEBUG:InboxActor: -> stopped
ERROR:__main__:Training failed:
Traceback (most recent call last):
  File "/usr/share/rhasspy/.venv/lib/python3.7/site-packages/quart/app.py", line 1471, in full_dispatch_request
    result = await self.dispatch_request(request_context)
  File "/usr/share/rhasspy/.venv/lib/python3.7/site-packages/quart/app.py", line 1519, in dispatch_request
    return await handler(**request_.view_args)
  File "app.py", line 640, in api_train
    raise Exception(f"Training failed: {result.reason}")
Exception: Training failed:
[2020-07-16 08:39:50,577] POST /api/train 1.1 500 17 22037
INFO:quart.serving: POST /api/train 1.1 500 17 22037
DEBUG:InboxActor: -> stopped
[2020-07-16 08:39:50,648] GET /api/problems 1.1 200 293 3295
INFO:quart.serving: GET /api/problems 1.1 200 293 3295

When I remove the parenthesis and spaces, everything works as expected. Removing just parenthesis gets rid of the error (but obviously has different meaning and doesn’t accomplish the intended outcome). Removing just the spaces still gets me a training error.

Appreciate the responses, if there’s any other info I can provide to help let me know.

Maybe not a direct answer to your problem, but have you considered migrating to Rhasspy 2.5? Development has moved on to the new version.

1 Like

I agree with @koan, time to pack up and move on to 2.5 @synesthesiam has done an amazing job.

1 Like

Somehow I managed to miss the move to the new docker hub location for 2.5.

Just updated and that seemed to do the trick. Thanks for all the help!