Mqtt error - coroutine 'get_test' was never awaited

I got a very simple test set up to be able to start programming…

from rhasspyhermes.nlu import NluIntent
from rhasspyhermes_app import EndSession, HermesApp

app = HermesApp(“HomeApp”)

@app.on_intent(“getTest”)
async def get_test(intent: NluIntent):
print(intent)
return EndSession(‘ja ich kann testen’)

app.run()

when running this script and calling the intent test I get the error

/home/pi/.local/lib/python3.7/site-packages/rhasspyhermes_app/init.py:149: RuntimeWarning: coroutine ‘get_test’ was never awaited

I frist though I used the wrong intent name or I used but if I change the intent name nothing happens so I guess that isnt the problem
this is my intent

[getTest]
kannst du testen?

I presume this is something small… who knows what I do wrong?

Is this version 1.0.0? I can’t reproduce this with the example app time_app.py, which is almost the same code.

Thanks for replying Koan!
version 1.0.0 of what? Yeah I took the code from the time_app.py and just changed the intent thats all
I use rhasspy 2.5.2 set up in a Virtual Environment without docker, last updated at 21th of july

Version 1.0.0 of rhasspy-hermes-app I mean.

YES! thanks Koan!! I was using the version 0.2.0 this of course didnt work at all, now it does… awesome!

Yes I already suspected this because 1.0.0 was the first one that required async. Have fun with testing your app and feel free to ask your further questions here on the forum.

1 Like

Yes I have another question, again this is presumably because being not very experienced with python (and presumably in reading a manual)

I have several intents some with 1 slots some with up to 3 slots
The intent PlayMusic has one slot named artist

@app.on_intent(“PlayMusic”)
async def play_music(intent: NluIntent):

the intent give me the following response:
NluIntent(input=‘spiele musik von Bob Marley’, intent=Intent(intent_name=‘PlayMusic’, confidence_score=1.0), site_id=‘default’, id=None, slots=[Slot(entity=‘artists’, value={‘kind’: ‘Unknown’, ‘value’: ‘Bob Marley’}, slot_name=‘artist’, raw_value=‘bob marley’, confidence=1.0, range=SlotRange(start=17, end=27, raw_start=17, raw_end=27))], session_id=‘default-hey-mycroft-2-53c25d70-c593-482a-b395-c94b2630c61f’, custom_data=None, asr_tokens=[[AsrToken(value=‘spiele’, confidence=1.0, range_start=0, range_end=6, time=None), AsrToken(value=‘musik’, confidence=1.0, range_start=7, range_end=12, time=None), AsrToken(value=‘von’, confidence=1.0, range_start=13, range_end=16, time=None), AsrToken(value=‘Bob’, confidence=1.0, range_start=17, range_end=20, time=None), AsrToken(value=‘Marley’, confidence=1.0, range_start=21, range_end=27, time=None)]], asr_confidence=None, raw_input=‘spiele musik von bob marley’, wakeword_id=‘hey-mycroft-2’, lang=None)

intent.intent.intent_name gives me => PlayMusic
intent.slots[0] => Slot(entity=‘artists’, value={‘kind’: ‘Unknown’, ‘value’: ‘Bob Marley’}, slot_name=‘artist’, raw_value=‘bob marley’, confidence=1.0, range=SlotRange(start=17, end=27, raw_start=17, raw_end=27))

intent.slots[0].value => {‘kind’: ‘Unknown’, ‘value’: ‘Bob Marley’}

intent.slots[0].value.value => ERROR AttributeError: ‘dict’ object has no attribute ‘value’

how do I get my slot value?
it would be great to just have to use: intent.slot.artists

but then I also have another intent Timer which can have up to 4 slots… here an example:

NluIntent(input=‘Nudel Timer 1 Stunde und 30 Minute und 20 Sekunden’, intent=Intent(intent_name=‘Timer’, confidence_score=1.0), site_id=‘default’, id=None, slots=[Slot(entity=‘timerType’, value={‘kind’: ‘Unknown’, ‘value’: ‘Nudel’}, slot_name=‘timerType’, raw_value=‘nudel’, confidence=1.0, range=SlotRange(start=0, end=5, raw_start=0, raw_end=5)), Slot(entity=‘rhasspy/number’, value={‘kind’: ‘Number’, ‘value’: 1}, slot_name=‘duration’, raw_value=‘eins’, confidence=1.0, range=SlotRange(start=12, end=13, raw_start=12, raw_end=16)), Slot(entity=‘durationUnit’, value={‘kind’: ‘Unknown’, ‘value’: ‘Stunde’}, slot_name=‘durationUnit’, raw_value=‘stunde’, confidence=1.0, range=SlotRange(start=14, end=20, raw_start=17, raw_end=23)), Slot(entity=‘rhasspy/number’, value={‘kind’: ‘Number’, ‘value’: 30}, slot_name=‘duration’, raw_value=‘dreißig’, confidence=1.0, range=SlotRange(start=25, end=27, raw_start=28, raw_end=35)), Slot(entity=‘durationUnit’, value={‘kind’: ‘Unknown’, ‘value’: ‘Minute’}, slot_name=‘durationUnit’, raw_value=‘minute’, confidence=1.0, range=SlotRange(start=28, end=34, raw_start=36, raw_end=42)), Slot(entity=‘rhasspy/number’, value={‘kind’: ‘Number’, ‘value’: 20}, slot_name=‘duration’, raw_value=‘zwanzig’, confidence=1.0, range=SlotRange(start=39, end=41, raw_start=47, raw_end=54)), Slot(entity=‘durationUnit’, value={‘kind’: ‘Unknown’, ‘value’: ‘Sekunden’}, slot_name=‘durationUnit’, raw_value=‘sekunden’, confidence=1.0, range=SlotRange(start=42, end=50, raw_start=55, raw_end=63))], session_id=‘default-hey-mycroft-2-e8857988-fc2e-4662-ac8c-b563ba11c614’, custom_data=None, asr_tokens=[[AsrToken(value=‘Nudel’, confidence=1.0, range_start=0, range_end=5, time=None), AsrToken(value=‘Timer’, confidence=1.0, range_start=6, range_end=11, time=None), AsrToken(value=‘1’, confidence=1.0, range_start=12, range_end=13, time=None), AsrToken(value=‘Stunde’, confidence=1.0, range_start=14, range_end=20, time=None), AsrToken(value=‘und’, confidence=1.0, range_start=21, range_end=24, time=None), AsrToken(value=‘30’, confidence=1.0, range_start=25, range_end=27, time=None), AsrToken(value=‘Minute’, confidence=1.0, range_start=28, range_end=34, time=None), AsrToken(value=‘und’, confidence=1.0, range_start=35, range_end=38, time=None), AsrToken(value=‘20’, confidence=1.0, range_start=39, range_end=41, time=None), AsrToken(value=‘Sekunden’, confidence=1.0, range_start=42, range_end=50, time=None)]], asr_confidence=None, raw_input=‘nudel timer eins stunde und dreißig minute und zwanzig sekunden’, wakeword_id=‘hey-mycroft-2’, lang=None)

I presume these are questions for dummies, would be great if you can help me out :slight_smile:

Thanks!

Yes, I’m still figuring out what the best way is to make it easier to access slot values.

Have a look here for one approach:

Can one use that? or is this just an idea?

I did had the slot value reading working before I started to use the rhasspy-hermes-app but now it doesnt work anymore… .
before I read the mqqt message like this:

intent = json.loads(msg.payload)
and for the MusicPlayer which has one slot this did work:
intent_message = intent[“slots”][0][“value”][“value”]

and for the timer intent I used

slotAmount = len(intent[“slots”])
for i in range(startAtIndex, slotAmount, 2):
if intent[“slots”][i + 1][‘slotName’] == ‘durationUnit’:
durationUnit = intent[“slots”][i + 1][“value”][“value”]
if durationUnit == LANGUAGE[‘timer’][‘durationUnit’][‘days’] or durationUnit == LANGUAGE[‘timer’][‘durationUnit’][‘day’] or durationUnit == LANGUAGE[‘timer’][‘durationUnit’][‘days2’]:
duration[“days”] = intent[“slots”][i][“value”][“value”]
if durationUnit == LANGUAGE[‘timer’][‘durationUnit’][‘hours’] or durationUnit == LANGUAGE[‘timer’][‘durationUnit’][‘hour’]:
duration[“hours”] = intent[“slots”][i][“value”][“value”]
if durationUnit == LANGUAGE[‘timer’][‘durationUnit’][‘minute’] or durationUnit == LANGUAGE[‘timer’][‘durationUnit’][‘minutes’]:
duration[“minutes”] = intent[“slots”][i][“value”][“value”]
if durationUnit == LANGUAGE[‘timer’][‘durationUnit’][‘seconds’] or durationUnit == LANGUAGE[‘timer’][‘durationUnit’][‘second’]:
duration[“seconds”] = intent[“slots”][i][“value”][“value”]

of couse this is not all ideal too but it worked… So if there isnt a solution I presume I should leave it the way it was

The code in the issue linked above should be ready to use.

It looks like the code you show is meant to be used on raw MQTT messages. If you want, you can do the same with Rhasspy Hermes App if you don’t use the on_intent decorator but on_topic. Have a look at the sample app for this decorator here:

However, I prefer on_intent, as it is less low-level.

Thanks for your Help Koen! It doesnt work for me somehow… .I get no payload nor data when I replace
“hermes/hotword/{hotword}/detected”

with my
“hermes/intent/PlayMusic” intent
nor when I add “hermes/intent/+”, or “hermes/intent/#”, or just even “#” or “+”
I am going to quit for today and hope you will have an easier solution for the slots some days

thank you very much for your help!

if you want to subscribe to an intent, the easier way is to just use the intent decorator

@app.on_intent("PlayMusic")

@No_one Yes I know, but as written here in this post I was not able with my pyhton knowledge to exctrect the slot data from the mqqt respone. If you can give me some help there I would presumable be able to use the on_intent decorant . I quoted 2 different intent response here one for the playMusic intent and one for the timer intent…

Have you tried the code from the GitHub issue I referred to above? Just add this function to your code:

def extract_slot_value(intent: NluIntent, slot_name: str, default=None):
    """extracts the value of a slot"""

    slot = next(filter(lambda slot: slot.slot_name == slot_name, intent.slots), None)
    if slot:
        if slot.value["kind"] != "Unknown":
            return slot.value.get("value", default)
    return default

Then use it in the intent handler function like this:

minutes = extract_slot_value(intent, "minutes", 0)
seconds = extract_slot_value(intent, "seconds", 0)

This of course if you have slots “minutes” and “seconds” defined in the intent.

@koan yes but like I wrote I got no response at all when I used

@app.on_topic(

and tried with a zillion different intent names

No, this code should be used with the on_intent decorator.

I prefer on_intent myself because it abstracts away the MQTT messages and the JSON content.

Can you try this first? Using on_topic is not my first choice because it’s more cumbersome to use and debug.

@koan this is the code:

def extract_slot_value(intent: NluIntent, slot_name: str, default=None):
    """extracts the value of a slot"""
    slot = next(filter(lambda slot: slot.slot_name == slot_name, intent.slots), None)
    if slot:
        if slot.value["kind"] != "Unknown":
            return slot.value.get("value", default)
    return default


@app.on_intent("PlayMusic")
async def play_music(intent: NluIntent):
    print('data', intent)
    test = extract_slot_value(intent, 'artist','')
    print('1')
    print(test)
    artists = extract_slot_value(intent, 'artist','')
    print('2')
    print(artists)
    return EndSession('jo')

and this result:

data NluIntent(input='spiele musik von Nancy Sinatra', intent=Intent(intent_name='PlayMusic', confidence_score=1.0), site_id='default', id=None, slots=[Slot(entity='artists', value={'kind': 'Unknown', 'value': 'Nancy Sinatra'}, slot_name='artist', raw_value='nancy sinatra', confidence=1.0, range=SlotRange(start=17, end=30, raw_start=17, raw_end=30))], session_id='default-hey-mycroft-2-b9adc4e9-6b3c-4a5f-a0ac-6aff8dde6a2e', custom_data=None, asr_tokens=[[AsrToken(value='spiele', confidence=1.0, range_start=0, range_end=6, time=None), AsrToken(value='musik', confidence=1.0, range_start=7, range_end=12, time=None), AsrToken(value='von', confidence=1.0, range_start=13, range_end=16, time=None), AsrToken(value='Nancy', confidence=1.0, range_start=17, range_end=22, time=None), AsrToken(value='Sinatra', confidence=1.0, range_start=23, range_end=30, time=None)]], asr_confidence=None, raw_input='spiele musik von nancy sinatra', wakeword_id='hey-mycroft-2', lang=None)
1

2

slot artist seems empty

Can you show us your sentences and slots?

well that does work… the intent does arrive in the correct way, and I do have the script working in my own way but not yet in the rhasspy rhasspy-hermes-app way, so I can help out with making skills for Rhasspy… you can check my own baby pyhton written working code here:


(there you can find some slots and sentences)

my goal is of course to be able to add train rhasspy when I for example add new songs and extend the artist slot… but that has nothing to do with my question which is I guess basicly, how to get the slots value of the incoming NluIntent?

this is what I get from rhasspy when invoking the StartMusic intent

[DEBUG:2020-08-18 20:57:50,775] rhasspyserver_hermes: <- NluIntent(input='spiele musik von Mozart', intent=Intent(intent_name='PlayMusic', confidence_score=1.0), site_id='default', id=None, slots=[Slot(entity='artists', value={'kind': 'Unknown', 'value': 'Mozart'}, slot_name='artist', raw_value='mozart', confidence=1.0, range=SlotRange(start=17, end=23, raw_start=17, raw_end=23))], session_id='default-hey-mycroft-2-5c937c24-91bb-475e-a838-247dbffaa1c5', custom_data=None, asr_tokens=[[AsrToken(value='spiele', confidence=1.0, range_start=0, range_end=6, time=None), AsrToken(value='musik', confidence=1.0, range_start=7, range_end=12, time=None), AsrToken(value='von', confidence=1.0, range_start=13, range_end=16, time=None), AsrToken(value='Mozart', confidence=1.0, range_start=17, range_end=23, time=None)]], asr_confidence=None, raw_input='spiele musik von mozart', wakeword_id='hey-mycroft-2', lang=None)

Your sentences look right but you need to say a name which is in your slots. Mozart isn’t at the moment. So maybe try: “Spiele Musik von Abba” And check again :wink: